diff --git a/.idea/misc.xml b/.idea/misc.xml
index 788713e1..9a7274f1 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -3,20 +3,30 @@
diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/ServerAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/ServerAdapter.java
new file mode 100644
index 00000000..9bb73413
--- /dev/null
+++ b/app/src/main/java/com/cappielloantonio/play/adapter/ServerAdapter.java
@@ -0,0 +1,127 @@
+package com.cappielloantonio.play.adapter;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.fragment.app.FragmentManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.cappielloantonio.play.App;
+import com.cappielloantonio.play.R;
+import com.cappielloantonio.play.interfaces.SystemCallback;
+import com.cappielloantonio.play.model.Server;
+import com.cappielloantonio.play.model.Song;
+import com.cappielloantonio.play.repository.SystemRepository;
+import com.cappielloantonio.play.ui.activity.MainActivity;
+import com.cappielloantonio.play.util.PreferenceUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+public class ServerAdapter extends RecyclerView.Adapter {
+ private static final String TAG = "ServerAdapter";
+
+ private List servers;
+ private final LayoutInflater mInflater;
+ private MainActivity mainActivity;
+ private Context context;
+
+ public ServerAdapter(MainActivity mainActivity, Context context) {
+ this.mInflater = LayoutInflater.from(context);
+ this.servers = new ArrayList<>();
+ this.mainActivity = mainActivity;
+ this.context = context;
+ }
+
+ @Override
+ public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ View view = mInflater.inflate(R.layout.item_login_server, parent, false);
+ return new ViewHolder(view);
+ }
+
+ @Override
+ public void onBindViewHolder(ViewHolder holder, int position) {
+ Server server = servers.get(position);
+
+ holder.serverName.setText(server.getServerName());
+ holder.serverAddress.setText(server.getAddress());
+ }
+
+ @Override
+ public int getItemCount() {
+ return servers.size();
+ }
+
+ public List getItems() {
+ return this.servers;
+ }
+
+ public void setItems(List servers) {
+ this.servers = servers;
+ notifyDataSetChanged();
+ }
+
+ public Server getItem(int id) {
+ return servers.get(id);
+ }
+
+ public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
+ TextView serverName;
+ TextView serverAddress;
+
+ ViewHolder(View itemView) {
+ super(itemView);
+
+ serverName = itemView.findViewById(R.id.server_name_text_view);
+ serverAddress = itemView.findViewById(R.id.server_address_text_view);
+
+ itemView.setOnClickListener(this);
+
+ serverName.setSelected(true);
+ }
+
+ @Override
+ public void onClick(View view) {
+ Server server = servers.get(getBindingAdapterPosition());
+ saveServerPreference(server.getAddress(), server.getUsername(), server.getToken(), server.getSalt());
+
+ SystemRepository systemRepository = new SystemRepository(App.getInstance());
+ systemRepository.checkUserCredential(new SystemCallback() {
+ @Override
+ public void onError(Exception exception) {
+ Toast.makeText(context, exception.getMessage(), Toast.LENGTH_SHORT).show();
+ }
+
+ @Override
+ public void onSuccess(String token, String salt) {
+ saveServerPreference(null, null, token, salt);
+ enter();
+ }
+ });
+ }
+
+ private void enter() {
+ mainActivity.goFromLogin();
+ }
+
+ private void saveServerPreference(String server, String user, String token, String salt) {
+ if (user != null) PreferenceUtil.getInstance(context).setUser(user);
+ if (server != null) PreferenceUtil.getInstance(context).setServer(server);
+
+ if (token != null && salt != null) {
+ PreferenceUtil.getInstance(context).setToken(token);
+ PreferenceUtil.getInstance(context).setSalt(salt);
+ PreferenceUtil.getInstance(context).setServerId(servers.get(getBindingAdapterPosition()).getServerId());
+
+ return;
+ }
+
+ App.getSubsonicClientInstance(context, true);
+ }
+ }
+}
diff --git a/app/src/main/java/com/cappielloantonio/play/database/AppDatabase.java b/app/src/main/java/com/cappielloantonio/play/database/AppDatabase.java
index 1328525e..e50be026 100644
--- a/app/src/main/java/com/cappielloantonio/play/database/AppDatabase.java
+++ b/app/src/main/java/com/cappielloantonio/play/database/AppDatabase.java
@@ -9,11 +9,13 @@ import androidx.room.RoomDatabase;
import com.cappielloantonio.play.database.dao.DownloadDao;
import com.cappielloantonio.play.database.dao.QueueDao;
import com.cappielloantonio.play.database.dao.RecentSearchDao;
+import com.cappielloantonio.play.database.dao.ServerDao;
import com.cappielloantonio.play.model.Download;
import com.cappielloantonio.play.model.Queue;
import com.cappielloantonio.play.model.RecentSearch;
+import com.cappielloantonio.play.model.Server;
-@Database(entities = {Queue.class, RecentSearch.class, Download.class}, version = 5, exportSchema = false)
+@Database(entities = {Queue.class, Server.class, RecentSearch.class, Download.class}, version = 9, exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
private static final String TAG = "AppDatabase";
@@ -31,6 +33,8 @@ public abstract class AppDatabase extends RoomDatabase {
public abstract QueueDao queueDao();
+ public abstract ServerDao serverDao();
+
public abstract RecentSearchDao recentSearchDao();
public abstract DownloadDao downloadDao();
diff --git a/app/src/main/java/com/cappielloantonio/play/database/dao/DownloadDao.java b/app/src/main/java/com/cappielloantonio/play/database/dao/DownloadDao.java
index 47d2276b..5659a061 100644
--- a/app/src/main/java/com/cappielloantonio/play/database/dao/DownloadDao.java
+++ b/app/src/main/java/com/cappielloantonio/play/database/dao/DownloadDao.java
@@ -15,8 +15,8 @@ public interface DownloadDao {
@Query("SELECT * FROM download")
List getAll();
- @Query("SELECT * FROM download LIMIT :size")
- LiveData> getSample(int size);
+ @Query("SELECT * FROM download WHERE server=:server LIMIT :size")
+ LiveData> getSample(int size, String server);
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(Download download);
@@ -27,6 +27,6 @@ public interface DownloadDao {
@Query("DELETE FROM download WHERE id = :id")
void delete(String id);
- @Query("DELETE FROM download")
- void deleteAll();
+ @Query("DELETE FROM download WHERE server=:server")
+ void deleteAll(String server);
}
\ No newline at end of file
diff --git a/app/src/main/java/com/cappielloantonio/play/database/dao/QueueDao.java b/app/src/main/java/com/cappielloantonio/play/database/dao/QueueDao.java
index 7f2986f7..75da98b1 100644
--- a/app/src/main/java/com/cappielloantonio/play/database/dao/QueueDao.java
+++ b/app/src/main/java/com/cappielloantonio/play/database/dao/QueueDao.java
@@ -12,20 +12,20 @@ import java.util.List;
@Dao
public interface QueueDao {
- @Query("SELECT * FROM queue")
- LiveData> getAll();
+ @Query("SELECT * FROM queue WHERE server = :server")
+ LiveData> getAll(String server);
- @Query("SELECT * FROM queue")
- List getAllSimple();
+ @Query("SELECT * FROM queue WHERE server = :server")
+ List getAllSimple(String server);
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertAll(List songQueueObject);
- @Query("DELETE FROM queue WHERE queue.track_order = :position")
- void deleteByPosition(int position);
+ @Query("DELETE FROM queue WHERE queue.track_order = :position AND server = :server")
+ void deleteByPosition(int position, String server);
- @Query("DELETE FROM queue")
- void deleteAll();
+ @Query("DELETE FROM queue WHERE server = :server")
+ void deleteAll(String server);
@Query("SELECT COUNT(*) FROM queue;")
int count();
diff --git a/app/src/main/java/com/cappielloantonio/play/database/dao/RecentSearchDao.java b/app/src/main/java/com/cappielloantonio/play/database/dao/RecentSearchDao.java
index 34bf58c0..ca8dea58 100644
--- a/app/src/main/java/com/cappielloantonio/play/database/dao/RecentSearchDao.java
+++ b/app/src/main/java/com/cappielloantonio/play/database/dao/RecentSearchDao.java
@@ -20,7 +20,4 @@ public interface RecentSearchDao {
@Delete
void delete(RecentSearch search);
-
- @Query("DELETE FROM recent_search")
- void deleteAll();
}
\ No newline at end of file
diff --git a/app/src/main/java/com/cappielloantonio/play/database/dao/ServerDao.java b/app/src/main/java/com/cappielloantonio/play/database/dao/ServerDao.java
new file mode 100644
index 00000000..cff8d416
--- /dev/null
+++ b/app/src/main/java/com/cappielloantonio/play/database/dao/ServerDao.java
@@ -0,0 +1,25 @@
+package com.cappielloantonio.play.database.dao;
+
+import androidx.lifecycle.LiveData;
+import androidx.room.Dao;
+import androidx.room.Delete;
+import androidx.room.Insert;
+import androidx.room.OnConflictStrategy;
+import androidx.room.Query;
+
+import com.cappielloantonio.play.model.Queue;
+import com.cappielloantonio.play.model.Server;
+
+import java.util.List;
+
+@Dao
+public interface ServerDao {
+ @Query("SELECT * FROM server")
+ LiveData> getAll();
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ void insert(Server server);
+
+ @Delete
+ void delete(Server server);
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/cappielloantonio/play/model/Album.java b/app/src/main/java/com/cappielloantonio/play/model/Album.java
index 7b6323b5..0cd539ce 100644
--- a/app/src/main/java/com/cappielloantonio/play/model/Album.java
+++ b/app/src/main/java/com/cappielloantonio/play/model/Album.java
@@ -34,7 +34,7 @@ public class Album implements Parcelable {
public Album(AlbumID3 albumID3) {
this.id = albumID3.getId();
this.title = albumID3.getName();
- this.year = albumID3.getYear();
+ this.year = albumID3.getYear() != null ? albumID3.getYear() : 0;
this.artistId = albumID3.getArtistId();
this.artistName = albumID3.getArtist();
this.primary = albumID3.getCoverArtId();
@@ -44,7 +44,7 @@ public class Album implements Parcelable {
public Album(AlbumWithSongsID3 albumWithSongsID3) {
this.id = albumWithSongsID3.getId();
this.title = albumWithSongsID3.getName();
- this.year = albumWithSongsID3.getYear();
+ this.year = albumWithSongsID3.getYear() != null ? albumWithSongsID3.getYear() : 0;
this.artistId = albumWithSongsID3.getArtistId();
this.artistName = albumWithSongsID3.getArtist();
this.primary = albumWithSongsID3.getCoverArtId();
diff --git a/app/src/main/java/com/cappielloantonio/play/model/Download.java b/app/src/main/java/com/cappielloantonio/play/model/Download.java
index ad5523c0..de404e81 100644
--- a/app/src/main/java/com/cappielloantonio/play/model/Download.java
+++ b/app/src/main/java/com/cappielloantonio/play/model/Download.java
@@ -33,7 +33,10 @@ public class Download {
@ColumnInfo(name = "duration")
private long duration;
- public Download(String songID, String title, String albumId, String albumName, String artistId, String artistName, String primary, long duration) {
+ @ColumnInfo(name = "server")
+ private String server;
+
+ public Download(String songID, String title, String albumId, String albumName, String artistId, String artistName, String primary, long duration, String server) {
this.songID = songID;
this.title = title;
this.albumId = albumId;
@@ -42,6 +45,7 @@ public class Download {
this.artistName = artistName;
this.primary = primary;
this.duration = duration;
+ this.server = server;
}
public Download(Song song) {
@@ -118,4 +122,12 @@ public class Download {
public void setDuration(long duration) {
this.duration = duration;
}
+
+ public String getServer() {
+ return server;
+ }
+
+ public void setServer(String server) {
+ this.server = server;
+ }
}
diff --git a/app/src/main/java/com/cappielloantonio/play/model/Queue.java b/app/src/main/java/com/cappielloantonio/play/model/Queue.java
index 319d3e89..abe860c8 100644
--- a/app/src/main/java/com/cappielloantonio/play/model/Queue.java
+++ b/app/src/main/java/com/cappielloantonio/play/model/Queue.java
@@ -36,7 +36,10 @@ public class Queue {
@ColumnInfo(name = "duration")
private long duration;
- public Queue(int trackOrder, String songID, String title, String albumId, String albumName, String artistId, String artistName, String primary, long duration) {
+ @ColumnInfo(name = "server")
+ private String server;
+
+ public Queue(int trackOrder, String songID, String title, String albumId, String albumName, String artistId, String artistName, String primary, long duration, String server) {
this.trackOrder = trackOrder;
this.songID = songID;
this.title = title;
@@ -46,6 +49,7 @@ public class Queue {
this.artistName = artistName;
this.primary = primary;
this.duration = duration;
+ this.server = server;
}
public int getTrackOrder() {
@@ -119,4 +123,12 @@ public class Queue {
public void setDuration(long duration) {
this.duration = duration;
}
+
+ public String getServer() {
+ return server;
+ }
+
+ public void setServer(String server) {
+ this.server = server;
+ }
}
diff --git a/app/src/main/java/com/cappielloantonio/play/model/RecentSearch.java b/app/src/main/java/com/cappielloantonio/play/model/RecentSearch.java
index 372e2d7b..d59f96f4 100644
--- a/app/src/main/java/com/cappielloantonio/play/model/RecentSearch.java
+++ b/app/src/main/java/com/cappielloantonio/play/model/RecentSearch.java
@@ -12,7 +12,7 @@ public class RecentSearch {
@ColumnInfo(name = "search")
private String search;
- public RecentSearch(String search) {
+ public RecentSearch(@NonNull String search) {
this.search = search;
}
@@ -21,7 +21,7 @@ public class RecentSearch {
return search;
}
- public void setSearch(String search) {
+ public void setSearch(@NonNull String search) {
this.search = search;
}
}
diff --git a/app/src/main/java/com/cappielloantonio/play/model/Server.java b/app/src/main/java/com/cappielloantonio/play/model/Server.java
new file mode 100644
index 00000000..6dce85cd
--- /dev/null
+++ b/app/src/main/java/com/cappielloantonio/play/model/Server.java
@@ -0,0 +1,99 @@
+package com.cappielloantonio.play.model;
+
+import androidx.annotation.NonNull;
+import androidx.room.ColumnInfo;
+import androidx.room.Entity;
+import androidx.room.PrimaryKey;
+
+@Entity(tableName = "server")
+public class Server {
+ @NonNull
+ @PrimaryKey
+ @ColumnInfo(name = "id")
+ private String serverId;
+
+ @ColumnInfo(name = "server_name")
+ private String serverName;
+
+ @ColumnInfo(name = "username")
+ private String username;
+
+ @ColumnInfo(name = "address")
+ private String address;
+
+ @ColumnInfo(name = "token")
+ private String token;
+
+ @ColumnInfo(name = "salt")
+ private String salt;
+
+ @ColumnInfo(name = "timestamp")
+ private long timestamp;
+
+ public Server(@NonNull String serverId, String serverName, String username, String address, String token, String salt, long timestamp) {
+ this.serverId = serverId;
+ this.serverName = serverName;
+ this.username = username;
+ this.address = address;
+ this.token = token;
+ this.salt = salt;
+ this.timestamp = timestamp;
+ }
+
+ @NonNull
+ public String getServerId() {
+ return serverId;
+ }
+
+ public void setServerId(@NonNull String serverId) {
+ this.serverId = serverId;
+ }
+
+ public String getServerName() {
+ return serverName;
+ }
+
+ public void setServerName(String serverName) {
+ this.serverName = serverName;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+
+ public String getSalt() {
+ return salt;
+ }
+
+ public void setSalt(String salt) {
+ this.salt = salt;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+}
diff --git a/app/src/main/java/com/cappielloantonio/play/repository/AlbumRepository.java b/app/src/main/java/com/cappielloantonio/play/repository/AlbumRepository.java
index b4f0b303..e6509743 100644
--- a/app/src/main/java/com/cappielloantonio/play/repository/AlbumRepository.java
+++ b/app/src/main/java/com/cappielloantonio/play/repository/AlbumRepository.java
@@ -275,17 +275,19 @@ public class AlbumRepository {
getFirstAlbum(first -> {
getLastAlbum(last -> {
- List decadeList = new ArrayList();
+ if(first != -1 && last != -1) {
+ List decadeList = new ArrayList();
- int startDecade = first - (first % 10);
- int lastDecade = last - (last % 10);
+ int startDecade = first - (first % 10);
+ int lastDecade = last - (last % 10);
- while (startDecade <= lastDecade) {
- decadeList.add(startDecade);
- startDecade = startDecade + 10;
+ while (startDecade <= lastDecade) {
+ decadeList.add(startDecade);
+ startDecade = startDecade + 10;
+ }
+
+ decades.setValue(decadeList);
}
-
- decades.setValue(decadeList);
});
});
@@ -295,7 +297,7 @@ public class AlbumRepository {
private void getFirstAlbum(DecadesCallback callback) {
App.getSubsonicClientInstance(application, false)
.getAlbumSongListClient()
- .getAlbumList2("byYear", 1, 0, 0, Calendar.getInstance().get(Calendar.YEAR))
+ .getAlbumList2("byYear", 1, 0, 1900, Calendar.getInstance().get(Calendar.YEAR))
.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
@@ -308,7 +310,7 @@ public class AlbumRepository {
@Override
public void onFailure(Call call, Throwable t) {
-
+ callback.onLoadYear(-1);
}
});
}
@@ -316,20 +318,23 @@ public class AlbumRepository {
private void getLastAlbum(DecadesCallback callback) {
App.getSubsonicClientInstance(application, false)
.getAlbumSongListClient()
- .getAlbumList2("byYear", 1, 0, Calendar.getInstance().get(Calendar.YEAR), 0)
+ .getAlbumList2("byYear", 1, 0, Calendar.getInstance().get(Calendar.YEAR), 1900)
.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
if (response.body().getStatus().getValue().equals(ResponseStatus.OK)) {
- if(response.body().getAlbumList2().getAlbums().get(0) != null){
+ if(response.body().getAlbumList2().getAlbums().size() > 0 && response.body().getAlbumList2().getAlbums().get(0) != null){
callback.onLoadYear(response.body().getAlbumList2().getAlbums().get(0).getYear());
}
+ else {
+ callback.onLoadYear(-1);
+ }
}
}
@Override
public void onFailure(Call call, Throwable t) {
-
+ callback.onLoadYear(-1);
}
});
}
diff --git a/app/src/main/java/com/cappielloantonio/play/repository/DownloadRepository.java b/app/src/main/java/com/cappielloantonio/play/repository/DownloadRepository.java
index 1c64e5e9..d02fddd9 100644
--- a/app/src/main/java/com/cappielloantonio/play/repository/DownloadRepository.java
+++ b/app/src/main/java/com/cappielloantonio/play/repository/DownloadRepository.java
@@ -5,9 +5,11 @@ import android.app.Application;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
+import com.cappielloantonio.play.App;
import com.cappielloantonio.play.database.AppDatabase;
import com.cappielloantonio.play.database.dao.DownloadDao;
import com.cappielloantonio.play.model.Download;
+import com.cappielloantonio.play.util.PreferenceUtil;
import java.util.ArrayList;
import java.util.List;
@@ -60,7 +62,7 @@ public class DownloadRepository {
}
public LiveData> getLiveDownloadSample(int size) {
- listLiveDownloadSample = downloadDao.getSample(size);
+ listLiveDownloadSample = downloadDao.getSample(size, PreferenceUtil.getInstance(App.getInstance()).getServerId());
return listLiveDownloadSample;
}
@@ -121,7 +123,7 @@ public class DownloadRepository {
@Override
public void run() {
- downloadDao.deleteAll();
+ downloadDao.deleteAll(PreferenceUtil.getInstance(App.getInstance()).getServerId());
}
}
diff --git a/app/src/main/java/com/cappielloantonio/play/repository/QueueRepository.java b/app/src/main/java/com/cappielloantonio/play/repository/QueueRepository.java
index 64d06730..61327354 100644
--- a/app/src/main/java/com/cappielloantonio/play/repository/QueueRepository.java
+++ b/app/src/main/java/com/cappielloantonio/play/repository/QueueRepository.java
@@ -4,11 +4,13 @@ import android.app.Application;
import androidx.lifecycle.LiveData;
+import com.cappielloantonio.play.App;
import com.cappielloantonio.play.database.AppDatabase;
import com.cappielloantonio.play.database.dao.QueueDao;
import com.cappielloantonio.play.model.Queue;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.util.MappingUtil;
+import com.cappielloantonio.play.util.PreferenceUtil;
import com.cappielloantonio.play.util.QueueUtil;
import java.util.ArrayList;
@@ -26,7 +28,7 @@ public class QueueRepository {
}
public LiveData> getLiveQueue() {
- listLiveQueue = queueDao.getAll();
+ listLiveQueue = queueDao.getAll(PreferenceUtil.getInstance(App.getInstance()).getServerId());
return listLiveQueue;
}
@@ -94,7 +96,7 @@ public class QueueRepository {
@Override
public void run() {
- songs = MappingUtil.mapQueue(queueDao.getAllSimple());
+ songs = MappingUtil.mapQueue(queueDao.getAllSimple(PreferenceUtil.getInstance(App.getInstance()).getServerId()));
}
public List getSongs() {
@@ -113,7 +115,7 @@ public class QueueRepository {
@Override
public void run() {
- queueDao.insertAll(QueueUtil.getQueueElementsFromSongs(songs));
+ queueDao.insertAll(QueueUtil.getQueueElementsFromSongs(songs, PreferenceUtil.getInstance(App.getInstance()).getServerId()));
}
}
@@ -128,7 +130,7 @@ public class QueueRepository {
@Override
public void run() {
- queueDao.deleteByPosition(position);
+ queueDao.deleteByPosition(position, PreferenceUtil.getInstance(App.getInstance()).getServerId());
}
}
@@ -141,7 +143,7 @@ public class QueueRepository {
@Override
public void run() {
- queueDao.deleteAll();
+ queueDao.deleteAll(PreferenceUtil.getInstance(App.getInstance()).getServerId());
}
}
diff --git a/app/src/main/java/com/cappielloantonio/play/repository/ServerRepository.java b/app/src/main/java/com/cappielloantonio/play/repository/ServerRepository.java
new file mode 100644
index 00000000..32c511a4
--- /dev/null
+++ b/app/src/main/java/com/cappielloantonio/play/repository/ServerRepository.java
@@ -0,0 +1,70 @@
+package com.cappielloantonio.play.repository;
+
+import android.app.Application;
+
+import androidx.lifecycle.LiveData;
+
+import com.cappielloantonio.play.database.AppDatabase;
+import com.cappielloantonio.play.database.dao.ServerDao;
+import com.cappielloantonio.play.model.Server;
+
+import java.util.List;
+
+public class ServerRepository {
+ private static final String TAG = "QueueRepository";
+
+ private ServerDao serverDao;
+ private LiveData> listLiveServer;
+
+ public ServerRepository(Application application) {
+ AppDatabase database = AppDatabase.getInstance(application);
+ serverDao = database.serverDao();
+ }
+
+ public LiveData> getLiveServer() {
+ listLiveServer = serverDao.getAll();
+ return listLiveServer;
+ }
+
+ public void insert(Server server) {
+ InsertThreadSafe insert = new InsertThreadSafe(serverDao, server);
+ Thread thread = new Thread(insert);
+ thread.start();
+ }
+
+ public void delete(Server server) {
+ DeleteThreadSafe delete = new DeleteThreadSafe(serverDao, server);
+ Thread thread = new Thread(delete);
+ thread.start();
+ }
+
+ private static class InsertThreadSafe implements Runnable {
+ private ServerDao serverDao;
+ private Server server;
+
+ public InsertThreadSafe(ServerDao serverDao, Server server) {
+ this.serverDao = serverDao;
+ this.server = server;
+ }
+
+ @Override
+ public void run() {
+ serverDao.insert(server);
+ }
+ }
+
+ private static class DeleteThreadSafe implements Runnable {
+ private ServerDao serverDao;
+ private Server server;
+
+ public DeleteThreadSafe(ServerDao serverDao, Server server) {
+ this.serverDao = serverDao;
+ this.server = server;
+ }
+
+ @Override
+ public void run() {
+ serverDao.delete(server);
+ }
+ }
+}
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/activity/MainActivity.java b/app/src/main/java/com/cappielloantonio/play/ui/activity/MainActivity.java
index 30cb5c7a..e9ec2d8f 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/activity/MainActivity.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/activity/MainActivity.java
@@ -179,8 +179,11 @@ public class MainActivity extends BaseActivity {
// NAVIGATION
public void goToLogin() {
- if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.landingFragment)
+ if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.landingFragment) {
navController.navigate(R.id.action_landingFragment_to_loginFragment);
+ } else if(Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.settingsFragment) {
+ navController.navigate(R.id.action_settingsFragment_to_loginFragment);
+ }
}
public void goToHome() {
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/LoginFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/LoginFragment.java
index d3a9e94d..d3e09a00 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/LoginFragment.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/LoginFragment.java
@@ -1,44 +1,64 @@
package com.cappielloantonio.play.ui.fragment;
import android.os.Bundle;
-import android.text.TextUtils;
-import android.util.Log;
import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.core.view.ViewCompat;
import androidx.fragment.app.Fragment;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.recyclerview.widget.ItemTouchHelper;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
-import com.cappielloantonio.play.App;
+import com.cappielloantonio.play.R;
+import com.cappielloantonio.play.adapter.ServerAdapter;
import com.cappielloantonio.play.databinding.FragmentLoginBinding;
-import com.cappielloantonio.play.interfaces.SystemCallback;
-import com.cappielloantonio.play.repository.SystemRepository;
+import com.cappielloantonio.play.service.MusicPlayerRemote;
import com.cappielloantonio.play.ui.activity.MainActivity;
-import com.cappielloantonio.play.util.PreferenceUtil;
+import com.cappielloantonio.play.ui.fragment.dialog.ServerSignupDialog;
+import com.cappielloantonio.play.viewmodel.LoginViewModel;
+
+import java.util.Collections;
public class LoginFragment extends Fragment {
private static final String TAG = "LoginFragment";
private FragmentLoginBinding bind;
private MainActivity activity;
+ private LoginViewModel loginViewModel;
- private String username;
- private String password;
- private String server;
+ private ServerAdapter serverAdapter;
- private SystemRepository systemRepository;
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ super.onCreateOptionsMenu(menu, inflater);
+ inflater.inflate(R.menu.login_page_menu, menu);
+ }
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
activity = (MainActivity) getActivity();
+ loginViewModel = new ViewModelProvider(requireActivity()).get(LoginViewModel.class);
bind = FragmentLoginBinding.inflate(inflater, container, false);
View view = bind.getRoot();
- init();
+
+ initAppBar();
+ initServerListView();
return view;
}
@@ -49,67 +69,75 @@ public class LoginFragment extends Fragment {
bind = null;
}
- private void init() {
- systemRepository = new SystemRepository(App.getInstance());
+ private void initAppBar() {
+ activity.setSupportActionBar(bind.toolbar);
- bind.loginButton.setOnClickListener(v -> {
- if (validateInput()) {
- saveServerPreference(server, username, password, null, null);
- authenticate();
+ bind.appBarLayout.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> {
+ if ((bind.serverInfoSector.getHeight() + verticalOffset) < (2 * ViewCompat.getMinimumHeight(bind.toolbar))) {
+ bind.toolbar.setTitle("Subsonic servers");
+ } else {
+ bind.toolbar.setTitle("");
}
});
}
- private boolean validateInput() {
- username = bind.usernameTextView.getText().toString().trim();
- password = bind.passwordTextView.getText().toString();
- server = bind.serverTextView.getText().toString().trim();
+ private void initServerListView() {
+ bind.serverListRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
+ bind.serverListRecyclerView.setHasFixedSize(true);
- if (TextUtils.isEmpty(username)) {
- Toast.makeText(requireContext(), "Empty username", Toast.LENGTH_SHORT).show();
- return false;
- }
-
- if (TextUtils.isEmpty(server)) {
- Toast.makeText(requireContext(), "Empty server url", Toast.LENGTH_SHORT).show();
- return false;
- }
-
- return true;
- }
-
- private void authenticate() {
- systemRepository.checkUserCredential(new SystemCallback() {
- @Override
- public void onError(Exception exception) {
- Log.e(TAG, exception.getMessage());
- Toast.makeText(requireContext(), exception.getMessage(), Toast.LENGTH_LONG).show();
+ serverAdapter = new ServerAdapter(activity, requireContext());
+ bind.serverListRecyclerView.setAdapter(serverAdapter);
+ loginViewModel.getServerList().observe(requireActivity(), servers -> {
+ if(servers.size() > 0) {
+ if (bind != null) bind.noServerAddedTextView.setVisibility(View.GONE);
+ if (bind != null) bind.serverListRecyclerView.setVisibility(View.VISIBLE);
+ serverAdapter.setItems(servers);
}
-
- @Override
- public void onSuccess(String token, String salt) {
- saveServerPreference(null, null, null, token, salt);
- enter();
+ else {
+ if (bind != null) bind.noServerAddedTextView.setVisibility(View.VISIBLE);
+ if (bind != null) bind.serverListRecyclerView.setVisibility(View.GONE);
}
});
+
+ new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.LEFT) {
+ int originalPosition = -1;
+ int fromPosition = -1;
+ int toPosition = -1;
+
+ @Override
+ public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
+ if (originalPosition == -1)
+ originalPosition = viewHolder.getBindingAdapterPosition();
+
+ fromPosition = viewHolder.getBindingAdapterPosition();
+ toPosition = target.getBindingAdapterPosition();
+
+ Collections.swap(serverAdapter.getItems(), fromPosition, toPosition);
+ recyclerView.getAdapter().notifyItemMoved(fromPosition, toPosition);
+
+ return false;
+ }
+
+ @Override
+ public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
+ loginViewModel.deleteServer(serverAdapter.getItem(viewHolder.getBindingAdapterPosition()));
+ bind.serverListRecyclerView.getAdapter().notifyItemRemoved(viewHolder.getBindingAdapterPosition());
+ }
+ }
+ ).attachToRecyclerView(bind.serverListRecyclerView);
}
- private void enter() {
- activity.goFromLogin();
- }
-
- private void saveServerPreference(String server, String user, String password, String token, String salt) {
- if (user != null) PreferenceUtil.getInstance(requireContext()).setUser(user);
- if (server != null) PreferenceUtil.getInstance(requireContext()).setServer(server);
- if (password != null) PreferenceUtil.getInstance(requireContext()).setPassword(password);
-
- if (token != null && salt != null) {
- PreferenceUtil.getInstance(requireContext()).setPassword(null);
- PreferenceUtil.getInstance(requireContext()).setToken(token);
- PreferenceUtil.getInstance(requireContext()).setSalt(salt);
- return;
+ @Override
+ public boolean onOptionsItemSelected(@NonNull MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.action_add:
+ ServerSignupDialog dialog = new ServerSignupDialog();
+ dialog.show(activity.getSupportFragmentManager(), null);
+ return true;
+ default:
+ break;
}
- App.getSubsonicClientInstance(requireContext(), true);
+ return false;
}
}
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/SettingsFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/SettingsFragment.java
index 10039ca5..45f2880e 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/SettingsFragment.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/SettingsFragment.java
@@ -6,11 +6,13 @@ import android.view.View;
import android.view.ViewGroup;
import androidx.preference.ListPreference;
+import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.helper.ThemeHelper;
import com.cappielloantonio.play.ui.activity.MainActivity;
+import com.cappielloantonio.play.util.PreferenceUtil;
public class SettingsFragment extends PreferenceFragmentCompat {
private static final String TAG = "SettingsFragment";
@@ -36,6 +38,24 @@ public class SettingsFragment extends PreferenceFragmentCompat {
activity.setBottomNavigationBarVisibility(false);
}
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ findPreference("logout").setOnPreferenceClickListener(preference -> {
+ PreferenceUtil.getInstance(requireContext()).setUser(null);
+ PreferenceUtil.getInstance(requireContext()).setServer(null);
+ PreferenceUtil.getInstance(requireContext()).setPassword(null);
+ PreferenceUtil.getInstance(requireContext()).setToken(null);
+ PreferenceUtil.getInstance(requireContext()).setSalt(null);
+ PreferenceUtil.getInstance(requireContext()).setServerId(null);
+
+ activity.goToLogin();
+
+ return true;
+ });
+ }
+
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.global_preferences, rootKey);
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/dialog/ServerSignupDialog.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/dialog/ServerSignupDialog.java
new file mode 100644
index 00000000..9a550008
--- /dev/null
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/dialog/ServerSignupDialog.java
@@ -0,0 +1,142 @@
+package com.cappielloantonio.play.ui.fragment.dialog;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.widget.Toast;
+
+import androidx.fragment.app.DialogFragment;
+import androidx.lifecycle.ViewModelProvider;
+
+import com.cappielloantonio.play.App;
+import com.cappielloantonio.play.R;
+import com.cappielloantonio.play.databinding.DialogServerSignupBinding;
+import com.cappielloantonio.play.interfaces.SystemCallback;
+import com.cappielloantonio.play.model.Server;
+import com.cappielloantonio.play.repository.SystemRepository;
+import com.cappielloantonio.play.ui.activity.MainActivity;
+import com.cappielloantonio.play.util.PreferenceUtil;
+import com.cappielloantonio.play.viewmodel.LoginViewModel;
+
+import java.util.Objects;
+import java.util.UUID;
+
+public class ServerSignupDialog extends DialogFragment {
+ private static final String TAG = "ServerSignupDialog";
+
+ private DialogServerSignupBinding bind;
+ private MainActivity activity;
+ private Context context;
+ private LoginViewModel loginViewModel;
+
+ private SystemRepository systemRepository;
+
+ private String serverName;
+ private String username;
+ private String password;
+ private String server;
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ activity = (MainActivity) getActivity();
+ context = requireContext();
+
+ loginViewModel = new ViewModelProvider(requireActivity()).get(LoginViewModel.class);
+ systemRepository = new SystemRepository(App.getInstance());
+
+ bind = DialogServerSignupBinding.inflate(LayoutInflater.from(requireContext()));
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+
+ builder.setView(bind.getRoot())
+ .setTitle("Add server")
+ .setPositiveButton("Enter", (dialog, id) -> { })
+ .setNegativeButton("Cancel", (dialog, id) -> dialog.cancel());
+
+ return builder.create();
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ ((AlertDialog) Objects.requireNonNull(getDialog())).getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(getResources().getColor(R.color.colorAccent, null));
+ ((AlertDialog) Objects.requireNonNull(getDialog())).getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(getResources().getColor(R.color.colorAccent, null));
+
+ ((AlertDialog) Objects.requireNonNull(getDialog())).getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(v -> {
+ if (validateInput()) {
+ saveServerPreference(server, username, password, null, null);
+ authenticate();
+ ((AlertDialog) Objects.requireNonNull(getDialog())).dismiss();
+ }
+ });
+ }
+
+ private boolean validateInput() {
+ serverName = bind.serverNameTextView.getText().toString().trim();
+ username = bind.usernameTextView.getText().toString().trim();
+ password = bind.passwordTextView.getText().toString();
+ server = bind.serverTextView.getText().toString().trim();
+
+ if (TextUtils.isEmpty(serverName)) {
+ bind.serverNameTextView.setError("Required");
+ return false;
+ }
+
+ if (TextUtils.isEmpty(username)) {
+ bind.usernameTextView.setError("Required");
+ return false;
+ }
+
+ if (TextUtils.isEmpty(server)) {
+ bind.serverTextView.setError("Required");
+ return false;
+ }
+
+ return true;
+ }
+
+ private void authenticate() {
+ systemRepository.checkUserCredential(new SystemCallback() {
+ @Override
+ public void onError(Exception exception) {
+ Log.e(TAG, exception.getMessage());
+ Toast.makeText(requireContext(), exception.getMessage(), Toast.LENGTH_LONG).show();
+ }
+
+ @Override
+ public void onSuccess(String token, String salt) {
+ saveServerPreference(null, null, null, token, salt);
+ enter();
+ }
+ });
+ }
+
+ private void enter() {
+ activity.goFromLogin();
+ }
+
+ private void saveServerPreference(String server, String user, String password, String token, String salt) {
+ if (user != null) PreferenceUtil.getInstance(context).setUser(user);
+ if (server != null) PreferenceUtil.getInstance(context).setServer(server);
+ if (password != null) PreferenceUtil.getInstance(context).setPassword(password);
+
+ if (token != null && salt != null) {
+ String serverID = UUID.randomUUID().toString();
+
+ PreferenceUtil.getInstance(context).setPassword(null);
+ PreferenceUtil.getInstance(context).setToken(token);
+ PreferenceUtil.getInstance(context).setSalt(salt);
+ PreferenceUtil.getInstance(context).setServerId(serverID);
+
+ loginViewModel.addServer(new Server(serverID, this.serverName, this.username, this.server, token, salt, System.currentTimeMillis()));
+
+ return;
+ }
+
+ App.getSubsonicClientInstance(requireContext(), true);
+ }
+}
diff --git a/app/src/main/java/com/cappielloantonio/play/util/PreferenceUtil.java b/app/src/main/java/com/cappielloantonio/play/util/PreferenceUtil.java
index 0e691b45..0a30a2ea 100644
--- a/app/src/main/java/com/cappielloantonio/play/util/PreferenceUtil.java
+++ b/app/src/main/java/com/cappielloantonio/play/util/PreferenceUtil.java
@@ -15,6 +15,7 @@ public class PreferenceUtil {
public static final String PASSWORD = "password";
public static final String TOKEN = "token";
public static final String SALT = "salt";
+ public static final String SERVER_ID = "server_id";
public static final String POSITION = "position";
public static final String PROGRESS = "progress";
public static final String IMAGE_CACHE_SIZE = "image_cache_size";
@@ -89,6 +90,16 @@ public class PreferenceUtil {
editor.apply();
}
+ public String getServerId() {
+ return mPreferences.getString(SERVER_ID, null);
+ }
+
+ public void setServerId(String serverId) {
+ final SharedPreferences.Editor editor = mPreferences.edit();
+ editor.putString(SERVER_ID, serverId);
+ editor.apply();
+ }
+
public int getPosition() {
return mPreferences.getInt(POSITION, -1);
}
diff --git a/app/src/main/java/com/cappielloantonio/play/util/QueueUtil.java b/app/src/main/java/com/cappielloantonio/play/util/QueueUtil.java
index f9e01252..dc7302f6 100644
--- a/app/src/main/java/com/cappielloantonio/play/util/QueueUtil.java
+++ b/app/src/main/java/com/cappielloantonio/play/util/QueueUtil.java
@@ -9,12 +9,12 @@ import java.util.List;
public class QueueUtil {
private static final String TAG = "QueueUtil";
- public static List getQueueElementsFromSongs(List songs) {
+ public static List getQueueElementsFromSongs(List songs, String serverID) {
int counter = 0;
List queue = new ArrayList<>();
for (Song song : songs) {
- queue.add(new Queue(counter, song.getId(), song.getTitle(), song.getAlbumId(), song.getAlbumName(), song.getArtistId(), song.getArtistName(), song.getPrimary(), song.getDuration()));
+ queue.add(new Queue(counter, song.getId(), song.getTitle(), song.getAlbumId(), song.getAlbumName(), song.getArtistId(), song.getArtistName(), song.getPrimary(), song.getDuration(), serverID));
counter++;
}
diff --git a/app/src/main/java/com/cappielloantonio/play/viewmodel/LoginViewModel.java b/app/src/main/java/com/cappielloantonio/play/viewmodel/LoginViewModel.java
new file mode 100644
index 00000000..c091b631
--- /dev/null
+++ b/app/src/main/java/com/cappielloantonio/play/viewmodel/LoginViewModel.java
@@ -0,0 +1,48 @@
+package com.cappielloantonio.play.viewmodel;
+
+import android.app.Application;
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+import androidx.lifecycle.AndroidViewModel;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+
+import com.cappielloantonio.play.App;
+import com.cappielloantonio.play.interfaces.MediaCallback;
+import com.cappielloantonio.play.model.Album;
+import com.cappielloantonio.play.model.Server;
+import com.cappielloantonio.play.repository.AlbumRepository;
+import com.cappielloantonio.play.repository.ServerRepository;
+import com.cappielloantonio.play.subsonic.models.AlbumID3;
+import com.cappielloantonio.play.subsonic.models.ResponseStatus;
+import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
+import com.cappielloantonio.play.util.MappingUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+
+public class LoginViewModel extends AndroidViewModel {
+ private ServerRepository serverRepository;
+
+ public LoginViewModel(@NonNull Application application) {
+ super(application);
+
+ serverRepository = new ServerRepository(application);
+ }
+
+ public LiveData> getServerList() {
+ return serverRepository.getLiveServer();
+ }
+
+ public void addServer(Server server) {
+ serverRepository.insert(server);
+ }
+
+ public void deleteServer(Server server) {
+ serverRepository.delete(server);
+ }
+}
diff --git a/app/src/main/res/drawable-v24/ic_add.xml b/app/src/main/res/drawable-v24/ic_add.xml
new file mode 100644
index 00000000..57198ebb
--- /dev/null
+++ b/app/src/main/res/drawable-v24/ic_add.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/layout/dialog_server_signup.xml b/app/src/main/res/layout/dialog_server_signup.xml
new file mode 100644
index 00000000..6fd24079
--- /dev/null
+++ b/app/src/main/res/layout/dialog_server_signup.xml
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_login.xml b/app/src/main/res/layout/fragment_login.xml
index 8e36b6b2..83477039 100644
--- a/app/src/main/res/layout/fragment_login.xml
+++ b/app/src/main/res/layout/fragment_login.xml
@@ -1,104 +1,70 @@
+ android:orientation="vertical">
-
+ android:layout_height="?attr/actionBarSize"
+ app:layout_collapseMode="pin" />
-
+
+
+ app:elevation="0dp">
-
+
-
+
+
+
-
-
-
+ android:paddingStart="16dp"
+ android:paddingTop="16dp"
+ android:paddingEnd="16dp"
+ android:gravity="center"
+ android:text="No server added"
+ android:clipToPadding="false"
+ android:paddingBottom="@dimen/global_padding_bottom"
+ app:layout_behavior="@string/appbar_scrolling_view_behavior"
+ android:visibility="gone"/>
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+ android:clipToPadding="false"
+ android:paddingBottom="@dimen/global_padding_bottom"
+ app:layout_behavior="@string/appbar_scrolling_view_behavior"
+ android:visibility="gone"/>
+
+
diff --git a/app/src/main/res/layout/item_login_server.xml b/app/src/main/res/layout/item_login_server.xml
new file mode 100644
index 00000000..bb0dc0cf
--- /dev/null
+++ b/app/src/main/res/layout/item_login_server.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/login_page_menu.xml b/app/src/main/res/menu/login_page_menu.xml
new file mode 100644
index 00000000..cb69dbd7
--- /dev/null
+++ b/app/src/main/res/menu/login_page_menu.xml
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml
index 2f7c6dba..56f8d59d 100644
--- a/app/src/main/res/navigation/nav_graph.xml
+++ b/app/src/main/res/navigation/nav_graph.xml
@@ -93,6 +93,11 @@
android:name="com.cappielloantonio.play.ui.fragment.SettingsFragment"
android:label="SettingsFragment"
tools:layout="@layout/fragment_settings">
+
+
+