mirror of
https://github.com/antebudimir/tempus.git
synced 2026-04-15 16:27:26 +00:00
wip: refactor song repo instant mix to take in a type
This commit is contained in:
parent
f59f572e5c
commit
8de9aff1f6
5 changed files with 93 additions and 52 deletions
|
|
@ -7,6 +7,7 @@ import com.cappielloantonio.tempo.App;
|
||||||
import com.cappielloantonio.tempo.subsonic.base.ApiResponse;
|
import com.cappielloantonio.tempo.subsonic.base.ApiResponse;
|
||||||
import com.cappielloantonio.tempo.subsonic.models.Child;
|
import com.cappielloantonio.tempo.subsonic.models.Child;
|
||||||
import com.cappielloantonio.tempo.subsonic.models.SubsonicResponse;
|
import com.cappielloantonio.tempo.subsonic.models.SubsonicResponse;
|
||||||
|
import com.cappielloantonio.tempo.util.Constants;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
@ -56,16 +57,26 @@ public class SongRepository {
|
||||||
/**
|
/**
|
||||||
* Used by ViewModels. Updates the LiveData list incrementally as songs are found.
|
* Used by ViewModels. Updates the LiveData list incrementally as songs are found.
|
||||||
*/
|
*/
|
||||||
public MutableLiveData<List<Child>> getInstantMix(String id, int count) {
|
public MutableLiveData<List<Child>> getInstantMix(String id, Constants.SEEDTYPE type, int count) {
|
||||||
MutableLiveData<List<Child>> instantMix = new MutableLiveData<>(new ArrayList<>());
|
MutableLiveData<List<Child>> instantMix = new MutableLiveData<>(new ArrayList<>());
|
||||||
|
|
||||||
performSmartMix(id, count, songs -> {
|
performSmartMix(id, type, count, songs -> {
|
||||||
List<Child> current = instantMix.getValue();
|
List<Child> current = instantMix.getValue();
|
||||||
if (current != null) {
|
if (current != null) {
|
||||||
for (Child s : songs) {
|
for (Child s : songs) {
|
||||||
if (!current.contains(s)) current.add(s);
|
if (!current.contains(s)) current.add(s);
|
||||||
}
|
}
|
||||||
instantMix.postValue(current);
|
|
||||||
|
if (current.size() < count / 2) {
|
||||||
|
fillWithRandom(count - current.size(), remainder -> {
|
||||||
|
for (Child r : remainder) {
|
||||||
|
if (!current.contains(r)) current.add(r);
|
||||||
|
}
|
||||||
|
instantMix.postValue(current);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
instantMix.postValue(current);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -75,57 +86,79 @@ public class SongRepository {
|
||||||
/**
|
/**
|
||||||
* Overloaded method used by other Repositories
|
* Overloaded method used by other Repositories
|
||||||
*/
|
*/
|
||||||
public void getInstantMix(String id, int count, MediaCallbackInternal callback) {
|
public void getInstantMix(String id, Constants.SEEDTYPE type, int count, MediaCallbackInternal callback) {
|
||||||
performSmartMix(id, count, callback);
|
performSmartMix(id, type, count, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void performSmartMix(final String id, final int count, final MediaCallbackInternal callback) {
|
private void performSmartMix(final String id, final Constants.SEEDTYPE type, final int count, final MediaCallbackInternal callback) {
|
||||||
App.getSubsonicClientInstance(false)
|
switch (type) {
|
||||||
.getBrowsingClient()
|
case ARTIST:
|
||||||
.getSimilarSongs(id, count)
|
fetchSimilarByArtist(id, count, callback);
|
||||||
.enqueue(new Callback<ApiResponse>() {
|
break;
|
||||||
@Override
|
case ALBUM:
|
||||||
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
fetchAlbumSongsThenSimilar(id, count, callback);
|
||||||
List<Child> songs = extractSongs(response, "similarSongs");
|
break;
|
||||||
if (!songs.isEmpty()) {
|
case TRACK:
|
||||||
callback.onSongsAvailable(songs);
|
fetchSingleTrackThenSimilar(id, count, callback);
|
||||||
}
|
break;
|
||||||
if (songs.size() < count / 2) {
|
}
|
||||||
fetchContextAndSeed(id, count, callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
|
|
||||||
fetchContextAndSeed(id, count, callback);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fetchContextAndSeed(final String id, final int count, final MediaCallbackInternal callback) {
|
private void fetchAlbumSongsThenSimilar(String albumId, int count, MediaCallbackInternal callback) {
|
||||||
App.getSubsonicClientInstance(false)
|
App.getSubsonicClientInstance(false).getBrowsingClient().getAlbum(albumId).enqueue(new Callback<ApiResponse>() {
|
||||||
.getBrowsingClient()
|
@Override
|
||||||
.getAlbum(id)
|
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
||||||
.enqueue(new Callback<ApiResponse>() {
|
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getAlbum() != null) {
|
||||||
@Override
|
List<Child> albumSongs = response.body().getSubsonicResponse().getAlbum().getSongs();
|
||||||
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
if (albumSongs != null && !albumSongs.isEmpty()) {
|
||||||
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getAlbum() != null) {
|
callback.onSongsAvailable(new ArrayList<>(albumSongs));
|
||||||
List<Child> albumSongs = response.body().getSubsonicResponse().getAlbum().getSongs();
|
fetchSimilarByArtist(albumSongs.get(0).getArtistId(), count, callback);
|
||||||
if (albumSongs != null && !albumSongs.isEmpty()) {
|
return;
|
||||||
callback.onSongsAvailable(new ArrayList<>(albumSongs));
|
|
||||||
String seedArtistId = albumSongs.get(0).getArtistId();
|
|
||||||
fetchSimilarByArtist(seedArtistId, count, callback);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fillWithRandom(count, callback);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
fillWithRandom(count, callback);
|
||||||
|
}
|
||||||
|
@Override public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
|
||||||
|
fillWithRandom(count, callback);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
private void fetchSingleTrackThenSimilar(String trackId, int count, MediaCallbackInternal callback) {
|
||||||
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
|
App.getSubsonicClientInstance(false).getBrowsingClient().getSong(trackId).enqueue(new Callback<ApiResponse>() {
|
||||||
fillWithRandom(count, callback);
|
@Override
|
||||||
|
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
Child song = response.body().getSubsonicResponse().getSong();
|
||||||
|
if (song != null) {
|
||||||
|
callback.onSongsAvailable(Collections.singletonList(song));
|
||||||
|
fetchSimilarOnly(trackId, count, callback);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
fillWithRandom(count, callback);
|
||||||
|
}
|
||||||
|
@Override public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
|
||||||
|
fillWithRandom(count, callback);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fetchSimilarOnly(String id, int count, MediaCallbackInternal callback) {
|
||||||
|
App.getSubsonicClientInstance(false).getBrowsingClient().getSimilarSongs(id, count).enqueue(new Callback<ApiResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
||||||
|
List<Child> songs = extractSongs(response, "similarSongs");
|
||||||
|
if (!songs.isEmpty()) {
|
||||||
|
callback.onSongsAvailable(songs);
|
||||||
|
} else {
|
||||||
|
fillWithRandom(count, callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
|
||||||
|
fillWithRandom(count, callback);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fetchSimilarByArtist(String artistId, final int count, final MediaCallbackInternal callback) {
|
private void fetchSimilarByArtist(String artistId, final int count, final MediaCallbackInternal callback) {
|
||||||
|
|
@ -138,9 +171,14 @@ public class SongRepository {
|
||||||
List<Child> similar = extractSongs(response, "similarSongs2");
|
List<Child> similar = extractSongs(response, "similarSongs2");
|
||||||
if (!similar.isEmpty()) {
|
if (!similar.isEmpty()) {
|
||||||
callback.onSongsAvailable(similar);
|
callback.onSongsAvailable(similar);
|
||||||
|
} else {
|
||||||
|
fillWithRandom(count, callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Override public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {}
|
@Override
|
||||||
|
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
|
||||||
|
fillWithRandom(count, callback);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import com.cappielloantonio.tempo.repository.SongRepository;
|
||||||
import com.cappielloantonio.tempo.subsonic.models.Child;
|
import com.cappielloantonio.tempo.subsonic.models.Child;
|
||||||
import com.cappielloantonio.tempo.subsonic.models.InternetRadioStation;
|
import com.cappielloantonio.tempo.subsonic.models.InternetRadioStation;
|
||||||
import com.cappielloantonio.tempo.subsonic.models.PodcastEpisode;
|
import com.cappielloantonio.tempo.subsonic.models.PodcastEpisode;
|
||||||
|
import com.cappielloantonio.tempo.util.Constants;
|
||||||
import com.cappielloantonio.tempo.util.MappingUtil;
|
import com.cappielloantonio.tempo.util.MappingUtil;
|
||||||
import com.cappielloantonio.tempo.util.Preferences;
|
import com.cappielloantonio.tempo.util.Preferences;
|
||||||
import com.cappielloantonio.tempo.viewmodel.PlaybackViewModel;
|
import com.cappielloantonio.tempo.viewmodel.PlaybackViewModel;
|
||||||
|
|
@ -442,7 +443,7 @@ public class MediaManager {
|
||||||
if (mediaItem != null && Preferences.isContinuousPlayEnabled() && Preferences.isInstantMixUsable()) {
|
if (mediaItem != null && Preferences.isContinuousPlayEnabled() && Preferences.isInstantMixUsable()) {
|
||||||
Preferences.setLastInstantMix();
|
Preferences.setLastInstantMix();
|
||||||
|
|
||||||
LiveData<List<Child>> instantMix = getSongRepository().getInstantMix(mediaItem.mediaId, 10);
|
LiveData<List<Child>> instantMix = getSongRepository().getInstantMix(mediaItem.mediaId, Constants.SEEDTYPE.TRACK, 10);
|
||||||
instantMix.observeForever(new Observer<List<Child>>() {
|
instantMix.observeForever(new Observer<List<Child>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onChanged(List<Child> media) {
|
public void onChanged(List<Child> media) {
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ 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.subsonic.models.Playlist;
|
import com.cappielloantonio.tempo.subsonic.models.Playlist;
|
||||||
import com.cappielloantonio.tempo.subsonic.models.Share;
|
import com.cappielloantonio.tempo.subsonic.models.Share;
|
||||||
|
import com.cappielloantonio.tempo.util.Constants;
|
||||||
import com.cappielloantonio.tempo.util.Preferences;
|
import com.cappielloantonio.tempo.util.Preferences;
|
||||||
import com.google.common.reflect.TypeToken;
|
import com.google.common.reflect.TypeToken;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
|
@ -223,7 +224,7 @@ public class HomeViewModel extends AndroidViewModel {
|
||||||
public LiveData<List<Child>> getMediaInstantMix(LifecycleOwner owner, Child media) {
|
public LiveData<List<Child>> getMediaInstantMix(LifecycleOwner owner, Child media) {
|
||||||
mediaInstantMix.setValue(Collections.emptyList());
|
mediaInstantMix.setValue(Collections.emptyList());
|
||||||
|
|
||||||
songRepository.getInstantMix(media.getId(), 20).observe(owner, mediaInstantMix::postValue);
|
songRepository.getInstantMix(media.getId(), Constants.SEEDTYPE.TRACK, 20).observe(owner, mediaInstantMix::postValue);
|
||||||
|
|
||||||
return mediaInstantMix;
|
return mediaInstantMix;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -278,7 +278,7 @@ public class PlayerBottomSheetViewModel extends AndroidViewModel {
|
||||||
public LiveData<List<Child>> getMediaInstantMix(LifecycleOwner owner, Child media) {
|
public LiveData<List<Child>> getMediaInstantMix(LifecycleOwner owner, Child media) {
|
||||||
instantMix.setValue(Collections.emptyList());
|
instantMix.setValue(Collections.emptyList());
|
||||||
|
|
||||||
songRepository.getInstantMix(media.getId(), 20).observe(owner, instantMix::postValue);
|
songRepository.getInstantMix(media.getId(), Constants.SEEDTYPE.TRACK, 20).observe(owner, instantMix::postValue);
|
||||||
|
|
||||||
return instantMix;
|
return instantMix;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ 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.Child;
|
import com.cappielloantonio.tempo.subsonic.models.Child;
|
||||||
import com.cappielloantonio.tempo.subsonic.models.Share;
|
import com.cappielloantonio.tempo.subsonic.models.Share;
|
||||||
|
import com.cappielloantonio.tempo.util.Constants;
|
||||||
import com.cappielloantonio.tempo.util.DownloadUtil;
|
import com.cappielloantonio.tempo.util.DownloadUtil;
|
||||||
import com.cappielloantonio.tempo.util.MappingUtil;
|
import com.cappielloantonio.tempo.util.MappingUtil;
|
||||||
import com.cappielloantonio.tempo.util.NetworkUtil;
|
import com.cappielloantonio.tempo.util.NetworkUtil;
|
||||||
|
|
@ -128,7 +129,7 @@ public class SongBottomSheetViewModel extends AndroidViewModel {
|
||||||
public LiveData<List<Child>> getInstantMix(LifecycleOwner owner, Child media) {
|
public LiveData<List<Child>> getInstantMix(LifecycleOwner owner, Child media) {
|
||||||
instantMix.setValue(Collections.emptyList());
|
instantMix.setValue(Collections.emptyList());
|
||||||
|
|
||||||
songRepository.getInstantMix(media.getId(), 20).observe(owner, instantMix::postValue);
|
songRepository.getInstantMix(media.getId(), Constants.SEEDTYPE.TRACK, 20).observe(owner, instantMix::postValue);
|
||||||
|
|
||||||
return instantMix;
|
return instantMix;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue