mirror of
https://github.com/antebudimir/tempus.git
synced 2025-12-31 17:43:32 +00:00
Add settings to pin and unpin playlist in toolbar menu
This commit is contained in:
parent
afe0e0751c
commit
e29b96d905
11 changed files with 170 additions and 5 deletions
|
|
@ -8,18 +8,20 @@ import androidx.room.Room;
|
|||
import androidx.room.RoomDatabase;
|
||||
|
||||
import com.cappielloantonio.play.database.dao.DownloadDao;
|
||||
import com.cappielloantonio.play.database.dao.PlaylistDao;
|
||||
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.Playlist;
|
||||
import com.cappielloantonio.play.model.Queue;
|
||||
import com.cappielloantonio.play.model.RecentSearch;
|
||||
import com.cappielloantonio.play.model.Server;
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
@Database(
|
||||
version = 23,
|
||||
entities = {Queue.class, Server.class, RecentSearch.class, Download.class}
|
||||
version = 24,
|
||||
entities = {Queue.class, Server.class, RecentSearch.class, Download.class, Playlist.class}
|
||||
// autoMigrations = { @AutoMigration(from = 23, to = 24) }
|
||||
)
|
||||
public abstract class AppDatabase extends RoomDatabase {
|
||||
|
|
@ -44,4 +46,6 @@ public abstract class AppDatabase extends RoomDatabase {
|
|||
public abstract RecentSearchDao recentSearchDao();
|
||||
|
||||
public abstract DownloadDao downloadDao();
|
||||
|
||||
public abstract PlaylistDao playlistDao();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
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.Playlist;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Dao
|
||||
public interface PlaylistDao {
|
||||
@Query("SELECT * FROM playlist")
|
||||
LiveData<List<Playlist>> getAll();
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
void insert(Playlist playlist);
|
||||
|
||||
@Delete
|
||||
void delete(Playlist playlist);
|
||||
}
|
||||
|
|
@ -4,16 +4,34 @@ import android.os.Parcel;
|
|||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.room.ColumnInfo;
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.Ignore;
|
||||
import androidx.room.PrimaryKey;
|
||||
|
||||
@Entity(tableName = "playlist")
|
||||
public class Playlist implements Parcelable {
|
||||
public static final String ALL = "ALL";
|
||||
public static final String DOWNLOADED = "DOWNLOADED";
|
||||
|
||||
@NonNull
|
||||
@PrimaryKey
|
||||
@ColumnInfo(name = "id")
|
||||
private String id;
|
||||
|
||||
@ColumnInfo(name = "playlist_name")
|
||||
private String name;
|
||||
|
||||
@Ignore
|
||||
private String primary;
|
||||
|
||||
@Ignore
|
||||
private String blurHash;
|
||||
|
||||
@Ignore
|
||||
private int songCount;
|
||||
|
||||
@Ignore
|
||||
private long duration;
|
||||
|
||||
public Playlist(com.cappielloantonio.play.subsonic.models.Playlist playlist) {
|
||||
|
|
@ -25,11 +43,12 @@ public class Playlist implements Parcelable {
|
|||
this.duration = playlist.getDuration();
|
||||
}
|
||||
|
||||
public Playlist(String id, String name) {
|
||||
public Playlist(@NonNull String id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,10 +3,15 @@ package com.cappielloantonio.play.repository;
|
|||
import android.app.Application;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
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.PlaylistDao;
|
||||
import com.cappielloantonio.play.database.dao.ServerDao;
|
||||
import com.cappielloantonio.play.model.Playlist;
|
||||
import com.cappielloantonio.play.model.Server;
|
||||
import com.cappielloantonio.play.model.Song;
|
||||
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
|
||||
import com.cappielloantonio.play.util.MappingUtil;
|
||||
|
|
@ -21,9 +26,13 @@ import retrofit2.Response;
|
|||
|
||||
public class PlaylistRepository {
|
||||
private final Application application;
|
||||
private final PlaylistDao playlistDao;
|
||||
|
||||
public PlaylistRepository(Application application) {
|
||||
this.application = application;
|
||||
|
||||
AppDatabase database = AppDatabase.getInstance(application);
|
||||
this.playlistDao = database.playlistDao();
|
||||
}
|
||||
|
||||
public MutableLiveData<List<Playlist>> getPlaylists(boolean random, int size) {
|
||||
|
|
@ -144,4 +153,50 @@ public class PlaylistRepository {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
public LiveData<List<Playlist>> getPinnedPlaylists() {
|
||||
return playlistDao.getAll();
|
||||
}
|
||||
|
||||
public void insert(Playlist playlist) {
|
||||
InsertThreadSafe insert = new InsertThreadSafe(playlistDao, playlist);
|
||||
Thread thread = new Thread(insert);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public void delete(Playlist playlist) {
|
||||
DeleteThreadSafe delete = new DeleteThreadSafe(playlistDao, playlist);
|
||||
Thread thread = new Thread(delete);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
private static class InsertThreadSafe implements Runnable {
|
||||
private final PlaylistDao playlistDao;
|
||||
private final Playlist playlist;
|
||||
|
||||
public InsertThreadSafe(PlaylistDao playlistDao, Playlist playlist) {
|
||||
this.playlistDao = playlistDao;
|
||||
this.playlist = playlist;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
playlistDao.insert(playlist);
|
||||
}
|
||||
}
|
||||
|
||||
private static class DeleteThreadSafe implements Runnable {
|
||||
private final PlaylistDao playlistDao;
|
||||
private final Playlist playlist;
|
||||
|
||||
public DeleteThreadSafe(PlaylistDao playlistDao, Playlist playlist) {
|
||||
this.playlistDao = playlistDao;
|
||||
this.playlist = playlist;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
playlistDao.delete(playlist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -478,4 +478,8 @@ public class HomeFragment extends Fragment {
|
|||
bind.homeLinearLayoutContainer.addView(bind.homeRecentlyPlayedAlbumsSector);
|
||||
}
|
||||
}
|
||||
|
||||
public void addPinnedPlaylistsView() {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import com.cappielloantonio.play.R;
|
|||
import com.cappielloantonio.play.adapter.SongHorizontalAdapter;
|
||||
import com.cappielloantonio.play.databinding.FragmentPlaylistPageBinding;
|
||||
import com.cappielloantonio.play.glide.CustomGlideRequest;
|
||||
import com.cappielloantonio.play.model.Song;
|
||||
import com.cappielloantonio.play.repository.QueueRepository;
|
||||
import com.cappielloantonio.play.service.MusicPlayerRemote;
|
||||
import com.cappielloantonio.play.ui.activity.MainActivity;
|
||||
|
|
@ -29,7 +28,6 @@ import com.cappielloantonio.play.util.MusicUtil;
|
|||
import com.cappielloantonio.play.viewmodel.PlaylistPageViewModel;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class PlaylistPageFragment extends Fragment {
|
||||
|
|
@ -50,6 +48,7 @@ public class PlaylistPageFragment extends Fragment {
|
|||
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
inflater.inflate(R.menu.playlist_page_menu, menu);
|
||||
initMenuOption(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -90,6 +89,12 @@ public class PlaylistPageFragment extends Fragment {
|
|||
}
|
||||
});
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.action_pin_playlist) {
|
||||
playlistPageViewModel.setPinned(true);
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.action_unpin_playlist) {
|
||||
playlistPageViewModel.setPinned(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -100,6 +105,13 @@ public class PlaylistPageFragment extends Fragment {
|
|||
playlistPageViewModel.setOffline(requireArguments().getBoolean("is_offline"));
|
||||
}
|
||||
|
||||
private void initMenuOption(Menu menu) {
|
||||
playlistPageViewModel.isPinned(requireActivity()).observe(requireActivity(), isPinned -> {
|
||||
menu.findItem(R.id.action_unpin_playlist).setVisible(isPinned);
|
||||
menu.findItem(R.id.action_pin_playlist).setVisible(!isPinned);
|
||||
});
|
||||
}
|
||||
|
||||
private void initAppBar() {
|
||||
activity.setSupportActionBar(bind.animToolbar);
|
||||
|
||||
|
|
|
|||
|
|
@ -57,4 +57,18 @@ public class PlaylistPageViewModel extends AndroidViewModel {
|
|||
public boolean isOffline() {
|
||||
return isOffline;
|
||||
}
|
||||
|
||||
public LiveData<Boolean> isPinned(FragmentActivity activity) {
|
||||
MutableLiveData<Boolean> isPinnedLive = new MutableLiveData<>();
|
||||
playlistRepository.getPinnedPlaylists().observe(activity, playlists -> isPinnedLive.postValue(playlists.contains(playlist)));
|
||||
return isPinnedLive;
|
||||
}
|
||||
|
||||
public void setPinned(boolean isNowPinned) {
|
||||
if(isNowPinned) {
|
||||
playlistRepository.insert(playlist);
|
||||
} else {
|
||||
playlistRepository.delete(playlist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
10
app/src/main/res/drawable/ic_pin_in.xml
Normal file
10
app/src/main/res/drawable/ic_pin_in.xml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@color/titleTextColor"
|
||||
android:pathData="M16,9V4l1,0c0.55,0 1,-0.45 1,-1v0c0,-0.55 -0.45,-1 -1,-1H7C6.45,2 6,2.45 6,3v0c0,0.55 0.45,1 1,1l1,0v5c0,1.66 -1.34,3 -3,3h0v2h5.97v7l1,1l1,-1v-7H19v-2h0C17.34,12 16,10.66 16,9z"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/ic_pin_out.xml
Normal file
9
app/src/main/res/drawable/ic_pin_out.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@color/titleTextColor"
|
||||
android:pathData="M14,4v5c0,1.12 0.37,2.16 1,3H9c0.65,-0.86 1,-1.9 1,-3V4H14M17,2H7C6.45,2 6,2.45 6,3c0,0.55 0.45,1 1,1c0,0 0,0 0,0l1,0v5c0,1.66 -1.34,3 -3,3v2h5.97v7l1,1l1,-1v-7H19v-2c0,0 0,0 0,0c-1.66,0 -3,-1.34 -3,-3V4l1,0c0,0 0,0 0,0c0.55,0 1,-0.45 1,-1C18,2.45 17.55,2 17,2L17,2z"/>
|
||||
</vector>
|
||||
|
|
@ -7,4 +7,16 @@
|
|||
android:iconTint="@color/titleTextColor"
|
||||
android:title="@string/menu_download_all_button"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/action_pin_playlist"
|
||||
android:icon="@drawable/ic_pin_in"
|
||||
android:iconTint="@color/titleTextColor"
|
||||
android:title="@string/menu_pin_button"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/action_unpin_playlist"
|
||||
android:icon="@drawable/ic_pin_out"
|
||||
android:iconTint="@color/titleTextColor"
|
||||
android:title="@string/menu_unpin_button"
|
||||
app:showAsAction="never" />
|
||||
</menu>
|
||||
|
|
@ -105,8 +105,10 @@
|
|||
<string name="menu_download_label">Download</string>
|
||||
<string name="menu_home_label">Home</string>
|
||||
<string name="menu_library_label">Library</string>
|
||||
<string name="menu_pin_button">Pin</string>
|
||||
<string name="menu_search_button">Search</string>
|
||||
<string name="menu_settings_button">Settings</string>
|
||||
<string name="menu_unpin_button">Unpin</string>
|
||||
<string name="player_bottom_sheet_title">Now playing</string>
|
||||
<string name="playing_notification_description">The playing notification provides actions for play/pause etc.</string>
|
||||
<string name="playing_notification_name">Playing Notification</string>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue