mirror of
https://github.com/antebudimir/tempus.git
synced 2026-04-15 16:27:26 +00:00
feat: add heart to artist/album pages, fixed artist cover art failing
This commit is contained in:
parent
a110faabe3
commit
fe60fea928
6 changed files with 345 additions and 84 deletions
|
|
@ -4,7 +4,7 @@ import android.content.ComponentName;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Parcelable;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
|
|
@ -12,6 +12,7 @@ import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
import android.widget.ToggleButton;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
@ -60,12 +61,14 @@ public class AlbumPageFragment extends Fragment implements ClickCallback {
|
||||||
private SongHorizontalAdapter songHorizontalAdapter;
|
private SongHorizontalAdapter songHorizontalAdapter;
|
||||||
private ListenableFuture<MediaBrowser> mediaBrowserListenableFuture;
|
private ListenableFuture<MediaBrowser> mediaBrowserListenableFuture;
|
||||||
|
|
||||||
|
/** @noinspection deprecation*/
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setHasOptionsMenu(true);
|
setHasOptionsMenu(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @noinspection deprecation*/
|
||||||
@Override
|
@Override
|
||||||
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
|
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
|
||||||
super.onCreateOptionsMenu(menu, inflater);
|
super.onCreateOptionsMenu(menu, inflater);
|
||||||
|
|
@ -81,7 +84,7 @@ public class AlbumPageFragment extends Fragment implements ClickCallback {
|
||||||
albumPageViewModel = new ViewModelProvider(requireActivity()).get(AlbumPageViewModel.class);
|
albumPageViewModel = new ViewModelProvider(requireActivity()).get(AlbumPageViewModel.class);
|
||||||
playbackViewModel = new ViewModelProvider(requireActivity()).get(PlaybackViewModel.class);
|
playbackViewModel = new ViewModelProvider(requireActivity()).get(PlaybackViewModel.class);
|
||||||
|
|
||||||
init();
|
init(view);
|
||||||
initAppBar();
|
initAppBar();
|
||||||
initAlbumInfoTextButton();
|
initAlbumInfoTextButton();
|
||||||
initAlbumNotes();
|
initAlbumNotes();
|
||||||
|
|
@ -119,12 +122,13 @@ public class AlbumPageFragment extends Fragment implements ClickCallback {
|
||||||
bind = null;
|
bind = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @noinspection deprecation*/
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||||
if (item.getItemId() == R.id.action_rate_album) {
|
if (item.getItemId() == R.id.action_rate_album) {
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
AlbumID3 album = albumPageViewModel.getAlbum().getValue();
|
AlbumID3 album = albumPageViewModel.getAlbum().getValue();
|
||||||
bundle.putParcelable(Constants.ALBUM_OBJECT, (Parcelable) album);
|
bundle.putParcelable(Constants.ALBUM_OBJECT, album);
|
||||||
RatingDialog dialog = new RatingDialog();
|
RatingDialog dialog = new RatingDialog();
|
||||||
dialog.setArguments(bundle);
|
dialog.setArguments(bundle);
|
||||||
dialog.show(requireActivity().getSupportFragmentManager(), null);
|
dialog.show(requireActivity().getSupportFragmentManager(), null);
|
||||||
|
|
@ -159,8 +163,21 @@ public class AlbumPageFragment extends Fragment implements ClickCallback {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init() {
|
private void init(View view) {
|
||||||
albumPageViewModel.setAlbum(getViewLifecycleOwner(), requireArguments().getParcelable(Constants.ALBUM_OBJECT));
|
AlbumID3 albumArg = requireArguments().getParcelable(Constants.ALBUM_OBJECT);
|
||||||
|
assert albumArg != null;
|
||||||
|
albumPageViewModel.setAlbum(getViewLifecycleOwner(), albumArg);
|
||||||
|
ToggleButton favoriteToggle = view.findViewById(R.id.button_favorite);
|
||||||
|
favoriteToggle.setChecked(albumArg.getStarred() != null);
|
||||||
|
|
||||||
|
favoriteToggle.setOnClickListener(v -> {
|
||||||
|
albumPageViewModel.setFavorite();
|
||||||
|
});
|
||||||
|
albumPageViewModel.getAlbum().observe(getViewLifecycleOwner(), album -> {
|
||||||
|
if (album != null) {
|
||||||
|
favoriteToggle.setChecked(album.getStarred() != null);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initAppBar() {
|
private void initAppBar() {
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,18 @@ package com.cappielloantonio.tempo.ui.fragment;
|
||||||
|
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
import android.widget.ToggleButton;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
|
|
@ -40,6 +44,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
public class ArtistPageFragment extends Fragment implements ClickCallback {
|
public class ArtistPageFragment extends Fragment implements ClickCallback {
|
||||||
|
|
@ -63,7 +68,7 @@ public class ArtistPageFragment extends Fragment implements ClickCallback {
|
||||||
artistPageViewModel = new ViewModelProvider(requireActivity()).get(ArtistPageViewModel.class);
|
artistPageViewModel = new ViewModelProvider(requireActivity()).get(ArtistPageViewModel.class);
|
||||||
playbackViewModel = new ViewModelProvider(requireActivity()).get(PlaybackViewModel.class);
|
playbackViewModel = new ViewModelProvider(requireActivity()).get(PlaybackViewModel.class);
|
||||||
|
|
||||||
init();
|
init(view);
|
||||||
initAppBar();
|
initAppBar();
|
||||||
initArtistInfo();
|
initArtistInfo();
|
||||||
initPlayButtons();
|
initPlayButtons();
|
||||||
|
|
@ -100,7 +105,7 @@ public class ArtistPageFragment extends Fragment implements ClickCallback {
|
||||||
bind = null;
|
bind = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init() {
|
private void init(View view) {
|
||||||
artistPageViewModel.setArtist(requireArguments().getParcelable(Constants.ARTIST_OBJECT));
|
artistPageViewModel.setArtist(requireArguments().getParcelable(Constants.ARTIST_OBJECT));
|
||||||
|
|
||||||
bind.mostStreamedSongTextViewClickable.setOnClickListener(v -> {
|
bind.mostStreamedSongTextViewClickable.setOnClickListener(v -> {
|
||||||
|
|
@ -109,6 +114,10 @@ public class ArtistPageFragment extends Fragment implements ClickCallback {
|
||||||
bundle.putParcelable(Constants.ARTIST_OBJECT, artistPageViewModel.getArtist());
|
bundle.putParcelable(Constants.ARTIST_OBJECT, artistPageViewModel.getArtist());
|
||||||
activity.navController.navigate(R.id.action_artistPageFragment_to_songListPageFragment, bundle);
|
activity.navController.navigate(R.id.action_artistPageFragment_to_songListPageFragment, bundle);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ToggleButton favoriteToggle = view.findViewById(R.id.button_favorite);
|
||||||
|
favoriteToggle.setChecked(artistPageViewModel.getArtist().getStarred() != null);
|
||||||
|
favoriteToggle.setOnClickListener(v -> artistPageViewModel.setFavorite(requireContext()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initAppBar() {
|
private void initAppBar() {
|
||||||
|
|
@ -133,10 +142,54 @@ public class ArtistPageFragment extends Fragment implements ClickCallback {
|
||||||
if (bind != null)
|
if (bind != null)
|
||||||
bind.bioMoreTextViewClickable.setVisibility(artistInfo.getLastFmUrl() != null ? View.VISIBLE : View.GONE);
|
bind.bioMoreTextViewClickable.setVisibility(artistInfo.getLastFmUrl() != null ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
if (getContext() != null && bind != null) CustomGlideRequest.Builder
|
if (getContext() != null && bind != null) {
|
||||||
.from(requireContext(), artistPageViewModel.getArtist().getId(), CustomGlideRequest.ResourceType.Artist)
|
ArtistID3 currentArtist = artistPageViewModel.getArtist();
|
||||||
|
String primaryId = currentArtist.getCoverArtId() != null && !currentArtist.getCoverArtId().trim().isEmpty()
|
||||||
|
? currentArtist.getCoverArtId()
|
||||||
|
: currentArtist.getId();
|
||||||
|
|
||||||
|
final String fallbackId = (Objects.requireNonNull(primaryId).equals(currentArtist.getCoverArtId()) &&
|
||||||
|
currentArtist.getId() != null &&
|
||||||
|
!currentArtist.getId().equals(primaryId))
|
||||||
|
? currentArtist.getId()
|
||||||
|
: null;
|
||||||
|
|
||||||
|
CustomGlideRequest.Builder
|
||||||
|
.from(requireContext(), primaryId, CustomGlideRequest.ResourceType.Artist)
|
||||||
|
.build()
|
||||||
|
.listener(new com.bumptech.glide.request.RequestListener<Drawable>() {
|
||||||
|
@Override
|
||||||
|
public boolean onLoadFailed(@Nullable com.bumptech.glide.load.engine.GlideException e,
|
||||||
|
Object model,
|
||||||
|
@NonNull com.bumptech.glide.request.target.Target<Drawable> target,
|
||||||
|
boolean isFirstResource) {
|
||||||
|
if (e != null) {
|
||||||
|
e.getMessage();
|
||||||
|
if (e.getMessage().contains("400") && fallbackId != null) {
|
||||||
|
|
||||||
|
Log.d("ArtistCover", "Primary ID failed (400), trying fallback: " + fallbackId);
|
||||||
|
|
||||||
|
CustomGlideRequest.Builder
|
||||||
|
.from(requireContext(), fallbackId, CustomGlideRequest.ResourceType.Artist)
|
||||||
.build()
|
.build()
|
||||||
.into(bind.artistBackdropImageView);
|
.into(bind.artistBackdropImageView);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onResourceReady(@NonNull Drawable resource,
|
||||||
|
@NonNull Object model,
|
||||||
|
com.bumptech.glide.request.target.Target<Drawable> target,
|
||||||
|
@NonNull com.bumptech.glide.load.DataSource dataSource,
|
||||||
|
boolean isFirstResource) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.into(bind.artistBackdropImageView);
|
||||||
|
}
|
||||||
|
|
||||||
if (bind != null) bind.bioTextView.setText(normalizedBio);
|
if (bind != null) bind.bioTextView.setText(normalizedBio);
|
||||||
|
|
||||||
|
|
@ -150,29 +203,24 @@ public class ArtistPageFragment extends Fragment implements ClickCallback {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initPlayButtons() {
|
private void initPlayButtons() {
|
||||||
bind.artistPageShuffleButton.setOnClickListener(v -> {
|
bind.artistPageShuffleButton.setOnClickListener(v -> artistPageViewModel.getArtistShuffleList().observe(getViewLifecycleOwner(), songs -> {
|
||||||
artistPageViewModel.getArtistShuffleList().observe(getViewLifecycleOwner(), songs -> {
|
|
||||||
if (!songs.isEmpty()) {
|
if (!songs.isEmpty()) {
|
||||||
MediaManager.startQueue(mediaBrowserListenableFuture, songs, 0);
|
MediaManager.startQueue(mediaBrowserListenableFuture, songs, 0);
|
||||||
activity.setBottomSheetInPeek(true);
|
activity.setBottomSheetInPeek(true);
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(requireContext(), getString(R.string.artist_error_retrieving_tracks), Toast.LENGTH_SHORT).show();
|
Toast.makeText(requireContext(), getString(R.string.artist_error_retrieving_tracks), Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
});
|
|
||||||
|
|
||||||
bind.artistPageRadioButton.setOnClickListener(v -> {
|
bind.artistPageRadioButton.setOnClickListener(v -> artistPageViewModel.getArtistInstantMix().observe(getViewLifecycleOwner(), songs -> {
|
||||||
artistPageViewModel.getArtistInstantMix().observe(getViewLifecycleOwner(), songs -> {
|
|
||||||
if (songs != null && !songs.isEmpty()) {
|
if (songs != null && !songs.isEmpty()) {
|
||||||
MediaManager.startQueue(mediaBrowserListenableFuture, songs, 0);
|
MediaManager.startQueue(mediaBrowserListenableFuture, songs, 0);
|
||||||
activity.setBottomSheetInPeek(true);
|
activity.setBottomSheetInPeek(true);
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(requireContext(), getString(R.string.artist_error_retrieving_radio), Toast.LENGTH_SHORT).show();
|
Toast.makeText(requireContext(), getString(R.string.artist_error_retrieving_radio), Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initTopSongsView() {
|
private void initTopSongsView() {
|
||||||
|
|
|
||||||
|
|
@ -8,18 +8,23 @@ import androidx.lifecycle.LifecycleOwner;
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
import androidx.lifecycle.MutableLiveData;
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
|
import com.cappielloantonio.tempo.interfaces.StarCallback;
|
||||||
import com.cappielloantonio.tempo.repository.AlbumRepository;
|
import com.cappielloantonio.tempo.repository.AlbumRepository;
|
||||||
import com.cappielloantonio.tempo.repository.ArtistRepository;
|
import com.cappielloantonio.tempo.repository.ArtistRepository;
|
||||||
|
import com.cappielloantonio.tempo.repository.FavoriteRepository;
|
||||||
import com.cappielloantonio.tempo.subsonic.models.AlbumID3;
|
import com.cappielloantonio.tempo.subsonic.models.AlbumID3;
|
||||||
import com.cappielloantonio.tempo.subsonic.models.AlbumInfo;
|
import com.cappielloantonio.tempo.subsonic.models.AlbumInfo;
|
||||||
import com.cappielloantonio.tempo.subsonic.models.ArtistID3;
|
import com.cappielloantonio.tempo.subsonic.models.ArtistID3;
|
||||||
import com.cappielloantonio.tempo.subsonic.models.Child;
|
import com.cappielloantonio.tempo.subsonic.models.Child;
|
||||||
|
import com.cappielloantonio.tempo.util.NetworkUtil;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class AlbumPageViewModel extends AndroidViewModel {
|
public class AlbumPageViewModel extends AndroidViewModel {
|
||||||
private final AlbumRepository albumRepository;
|
private final AlbumRepository albumRepository;
|
||||||
private final ArtistRepository artistRepository;
|
private final ArtistRepository artistRepository;
|
||||||
|
private final FavoriteRepository favoriteRepository;
|
||||||
private String albumId;
|
private String albumId;
|
||||||
private String artistId;
|
private String artistId;
|
||||||
private final MutableLiveData<AlbumID3> album = new MutableLiveData<>(null);
|
private final MutableLiveData<AlbumID3> album = new MutableLiveData<>(null);
|
||||||
|
|
@ -29,6 +34,7 @@ public class AlbumPageViewModel extends AndroidViewModel {
|
||||||
|
|
||||||
albumRepository = new AlbumRepository();
|
albumRepository = new AlbumRepository();
|
||||||
artistRepository = new ArtistRepository();
|
artistRepository = new ArtistRepository();
|
||||||
|
favoriteRepository = new FavoriteRepository();
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<List<Child>> getAlbumSongLiveList() {
|
public LiveData<List<Child>> getAlbumSongLiveList() {
|
||||||
|
|
@ -49,6 +55,61 @@ public class AlbumPageViewModel extends AndroidViewModel {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setFavorite() {
|
||||||
|
AlbumID3 currentAlbum = album.getValue();
|
||||||
|
if (currentAlbum == null) return;
|
||||||
|
|
||||||
|
if (currentAlbum.getStarred() != null) {
|
||||||
|
if (NetworkUtil.isOffline()) {
|
||||||
|
removeFavoriteOffline(currentAlbum);
|
||||||
|
} else {
|
||||||
|
removeFavoriteOnline(currentAlbum);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (NetworkUtil.isOffline()) {
|
||||||
|
setFavoriteOffline(currentAlbum);
|
||||||
|
} else {
|
||||||
|
setFavoriteOnline(currentAlbum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeFavoriteOffline(AlbumID3 album) {
|
||||||
|
favoriteRepository.starLater(null, album.getId(), null, false);
|
||||||
|
album.setStarred(null);
|
||||||
|
this.album.postValue(album);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeFavoriteOnline(AlbumID3 album) {
|
||||||
|
favoriteRepository.unstar(null, album.getId(), null, new StarCallback() {
|
||||||
|
@Override
|
||||||
|
public void onError() {
|
||||||
|
favoriteRepository.starLater(null, album.getId(), null, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
album.setStarred(null);
|
||||||
|
this.album.postValue(album);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setFavoriteOffline(AlbumID3 album) {
|
||||||
|
favoriteRepository.starLater(null, album.getId(), null, true);
|
||||||
|
album.setStarred(new Date());
|
||||||
|
this.album.postValue(album);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setFavoriteOnline(AlbumID3 album) {
|
||||||
|
favoriteRepository.star(null, album.getId(), null, new StarCallback() {
|
||||||
|
@Override
|
||||||
|
public void onError() {
|
||||||
|
favoriteRepository.starLater(null, album.getId(), null, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
album.setStarred(new Date());
|
||||||
|
this.album.postValue(album);
|
||||||
|
}
|
||||||
|
|
||||||
public LiveData<ArtistID3> getArtist() {
|
public LiveData<ArtistID3> getArtist() {
|
||||||
return artistRepository.getArtistInfo(artistId);
|
return artistRepository.getArtistInfo(artistId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,37 @@
|
||||||
package com.cappielloantonio.tempo.viewmodel;
|
package com.cappielloantonio.tempo.viewmodel;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.OptIn;
|
||||||
import androidx.lifecycle.AndroidViewModel;
|
import androidx.lifecycle.AndroidViewModel;
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.media3.common.util.UnstableApi;
|
||||||
|
|
||||||
|
import com.cappielloantonio.tempo.model.Download;
|
||||||
|
import com.cappielloantonio.tempo.interfaces.StarCallback;
|
||||||
import com.cappielloantonio.tempo.repository.AlbumRepository;
|
import com.cappielloantonio.tempo.repository.AlbumRepository;
|
||||||
import com.cappielloantonio.tempo.repository.ArtistRepository;
|
import com.cappielloantonio.tempo.repository.ArtistRepository;
|
||||||
|
import com.cappielloantonio.tempo.repository.FavoriteRepository;
|
||||||
import com.cappielloantonio.tempo.subsonic.models.AlbumID3;
|
import com.cappielloantonio.tempo.subsonic.models.AlbumID3;
|
||||||
import com.cappielloantonio.tempo.subsonic.models.ArtistID3;
|
import com.cappielloantonio.tempo.subsonic.models.ArtistID3;
|
||||||
import com.cappielloantonio.tempo.subsonic.models.ArtistInfo2;
|
import com.cappielloantonio.tempo.subsonic.models.ArtistInfo2;
|
||||||
import com.cappielloantonio.tempo.subsonic.models.Child;
|
import com.cappielloantonio.tempo.subsonic.models.Child;
|
||||||
|
import com.cappielloantonio.tempo.util.DownloadUtil;
|
||||||
|
import com.cappielloantonio.tempo.util.MappingUtil;
|
||||||
|
import com.cappielloantonio.tempo.util.NetworkUtil;
|
||||||
|
import com.cappielloantonio.tempo.util.Preferences;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class ArtistPageViewModel extends AndroidViewModel {
|
public class ArtistPageViewModel extends AndroidViewModel {
|
||||||
private final AlbumRepository albumRepository;
|
private final AlbumRepository albumRepository;
|
||||||
private final ArtistRepository artistRepository;
|
private final ArtistRepository artistRepository;
|
||||||
|
private final FavoriteRepository favoriteRepository;
|
||||||
|
|
||||||
private ArtistID3 artist;
|
private ArtistID3 artist;
|
||||||
|
|
||||||
|
|
@ -26,6 +40,7 @@ public class ArtistPageViewModel extends AndroidViewModel {
|
||||||
|
|
||||||
albumRepository = new AlbumRepository();
|
albumRepository = new AlbumRepository();
|
||||||
artistRepository = new ArtistRepository();
|
artistRepository = new ArtistRepository();
|
||||||
|
favoriteRepository = new FavoriteRepository();
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<List<AlbumID3>> getAlbumList() {
|
public LiveData<List<AlbumID3>> getAlbumList() {
|
||||||
|
|
@ -55,4 +70,71 @@ public class ArtistPageViewModel extends AndroidViewModel {
|
||||||
public void setArtist(ArtistID3 artist) {
|
public void setArtist(ArtistID3 artist) {
|
||||||
this.artist = artist;
|
this.artist = artist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setFavorite(Context context) {
|
||||||
|
if (artist.getStarred() != null) {
|
||||||
|
if (NetworkUtil.isOffline()) {
|
||||||
|
removeFavoriteOffline();
|
||||||
|
} else {
|
||||||
|
removeFavoriteOnline();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (NetworkUtil.isOffline()) {
|
||||||
|
setFavoriteOffline();
|
||||||
|
} else {
|
||||||
|
setFavoriteOnline(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeFavoriteOffline() {
|
||||||
|
favoriteRepository.starLater(null, null, artist.getId(), false);
|
||||||
|
artist.setStarred(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeFavoriteOnline() {
|
||||||
|
favoriteRepository.unstar(null, null, artist.getId(), new StarCallback() {
|
||||||
|
@Override
|
||||||
|
public void onError() {
|
||||||
|
favoriteRepository.starLater(null, null, artist.getId(), false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
artist.setStarred(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setFavoriteOffline() {
|
||||||
|
favoriteRepository.starLater(null, null, artist.getId(), true);
|
||||||
|
artist.setStarred(new Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setFavoriteOnline(Context context) {
|
||||||
|
favoriteRepository.star(null, null, artist.getId(), new StarCallback() {
|
||||||
|
@Override
|
||||||
|
public void onError() {
|
||||||
|
favoriteRepository.starLater(null, null, artist.getId(), true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
artist.setStarred(new Date());
|
||||||
|
|
||||||
|
if (Preferences.isStarredArtistsSyncEnabled()) {
|
||||||
|
artistRepository.getArtistAllSongs(artist.getId(), new ArtistRepository.ArtistSongsCallback() {
|
||||||
|
@OptIn(markerClass = UnstableApi.class)
|
||||||
|
@Override
|
||||||
|
public void onSongsCollected(List<Child> songs) {
|
||||||
|
if (songs != null && !songs.isEmpty()) {
|
||||||
|
DownloadUtil.getDownloadTracker(context).download(
|
||||||
|
MappingUtil.mapDownloads(songs),
|
||||||
|
songs.stream().map(Download::new).collect(Collectors.toList())
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Log.d("ArtistSync", "Artist sync preference is disabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,6 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/album_notes_textview" />
|
app:layout_constraintTop_toBottomOf="@+id/album_notes_textview" />
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
|
|
@ -188,23 +187,33 @@
|
||||||
app:layout_constraintTop_toBottomOf="@+id/album_detail_view" />
|
app:layout_constraintTop_toBottomOf="@+id/album_detail_view" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/album_page_button_layout"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingTop="4dp"
|
android:paddingTop="4dp"
|
||||||
android:paddingBottom="4dp"
|
android:paddingBottom="4dp"
|
||||||
|
android:paddingStart="12dp"
|
||||||
|
android:paddingEnd="12dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/upper_button_divider">
|
app:layout_constraintTop_toBottomOf="@+id/upper_button_divider">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/album_page_button_layout"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/album_page_play_button"
|
android:id="@+id/album_page_play_button"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_marginEnd="4dp"
|
||||||
android:padding="10dp"
|
android:padding="10dp"
|
||||||
android:text="@string/album_page_play_button"
|
android:text="@string/album_page_play_button"
|
||||||
android:textAllCaps="false"
|
android:textAllCaps="false"
|
||||||
|
|
@ -216,9 +225,9 @@
|
||||||
android:id="@+id/album_page_shuffle_button"
|
android:id="@+id/album_page_shuffle_button"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_marginEnd="4dp"
|
||||||
android:padding="10dp"
|
android:padding="10dp"
|
||||||
android:text="@string/album_page_shuffle_button"
|
android:text="@string/album_page_shuffle_button"
|
||||||
android:textAllCaps="false"
|
android:textAllCaps="false"
|
||||||
|
|
@ -227,6 +236,22 @@
|
||||||
app:iconPadding="18dp" />
|
app:iconPadding="18dp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ToggleButton
|
||||||
|
android:id="@+id/button_favorite"
|
||||||
|
android:layout_width="34dp"
|
||||||
|
android:layout_height="34dp"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:layout_marginEnd="0dp"
|
||||||
|
android:background="@drawable/button_favorite_selector"
|
||||||
|
android:checked="false"
|
||||||
|
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text=""
|
||||||
|
android:textOff=""
|
||||||
|
android:textOn="" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/album_bio_label"
|
android:id="@+id/album_bio_label"
|
||||||
style="@style/LabelSmall"
|
style="@style/LabelSmall"
|
||||||
|
|
@ -239,7 +264,8 @@
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/album_page_button_layout" />
|
app:layout_constraintTop_toBottomOf="@id/album_page_button_layout"
|
||||||
|
tools:ignore="NotSibling" />
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/bottom_button_divider"
|
android:id="@+id/bottom_button_divider"
|
||||||
|
|
@ -249,7 +275,7 @@
|
||||||
android:layout_marginBottom="18dp"
|
android:layout_marginBottom="18dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/album_page_button_layout" />
|
app:layout_constraintTop_toBottomOf="@+id/album_bio_label" />
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,20 +63,31 @@
|
||||||
android:layout_marginEnd="18dp" />
|
android:layout_marginEnd="18dp" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/album_page_button_layout"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingTop="4dp"
|
android:paddingTop="4dp"
|
||||||
android:paddingBottom="4dp">
|
android:paddingBottom="4dp"
|
||||||
|
android:paddingStart="12dp"
|
||||||
|
android:paddingEnd="12dp"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/album_page_button_layout"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/artist_page_shuffle_button"
|
android:id="@+id/artist_page_shuffle_button"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="6dp"
|
||||||
|
android:layout_marginEnd="6dp"
|
||||||
android:padding="10dp"
|
android:padding="10dp"
|
||||||
android:text="@string/artist_page_shuffle_button"
|
android:text="@string/artist_page_shuffle_button"
|
||||||
android:textAllCaps="false"
|
android:textAllCaps="false"
|
||||||
|
|
@ -88,9 +99,9 @@
|
||||||
android:id="@+id/artist_page_radio_button"
|
android:id="@+id/artist_page_radio_button"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="6dp"
|
||||||
|
android:layout_marginEnd="6dp"
|
||||||
android:padding="10dp"
|
android:padding="10dp"
|
||||||
android:text="@string/artist_page_radio_button"
|
android:text="@string/artist_page_radio_button"
|
||||||
android:textAllCaps="false"
|
android:textAllCaps="false"
|
||||||
|
|
@ -99,6 +110,22 @@
|
||||||
app:iconPadding="18dp" />
|
app:iconPadding="18dp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ToggleButton
|
||||||
|
android:id="@+id/button_favorite"
|
||||||
|
android:layout_width="34dp"
|
||||||
|
android:layout_height="34dp"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:layout_marginEnd="0dp"
|
||||||
|
android:background="@drawable/button_favorite_selector"
|
||||||
|
android:checked="false"
|
||||||
|
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text=""
|
||||||
|
android:textOff=""
|
||||||
|
android:textOn="" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/bottom_button_divider"
|
android:id="@+id/bottom_button_divider"
|
||||||
style="@style/Divider"
|
style="@style/Divider"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue