First reimplementation of download functionality

This commit is contained in:
antonio 2023-03-10 09:31:15 +01:00
parent 77a3b90b4e
commit 3e7d260d6a
16 changed files with 143 additions and 92 deletions

View file

@ -18,6 +18,8 @@ import com.cappielloantonio.play.R;
import com.cappielloantonio.play.glide.CustomGlideRequest;
import com.cappielloantonio.play.interfaces.ClickCallback;
import com.cappielloantonio.play.subsonic.models.Child;
import com.cappielloantonio.play.util.DownloadUtil;
import com.cappielloantonio.play.util.MappingUtil;
import com.cappielloantonio.play.util.MusicUtil;
import java.util.ArrayList;
@ -54,12 +56,11 @@ public class SongHorizontalAdapter extends RecyclerView.Adapter<SongHorizontalAd
holder.songSubtitle.setText(context.getString(R.string.song_subtitle_formatter, MusicUtil.getReadableString(song.getArtist()), MusicUtil.getReadableDurationString(song.getDuration(), false)));
holder.trackNumber.setText(String.valueOf(song.getTrack()));
// TODO
/* if (DownloadUtil.getDownloadTracker(context).isDownloaded(MappingUtil.mapMediaItem(context, song, false))) {
if (DownloadUtil.getDownloadTracker(context).isDownloaded(MappingUtil.mapMediaItem(context, song, false))) {
holder.downloadIndicator.setVisibility(View.VISIBLE);
} else {
holder.downloadIndicator.setVisibility(View.GONE);
} */
}
if (isCoverVisible) CustomGlideRequest.Builder
.from(context, song.getCoverArtId(), CustomGlideRequest.SONG_PIC, null)

View file

@ -22,7 +22,7 @@ import com.cappielloantonio.play.model.Server;
import com.cappielloantonio.play.subsonic.models.Playlist;
@Database(
version = 52,
version = 53,
entities = {Queue.class, Server.class, RecentSearch.class, Download.class, Playlist.class, Chronology.class}
// autoMigrations = {@AutoMigration(from = 43, to = 44)}
)

View file

@ -12,32 +12,32 @@ import java.util.List;
@Dao
public interface DownloadDao {
@Query("SELECT * FROM download WHERE server=:server")
LiveData<List<Download>> getAll(String server);
@Query("SELECT * FROM download")
LiveData<List<Download>> getAll();
@Query("SELECT * FROM download WHERE server=:server AND playlist_id IS NULL GROUP BY artist LIMIT :size")
LiveData<List<Download>> getSampleArtist(int size, String server);
@Query("SELECT * FROM download WHERE playlist_id IS NULL GROUP BY artist LIMIT :size")
LiveData<List<Download>> getSampleArtist(int size);
@Query("SELECT * FROM download WHERE server=:server AND playlist_id IS NULL GROUP BY album LIMIT :size")
LiveData<List<Download>> getSampleAlbum(int size, String server);
@Query("SELECT * FROM download WHERE playlist_id IS NULL GROUP BY album LIMIT :size")
LiveData<List<Download>> getSampleAlbum(int size);
@Query("SELECT * FROM download WHERE server=:server AND playlist_id IS NOT NULL GROUP BY playlist_id LIMIT :size")
LiveData<List<Download>> getSamplePlaylist(int size, String server);
@Query("SELECT * FROM download WHERE playlist_id IS NOT NULL GROUP BY playlist_id LIMIT :size")
LiveData<List<Download>> getSamplePlaylist(int size);
@Query("SELECT * FROM download WHERE server=:server LIMIT :size")
LiveData<List<Download>> getSample(int size, String server);
@Query("SELECT * FROM download LIMIT :size")
LiveData<List<Download>> getSample(int size);
@Query("SELECT * FROM download WHERE server=:server AND artist=:artistId")
LiveData<List<Download>> getAllFromArtist(String server, String artistId);
@Query("SELECT * FROM download WHERE artist=:artistId")
LiveData<List<Download>> getAllFromArtist(String artistId);
@Query("SELECT * FROM download WHERE server=:server AND album=:albumId ORDER BY track ASC")
LiveData<List<Download>> getAllFromAlbum(String server, String albumId);
@Query("SELECT * FROM download WHERE album=:albumId ORDER BY track ASC")
LiveData<List<Download>> getAllFromAlbum(String albumId);
@Query("SELECT * FROM download WHERE server=:server AND playlist_id=:playlistId")
LiveData<List<Download>> getAllFromPlaylist(String server, String playlistId);
@Query("SELECT * FROM download WHERE playlist_id=:playlistId")
LiveData<List<Download>> getAllFromPlaylist(String playlistId);
@Query("SELECT * FROM download WHERE server=:server AND playlist_id IS NOT NULL GROUP BY playlist_id")
LiveData<List<Download>> getAllPlaylists(String server);
@Query("SELECT * FROM download WHERE playlist_id IS NOT NULL GROUP BY playlist_id")
LiveData<List<Download>> getAllPlaylists();
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(Download download);
@ -45,9 +45,9 @@ public interface DownloadDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertAll(List<Download> downloads);
@Query("DELETE FROM download WHERE media_id = :mediaId")
void delete(String mediaId);
@Query("DELETE FROM download WHERE id = :id")
void delete(String id);
@Query("DELETE FROM download WHERE server=:server")
void deleteAll(String server);
@Query("DELETE FROM download")
void deleteAll();
}

View file

@ -11,12 +11,42 @@ import kotlinx.android.parcel.Parcelize
@Parcelize
@Entity(tableName = "download")
class Download(@PrimaryKey override val id: String) : Child(id) {
@ColumnInfo(name = "media_id")
var mediaID: String? = null
@ColumnInfo
var server: String? = null
@ColumnInfo(name = "playlist_id")
var playlistId: String? = null
@ColumnInfo(name = "playlist_name")
var playlistName: String? = null
constructor(child: Child) : this(child.id) {
parentId = child.parentId
isDir = child.isDir
title = child.title
album = child.album
artist = child.artist
track = child.track
year = child.year
genre = child.genre
coverArtId = child.coverArtId
size = child.size
contentType = child.contentType
suffix = child.suffix
transcodedContentType = child.transcodedContentType
transcodedSuffix = child.transcodedSuffix
duration = child.duration
bitrate = child.bitrate
path = child.path
isVideo = child.isVideo
userRating = child.userRating
averageRating = child.averageRating
playCount = child.playCount
discNumber = child.discNumber
created = child.created
starred = child.starred
albumId = child.albumId
artistId = child.artistId
type = child.type
bookmarkPosition = child.bookmarkPosition
originalWidth = child.originalWidth
originalHeight = child.originalHeight
}
}

View file

@ -20,31 +20,31 @@ public class DownloadRepository {
}
public LiveData<List<Download>> getLiveDownload() {
return downloadDao.getAll(Preferences.getServerId());
return downloadDao.getAll();
}
public LiveData<List<Download>> getLiveDownloadSample(int size, boolean isArtist, boolean isAlbum, boolean isTrack, boolean isPlaylist) {
if (isArtist) return downloadDao.getSampleArtist(size, Preferences.getServerId());
else if (isAlbum) return downloadDao.getSampleAlbum(size, Preferences.getServerId());
else if (isTrack) return downloadDao.getSample(size, Preferences.getServerId());
else if (isPlaylist) return downloadDao.getSamplePlaylist(size, Preferences.getServerId());
else return downloadDao.getSample(size, Preferences.getServerId());
if (isArtist) return downloadDao.getSampleArtist(size);
else if (isAlbum) return downloadDao.getSampleAlbum(size);
else if (isTrack) return downloadDao.getSample(size);
else if (isPlaylist) return downloadDao.getSamplePlaylist(size);
else return downloadDao.getSample(size);
}
public LiveData<List<Download>> getLiveDownloadFromArtist(String artistId) {
return downloadDao.getAllFromArtist(Preferences.getServerId(), artistId);
return downloadDao.getAllFromArtist(artistId);
}
public LiveData<List<Download>> getLiveDownloadFromAlbum(String albumId) {
return downloadDao.getAllFromAlbum(Preferences.getServerId(), albumId);
return downloadDao.getAllFromAlbum(albumId);
}
public LiveData<List<Download>> getLiveDownloadFromPlaylist(String playlistId) {
return downloadDao.getAllFromPlaylist(Preferences.getServerId(), playlistId);
return downloadDao.getAllFromPlaylist(playlistId);
}
public LiveData<List<Download>> getLivePlaylist() {
return downloadDao.getAllPlaylists(Preferences.getServerId());
return downloadDao.getAllPlaylists();
}
public void insert(Download download) {
@ -104,7 +104,7 @@ public class DownloadRepository {
@Override
public void run() {
downloadDao.deleteAll(Preferences.getServerId());
downloadDao.deleteAll();
}
}
@ -125,7 +125,7 @@ public class DownloadRepository {
@Override
public void run() {
downloadDao.delete(download.getMediaID());
downloadDao.delete(download.getId());
}
}
}

View file

@ -15,11 +15,11 @@ open class AlbumID3 : Parcelable {
@SerializedName("coverArt")
var coverArtId: String? = null
var songCount = 0
var duration = 0
var songCount: Int? = 0
var duration: Int? = 0
var playCount: Long? = null
var created: Date? = null
var starred: Date? = null
var year: Int? = null
var year: Int = 0
var genre: String? = null
}

View file

@ -12,12 +12,14 @@ import androidx.lifecycle.ViewModelProvider;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.databinding.DialogConnectionAlertBinding;
import com.cappielloantonio.play.model.Download;
import com.cappielloantonio.play.util.DownloadUtil;
import com.cappielloantonio.play.util.MappingUtil;
import com.cappielloantonio.play.util.Preferences;
import com.cappielloantonio.play.viewmodel.StarredSyncViewModel;
import java.util.Objects;
import java.util.stream.Collectors;
public class StarredSyncDialog extends DialogFragment {
private static final String TAG = "ServerUnreachableDialog";
@ -62,7 +64,7 @@ public class StarredSyncDialog extends DialogFragment {
if (songs != null) {
DownloadUtil.getDownloadTracker(context).download(
MappingUtil.mapMediaItems(context, songs, false),
MappingUtil.mapDownload(songs, null, null)
songs.stream().map(Download::new).collect(Collectors.toList())
);
}
});

View file

@ -27,6 +27,7 @@ import com.cappielloantonio.play.adapter.SongHorizontalAdapter;
import com.cappielloantonio.play.databinding.FragmentAlbumPageBinding;
import com.cappielloantonio.play.glide.CustomGlideRequest;
import com.cappielloantonio.play.interfaces.ClickCallback;
import com.cappielloantonio.play.model.Download;
import com.cappielloantonio.play.service.MediaManager;
import com.cappielloantonio.play.service.MediaService;
import com.cappielloantonio.play.ui.activity.MainActivity;
@ -38,6 +39,7 @@ import com.google.common.util.concurrent.ListenableFuture;
import java.util.Collections;
import java.util.Objects;
import java.util.stream.Collectors;
@UnstableApi
public class AlbumPageFragment extends Fragment implements ClickCallback {
@ -105,7 +107,7 @@ public class AlbumPageFragment extends Fragment implements ClickCallback {
if (isVisible() && getActivity() != null) {
DownloadUtil.getDownloadTracker(requireContext()).download(
MappingUtil.mapMediaItems(requireContext(), songs, false),
MappingUtil.mapDownload(songs, null, null)
songs.stream().map(Download::new).collect(Collectors.toList())
);
}
});

View file

@ -179,8 +179,7 @@ public class DownloadFragment extends Fragment implements ClickCallback {
if (bind != null)
bind.downloadedArtistRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), UIUtil.getSpanCount(artists.size(), 5), GridLayoutManager.HORIZONTAL, false));
// TODO
// downloadedArtistAdapter.setItems(artists);
downloadedArtistAdapter.setItems(artists);
}
});
@ -215,8 +214,7 @@ public class DownloadFragment extends Fragment implements ClickCallback {
if (bind != null)
bind.downloadedAlbumRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), UIUtil.getSpanCount(albums.size(), 5), GridLayoutManager.HORIZONTAL, false));
// TODO
//downloadedAlbumAdapter.setItems(albums);
downloadedAlbumAdapter.setItems(albums);
}
});

View file

@ -22,6 +22,7 @@ import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.cappielloantonio.play.databinding.InnerFragmentPlayerCoverBinding;
import com.cappielloantonio.play.glide.CustomGlideRequest;
import com.cappielloantonio.play.model.Download;
import com.cappielloantonio.play.service.MediaManager;
import com.cappielloantonio.play.service.MediaService;
import com.cappielloantonio.play.ui.dialog.PlaylistChooserDialog;
@ -90,7 +91,7 @@ public class PlayerCoverFragment extends Fragment {
bind.innerButtonTopLeft.setOnClickListener(view -> {
DownloadUtil.getDownloadTracker(requireContext()).download(
MappingUtil.mapMediaItem(requireContext(), song, false),
MappingUtil.mapDownload(song, null, null)
new Download(song)
);
});

View file

@ -26,6 +26,7 @@ import com.cappielloantonio.play.adapter.SongHorizontalAdapter;
import com.cappielloantonio.play.databinding.FragmentPlaylistPageBinding;
import com.cappielloantonio.play.glide.CustomGlideRequest;
import com.cappielloantonio.play.interfaces.ClickCallback;
import com.cappielloantonio.play.model.Download;
import com.cappielloantonio.play.service.MediaManager;
import com.cappielloantonio.play.service.MediaService;
import com.cappielloantonio.play.ui.activity.MainActivity;
@ -37,6 +38,7 @@ import com.google.common.util.concurrent.ListenableFuture;
import java.util.Collections;
import java.util.Objects;
import java.util.stream.Collectors;
@UnstableApi
public class PlaylistPageFragment extends Fragment implements ClickCallback {
@ -104,7 +106,12 @@ public class PlaylistPageFragment extends Fragment implements ClickCallback {
if (isVisible() && getActivity() != null) {
DownloadUtil.getDownloadTracker(requireContext()).download(
MappingUtil.mapMediaItems(requireContext(), songs, false),
MappingUtil.mapDownload(songs, playlistPageViewModel.getPlaylist().getId(), playlistPageViewModel.getPlaylist().getName())
songs.stream().map(child -> {
Download toDownload = new Download(child);
toDownload.setPlaylistId(playlistPageViewModel.getPlaylist().getId());
toDownload.setPlaylistName(playlistPageViewModel.getPlaylist().getName());
return toDownload;
}).collect(Collectors.toList())
);
}
});

View file

@ -41,6 +41,7 @@ import com.google.common.util.concurrent.ListenableFuture;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@UnstableApi
public class AlbumBottomSheetDialog extends BottomSheetDialogFragment implements View.OnClickListener {
@ -154,7 +155,7 @@ public class AlbumBottomSheetDialog extends BottomSheetDialogFragment implements
albumBottomSheetViewModel.getAlbumTracks().observe(getViewLifecycleOwner(), songs -> {
List<MediaItem> mediaItems = MappingUtil.mapMediaItems(requireContext(), songs, false);
List<Download> downloads = MappingUtil.mapDownload(songs, null, null);
List<Download> downloads = songs.stream().map(Download::new).collect(Collectors.toList());
downloadAll.setOnClickListener(v -> {
DownloadUtil.getDownloadTracker(requireContext()).download(mediaItems, downloads);

View file

@ -21,6 +21,7 @@ import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.glide.CustomGlideRequest;
import com.cappielloantonio.play.model.Download;
import com.cappielloantonio.play.service.MediaManager;
import com.cappielloantonio.play.service.MediaService;
import com.cappielloantonio.play.subsonic.models.Child;
@ -155,7 +156,7 @@ public class SongBottomSheetDialog extends BottomSheetDialogFragment implements
download.setOnClickListener(v -> {
DownloadUtil.getDownloadTracker(requireContext()).download(
MappingUtil.mapMediaItem(requireContext(), song, false),
MappingUtil.mapDownload(song, null, null)
new Download(song)
);
dismissBottomSheet();
});
@ -164,7 +165,7 @@ public class SongBottomSheetDialog extends BottomSheetDialogFragment implements
remove.setOnClickListener(v -> {
DownloadUtil.getDownloadTracker(requireContext()).remove(
MappingUtil.mapMediaItem(requireContext(), song, false),
MappingUtil.mapDownload(song, null, null)
new Download(song)
);
dismissBottomSheet();
});

View file

@ -60,28 +60,6 @@ public class MappingUtil {
return playlists;
}
public static ArrayList<Download> mapDownload(List<Child> media, String playlistId, String playlistName) {
ArrayList<Download> downloads = new ArrayList();
// TODO
/* for (Child item : media) {
Download download = (Download) item;
download.setMediaID();
download.setServer();
download.setPlaylistId();
downloads.add(download);
} */
return downloads;
}
public static Download mapDownload(Child media, String playlistId, String playlistName) {
// TODO
//return new Download(media, playlistId, playlistName);
return null;
}
@OptIn(markerClass = UnstableApi.class)
public static MediaItem mapMediaItem(Context context, Child media, boolean stream) {
boolean isDownloaded = DownloadUtil.getDownloadTracker(context).isDownloaded(MusicUtil.getDownloadUri(media.getId()));

View file

@ -8,10 +8,10 @@ import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import com.cappielloantonio.play.model.Album;
import com.cappielloantonio.play.model.Artist;
import com.cappielloantonio.play.model.Playlist;
import com.cappielloantonio.play.repository.DownloadRepository;
import com.cappielloantonio.play.subsonic.models.AlbumID3;
import com.cappielloantonio.play.subsonic.models.ArtistID3;
import com.cappielloantonio.play.subsonic.models.Child;
import com.cappielloantonio.play.util.MappingUtil;
@ -23,8 +23,8 @@ public class DownloadViewModel extends AndroidViewModel {
private final DownloadRepository downloadRepository;
private final MutableLiveData<List<Artist>> downloadedArtistSample = new MutableLiveData<>(null);
private final MutableLiveData<List<Album>> downloadedAlbumSample = new MutableLiveData<>(null);
private final MutableLiveData<List<ArtistID3>> downloadedArtistSample = new MutableLiveData<>(null);
private final MutableLiveData<List<AlbumID3>> downloadedAlbumSample = new MutableLiveData<>(null);
private final MutableLiveData<List<Child>> downloadedTrackSample = new MutableLiveData<>(null);
private final MutableLiveData<List<Playlist>> downloadedPlaylistSample = new MutableLiveData<>(null);
@ -34,13 +34,40 @@ public class DownloadViewModel extends AndroidViewModel {
downloadRepository = new DownloadRepository(application);
}
public LiveData<List<Artist>> getDownloadedArtists(LifecycleOwner owner, int size) {
downloadRepository.getLiveDownloadSample(size, true, false, false, false).observe(owner, downloads -> downloadedArtistSample.postValue(MappingUtil.mapDownloadToArtist(downloads)));
public LiveData<List<ArtistID3>> getDownloadedArtists(LifecycleOwner owner, int size) {
downloadRepository.getLiveDownloadSample(size, true, false, false, false)
.observe(owner, downloads -> downloadedArtistSample.postValue(downloads.stream().map(download -> {
ArtistID3 artist = new ArtistID3();
artist.setId(download.getArtistId());
artist.setName(download.getArtist());
artist.setCoverArtId(download.getCoverArtId());
// artist.setAlbumCount(0);
// artist.setStarred(null);
return artist;
}).collect(Collectors.toList())));
return downloadedArtistSample;
}
public LiveData<List<Album>> getDownloadedAlbums(LifecycleOwner owner, int size) {
downloadRepository.getLiveDownloadSample(size, false, true, false, false).observe(owner, downloads -> downloadedAlbumSample.postValue(MappingUtil.mapDownloadToAlbum(downloads)));
public LiveData<List<AlbumID3>> getDownloadedAlbums(LifecycleOwner owner, int size) {
downloadRepository.getLiveDownloadSample(size, false, true, false, false)
.observe(owner, downloads -> downloadedAlbumSample.postValue(downloads.stream().map(download -> {
AlbumID3 album = new AlbumID3();
album.setId(download.getAlbumId());
album.setName(download.getAlbum());
album.setArtist(album.getArtist());
album.setArtistId(album.getArtistId());
album.setCoverArtId(album.getCoverArtId());
// album.setSongCount(0);
// album.setDuration(0);
// album.setPlayCount(null);
// album.setCreated(null);
// album.setStarred(null);
album.setYear(album.getYear());
// album.setGenre(null);
return album;
}).collect(Collectors.toList())));
return downloadedAlbumSample;
}

View file

@ -10,12 +10,16 @@ import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.media3.common.util.UnstableApi;
import com.cappielloantonio.play.model.Download;
import com.cappielloantonio.play.repository.AlbumRepository;
import com.cappielloantonio.play.repository.ArtistRepository;
import com.cappielloantonio.play.repository.SongRepository;
import com.cappielloantonio.play.subsonic.models.AlbumID3;
import com.cappielloantonio.play.subsonic.models.ArtistID3;
import com.cappielloantonio.play.subsonic.models.Child;
import com.cappielloantonio.play.util.DownloadUtil;
import com.cappielloantonio.play.util.MappingUtil;
import com.cappielloantonio.play.util.Preferences;
import java.util.Collections;
import java.util.Date;
@ -55,13 +59,12 @@ public class SongBottomSheetViewModel extends AndroidViewModel {
songRepository.star(song.getId());
song.setStarred(new Date());
// TODO
/* if (Preferences.isStarredSyncEnabled()) {
if (Preferences.isStarredSyncEnabled()) {
DownloadUtil.getDownloadTracker(context).download(
MappingUtil.mapMediaItem(context, song, false),
MappingUtil.mapDownload(song, null, null)
new Download(song)
);
} */
}
}
}