Graphic and functional improvements in the synchronization section

This commit is contained in:
CappielloAntonio 2021-04-28 18:10:22 +02:00
parent fdc104f70b
commit 67803b9149
19 changed files with 991 additions and 215 deletions

View file

@ -66,7 +66,7 @@ public interface SongDao {
@Query("SELECT * FROM song WHERE favorite = 1")
LiveData<List<Song>> getFavoriteSong();
@Query("SELECT * FROM song WHERE offline = 1 ORDER BY RANDOM() LIMIT :number")
@Query("SELECT * FROM song WHERE offline = 1 LIMIT :number")
LiveData<List<Song>> getDownloadedSongSample(int number);
@Query("SELECT * FROM song WHERE offline = 1 ORDER BY path, albumName, trackNumber")

View file

@ -66,8 +66,8 @@ public class DownloadTracker {
}
@Nullable
public DownloadRequest getDownloadRequest(Uri uri) {
return new DownloadRequest.Builder(uri.toString(), uri).build();
public DownloadRequest getDownloadRequest(String id, Uri uri) {
return new DownloadRequest.Builder(id, uri).build();
}
public void toggleDownload(List<Song> songs) {
@ -83,7 +83,7 @@ public class DownloadTracker {
DownloadService.sendRemoveDownload(context, DownloaderService.class, download.request.id, false);
} else {
song.setOffline(true);
DownloadService.sendAddDownload(context, DownloaderService.class, getDownloadRequest(mediaItem.playbackProperties.uri), false);
DownloadService.sendAddDownload(context, DownloaderService.class, getDownloadRequest(song.getId(), mediaItem.playbackProperties.uri), false);
}
songRepository.setOfflineStatus(song);
@ -113,22 +113,19 @@ public class DownloadTracker {
}
private class DownloadManagerListener implements DownloadManager.Listener {
@Override
public void onDownloadChanged(
@NonNull DownloadManager downloadManager,
@NonNull Download download,
@Nullable Exception finalException) {
public void onDownloadChanged(@NonNull DownloadManager downloadManager, @NonNull Download download, @Nullable Exception finalException) {
downloads.put(download.request.uri, download);
for (Listener listener : listeners) {
listener.onDownloadsChanged();
}
}
@Override
public void onDownloadRemoved(
@NonNull DownloadManager downloadManager, @NonNull Download download) {
public void onDownloadRemoved(@NonNull DownloadManager downloadManager, @NonNull Download download) {
downloads.remove(download.request.uri);
for (Listener listener : listeners) {
listener.onDownloadsChanged();
}

View file

@ -48,7 +48,6 @@ public class DownloaderService extends DownloadService {
}
private static final class TerminalStateNotificationHelper implements DownloadManager.Listener {
private final Context context;
private final DownloadNotificationHelper notificationHelper;
@ -65,7 +64,7 @@ public class DownloaderService extends DownloadService {
Notification notification;
if (download.state == Download.STATE_COMPLETED) {
notification = notificationHelper.buildDownloadCompletedNotification(context, R.drawable.ic_done, null, Util.fromUtf8Bytes(download.request.data));
notification = notificationHelper.buildDownloadCompletedNotification(context, R.drawable.ic_check_circle, null, Util.fromUtf8Bytes(download.request.data));
} else if (download.state == Download.STATE_FAILED) {
notification = notificationHelper.buildDownloadFailedNotification(context, R.drawable.ic_error, null, Util.fromUtf8Bytes(download.request.data));
} else {

View file

@ -218,14 +218,8 @@ public class MainActivity extends BaseActivity {
setBottomSheetVisibility(false);
if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.loginFragment) {
Bundle bundle = SyncUtil.getSyncBundle(true, true, true, true, true, false);
Bundle bundle = SyncUtil.getSyncBundle(true, true, true, true, true, true);
navController.navigate(R.id.action_loginFragment_to_syncFragment, bundle);
} else if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.homeFragment) {
Bundle bundle = SyncUtil.getSyncBundle(true, true, true, true, true, false);
navController.navigate(R.id.action_homeFragment_to_syncFragment, bundle);
} else if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.libraryFragment) {
Bundle bundle = SyncUtil.getSyncBundle(false, false, true, false, false, true);
navController.navigate(R.id.action_libraryFragment_to_syncFragment, bundle);
}
}

View file

@ -51,7 +51,7 @@ public class HomeFragment extends Fragment {
homeViewModel = new ViewModelProvider(requireActivity()).get(HomeViewModel.class);
init();
initForYouBar();
initListenNowBar();
return view;
}
@ -114,7 +114,7 @@ public class HomeFragment extends Fragment {
});
}
private void initForYouBar() {
private void initListenNowBar() {
bind.homeDateLabel.setText(Util.getDate());
bind.homeSettingsImageView.setOnClickListener(v -> activity.navController.navigate(R.id.action_homeFragment_to_settingsFragment));
@ -229,7 +229,7 @@ public class HomeFragment extends Fragment {
public void reorder() {
if(bind != null) {
bind.homeLinearLayoutContainer.removeAllViews();
bind.homeLinearLayoutContainer.addView(bind.forYouSector);
bind.homeLinearLayoutContainer.addView(bind.listenNowSector);
bind.homeLinearLayoutContainer.addView(bind.homeDiscoverSector);
bind.homeLinearLayoutContainer.addView(bind.homeRecentlyAddedTracksSector);
bind.homeLinearLayoutContainer.addView(bind.homeFlashbackSector);

View file

@ -34,6 +34,12 @@ public class SettingsFragment extends PreferenceFragmentCompat {
return view;
}
@Override
public void onStart() {
super.onStart();
activity.setBottomNavigationBarVisibility(false);
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.global_preferences, rootKey);
@ -58,21 +64,7 @@ public class SettingsFragment extends PreferenceFragmentCompat {
PreferenceUtil.getInstance(requireContext()).setSync(false);
PreferenceUtil.getInstance(requireContext()).setSongGenreSync(false);
Bundle bundle = SyncUtil.getSyncBundle(true, true, true, true, true, false);
activity.goFromSettingsToSync(bundle);
})
.show();
return true;
});
Preference cross_sync_button = findPreference(getString(R.string.genres_music_cross_sync));
cross_sync_button.setOnPreferenceClickListener(preference -> {
AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
builder.setMessage("Force sync song's genres to display updated and correct songs in each genre category")
.setTitle("Force sync song's genres")
.setNegativeButton(R.string.ignore, null)
.setPositiveButton("Sync", (dialog, id) -> {
Bundle bundle = SyncUtil.getSyncBundle(false, false, true, false, false, true);
Bundle bundle = SyncUtil.getSyncBundle(true, true, true, true, true, true);
activity.goFromSettingsToSync(bundle);
})
.show();
@ -93,5 +85,4 @@ public class SettingsFragment extends PreferenceFragmentCompat {
return true;
});
}
}

View file

@ -1,17 +1,17 @@
package com.cappielloantonio.play.ui.fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.databinding.FragmentSyncBinding;
import com.cappielloantonio.play.interfaces.MediaCallback;
import com.cappielloantonio.play.model.Album;
@ -32,8 +32,10 @@ import com.cappielloantonio.play.repository.PlaylistSongRepository;
import com.cappielloantonio.play.repository.SongArtistRepository;
import com.cappielloantonio.play.repository.SongRepository;
import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.util.DownloadUtil;
import com.cappielloantonio.play.util.PreferenceUtil;
import com.cappielloantonio.play.util.SyncUtil;
import com.cappielloantonio.play.util.Util;
import com.cappielloantonio.play.viewmodel.SyncViewModel;
import org.jellyfin.apiclient.model.dto.BaseItemDto;
@ -57,6 +59,15 @@ public class SyncFragment extends Fragment {
private AlbumArtistRepository albumArtistRepository;
private PlaylistSongRepository playlistSongRepository;
private final int LIBRARIES = 0;
private final int ALBUMS = 1;
private final int ARTISTS = 2;
private final int GENRES = 3;
private final int PLAYLISTS = 4;
private final int SONGS = 5;
private final int SONG_X_GENRE = 6;
private final int SONG_X_PLAYLIST = 7;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
@ -76,6 +87,8 @@ public class SyncFragment extends Fragment {
playlistSongRepository = new PlaylistSongRepository(activity.getApplication());
init();
initView();
initButtonListeners();
syncLibraries();
return view;
@ -89,14 +102,72 @@ public class SyncFragment extends Fragment {
private void init() {
syncViewModel.setArguemnts(getArguments());
bind.loadingProgressBar.setVisibility(View.VISIBLE);
bind.syncingDateLabel.setText(Util.getDate());
}
private void initView() {
if (!syncViewModel.isSyncAlbum()) bind.syncAlbumsSector.setVisibility(View.GONE);
if (!syncViewModel.isSyncArtist()) bind.syncArtistsSector.setVisibility(View.GONE);
if (!syncViewModel.isSyncGenres()) bind.syncGenresSector.setVisibility(View.GONE);
if (!syncViewModel.isSyncPlaylist()) bind.syncPlaylistsSector.setVisibility(View.GONE);
if (!syncViewModel.isSyncPlaylist()) bind.syncSongXPlaylistSector.setVisibility(View.GONE);
if (!syncViewModel.isSyncSong()) bind.syncSongsSector.setVisibility(View.GONE);
if (!syncViewModel.isCrossSyncSongGenre())
bind.syncSongXGenreSector.setVisibility(View.GONE);
}
private void initButtonListeners() {
bind.syncLibrariesRetryImageView.setOnClickListener(v -> {
resetSectorInfo(LIBRARIES);
syncLibraries();
});
bind.syncAlbumsRetryImageView.setOnClickListener(v -> {
resetSectorInfo(ALBUMS);
syncAlbums();
});
bind.syncArtistsRetryImageView.setOnClickListener(v -> {
resetSectorInfo(ARTISTS);
syncArtists();
});
bind.syncGenresRetryImageView.setOnClickListener(v -> {
resetSectorInfo(GENRES);
syncGenres();
});
bind.syncPlaylistsRetryImageView.setOnClickListener(v -> {
resetSectorInfo(PLAYLISTS);
syncPlaylist();
});
bind.syncSongsRetryImageView.setOnClickListener(v -> {
resetSectorInfo(SONGS);
syncSongs();
});
bind.syncSongXGenreRetryImageView.setOnClickListener(v -> {
resetSectorInfo(SONG_X_GENRE);
syncSongsPerGenre(syncViewModel.getGenreList());
});
bind.syncSongXPlaylistRetryImageView.setOnClickListener(v -> {
resetSectorInfo(SONG_X_PLAYLIST);
syncSongsPerPlaylist(syncViewModel.getPlaylistList());
});
bind.syncingGoHomeImageView.setOnClickListener(v -> {
AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
builder.setMessage("Make sure each category has been properly synchronized")
.setTitle("Go home")
.setNegativeButton(R.string.ignore, null)
.setPositiveButton("Go", (dialog, id) -> {
PreferenceUtil.getInstance(requireContext()).setSync(true);
activity.goToHome();
})
.show();
});
}
private void syncLibraries() {
SyncUtil.getLibraries(requireContext(), new MediaCallback() {
@Override
public void onError(Exception exception) {
Log.e(TAG, "onError: " + exception.getMessage());
loadSectorInfo(LIBRARIES, exception.getMessage(), false);
}
@Override
@ -104,36 +175,29 @@ public class SyncFragment extends Fragment {
List<BaseItemDto> libraries = (List<BaseItemDto>) media;
for (BaseItemDto itemDto : libraries) {
if (itemDto.getCollectionType().equals("music"))
if (itemDto.getCollectionType().equals("music")) {
PreferenceUtil.getInstance(requireContext()).setMusicLibraryID(itemDto.getId());
}
}
startSyncing();
loadSectorInfo(LIBRARIES, "", true);
}
});
}
private void startSyncing() {
if(syncViewModel.isSyncAlbum()) syncAlbums();
if(syncViewModel.isSyncArtist()) syncArtists();
if(syncViewModel.isSyncGenres()) syncGenres();
if(syncViewModel.isSyncPlaylist()) syncPlaylist();
if(syncViewModel.isSyncSong()) syncSongs();
}
private void syncAlbums() {
SyncUtil.getAlbums(requireContext(), new MediaCallback() {
@Override
public void onError(Exception exception) {
Log.e(TAG, "onError: " + exception.getMessage());
animateProgressBar(false);
loadSectorInfo(ALBUMS, exception.getMessage(), false);
}
@Override
public void onLoadMedia(List<?> media) {
albumRepository.insertAll((ArrayList<Album>) media);
syncAlbumArtistCross((ArrayList<Album>) media);
animateProgressBar(true);
syncViewModel.setAlbumList((ArrayList<Album>) media);
albumRepository.insertAll(syncViewModel.getAlbumList());
syncAlbumArtistCross(syncViewModel.getAlbumList());
loadSectorInfo(ALBUMS, "Found " + syncViewModel.getAlbumList().size() + " elements", true);
}
});
}
@ -142,14 +206,14 @@ public class SyncFragment extends Fragment {
SyncUtil.getArtists(requireContext(), new MediaCallback() {
@Override
public void onError(Exception exception) {
Log.e(TAG, "onError: " + exception.getMessage());
animateProgressBar(false);
loadSectorInfo(ARTISTS, exception.getMessage(), false);
}
@Override
public void onLoadMedia(List<?> media) {
artistRepository.insertAll((ArrayList<Artist>) media);
animateProgressBar(true);
syncViewModel.setArtistList((ArrayList<Artist>) media);
artistRepository.insertAll(syncViewModel.getArtistList());
loadSectorInfo(ARTISTS, "Found " + syncViewModel.getArtistList().size() + " elements", true);
}
});
}
@ -158,17 +222,14 @@ public class SyncFragment extends Fragment {
SyncUtil.getGenres(requireContext(), new MediaCallback() {
@Override
public void onError(Exception exception) {
Log.e(TAG, "onError: " + exception.getMessage());
animateProgressBar(false);
loadSectorInfo(GENRES, exception.getMessage(), false);
}
@Override
public void onLoadMedia(List<?> media) {
genreRepository.insertAll((ArrayList<Genre>) media);
animateProgressBar(true);
if(syncViewModel.isCrossSyncSongGenre()) syncSongsPerGenre((ArrayList<Genre>) media);
syncViewModel.setGenreList((ArrayList<Genre>) media);
genreRepository.insertAll(syncViewModel.getGenreList());
loadSectorInfo(GENRES, "Found " + syncViewModel.getGenreList().size() + " elements", true);
}
});
}
@ -177,15 +238,14 @@ public class SyncFragment extends Fragment {
SyncUtil.getPlaylists(requireContext(), new MediaCallback() {
@Override
public void onError(Exception exception) {
Log.e(TAG, "onError: " + exception.getMessage());
animateProgressBar(false);
loadSectorInfo(PLAYLISTS, exception.getMessage(), false);
}
@Override
public void onLoadMedia(List<?> media) {
playlistRepository.insertAll((ArrayList<Playlist>) media);
syncSongsPerPlaylist((ArrayList<Playlist>) media);
animateProgressBar(true);
syncViewModel.setPlaylistList((ArrayList<Playlist>) media);
playlistRepository.insertAll(syncViewModel.getPlaylistList());
loadSectorInfo(PLAYLISTS, "Found " + syncViewModel.getPlaylistList().size() + " elements", true);
}
});
}
@ -194,17 +254,22 @@ public class SyncFragment extends Fragment {
SyncUtil.getSongs(requireContext(), syncViewModel.getCatalogue(), new MediaCallback() {
@Override
public void onError(Exception exception) {
Log.e(TAG, "onError: " + exception.getMessage());
animateProgressBar(false);
loadSectorInfo(SONGS, exception.getMessage(), false);
}
@Override
public void onLoadMedia(List<?> media) {
syncViewModel.setSongList((ArrayList<Song>) media);
songRepository.deleteAllSongGenreCross();
songRepository.insertAll((ArrayList<Song>) media);
syncSongArtistCross((ArrayList<Song>) media);
PreferenceUtil.getInstance(requireContext()).setSongNumber(media.size());
animateProgressBar(true);
songRepository.insertAll(syncViewModel.getSongList());
syncSongArtistCross(syncViewModel.getSongList());
syncDownloadedSong();
loadSectorInfo(SONGS, "Found " + syncViewModel.getSongList().size() + " elements", true);
PreferenceUtil.getInstance(requireContext()).setSongNumber(syncViewModel.getSongList().size());
}
});
}
@ -214,17 +279,17 @@ public class SyncFragment extends Fragment {
SyncUtil.getSongsPerGenre(requireContext(), new MediaCallback() {
@Override
public void onError(Exception exception) {
Log.e(TAG, "onError: " + exception.getMessage());
loadSectorInfo(SONG_X_GENRE, exception.getMessage(), false);
}
@Override
public void onLoadMedia(List<?> media) {
songRepository.insertSongPerGenre((ArrayList<SongGenreCross>) media);
loadSectorInfo(SONG_X_GENRE, "Genre processed: " + genre.getName(), true);
}
}, genre.id);
}
animateProgressBar(true);
PreferenceUtil.getInstance(requireContext()).setSongGenreSync(true);
}
@ -233,38 +298,18 @@ public class SyncFragment extends Fragment {
SyncUtil.getSongsPerPlaylist(requireContext(), new MediaCallback() {
@Override
public void onError(Exception exception) {
Log.e(TAG, "onError: " + exception.getMessage());
loadSectorInfo(SONG_X_PLAYLIST, exception.getMessage(), false);
}
@Override
public void onLoadMedia(List<?> media) {
playlistSongRepository.insertAll((ArrayList<PlaylistSongCross>) media);
loadSectorInfo(SONG_X_PLAYLIST, "Playlist processed: " + playlist.getName(), true);
}
}, playlist.getId());
}
}
private void animateProgressBar(boolean step) {
syncViewModel.setProgress(step);
bind.loadingProgressBar.setProgress(syncViewModel.getProgressBarInfo(), true);
countProgress();
}
private void countProgress() {
if (syncViewModel.getProgress() == syncViewModel.getStep()) {
if (syncViewModel.getProgressBarInfo() < 100)
Toast.makeText(requireContext(), "Sync error", Toast.LENGTH_SHORT).show();
terminate();
}
}
private void terminate() {
PreferenceUtil.getInstance(requireContext()).setSync(true);
activity.goToHome();
}
// ---------------------------------------------------------------------------------------------
/*
* Sincronizzazzione dell'album con gli artisti che lo hanno prodotto | isProduced = true
@ -273,19 +318,19 @@ public class SyncFragment extends Fragment {
private void syncAlbumArtistCross(ArrayList<Album> albums) {
List<AlbumArtistCross> crosses = new ArrayList<>();
for(Album album: albums) {
for (Album album : albums) {
List<Artist> artists = new ArrayList<>();
if(album.albumArtists.size() > 0) {
for (Artist artist: album.albumArtists) {
if (album.albumArtists.size() > 0) {
for (Artist artist : album.albumArtists) {
artists.add(artist);
crosses.add(new AlbumArtistCross(album.getId(), artist.getId(), true));
}
}
if(album.artistItems.size() > 0) {
for (Artist artist: album.artistItems) {
if(!artists.contains(artist)) {
if (album.artistItems.size() > 0) {
for (Artist artist : album.artistItems) {
if (!artists.contains(artist)) {
crosses.add(new AlbumArtistCross(album.getId(), artist.getId(), false));
}
}
@ -298,19 +343,19 @@ public class SyncFragment extends Fragment {
private void syncSongArtistCross(ArrayList<Song> songs) {
List<SongArtistCross> crosses = new ArrayList<>();
for(Song song: songs) {
for (Song song : songs) {
List<Artist> artists = new ArrayList<>();
if(song.albumArtists.size() > 0) {
for (Artist artist: song.albumArtists) {
if (song.albumArtists.size() > 0) {
for (Artist artist : song.albumArtists) {
artists.add(artist);
crosses.add(new SongArtistCross(song.getId(), artist.getId()));
}
}
if(song.artistItems.size() > 0) {
for (Artist artist: song.artistItems) {
if(!artists.contains(artist)) {
if (song.artistItems.size() > 0) {
for (Artist artist : song.artistItems) {
if (!artists.contains(artist)) {
crosses.add(new SongArtistCross(song.getId(), artist.getId()));
}
}
@ -319,4 +364,207 @@ public class SyncFragment extends Fragment {
songArtistRepository.insertAll(crosses);
}
private void syncDownloadedSong() {
songRepository.getListLiveDownloadedSong().observe(requireActivity(), songs -> {
for (Song song : songs) {
if (!DownloadUtil.getDownloadTracker(requireContext()).isDownloaded(song)) {
song.setOffline(false);
songRepository.setOfflineStatus(song);
}
}
});
}
private void loadSectorInfo(int sector, String message, boolean isSuccess) {
switch (sector) {
case LIBRARIES:
if (isSuccess) {
bind.syncLibrariesStatusLabel.setText("Status: SUCCESS");
bind.syncLibrariesDetailLabel.setVisibility(View.GONE);
bind.syncLibrariesRetryImageView.setVisibility(View.GONE);
syncNextSector(LIBRARIES);
} else {
bind.syncLibrariesStatusLabel.setText("Status: ERROR");
bind.syncLibrariesDetailLabel.setText(message);
bind.syncLibrariesDetailLabel.setVisibility(View.VISIBLE);
bind.syncLibrariesRetryImageView.setVisibility(View.VISIBLE);
}
break;
case ALBUMS:
if (isSuccess) {
bind.syncAlbumsStatusLabel.setText("Status: SUCCESS");
bind.syncAlbumsDetailLabel.setText(message);
bind.syncAlbumsRetryImageView.setVisibility(View.GONE);
syncViewModel.increaseProggress();
checkStep();
syncNextSector(ALBUMS);
} else {
bind.syncLibrariesStatusLabel.setText("Status: ERROR");
bind.syncAlbumsDetailLabel.setText(message);
bind.syncAlbumsRetryImageView.setVisibility(View.VISIBLE);
}
break;
case ARTISTS:
if (isSuccess) {
bind.syncArtistsStatusLabel.setText("Status: SUCCESS");
bind.syncArtistsDetailLabel.setText(message);
bind.syncArtistsRetryImageView.setVisibility(View.GONE);
syncViewModel.increaseProggress();
checkStep();
syncNextSector(ARTISTS);
} else {
bind.syncArtistsStatusLabel.setText("Status: ERROR");
bind.syncArtistsDetailLabel.setText(message);
bind.syncArtistsRetryImageView.setVisibility(View.VISIBLE);
}
break;
case GENRES:
if (isSuccess) {
bind.syncGenresStatusLabel.setText("Status: SUCCESS");
bind.syncGenresDetailLabel.setText(message);
bind.syncGenresRetryImageView.setVisibility(View.GONE);
syncViewModel.increaseProggress();
checkStep();
syncNextSector(GENRES);
} else {
bind.syncGenresStatusLabel.setText("Status: ERROR");
bind.syncGenresDetailLabel.setText(message);
bind.syncGenresRetryImageView.setVisibility(View.VISIBLE);
}
break;
case PLAYLISTS:
if (isSuccess) {
bind.syncPlaylistsStatusLabel.setText("Status: SUCCESS");
bind.syncPlaylistsDetailLabel.setText(message);
bind.syncPlaylistsRetryImageView.setVisibility(View.GONE);
syncViewModel.increaseProggress();
checkStep();
syncNextSector(PLAYLISTS);
} else {
bind.syncPlaylistsStatusLabel.setText("Status: ERROR");
bind.syncPlaylistsDetailLabel.setText(message);
bind.syncPlaylistsRetryImageView.setVisibility(View.VISIBLE);
}
break;
case SONGS:
if (isSuccess) {
bind.syncSongsStatusLabel.setText("Status: SUCCESS");
bind.syncSongsDetailLabel.setText(message);
bind.syncSongsRetryImageView.setVisibility(View.GONE);
syncViewModel.increaseProggress();
checkStep();
syncNextSector(SONGS);
} else {
bind.syncSongsStatusLabel.setText("Status: ERROR");
bind.syncSongsDetailLabel.setText(message);
bind.syncSongsRetryImageView.setVisibility(View.VISIBLE);
}
break;
case SONG_X_GENRE:
if (isSuccess) {
bind.syncSongXGenreStatusLabel.setText("Status: SUCCESS");
bind.syncSongXGenreDetailLabel.setText(message);
bind.syncSongXGenreRetryImageView.setVisibility(View.GONE);
checkStep();
} else {
bind.syncSongXGenreStatusLabel.setText("Status: ERROR");
bind.syncSongXGenreDetailLabel.setText(message);
bind.syncSongXGenreRetryImageView.setVisibility(View.VISIBLE);
}
break;
case SONG_X_PLAYLIST:
if (isSuccess) {
bind.syncSongXPlaylistStatusLabel.setText("Status: SUCCESS");
bind.syncSongXPlaylistDetailLabel.setText(message);
bind.syncSongXPlaylistRetryImageView.setVisibility(View.GONE);
checkStep();
} else {
bind.syncSongXPlaylistStatusLabel.setText("Status: ERROR");
bind.syncSongXPlaylistDetailLabel.setText(message);
bind.syncSongXPlaylistRetryImageView.setVisibility(View.VISIBLE);
}
break;
}
}
private void resetSectorInfo(int sector) {
switch (sector) {
case LIBRARIES:
bind.syncLibrariesStatusLabel.setText("Loading...");
bind.syncLibrariesDetailLabel.setText(R.string.label_placeholder);
bind.syncLibrariesDetailLabel.setVisibility(View.GONE);
bind.syncLibrariesRetryImageView.setVisibility(View.GONE);
break;
case ALBUMS:
bind.syncAlbumsStatusLabel.setText("Loading...");
bind.syncAlbumsDetailLabel.setText(R.string.label_placeholder);
bind.syncAlbumsRetryImageView.setVisibility(View.GONE);
break;
case ARTISTS:
bind.syncArtistsStatusLabel.setText("Loading...");
bind.syncArtistsDetailLabel.setText(R.string.label_placeholder);
bind.syncArtistsRetryImageView.setVisibility(View.GONE);
break;
case GENRES:
bind.syncGenresStatusLabel.setText("Loading...");
bind.syncGenresDetailLabel.setText(R.string.label_placeholder);
bind.syncGenresRetryImageView.setVisibility(View.GONE);
break;
case PLAYLISTS:
bind.syncPlaylistsStatusLabel.setText("Loading...");
bind.syncPlaylistsDetailLabel.setText(R.string.label_placeholder);
bind.syncPlaylistsRetryImageView.setVisibility(View.GONE);
break;
case SONGS:
bind.syncSongsStatusLabel.setText("Loading...");
bind.syncSongsDetailLabel.setText(R.string.label_placeholder);
bind.syncSongsRetryImageView.setVisibility(View.GONE);
break;
case SONG_X_GENRE:
bind.syncSongXGenreStatusLabel.setText("Loading...");
bind.syncSongXGenreDetailLabel.setText(R.string.label_placeholder);
bind.syncSongXGenreRetryImageView.setVisibility(View.GONE);
break;
case SONG_X_PLAYLIST:
bind.syncSongXPlaylistStatusLabel.setText("Loading...");
bind.syncSongXPlaylistDetailLabel.setText(R.string.label_placeholder);
bind.syncSongXPlaylistRetryImageView.setVisibility(View.GONE);
break;
}
}
private void syncNextSector(int sector) {
switch (sector) {
case LIBRARIES:
if (syncViewModel.isSyncAlbum()) syncAlbums();
else syncPlaylist();
break;
case ALBUMS:
syncArtists();
break;
case ARTISTS:
syncGenres();
break;
case GENRES:
syncPlaylist();
break;
case PLAYLISTS:
if (syncViewModel.isSyncSong()) syncSongs();
else syncSongsPerPlaylist(syncViewModel.getPlaylistList());
break;
case SONGS:
syncSongsPerGenre(syncViewModel.getGenreList());
syncSongsPerPlaylist(syncViewModel.getPlaylistList());
break;
case SONG_X_GENRE | SONG_X_PLAYLIST:
break;
}
}
private void checkStep() {
if (syncViewModel.getStep() == syncViewModel.getProgress()) {
bind.syncingGoHomeImageView.setVisibility(View.VISIBLE);
}
}
}

View file

@ -44,7 +44,6 @@ public class SongBottomSheetDialog extends BottomSheetDialogFragment implements
private TextView titleSong;
private TextView artistSong;
private ToggleButton favoriteToggle;
private ImageView downloadIndicator;
private TextView playRadio;
private TextView playNext;
@ -91,8 +90,6 @@ public class SongBottomSheetDialog extends BottomSheetDialogFragment implements
dismissBottomSheet();
});
downloadIndicator = view.findViewById(R.id.bottom_sheet_song_dowanload_indicator_image_view);
playRadio = view.findViewById(R.id.play_radio_text_view);
playRadio.setOnClickListener(v -> {
SyncUtil.getInstantMix(requireContext(), new MediaCallback() {
@ -183,10 +180,8 @@ public class SongBottomSheetDialog extends BottomSheetDialogFragment implements
private void initDownloadedUI() {
if (song.isOffline()) {
downloadIndicator.setVisibility(View.VISIBLE);
download.setText("Remove");
} else {
downloadIndicator.setVisibility(View.GONE);
download.setText("Download");
}
}

View file

@ -49,11 +49,9 @@ public final class DownloadUtil {
return httpDataSourceFactory;
}
public static synchronized DownloadNotificationHelper getDownloadNotificationHelper(
Context context) {
public static synchronized DownloadNotificationHelper getDownloadNotificationHelper(Context context) {
if (downloadNotificationHelper == null) {
downloadNotificationHelper =
new DownloadNotificationHelper(context, DOWNLOAD_NOTIFICATION_CHANNEL_ID);
downloadNotificationHelper = new DownloadNotificationHelper(context, DOWNLOAD_NOTIFICATION_CHANNEL_ID);
}
return downloadNotificationHelper;
}
@ -70,11 +68,8 @@ public final class DownloadUtil {
public static synchronized Cache getDownloadCache(Context context) {
if (downloadCache == null) {
File downloadContentDirectory =
new File(getDownloadDirectory(context), DOWNLOAD_CONTENT_DIRECTORY);
downloadCache =
new SimpleCache(
downloadContentDirectory, new NoOpCacheEvictor(), getDatabaseProvider(context));
File downloadContentDirectory = new File(getDownloadDirectory(context), DOWNLOAD_CONTENT_DIRECTORY);
downloadCache = new SimpleCache(downloadContentDirectory, new NoOpCacheEvictor(), getDatabaseProvider(context));
}
return downloadCache;
}
@ -82,37 +77,16 @@ public final class DownloadUtil {
private static synchronized void ensureDownloadManagerInitialized(Context context) {
if (downloadManager == null) {
DefaultDownloadIndex downloadIndex = new DefaultDownloadIndex(getDatabaseProvider(context));
upgradeActionFile(
context, DOWNLOAD_ACTION_FILE, downloadIndex, false);
upgradeActionFile(
context,
DOWNLOAD_TRACKER_ACTION_FILE,
downloadIndex,
true);
downloadManager =
new DownloadManager(
context,
getDatabaseProvider(context),
getDownloadCache(context),
getHttpDataSourceFactory(context),
Executors.newFixedThreadPool(6));
downloadTracker =
new DownloadTracker(context, getHttpDataSourceFactory(context), downloadManager);
upgradeActionFile(context, DOWNLOAD_ACTION_FILE, downloadIndex, false);
upgradeActionFile(context, DOWNLOAD_TRACKER_ACTION_FILE, downloadIndex, true);
downloadManager = new DownloadManager(context, getDatabaseProvider(context), getDownloadCache(context), getHttpDataSourceFactory(context), Executors.newFixedThreadPool(6));
downloadTracker = new DownloadTracker(context, getHttpDataSourceFactory(context), downloadManager);
}
}
private static synchronized void upgradeActionFile(
Context context,
String fileName,
DefaultDownloadIndex downloadIndex,
boolean addNewDownloadsAsCompleted) {
private static synchronized void upgradeActionFile(Context context, String fileName, DefaultDownloadIndex downloadIndex, boolean addNewDownloadsAsCompleted) {
try {
ActionFileUpgradeUtil.upgradeAndDelete(
new File(getDownloadDirectory(context), fileName),
null,
downloadIndex,
true,
addNewDownloadsAsCompleted);
ActionFileUpgradeUtil.upgradeAndDelete(new File(getDownloadDirectory(context), fileName), null, downloadIndex, true, addNewDownloadsAsCompleted);
} catch (IOException e) {
Log.e(TAG, "Failed to upgrade action file: " + fileName, e);
}

View file

@ -6,9 +6,14 @@ import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import com.cappielloantonio.play.model.Album;
import com.cappielloantonio.play.model.Artist;
import com.cappielloantonio.play.model.Genre;
import com.cappielloantonio.play.model.Playlist;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.repository.SongRepository;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@ -24,10 +29,15 @@ public class SyncViewModel extends AndroidViewModel {
private boolean syncSong = false;
private boolean crossSyncSongGenre = false;
private ArrayList<Album> albumList = new ArrayList<>();
private ArrayList<Artist> artistList = new ArrayList<>();
private ArrayList<Genre> genreList = new ArrayList<>();
private ArrayList<Playlist> playlistList = new ArrayList<>();
private ArrayList<Song> songList = new ArrayList<>();
private int step = 0;
private int progress = 0;
public SyncViewModel(@NonNull Application application) {
super(application);
@ -54,7 +64,6 @@ public class SyncViewModel extends AndroidViewModel {
if (syncGenres) step++;
if (syncPlaylist) step++;
if (syncSong) step++;
if (crossSyncSongGenre) step++;
}
public boolean isSyncAlbum() {
@ -81,6 +90,50 @@ public class SyncViewModel extends AndroidViewModel {
return crossSyncSongGenre;
}
public ArrayList<Album> getAlbumList() {
return albumList;
}
public void setAlbumList(ArrayList<Album> albumList) {
this.albumList = albumList;
}
public ArrayList<Artist> getArtistList() {
return artistList;
}
public void setArtistList(ArrayList<Artist> artistList) {
this.artistList = artistList;
}
public ArrayList<Genre> getGenreList() {
return genreList;
}
public void setGenreList(ArrayList<Genre> genreList) {
this.genreList = genreList;
}
public ArrayList<Playlist> getPlaylistList() {
return playlistList;
}
public void setPlaylistList(ArrayList<Playlist> playlistList) {
this.playlistList = playlistList;
}
public ArrayList<Song> getSongList() {
return songList;
}
public void setSongList(ArrayList<Song> songList) {
this.songList = songList;
}
public void increaseProggress() {
progress++;
}
public int getStep() {
return step;
}
@ -89,13 +142,6 @@ public class SyncViewModel extends AndroidViewModel {
return progress;
}
public void setProgress(Boolean step) {
if (step) progress++;
}
public int getProgressBarInfo() {
return progress * (100 / step);
}
public Map<Integer, Song> getCatalogue() {
Map<Integer, Song> map = new HashMap<>();