mirror of
https://github.com/antebudimir/tempus.git
synced 2026-04-15 16:27:26 +00:00
wip: initial refactor of instant mix in to be used everywhere else
This commit is contained in:
parent
bbd6d0864c
commit
3c1975f6bf
1 changed files with 174 additions and 160 deletions
|
|
@ -6,17 +6,22 @@ import androidx.lifecycle.MutableLiveData;
|
||||||
import com.cappielloantonio.tempo.App;
|
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 java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
import retrofit2.Callback;
|
import retrofit2.Callback;
|
||||||
import retrofit2.Response;
|
import retrofit2.Response;
|
||||||
|
|
||||||
public class SongRepository {
|
public class SongRepository {
|
||||||
private static final String TAG = "SongRepository";
|
|
||||||
|
public interface MediaCallbackInternal {
|
||||||
|
void onSongsAvailable(List<Child> songs);
|
||||||
|
}
|
||||||
|
|
||||||
public MutableLiveData<List<Child>> getStarredSongs(boolean random, int size) {
|
public MutableLiveData<List<Child>> getStarredSongs(boolean random, int size) {
|
||||||
MutableLiveData<List<Child>> starredSongs = new MutableLiveData<>(Collections.emptyList());
|
MutableLiveData<List<Child>> starredSongs = new MutableLiveData<>(Collections.emptyList());
|
||||||
|
|
@ -42,219 +47,228 @@ public class SongRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
|
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {}
|
||||||
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return starredSongs;
|
return starredSongs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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, int count) {
|
||||||
MutableLiveData<List<Child>> instantMix = new MutableLiveData<>();
|
MutableLiveData<List<Child>> instantMix = new MutableLiveData<>(new ArrayList<>());
|
||||||
|
|
||||||
App.getSubsonicClientInstance(false)
|
performSmartMix(id, count, songs -> {
|
||||||
.getBrowsingClient()
|
List<Child> current = instantMix.getValue();
|
||||||
.getSimilarSongs2(id, count)
|
if (current != null) {
|
||||||
.enqueue(new Callback<ApiResponse>() {
|
for (Child s : songs) {
|
||||||
@Override
|
if (!current.contains(s)) current.add(s);
|
||||||
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
}
|
||||||
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getSimilarSongs2() != null) {
|
instantMix.postValue(current);
|
||||||
instantMix.setValue(response.body().getSubsonicResponse().getSimilarSongs2().getSongs());
|
}
|
||||||
}
|
});
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
|
|
||||||
instantMix.setValue(null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return instantMix;
|
return instantMix;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MutableLiveData<List<Child>> getRandomSample(int number, Integer fromYear, Integer toYear) {
|
/**
|
||||||
MutableLiveData<List<Child>> randomSongsSample = new MutableLiveData<>();
|
* Overloaded method used by other Repositories
|
||||||
|
*/
|
||||||
|
public void getInstantMix(String id, int count, MediaCallbackInternal callback) {
|
||||||
|
performSmartMix(id, count, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performSmartMix(final String id, final int count, final MediaCallbackInternal callback) {
|
||||||
App.getSubsonicClientInstance(false)
|
App.getSubsonicClientInstance(false)
|
||||||
.getAlbumSongListClient()
|
.getBrowsingClient()
|
||||||
.getRandomSongs(number, fromYear, toYear)
|
.getSimilarSongs(id, count)
|
||||||
.enqueue(new Callback<ApiResponse>() {
|
.enqueue(new Callback<ApiResponse>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
||||||
List<Child> songs = new ArrayList<>();
|
List<Child> songs = extractSongs(response, "similarSongs");
|
||||||
|
if (!songs.isEmpty()) {
|
||||||
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getRandomSongs() != null && response.body().getSubsonicResponse().getRandomSongs().getSongs() != null) {
|
callback.onSongsAvailable(songs);
|
||||||
songs.addAll(response.body().getSubsonicResponse().getRandomSongs().getSongs());
|
}
|
||||||
|
if (songs.size() < count / 2) {
|
||||||
|
fetchContextAndSeed(id, count, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
randomSongsSample.setValue(songs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
|
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) {
|
||||||
|
App.getSubsonicClientInstance(false)
|
||||||
|
.getBrowsingClient()
|
||||||
|
.getAlbum(id)
|
||||||
|
.enqueue(new Callback<ApiResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getAlbum() != null) {
|
||||||
|
List<Child> albumSongs = response.body().getSubsonicResponse().getAlbum().getSongs();
|
||||||
|
if (albumSongs != null && !albumSongs.isEmpty()) {
|
||||||
|
callback.onSongsAvailable(new ArrayList<>(albumSongs));
|
||||||
|
String seedArtistId = albumSongs.get(0).getArtistId();
|
||||||
|
fetchSimilarByArtist(seedArtistId, count, callback);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
App.getSubsonicClientInstance(false)
|
||||||
|
.getBrowsingClient()
|
||||||
|
.getSimilarSongs2(artistId, count)
|
||||||
|
.enqueue(new Callback<ApiResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
||||||
|
List<Child> similar = extractSongs(response, "similarSongs2");
|
||||||
|
if (!similar.isEmpty()) {
|
||||||
|
callback.onSongsAvailable(similar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fillWithRandom(int target, final MediaCallbackInternal callback) {
|
||||||
|
App.getSubsonicClientInstance(false)
|
||||||
|
.getAlbumSongListClient()
|
||||||
|
.getRandomSongs(target, null, null)
|
||||||
|
.enqueue(new Callback<ApiResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
||||||
|
callback.onSongsAvailable(extractSongs(response, "randomSongs"));
|
||||||
|
}
|
||||||
|
@Override public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Child> extractSongs(Response<ApiResponse> response, String type) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
SubsonicResponse res = response.body().getSubsonicResponse();
|
||||||
|
List<Child> list = null;
|
||||||
|
if (type.equals("similarSongs") && res.getSimilarSongs() != null) {
|
||||||
|
list = res.getSimilarSongs().getSongs();
|
||||||
|
} else if (type.equals("similarSongs2") && res.getSimilarSongs2() != null) {
|
||||||
|
list = res.getSimilarSongs2().getSongs();
|
||||||
|
} else if (type.equals("randomSongs") && res.getRandomSongs() != null) {
|
||||||
|
list = res.getRandomSongs().getSongs();
|
||||||
|
}
|
||||||
|
return (list != null) ? list : new ArrayList<>();
|
||||||
|
}
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
public MutableLiveData<List<Child>> getRandomSample(int number, Integer fromYear, Integer toYear) {
|
||||||
|
MutableLiveData<List<Child>> randomSongsSample = new MutableLiveData<>();
|
||||||
|
App.getSubsonicClientInstance(false).getAlbumSongListClient().getRandomSongs(number, fromYear, toYear).enqueue(new Callback<ApiResponse>() {
|
||||||
|
@Override public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
||||||
|
List<Child> songs = new ArrayList<>();
|
||||||
|
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getRandomSongs() != null) {
|
||||||
|
songs.addAll(Objects.requireNonNull(response.body().getSubsonicResponse().getRandomSongs().getSongs()));
|
||||||
|
}
|
||||||
|
randomSongsSample.setValue(songs);
|
||||||
|
}
|
||||||
|
@Override public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {}
|
||||||
|
});
|
||||||
return randomSongsSample;
|
return randomSongsSample;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MutableLiveData<List<Child>> getRandomSampleWithGenre(int number, Integer fromYear, Integer toYear, String genre) {
|
public MutableLiveData<List<Child>> getRandomSampleWithGenre(int number, Integer fromYear, Integer toYear, String genre) {
|
||||||
MutableLiveData<List<Child>> randomSongsSample = new MutableLiveData<>();
|
MutableLiveData<List<Child>> randomSongsSample = new MutableLiveData<>();
|
||||||
|
App.getSubsonicClientInstance(false).getAlbumSongListClient().getRandomSongs(number, fromYear, toYear, genre).enqueue(new Callback<ApiResponse>() {
|
||||||
App.getSubsonicClientInstance(false)
|
@Override public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
||||||
.getAlbumSongListClient()
|
List<Child> songs = new ArrayList<>();
|
||||||
.getRandomSongs(number, fromYear, toYear, genre)
|
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getRandomSongs() != null) {
|
||||||
.enqueue(new Callback<ApiResponse>() {
|
songs.addAll(Objects.requireNonNull(response.body().getSubsonicResponse().getRandomSongs().getSongs()));
|
||||||
@Override
|
}
|
||||||
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
randomSongsSample.setValue(songs);
|
||||||
List<Child> songs = new ArrayList<>();
|
}
|
||||||
|
@Override public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {}
|
||||||
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getRandomSongs() != null && response.body().getSubsonicResponse().getRandomSongs().getSongs() != null) {
|
});
|
||||||
songs.addAll(response.body().getSubsonicResponse().getRandomSongs().getSongs());
|
|
||||||
}
|
|
||||||
|
|
||||||
randomSongsSample.setValue(songs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return randomSongsSample;
|
return randomSongsSample;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void scrobble(String id, boolean submission) {
|
public void scrobble(String id, boolean submission) {
|
||||||
App.getSubsonicClientInstance(false)
|
App.getSubsonicClientInstance(false).getMediaAnnotationClient().scrobble(id, submission).enqueue(new Callback<ApiResponse>() {
|
||||||
.getMediaAnnotationClient()
|
@Override public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {}
|
||||||
.scrobble(id, submission)
|
@Override public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {}
|
||||||
.enqueue(new Callback<ApiResponse>() {
|
});
|
||||||
@Override
|
|
||||||
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRating(String id, int rating) {
|
public void setRating(String id, int rating) {
|
||||||
App.getSubsonicClientInstance(false)
|
App.getSubsonicClientInstance(false).getMediaAnnotationClient().setRating(id, rating).enqueue(new Callback<ApiResponse>() {
|
||||||
.getMediaAnnotationClient()
|
@Override public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {}
|
||||||
.setRating(id, rating)
|
@Override public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {}
|
||||||
.enqueue(new Callback<ApiResponse>() {
|
});
|
||||||
@Override
|
|
||||||
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MutableLiveData<List<Child>> getSongsByGenre(String id, int page) {
|
public MutableLiveData<List<Child>> getSongsByGenre(String id, int page) {
|
||||||
MutableLiveData<List<Child>> songsByGenre = new MutableLiveData<>();
|
MutableLiveData<List<Child>> songsByGenre = new MutableLiveData<>();
|
||||||
|
App.getSubsonicClientInstance(false).getAlbumSongListClient().getSongsByGenre(id, 100, 100 * page).enqueue(new Callback<ApiResponse>() {
|
||||||
App.getSubsonicClientInstance(false)
|
@Override public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
||||||
.getAlbumSongListClient()
|
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getSongsByGenre() != null) {
|
||||||
.getSongsByGenre(id, 100, 100 * page)
|
songsByGenre.setValue(response.body().getSubsonicResponse().getSongsByGenre().getSongs());
|
||||||
.enqueue(new Callback<ApiResponse>() {
|
}
|
||||||
@Override
|
}
|
||||||
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
@Override public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {}
|
||||||
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getSongsByGenre() != null) {
|
});
|
||||||
songsByGenre.setValue(response.body().getSubsonicResponse().getSongsByGenre().getSongs());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return songsByGenre;
|
return songsByGenre;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MutableLiveData<List<Child>> getSongsByGenres(ArrayList<String> genresId) {
|
public MutableLiveData<List<Child>> getSongsByGenres(ArrayList<String> genresId) {
|
||||||
MutableLiveData<List<Child>> songsByGenre = new MutableLiveData<>();
|
MutableLiveData<List<Child>> songsByGenre = new MutableLiveData<>();
|
||||||
|
for (String id : genresId) {
|
||||||
for (String id : genresId)
|
App.getSubsonicClientInstance(false).getAlbumSongListClient().getSongsByGenre(id, 500, 0).enqueue(new Callback<ApiResponse>() {
|
||||||
App.getSubsonicClientInstance(false)
|
@Override public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
||||||
.getAlbumSongListClient()
|
List<Child> songs = new ArrayList<>();
|
||||||
.getSongsByGenre(id, 500, 0)
|
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getSongsByGenre() != null) {
|
||||||
.enqueue(new Callback<ApiResponse>() {
|
songs.addAll(Objects.requireNonNull(response.body().getSubsonicResponse().getSongsByGenre().getSongs()));
|
||||||
@Override
|
}
|
||||||
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
songsByGenre.setValue(songs);
|
||||||
List<Child> songs = new ArrayList<>();
|
}
|
||||||
|
@Override public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {}
|
||||||
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getSongsByGenre() != null) {
|
});
|
||||||
songs.addAll(response.body().getSubsonicResponse().getSongsByGenre().getSongs());
|
}
|
||||||
}
|
|
||||||
|
|
||||||
songsByGenre.setValue(songs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return songsByGenre;
|
return songsByGenre;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MutableLiveData<Child> getSong(String id) {
|
public MutableLiveData<Child> getSong(String id) {
|
||||||
MutableLiveData<Child> song = new MutableLiveData<>();
|
MutableLiveData<Child> song = new MutableLiveData<>();
|
||||||
|
App.getSubsonicClientInstance(false).getBrowsingClient().getSong(id).enqueue(new Callback<ApiResponse>() {
|
||||||
App.getSubsonicClientInstance(false)
|
@Override public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
||||||
.getBrowsingClient()
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
.getSong(id)
|
song.setValue(response.body().getSubsonicResponse().getSong());
|
||||||
.enqueue(new Callback<ApiResponse>() {
|
}
|
||||||
@Override
|
}
|
||||||
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
@Override public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {}
|
||||||
if (response.isSuccessful() && response.body() != null) {
|
});
|
||||||
song.setValue(response.body().getSubsonicResponse().getSong());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return song;
|
return song;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MutableLiveData<String> getSongLyrics(Child song) {
|
public MutableLiveData<String> getSongLyrics(Child song) {
|
||||||
MutableLiveData<String> lyrics = new MutableLiveData<>(null);
|
MutableLiveData<String> lyrics = new MutableLiveData<>(null);
|
||||||
|
App.getSubsonicClientInstance(false).getMediaRetrievalClient().getLyrics(song.getArtist(), song.getTitle()).enqueue(new Callback<ApiResponse>() {
|
||||||
App.getSubsonicClientInstance(false)
|
@Override public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
||||||
.getMediaRetrievalClient()
|
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getLyrics() != null) {
|
||||||
.getLyrics(song.getArtist(), song.getTitle())
|
lyrics.setValue(response.body().getSubsonicResponse().getLyrics().getValue());
|
||||||
.enqueue(new Callback<ApiResponse>() {
|
}
|
||||||
@Override
|
}
|
||||||
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
@Override public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {}
|
||||||
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getLyrics() != null) {
|
});
|
||||||
lyrics.setValue(response.body().getSubsonicResponse().getLyrics().getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return lyrics;
|
return lyrics;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue