- Switched from subsonic-response in xml to response in json

- Retrofitting of all Subsonic models
This commit is contained in:
antonio 2023-03-08 19:19:09 +01:00
parent ca15f51c85
commit 521c51b17e
85 changed files with 682 additions and 898 deletions

View file

@ -7,11 +7,11 @@ android {
buildToolsVersion '33.0.0'
defaultConfig {
applicationId "com.cappielloantonio.playforsubsonic"
applicationId "com.cappielloantonio.playforsubsonic.test"
minSdkVersion 26
targetSdkVersion 33
versionCode 4
versionName "2.1.0"
versionName "3.0.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@ -66,33 +66,27 @@ dependencies {
implementation "com.arthurivanets.adapster:adapster:1.0.13"
// Glide
implementation 'com.github.bumptech.glide:glide:4.14.2'
implementation 'com.github.bumptech.glide:annotations:4.14.2'
implementation 'com.github.bumptech.glide:glide:4.15.0'
implementation 'com.github.bumptech.glide:annotations:4.15.0'
// Media3
implementation 'androidx.media3:media3-session:1.0.0-rc01'
implementation 'androidx.media3:media3-common:1.0.0-rc01'
implementation 'androidx.media3:media3-exoplayer:1.0.0-rc01'
implementation 'androidx.media3:media3-ui:1.0.0-rc01'
implementation 'androidx.media3:media3-cast:1.0.0-rc01'
implementation 'androidx.media3:media3-session:1.0.0-rc02'
implementation 'androidx.media3:media3-common:1.0.0-rc02'
implementation 'androidx.media3:media3-exoplayer:1.0.0-rc02'
implementation 'androidx.media3:media3-ui:1.0.0-rc02'
implementation 'androidx.media3:media3-cast:1.0.0-rc02'
annotationProcessor 'com.github.bumptech.glide:compiler:4.14.2'
annotationProcessor 'com.github.bumptech.glide:compiler:4.15.0'
annotationProcessor 'androidx.room:room-compiler:2.5.0'
// Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.6'
implementation 'com.tickaroo.tikxml:retrofit-converter:0.8.15'
// XMLParser
implementation 'com.tickaroo.tikxml:annotation:0.9.0_11-SNAPSHOT'
implementation 'com.tickaroo.tikxml:core:0.9.0_11-SNAPSHOT'
annotationProcessor 'com.tickaroo.tikxml:processor:0.9.0_11-SNAPSHOT'
implementation 'com.tickaroo.tikxml:converter-date-rfc3339:0.9.0_11-SNAPSHOT'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
// Crash Report
// debugImplementation 'com.balsikandar.android:crashreporter:1.1.0'
// DB debug
// debugImplementation 'com.amitshekhar.android:debug-db:1.0.6'
debugImplementation 'com.amitshekhar.android:debug-db:1.0.6'
}

View file

@ -9,7 +9,6 @@ import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.navigation.Navigation;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
@ -83,7 +82,7 @@ public class ArtistSimilarAdapter extends RecyclerView.Adapter<ArtistSimilarAdap
.into(cover);
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
public class ViewHolder extends RecyclerView.ViewHolder {
TextView textArtistName;
ImageView cover;
@ -93,27 +92,12 @@ public class ArtistSimilarAdapter extends RecyclerView.Adapter<ArtistSimilarAdap
textArtistName = itemView.findViewById(R.id.artist_name_label);
cover = itemView.findViewById(R.id.similar_artist_cover_image_view);
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
itemView.setOnClickListener(v -> onClick());
itemView.setOnLongClickListener(v -> onLongClick());
textArtistName.setSelected(true);
}
@Override
public void onClick(View view) {
Bundle bundle = new Bundle();
bundle.putParcelable("artist_object", artists.get(getBindingAdapterPosition()));
Navigation.findNavController(view).navigate(R.id.artistPageFragment, bundle);
}
@Override
public boolean onLongClick(View view) {
Bundle bundle = new Bundle();
bundle.putParcelable("artist_object", artists.get(getBindingAdapterPosition()));
Navigation.findNavController(view).navigate(R.id.artistBottomSheetDialog, bundle);
return true;
}
public void onClick() {
Bundle bundle = new Bundle();
bundle.putParcelable("artist_object", artists.get(getBindingAdapterPosition()));

View file

@ -78,8 +78,6 @@ public class PlaylistDialogHorizontalAdapter extends RecyclerView.Adapter<Playli
}
public void onClick() {
Bundle bundle = new Bundle();
bundle.putParcelable("playlist_object", playlists.get(getBindingAdapterPosition()));

View file

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

View file

@ -1,11 +1,14 @@
package com.cappielloantonio.play.model
import androidx.annotation.Keep
import androidx.media3.common.MediaItem
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.cappielloantonio.play.subsonic.models.Child
import com.cappielloantonio.play.util.Preferences
import kotlinx.android.parcel.Parcelize
import java.util.*
@Keep
@Parcelize
@ -16,4 +19,39 @@ class Chronology(@PrimaryKey override val id: String) : Child(id) {
@ColumnInfo(name = "server")
var server: String? = null
constructor(mediaItem: MediaItem) : this(mediaItem.mediaMetadata.extras!!.getString("id")!!) {
parentId = mediaItem.mediaMetadata.extras!!.getString("parentId")
isDir = mediaItem.mediaMetadata.extras!!.getBoolean("isDir")
title = mediaItem.mediaMetadata.extras!!.getString("title")
album = mediaItem.mediaMetadata.extras!!.getString("album")
artist = mediaItem.mediaMetadata.extras!!.getString("artist")
track = mediaItem.mediaMetadata.extras!!.getInt("track")
year = mediaItem.mediaMetadata.extras!!.getInt("year")
genre = mediaItem.mediaMetadata.extras!!.getString("genre")
coverArtId = mediaItem.mediaMetadata.extras!!.getString("coverArtId")
size = mediaItem.mediaMetadata.extras!!.getLong("size")
contentType = mediaItem.mediaMetadata.extras!!.getString("contentType")
suffix = mediaItem.mediaMetadata.extras!!.getString("suffix")
transcodedContentType = mediaItem.mediaMetadata.extras!!.getString("transcodedContentType")
transcodedSuffix = mediaItem.mediaMetadata.extras!!.getString("transcodedSuffix")
duration = mediaItem.mediaMetadata.extras!!.getInt("duration")
bitrate = mediaItem.mediaMetadata.extras!!.getInt("bitrate")
path = mediaItem.mediaMetadata.extras!!.getString("path")
isVideo = mediaItem.mediaMetadata.extras!!.getBoolean("isVideo")
userRating = mediaItem.mediaMetadata.extras!!.getInt("userRating")
averageRating = mediaItem.mediaMetadata.extras!!.getDouble("averageRating")
playCount = mediaItem.mediaMetadata.extras!!.getLong("playCount")
discNumber = mediaItem.mediaMetadata.extras!!.getInt("discNumber")
created = Date(mediaItem.mediaMetadata.extras!!.getLong("created"))
starred = Date(mediaItem.mediaMetadata.extras!!.getLong("starred"))
albumId = mediaItem.mediaMetadata.extras!!.getString("albumId")
artistId = mediaItem.mediaMetadata.extras!!.getString("artistId")
type = mediaItem.mediaMetadata.extras!!.getString("type")
bookmarkPosition = mediaItem.mediaMetadata.extras!!.getLong("bookmarkPosition")
originalWidth = mediaItem.mediaMetadata.extras!!.getInt("originalWidth")
originalHeight = mediaItem.mediaMetadata.extras!!.getInt("originalHeight")
server = Preferences.getServerId()
timestamp = Date().time
}
}

View file

@ -11,16 +11,49 @@ import kotlinx.android.parcel.Parcelize
@Parcelize
@Entity(tableName = "queue")
class Queue(override val id: String) : Child(id) {
@PrimaryKey(autoGenerate = true)
@PrimaryKey
@ColumnInfo(name = "track_order")
var trackOrder: Int = 0
@ColumnInfo(name = "last_play", defaultValue = "0")
@ColumnInfo(name = "last_play")
var lastPlay: Long = 0
@ColumnInfo(name = "playing_changed", defaultValue = "0")
@ColumnInfo(name = "playing_changed")
var playingChanged: Long = 0
@ColumnInfo(name = "stream_id")
var streamId: String? = null
constructor(child: Child) : this(child.id) {
parentId = child.parentId
isDir = child.isDir
title = child.title
album = child.album
artist = child.artist
track = child.track
year = child.year
genre = child.genre
coverArtId = child.coverArtId
size = child.size
contentType = child.contentType
suffix = child.suffix
transcodedContentType = child.transcodedContentType
transcodedSuffix = child.transcodedSuffix
duration = child.duration
bitrate = child.bitrate
path = child.path
isVideo = child.isVideo
userRating = child.userRating
averageRating = child.averageRating
playCount = child.playCount
discNumber = child.discNumber
created = child.created
starred = child.starred
albumId = child.albumId
artistId = child.artistId
type = child.type
bookmarkPosition = child.bookmarkPosition
originalWidth = child.originalWidth
originalHeight = child.originalHeight
}
}

View file

@ -8,6 +8,7 @@ import androidx.lifecycle.MutableLiveData;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.interfaces.DecadesCallback;
import com.cappielloantonio.play.interfaces.MediaCallback;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.AlbumID3;
import com.cappielloantonio.play.subsonic.models.Child;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
@ -32,21 +33,21 @@ public class AlbumRepository {
}
public MutableLiveData<List<AlbumID3>> getAlbums(String type, int size, Integer fromYear, Integer toYear) {
MutableLiveData<List<AlbumID3>> listLiveAlbums = new MutableLiveData<>(new ArrayList<>());
MutableLiveData<List<AlbumID3>> listLiveAlbums = new MutableLiveData<>();
App.getSubsonicClientInstance(application, false)
.getAlbumSongListClient()
.getAlbumList2(type, size, 0, fromYear, toYear)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getAlbumList2() != null) {
listLiveAlbums.setValue(response.body().getAlbumList2().getAlbums());
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getAlbumList2() != null) {
listLiveAlbums.setValue(response.body().getSubsonicResponse().getAlbumList2().getAlbums());
}
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -60,11 +61,11 @@ public class AlbumRepository {
App.getSubsonicClientInstance(application, false)
.getAlbumSongListClient()
.getStarred2()
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getStarred2() != null) {
List<AlbumID3> albums = response.body().getStarred2().getAlbums();
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getStarred2() != null) {
List<AlbumID3> albums = response.body().getSubsonicResponse().getStarred2().getAlbums();
if (random) {
Collections.shuffle(albums);
@ -76,7 +77,7 @@ public class AlbumRepository {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -88,14 +89,14 @@ public class AlbumRepository {
App.getSubsonicClientInstance(application, false)
.getMediaAnnotationClient()
.star(null, id, null)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -105,14 +106,14 @@ public class AlbumRepository {
App.getSubsonicClientInstance(application, false)
.getMediaAnnotationClient()
.unstar(null, id, null)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -122,14 +123,14 @@ public class AlbumRepository {
App.getSubsonicClientInstance(application, false)
.getMediaAnnotationClient()
.setRating(id, rating)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -141,20 +142,20 @@ public class AlbumRepository {
App.getSubsonicClientInstance(application, false)
.getBrowsingClient()
.getAlbum(id)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
List<Child> tracks = new ArrayList<>();
if (response.isSuccessful() && response.body() != null && response.body().getAlbum() != null) {
tracks.addAll(response.body().getAlbum().getSongs());
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getAlbum() != null) {
tracks.addAll(response.body().getSubsonicResponse().getAlbum().getSongs());
}
albumTracks.setValue(tracks);
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -168,18 +169,18 @@ public class AlbumRepository {
App.getSubsonicClientInstance(application, false)
.getBrowsingClient()
.getArtist(id)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getArtist() != null) {
List<AlbumID3> albums = response.body().getArtist().getAlbums();
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getArtist() != null) {
List<AlbumID3> albums = response.body().getSubsonicResponse().getArtist().getAlbums();
albums.sort(Comparator.comparing(AlbumID3::getYear));
artistsAlbum.setValue(albums);
}
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -193,16 +194,16 @@ public class AlbumRepository {
App.getSubsonicClientInstance(application, false)
.getBrowsingClient()
.getAlbum(id)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getAlbum() != null) {
album.setValue(response.body().getAlbum());
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getAlbum() != null) {
album.setValue(response.body().getSubsonicResponse().getAlbum());
}
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -214,20 +215,20 @@ public class AlbumRepository {
App.getSubsonicClientInstance(application, false)
.getBrowsingClient()
.getSimilarSongs2(album.getId(), count)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
List<Child> songs = new ArrayList<>();
if (response.isSuccessful() && response.body() != null && response.body().getSimilarSongs2() != null) {
songs.addAll(response.body().getSimilarSongs2().getSongs());
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getSimilarSongs2() != null) {
songs.addAll(response.body().getSubsonicResponse().getSimilarSongs2().getSongs());
}
callback.onLoadMedia(songs);
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
callback.onLoadMedia(new ArrayList<>());
}
});
@ -259,16 +260,16 @@ public class AlbumRepository {
App.getSubsonicClientInstance(application, false)
.getAlbumSongListClient()
.getAlbumList2("byYear", 1, 0, 1900, Calendar.getInstance().get(Calendar.YEAR))
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getAlbumList2() != null && response.body().getAlbumList2().getAlbums() != null && !response.body().getAlbumList2().getAlbums().isEmpty()) {
callback.onLoadYear(response.body().getAlbumList2().getAlbums().get(0).getYear());
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getAlbumList2() != null && response.body().getSubsonicResponse().getAlbumList2().getAlbums() != null && !response.body().getSubsonicResponse().getAlbumList2().getAlbums().isEmpty()) {
callback.onLoadYear(response.body().getSubsonicResponse().getAlbumList2().getAlbums().get(0).getYear());
}
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
callback.onLoadYear(-1);
}
});
@ -278,12 +279,12 @@ public class AlbumRepository {
App.getSubsonicClientInstance(application, false)
.getAlbumSongListClient()
.getAlbumList2("byYear", 1, 0, Calendar.getInstance().get(Calendar.YEAR), 1900)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getAlbumList2() != null) {
if (response.body().getAlbumList2().getAlbums().size() > 0 && !response.body().getAlbumList2().getAlbums().isEmpty()) {
callback.onLoadYear(response.body().getAlbumList2().getAlbums().get(0).getYear());
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getAlbumList2() != null) {
if (response.body().getSubsonicResponse().getAlbumList2().getAlbums().size() > 0 && !response.body().getSubsonicResponse().getAlbumList2().getAlbums().isEmpty()) {
callback.onLoadYear(response.body().getSubsonicResponse().getAlbumList2().getAlbums().get(0).getYear());
} else {
callback.onLoadYear(-1);
}
@ -291,7 +292,7 @@ public class AlbumRepository {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
callback.onLoadYear(-1);
}
});

View file

@ -7,12 +7,12 @@ import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.MutableLiveData;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.AlbumID3;
import com.cappielloantonio.play.subsonic.models.ArtistID3;
import com.cappielloantonio.play.subsonic.models.ArtistInfo2;
import com.cappielloantonio.play.subsonic.models.Child;
import com.cappielloantonio.play.subsonic.models.IndexID3;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import java.util.ArrayList;
import java.util.Collections;
@ -35,11 +35,11 @@ public class ArtistRepository {
App.getSubsonicClientInstance(application, false)
.getAlbumSongListClient()
.getStarred2()
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getStarred2() != null) {
List<ArtistID3> artists = response.body().getStarred2().getArtists();
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getStarred2() != null) {
List<ArtistID3> artists = response.body().getSubsonicResponse().getStarred2().getArtists();
if (!random) {
getArtistInfo(artists, starredArtists);
@ -51,7 +51,7 @@ public class ArtistRepository {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -65,13 +65,13 @@ public class ArtistRepository {
App.getSubsonicClientInstance(application, false)
.getBrowsingClient()
.getArtists()
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null) {
List<ArtistID3> artists = new ArrayList<>();
for (IndexID3 index : response.body().getArtists().getIndices()) {
for (IndexID3 index : response.body().getSubsonicResponse().getArtists().getIndices()) {
artists.addAll(index.getArtists());
}
@ -85,7 +85,7 @@ public class ArtistRepository {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -104,16 +104,16 @@ public class ArtistRepository {
App.getSubsonicClientInstance(application, false)
.getBrowsingClient()
.getArtist(artist.getId())
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getArtist() != null) {
addToMutableLiveData(list, response.body().getArtist());
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getArtist() != null) {
addToMutableLiveData(list, response.body().getSubsonicResponse().getArtist());
}
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -126,16 +126,16 @@ public class ArtistRepository {
App.getSubsonicClientInstance(application, false)
.getBrowsingClient()
.getArtist(id)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getArtist() != null) {
artist.setValue(response.body().getArtist());
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getArtist() != null) {
artist.setValue(response.body().getSubsonicResponse().getArtist());
}
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -152,16 +152,16 @@ public class ArtistRepository {
App.getSubsonicClientInstance(application, false)
.getBrowsingClient()
.getArtistInfo2(id)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getArtistInfo2() != null) {
artistFullInfo.setValue(response.body().getArtistInfo2());
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getArtistInfo2() != null) {
artistFullInfo.setValue(response.body().getSubsonicResponse().getArtistInfo2());
}
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -173,14 +173,14 @@ public class ArtistRepository {
App.getSubsonicClientInstance(application, false)
.getMediaAnnotationClient()
.star(null, null, id)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -190,14 +190,14 @@ public class ArtistRepository {
App.getSubsonicClientInstance(application, false)
.getMediaAnnotationClient()
.unstar(null, null, id)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -207,14 +207,14 @@ public class ArtistRepository {
App.getSubsonicClientInstance(application, false)
.getMediaAnnotationClient()
.setRating(id, rating)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -226,16 +226,16 @@ public class ArtistRepository {
App.getSubsonicClientInstance(application, false)
.getBrowsingClient()
.getArtist(id)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getArtist() != null) {
artist.setValue(response.body().getArtist());
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getArtist() != null) {
artist.setValue(response.body().getSubsonicResponse().getArtist());
}
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -249,16 +249,16 @@ public class ArtistRepository {
App.getSubsonicClientInstance(application, false)
.getBrowsingClient()
.getSimilarSongs2(artist.getId(), count)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSimilarSongs2() != null) {
instantMix.setValue(response.body().getSimilarSongs2().getSongs());
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getSimilarSongs2() != null) {
instantMix.setValue(response.body().getSubsonicResponse().getSimilarSongs2().getSongs());
}
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -272,11 +272,11 @@ public class ArtistRepository {
App.getSubsonicClientInstance(application, false)
.getBrowsingClient()
.getArtist(artist.getId())
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getArtist() != null && response.body().getArtist().getAlbums() != null) {
List<AlbumID3> albums = response.body().getArtist().getAlbums();
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getArtist() != null && response.body().getSubsonicResponse().getArtist().getAlbums() != null) {
List<AlbumID3> albums = response.body().getSubsonicResponse().getArtist().getAlbums();
if (albums.size() > 0) {
AlbumRepository albumRepository = new AlbumRepository(App.getInstance());
@ -295,7 +295,7 @@ public class ArtistRepository {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -304,21 +304,21 @@ public class ArtistRepository {
}
public MutableLiveData<List<Child>> getTopSongs(String artistName, int count) {
MutableLiveData<List<Child>> topSongs = new MutableLiveData<>();
MutableLiveData<List<Child>> topSongs = new MutableLiveData<>(new ArrayList<>());
App.getSubsonicClientInstance(application, false)
.getBrowsingClient()
.getTopSongs(artistName, count)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getTopSongs() != null) {
topSongs.setValue(response.body().getTopSongs().getSongs());
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getTopSongs() != null && response.body().getSubsonicResponse().getTopSongs().getSongs() != null) {
topSongs.setValue(response.body().getSubsonicResponse().getTopSongs().getSongs());
}
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});

View file

@ -6,6 +6,7 @@ import androidx.annotation.NonNull;
import androidx.lifecycle.MutableLiveData;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.Genre;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
@ -31,11 +32,11 @@ public class GenreRepository {
App.getSubsonicClientInstance(application, false)
.getBrowsingClient()
.getGenres()
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getGenres() != null) {
List<Genre> genreList = response.body().getGenres().getGenres();
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getGenres() != null) {
List<Genre> genreList = response.body().getSubsonicResponse().getGenres().getGenres();
if (random) {
Collections.shuffle(genreList);
@ -50,7 +51,7 @@ public class GenreRepository {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});

View file

@ -10,9 +10,9 @@ import androidx.lifecycle.MutableLiveData;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.database.AppDatabase;
import com.cappielloantonio.play.database.dao.PlaylistDao;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.Child;
import com.cappielloantonio.play.subsonic.models.Playlist;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import java.util.ArrayList;
import java.util.Collections;
@ -34,16 +34,16 @@ public class PlaylistRepository {
}
public MutableLiveData<List<Playlist>> getPlaylists(boolean random, int size) {
MutableLiveData<List<Playlist>> listLivePlaylists = new MutableLiveData<>();
MutableLiveData<List<Playlist>> listLivePlaylists = new MutableLiveData<>(new ArrayList<>());
App.getSubsonicClientInstance(application, false)
.getPlaylistClient()
.getPlaylists()
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getPlaylists() != null) {
List<Playlist> playlists = response.body().getPlaylists().getPlaylists();
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getPlaylists() != null && response.body().getSubsonicResponse().getPlaylists().getPlaylists() != null) {
List<Playlist> playlists = response.body().getSubsonicResponse().getPlaylists().getPlaylists();
if (random) {
Collections.shuffle(playlists);
@ -55,7 +55,7 @@ public class PlaylistRepository {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -68,17 +68,17 @@ public class PlaylistRepository {
App.getSubsonicClientInstance(application, false)
.getPlaylistClient()
.getPlaylist(id)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getPlaylist() != null) {
List<Child> songs = response.body().getPlaylist().getEntries();
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getPlaylist() != null) {
List<Child> songs = response.body().getSubsonicResponse().getPlaylist().getEntries();
listLivePlaylistSongs.setValue(songs);
}
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -89,14 +89,14 @@ public class PlaylistRepository {
App.getSubsonicClientInstance(application, false)
.getPlaylistClient()
.updatePlaylist(playlistId, null, true, songsId, null)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -106,14 +106,14 @@ public class PlaylistRepository {
App.getSubsonicClientInstance(application, false)
.getPlaylistClient()
.createPlaylist(playlistId, name, songsId)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
Log.d("PLAYLIST", response.toString());
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
Log.d("PLAYLIST", t.toString());
}
});
@ -123,14 +123,14 @@ public class PlaylistRepository {
App.getSubsonicClientInstance(application, false)
.getPlaylistClient()
.updatePlaylist(playlistId, name, isPublic, songIdToAdd, songIndexToRemove)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -140,14 +140,14 @@ public class PlaylistRepository {
App.getSubsonicClientInstance(application, false)
.getPlaylistClient()
.deletePlaylist(playlistId)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});

View file

@ -7,6 +7,7 @@ import androidx.annotation.NonNull;
import androidx.lifecycle.MutableLiveData;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.PodcastChannel;
import com.cappielloantonio.play.subsonic.models.PodcastEpisode;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
@ -32,16 +33,16 @@ public class PodcastRepository {
App.getSubsonicClientInstance(application, false)
.getPodcastClient()
.getPodcasts(includeEpisodes, channelId)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getPodcasts() != null) {
livePodcastChannel.setValue(response.body().getPodcasts().getChannels());
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getPodcasts() != null) {
livePodcastChannel.setValue(response.body().getSubsonicResponse().getPodcasts().getChannels());
}
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -55,16 +56,16 @@ public class PodcastRepository {
App.getSubsonicClientInstance(application, false)
.getPodcastClient()
.getNewestPodcasts(count)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getNewestPodcasts() != null) {
liveNewestPodcastEpisodes.setValue(response.body().getNewestPodcasts().getEpisodes());
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getNewestPodcasts() != null) {
liveNewestPodcastEpisodes.setValue(response.body().getSubsonicResponse().getNewestPodcasts().getEpisodes());
}
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
Log.d(TAG, "onFailure()");
}
});
@ -76,14 +77,14 @@ public class PodcastRepository {
App.getSubsonicClientInstance(application, false)
.getPodcastClient()
.refreshPodcasts()
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});

View file

@ -62,7 +62,12 @@ public class QueueRepository {
mediaList = getMediaThreadSafe.getMedia();
}
mediaList.add(afterIndex, (Queue) media);
Queue queueItem = new Queue(media);
mediaList.add(afterIndex, queueItem);
for (int i = 0; i < mediaList.size(); i++) {
mediaList.get(i).setTrackOrder(i);
}
Thread delete = new Thread(new DeleteAllThreadSafe(queueDao));
delete.start();
@ -90,7 +95,12 @@ public class QueueRepository {
}
for (int i = 0; i < toAdd.size(); i++) {
media.add(afterIndex + i, (Queue) toAdd.get(i));
Queue queueItem = new Queue(toAdd.get(i));
media.add(afterIndex + i, queueItem);
}
for (int i = 0; i < media.size(); i++) {
media.get(i).setTrackOrder(i);
}
Thread delete = new Thread(new DeleteAllThreadSafe(queueDao));

View file

@ -6,6 +6,7 @@ import androidx.annotation.NonNull;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.interfaces.ScanCallback;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import retrofit2.Call;
@ -24,16 +25,16 @@ public class ScanRepository {
App.getSubsonicClientInstance(application, false)
.getMediaLibraryScanningClient()
.startScan()
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull retrofit2.Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getScanStatus() != null) {
callback.onSuccess(response.body().getScanStatus().isScanning(), response.body().getScanStatus().getCount());
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull retrofit2.Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getScanStatus() != null) {
callback.onSuccess(response.body().getSubsonicResponse().getScanStatus().isScanning(), response.body().getSubsonicResponse().getScanStatus().getCount());
}
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
callback.onError(new Exception(t.getMessage()));
}
});
@ -43,16 +44,16 @@ public class ScanRepository {
App.getSubsonicClientInstance(application, false)
.getMediaLibraryScanningClient()
.startScan()
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull retrofit2.Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getScanStatus() != null) {
callback.onSuccess(response.body().getScanStatus().isScanning(), response.body().getScanStatus().getCount());
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull retrofit2.Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getScanStatus() != null) {
callback.onSuccess(response.body().getSubsonicResponse().getScanStatus().isScanning(), response.body().getSubsonicResponse().getScanStatus().getCount());
}
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
callback.onError(new Exception(t.getMessage()));
}
});

View file

@ -9,6 +9,7 @@ import com.cappielloantonio.play.App;
import com.cappielloantonio.play.database.AppDatabase;
import com.cappielloantonio.play.database.dao.RecentSearchDao;
import com.cappielloantonio.play.model.RecentSearch;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.AlbumID3;
import com.cappielloantonio.play.subsonic.models.ArtistID3;
import com.cappielloantonio.play.subsonic.models.Child;
@ -39,15 +40,15 @@ public class SearchingRepository {
App.getSubsonicClientInstance(application, false)
.getSearchingClient()
.search3(query, 20, 0, 0)
.enqueue(new Callback<SubsonicResponse>() {
.search3(query, 20, 20, 20)
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
result.setValue(response.body().getSearchResult3());
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
result.setValue(response.body().getSubsonicResponse().getSearchResult3());
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -61,23 +62,29 @@ public class SearchingRepository {
App.getSubsonicClientInstance(application, false)
.getSearchingClient()
.search3(query, 5, 5, 5)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
List<String> newSuggestions = new ArrayList();
if (response.isSuccessful() && response.body() != null) {
for (ArtistID3 artistID3 : response.body().getSearchResult3().getArtists()) {
if(response.body().getSubsonicResponse().getSearchResult3().getArtists() != null) {
for (ArtistID3 artistID3 : response.body().getSubsonicResponse().getSearchResult3().getArtists()) {
newSuggestions.add(artistID3.getName());
}
for (AlbumID3 albumID3 : response.body().getSearchResult3().getAlbums()) {
newSuggestions.add(albumID3.getName());
}
for (Child song : response.body().getSearchResult3().getSongs()) {
if(response.body().getSubsonicResponse().getSearchResult3().getAlbums() != null) {
for (AlbumID3 albumID3 : response.body().getSubsonicResponse().getSearchResult3().getAlbums()) {
newSuggestions.add(albumID3.getName());
}
}
if(response.body().getSubsonicResponse().getSearchResult3().getSongs() != null) {
for (Child song : response.body().getSubsonicResponse().getSearchResult3().getSongs()) {
newSuggestions.add(song.getTitle());
}
}
LinkedHashSet<String> hashSet = new LinkedHashSet<>(newSuggestions);
ArrayList<String> suggestionsWithoutDuplicates = new ArrayList<>(hashSet);
@ -87,7 +94,7 @@ public class SearchingRepository {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});

View file

@ -1,19 +1,23 @@
package com.cappielloantonio.play.repository;
import android.app.Application;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.MutableLiveData;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.Child;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.stream.Collectors;
import kotlin.collections.EmptyList;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
@ -28,17 +32,18 @@ public class SongRepository {
}
public MutableLiveData<List<Child>> getStarredSongs(boolean random, int size) {
MutableLiveData<List<Child>> starredSongs = new MutableLiveData<>();
MutableLiveData<List<Child>> starredSongs = new MutableLiveData<>(Collections.EMPTY_LIST);
App.getSubsonicClientInstance(application, false)
.getAlbumSongListClient()
.getStarred2()
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getStarred2() != null) {
List<Child> songs = response.body().getStarred2().getSongs();
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getStarred2() != null) {
List<Child> songs = response.body().getSubsonicResponse().getStarred2().getSongs();
if (songs != null) {
if (!random) {
starredSongs.setValue(songs);
} else {
@ -47,9 +52,10 @@ public class SongRepository {
}
}
}
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -63,16 +69,16 @@ public class SongRepository {
App.getSubsonicClientInstance(application, false)
.getBrowsingClient()
.getSimilarSongs2(song.getId(), count)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSimilarSongs2() != null) {
instantMix.setValue(response.body().getSimilarSongs2().getSongs());
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getSimilarSongs2() != null) {
instantMix.setValue(response.body().getSubsonicResponse().getSimilarSongs2().getSongs());
}
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
instantMix.setValue(null);
}
});
@ -86,21 +92,21 @@ public class SongRepository {
App.getSubsonicClientInstance(application, false)
.getAlbumSongListClient()
.getRandomSongs(number, fromYear, toYear)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
List<Child> songs = new ArrayList<>();
if (response.isSuccessful() && response.body() != null && response.body().getRandomSongs() != null) {
songs.addAll(response.body().getRandomSongs().getSongs());
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getRandomSongs() != null) {
songs.addAll(response.body().getSubsonicResponse().getRandomSongs().getSongs());
}
randomSongsSample.setValue(songs);
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
Log.d(TAG, "onFailure: ");
}
});
@ -111,14 +117,14 @@ public class SongRepository {
App.getSubsonicClientInstance(application, false)
.getMediaAnnotationClient()
.scrobble(id)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -128,14 +134,14 @@ public class SongRepository {
App.getSubsonicClientInstance(application, false)
.getMediaAnnotationClient()
.star(id, null, null)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -145,14 +151,14 @@ public class SongRepository {
App.getSubsonicClientInstance(application, false)
.getMediaAnnotationClient()
.unstar(id, null, null)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -162,14 +168,14 @@ public class SongRepository {
App.getSubsonicClientInstance(application, false)
.getMediaAnnotationClient()
.setRating(id, rating)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -181,11 +187,11 @@ public class SongRepository {
App.getSubsonicClientInstance(application, false)
.getAlbumSongListClient()
.getSongsByGenre(id, 500, 0)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSongsByGenre() != null) {
List<Child> newSongs = response.body().getSongsByGenre().getSongs();
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getSongsByGenre() != null) {
List<Child> newSongs = response.body().getSubsonicResponse().getSongsByGenre().getSongs();
List<Child> songs = songsByGenre.getValue();
if (songs == null) songs = new ArrayList<>();
@ -200,7 +206,7 @@ public class SongRepository {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -215,20 +221,20 @@ public class SongRepository {
App.getSubsonicClientInstance(application, false)
.getAlbumSongListClient()
.getSongsByGenre(id, 500, 0)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
List<Child> songs = new ArrayList<>();
if (response.isSuccessful() && response.body() != null && response.body().getSongsByGenre() != null) {
songs.addAll(response.body().getSongsByGenre().getSongs());
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<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
@ -242,17 +248,17 @@ public class SongRepository {
App.getSubsonicClientInstance(application, false)
.getBrowsingClient()
.getSong(id)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null) {
song.setValue(response.body().getSong());
song.setValue(response.body().getSubsonicResponse().getSong());
}
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
Log.d(TAG, "onFailure: ");
}
});
@ -265,16 +271,16 @@ public class SongRepository {
App.getSubsonicClientInstance(application, false)
.getMediaRetrievalClient()
.getLyrics(song.getArtist(), song.getTitle())
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getLyrics() != null) {
lyrics.setValue(response.body().getLyrics().getContent());
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getLyrics() != null) {
lyrics.setValue(response.body().getSubsonicResponse().getLyrics().getContent());
}
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});

View file

@ -7,6 +7,7 @@ import androidx.lifecycle.MutableLiveData;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.interfaces.SystemCallback;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.ResponseStatus;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
@ -27,13 +28,13 @@ public class SystemRepository {
App.getSubsonicClientInstance(application, false)
.getSystemClient()
.ping()
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull retrofit2.Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull retrofit2.Response<ApiResponse> response) {
if (response.body() != null) {
if (response.body().getStatus().getValue().equals(ResponseStatus.FAILED)) {
callback.onError(new Exception(response.body().getError().getCode().getValue() + " - " + response.body().getError().getMessage()));
} else if (response.body().getStatus().getValue().equals(ResponseStatus.OK)) {
if (response.body().getSubsonicResponse().getStatus().equals(ResponseStatus.FAILED)) {
callback.onError(new Exception(response.body().getSubsonicResponse().getError().getCode().getValue() + " - " + response.body().getSubsonicResponse().getError().getMessage()));
} else if (response.body().getSubsonicResponse().getStatus().equals(ResponseStatus.OK)) {
String password = response.raw().request().url().queryParameter("p");
String token = response.raw().request().url().queryParameter("t");
String salt = response.raw().request().url().queryParameter("s");
@ -47,7 +48,7 @@ public class SystemRepository {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
callback.onError(new Exception(t.getMessage()));
}
});
@ -59,16 +60,16 @@ public class SystemRepository {
App.getSubsonicClientInstance(application, false)
.getSystemClient()
.ping()
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull Response<SubsonicResponse> response) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null) {
pingResult.postValue(true);
}
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
pingResult.postValue(false);
}
});

View file

@ -7,6 +7,7 @@ import androidx.media3.session.MediaBrowser;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.interfaces.MediaIndexCallback;
import com.cappielloantonio.play.model.Chronology;
import com.cappielloantonio.play.repository.ChronologyRepository;
import com.cappielloantonio.play.repository.QueueRepository;
import com.cappielloantonio.play.repository.SongRepository;
@ -306,7 +307,7 @@ public class MediaManager {
public static void saveChronology(MediaItem mediaItem) {
if (mediaItem != null)
if (getQueueRepository().isMediaPlayingPlausible(mediaItem))
getChronologyRepository().insert(mediaItem.mediaMetadata.extras.getParcelable("child"));
getChronologyRepository().insert(new Chronology(mediaItem));
}
private static QueueRepository getQueueRepository() {

View file

@ -234,7 +234,7 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
if (mediaItem == null) return
if (mediaItem.mediaMetadata.extras!!.getString("mediaType") == Media.MEDIA_TYPE_MUSIC) {
if (mediaItem.mediaMetadata.extras?.getString("type") == Media.MEDIA_TYPE_MUSIC) {
MediaManager.scrobble(mediaItem)
MediaManager.saveChronology(mediaItem)
}
@ -243,7 +243,7 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
}
override fun onIsPlayingChanged(isPlaying: Boolean) {
if (isPlaying) {
if (!isPlaying) {
MediaManager.setPlayingPausedTimestamp(
player.currentMediaItem,
player.currentPosition

View file

@ -4,9 +4,10 @@ import android.content.Context;
import android.util.Log;
import com.cappielloantonio.play.subsonic.Subsonic;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import com.cappielloantonio.play.subsonic.utils.CacheUtil;
import com.tickaroo.tikxml.retrofit.TikXmlConverterFactory;
import com.google.gson.GsonBuilder;
import java.util.concurrent.TimeUnit;
@ -15,6 +16,7 @@ import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class AlbumSongListClient {
private static final String TAG = "BrowsingClient";
@ -29,44 +31,44 @@ public class AlbumSongListClient {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(subsonic.getUrl())
.addConverterFactory(TikXmlConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder().setLenient().create()))
.client(getOkHttpClient())
.build();
this.albumSongListService = retrofit.create(AlbumSongListService.class);
}
public Call<SubsonicResponse> getAlbumList(String type, int size, int offset) {
public Call<ApiResponse> getAlbumList(String type, int size, int offset) {
Log.d(TAG, "getAlbumList()");
return albumSongListService.getAlbumList(subsonic.getParams(), type, size, offset);
}
public Call<SubsonicResponse> getAlbumList2(String type, int size, int offset, Integer fromYear, Integer toYear) {
public Call<ApiResponse> getAlbumList2(String type, int size, int offset, Integer fromYear, Integer toYear) {
Log.d(TAG, "getAlbumList2()");
return albumSongListService.getAlbumList2(subsonic.getParams(), type, size, offset, fromYear, toYear);
}
public Call<SubsonicResponse> getRandomSongs(int size, Integer fromYear, Integer toYear) {
public Call<ApiResponse> getRandomSongs(int size, Integer fromYear, Integer toYear) {
Log.d(TAG, "getRandomSongs()");
return albumSongListService.getRandomSongs(subsonic.getParams(), size, fromYear, toYear);
}
public Call<SubsonicResponse> getSongsByGenre(String genre, int count, int offset) {
public Call<ApiResponse> getSongsByGenre(String genre, int count, int offset) {
Log.d(TAG, "getSongsByGenre()");
return albumSongListService.getSongsByGenre(subsonic.getParams(), genre, count, offset);
}
public Call<SubsonicResponse> getNowPlaying() {
public Call<ApiResponse> getNowPlaying() {
Log.d(TAG, "getNowPlaying()");
return albumSongListService.getNowPlaying(subsonic.getParams());
}
public Call<SubsonicResponse> getStarred() {
public Call<ApiResponse> getStarred() {
Log.d(TAG, "getStarred()");
return albumSongListService.getStarred(subsonic.getParams());
}
public Call<SubsonicResponse> getStarred2() {
public Call<ApiResponse> getStarred2() {
Log.d(TAG, "getStarred2()");
return albumSongListService.getStarred2(subsonic.getParams());
}

View file

@ -1,5 +1,6 @@
package com.cappielloantonio.play.subsonic.api.albumsonglist;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import java.util.Map;
@ -11,23 +12,23 @@ import retrofit2.http.QueryMap;
public interface AlbumSongListService {
@GET("getAlbumList")
Call<SubsonicResponse> getAlbumList(@QueryMap Map<String, String> params, @Query("type") String type, @Query("size") int size, @Query("offset") int offset);
Call<ApiResponse> getAlbumList(@QueryMap Map<String, String> params, @Query("type") String type, @Query("size") int size, @Query("offset") int offset);
@GET("getAlbumList2")
Call<SubsonicResponse> getAlbumList2(@QueryMap Map<String, String> params, @Query("type") String type, @Query("size") int size, @Query("offset") int offset, @Query("fromYear") Integer fromYear, @Query("toYear") Integer toYear);
Call<ApiResponse> getAlbumList2(@QueryMap Map<String, String> params, @Query("type") String type, @Query("size") int size, @Query("offset") int offset, @Query("fromYear") Integer fromYear, @Query("toYear") Integer toYear);
@GET("getRandomSongs")
Call<SubsonicResponse> getRandomSongs(@QueryMap Map<String, String> params, @Query("size") int size, @Query("fromYear") Integer fromYear, @Query("toYear") Integer toYear);
Call<ApiResponse> getRandomSongs(@QueryMap Map<String, String> params, @Query("size") int size, @Query("fromYear") Integer fromYear, @Query("toYear") Integer toYear);
@GET("getSongsByGenre")
Call<SubsonicResponse> getSongsByGenre(@QueryMap Map<String, String> params, @Query("genre") String genre, @Query("count") int count, @Query("offset") int offset);
Call<ApiResponse> getSongsByGenre(@QueryMap Map<String, String> params, @Query("genre") String genre, @Query("count") int count, @Query("offset") int offset);
@GET("getNowPlaying")
Call<SubsonicResponse> getNowPlaying(@QueryMap Map<String, String> params);
Call<ApiResponse> getNowPlaying(@QueryMap Map<String, String> params);
@GET("getStarred")
Call<SubsonicResponse> getStarred(@QueryMap Map<String, String> params);
Call<ApiResponse> getStarred(@QueryMap Map<String, String> params);
@GET("getStarred2")
Call<SubsonicResponse> getStarred2(@QueryMap Map<String, String> params);
Call<ApiResponse> getStarred2(@QueryMap Map<String, String> params);
}

View file

@ -4,9 +4,10 @@ import android.content.Context;
import android.util.Log;
import com.cappielloantonio.play.subsonic.Subsonic;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import com.cappielloantonio.play.subsonic.utils.CacheUtil;
import com.tickaroo.tikxml.retrofit.TikXmlConverterFactory;
import com.google.gson.GsonBuilder;
import java.util.concurrent.TimeUnit;
@ -15,6 +16,7 @@ import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class BrowsingClient {
private static final String TAG = "BrowsingClient";
@ -29,94 +31,94 @@ public class BrowsingClient {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(subsonic.getUrl())
.addConverterFactory(TikXmlConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder().setLenient().create()))
.client(getOkHttpClient())
.build();
this.browsingService = retrofit.create(BrowsingService.class);
}
public Call<SubsonicResponse> getMusicFolders() {
public Call<ApiResponse> getMusicFolders() {
Log.d(TAG, "getMusicFolders()");
return browsingService.getMusicFolders(subsonic.getParams());
}
public Call<SubsonicResponse> getIndexes() {
public Call<ApiResponse> getIndexes() {
Log.d(TAG, "getIndexes()");
return browsingService.getIndexes(subsonic.getParams());
}
public Call<SubsonicResponse> getMusicDirectory(String id) {
public Call<ApiResponse> getMusicDirectory(String id) {
Log.d(TAG, "getMusicDirectory()");
return browsingService.getMusicDirectory(subsonic.getParams(), id);
}
public Call<SubsonicResponse> getGenres() {
public Call<ApiResponse> getGenres() {
Log.d(TAG, "getGenres()");
return browsingService.getGenres(subsonic.getParams());
}
public Call<SubsonicResponse> getArtists() {
public Call<ApiResponse> getArtists() {
Log.d(TAG, "getArtists()");
return browsingService.getArtists(subsonic.getParams());
}
public Call<SubsonicResponse> getArtist(String id) {
public Call<ApiResponse> getArtist(String id) {
Log.d(TAG, "getArtist()");
return browsingService.getArtist(subsonic.getParams(), id);
}
public Call<SubsonicResponse> getAlbum(String id) {
public Call<ApiResponse> getAlbum(String id) {
Log.d(TAG, "getAlbum()");
return browsingService.getAlbum(subsonic.getParams(), id);
}
public Call<SubsonicResponse> getSong(String id) {
public Call<ApiResponse> getSong(String id) {
Log.d(TAG, "getSong()");
return browsingService.getSong(subsonic.getParams(), id);
}
public Call<SubsonicResponse> getVideos() {
public Call<ApiResponse> getVideos() {
Log.d(TAG, "getVideos()");
return browsingService.getVideos(subsonic.getParams());
}
public Call<SubsonicResponse> getVideoInfo(String id) {
public Call<ApiResponse> getVideoInfo(String id) {
Log.d(TAG, "getVideoInfo()");
return browsingService.getVideoInfo(subsonic.getParams(), id);
}
public Call<SubsonicResponse> getArtistInfo(String id) {
public Call<ApiResponse> getArtistInfo(String id) {
Log.d(TAG, "getArtistInfo()");
return browsingService.getArtistInfo(subsonic.getParams(), id);
}
public Call<SubsonicResponse> getArtistInfo2(String id) {
public Call<ApiResponse> getArtistInfo2(String id) {
Log.d(TAG, "getArtistInfo2()");
return browsingService.getArtistInfo2(subsonic.getParams(), id);
}
public Call<SubsonicResponse> getAlbumInfo(String id) {
public Call<ApiResponse> getAlbumInfo(String id) {
Log.d(TAG, "getAlbumInfo()");
return browsingService.getAlbumInfo(subsonic.getParams(), id);
}
public Call<SubsonicResponse> getAlbumInfo2(String id) {
public Call<ApiResponse> getAlbumInfo2(String id) {
Log.d(TAG, "getAlbumInfo2()");
return browsingService.getAlbumInfo2(subsonic.getParams(), id);
}
public Call<SubsonicResponse> getSimilarSongs(String id, int count) {
public Call<ApiResponse> getSimilarSongs(String id, int count) {
Log.d(TAG, "getSimilarSongs()");
return browsingService.getSimilarSongs(subsonic.getParams(), id, count);
}
public Call<SubsonicResponse> getSimilarSongs2(String id, int limit) {
public Call<ApiResponse> getSimilarSongs2(String id, int limit) {
Log.d(TAG, "getSimilarSongs2()");
return browsingService.getSimilarSongs2(subsonic.getParams(), id, limit);
}
public Call<SubsonicResponse> getTopSongs(String artist, int count) {
public Call<ApiResponse> getTopSongs(String artist, int count) {
Log.d(TAG, "getTopSongs()");
return browsingService.getTopSongs(subsonic.getParams(), artist, count);
}

View file

@ -1,5 +1,6 @@
package com.cappielloantonio.play.subsonic.api.browsing;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import java.util.Map;
@ -11,53 +12,53 @@ import retrofit2.http.QueryMap;
public interface BrowsingService {
@GET("getMusicFolders")
Call<SubsonicResponse> getMusicFolders(@QueryMap Map<String, String> params);
Call<ApiResponse> getMusicFolders(@QueryMap Map<String, String> params);
@GET("getIndexes")
Call<SubsonicResponse> getIndexes(@QueryMap Map<String, String> params);
Call<ApiResponse> getIndexes(@QueryMap Map<String, String> params);
@GET("getMusicDirectory")
Call<SubsonicResponse> getMusicDirectory(@QueryMap Map<String, String> params, @Query("id") String id);
Call<ApiResponse> getMusicDirectory(@QueryMap Map<String, String> params, @Query("id") String id);
@GET("getGenres")
Call<SubsonicResponse> getGenres(@QueryMap Map<String, String> params);
Call<ApiResponse> getGenres(@QueryMap Map<String, String> params);
@GET("getArtists")
Call<SubsonicResponse> getArtists(@QueryMap Map<String, String> params);
Call<ApiResponse> getArtists(@QueryMap Map<String, String> params);
@GET("getArtist")
Call<SubsonicResponse> getArtist(@QueryMap Map<String, String> params, @Query("id") String id);
Call<ApiResponse> getArtist(@QueryMap Map<String, String> params, @Query("id") String id);
@GET("getAlbum")
Call<SubsonicResponse> getAlbum(@QueryMap Map<String, String> params, @Query("id") String id);
Call<ApiResponse> getAlbum(@QueryMap Map<String, String> params, @Query("id") String id);
@GET("getSong")
Call<SubsonicResponse> getSong(@QueryMap Map<String, String> params, @Query("id") String id);
Call<ApiResponse> getSong(@QueryMap Map<String, String> params, @Query("id") String id);
@GET("getVideos")
Call<SubsonicResponse> getVideos(@QueryMap Map<String, String> params);
Call<ApiResponse> getVideos(@QueryMap Map<String, String> params);
@GET("getVideoInfo")
Call<SubsonicResponse> getVideoInfo(@QueryMap Map<String, String> params, @Query("id") String id);
Call<ApiResponse> getVideoInfo(@QueryMap Map<String, String> params, @Query("id") String id);
@GET("getArtistInfo")
Call<SubsonicResponse> getArtistInfo(@QueryMap Map<String, String> params, @Query("id") String id);
Call<ApiResponse> getArtistInfo(@QueryMap Map<String, String> params, @Query("id") String id);
@GET("getArtistInfo2")
Call<SubsonicResponse> getArtistInfo2(@QueryMap Map<String, String> params, @Query("id") String id);
Call<ApiResponse> getArtistInfo2(@QueryMap Map<String, String> params, @Query("id") String id);
@GET("getAlbumInfo")
Call<SubsonicResponse> getAlbumInfo(@QueryMap Map<String, String> params, @Query("id") String id);
Call<ApiResponse> getAlbumInfo(@QueryMap Map<String, String> params, @Query("id") String id);
@GET("getAlbumInfo2")
Call<SubsonicResponse> getAlbumInfo2(@QueryMap Map<String, String> params, @Query("id") String id);
Call<ApiResponse> getAlbumInfo2(@QueryMap Map<String, String> params, @Query("id") String id);
@GET("getSimilarSongs")
Call<SubsonicResponse> getSimilarSongs(@QueryMap Map<String, String> params, @Query("id") String id, @Query("count") int count);
Call<ApiResponse> getSimilarSongs(@QueryMap Map<String, String> params, @Query("id") String id, @Query("count") int count);
@GET("getSimilarSongs2")
Call<SubsonicResponse> getSimilarSongs2(@QueryMap Map<String, String> params, @Query("id") String id, @Query("count") int count);
Call<ApiResponse> getSimilarSongs2(@QueryMap Map<String, String> params, @Query("id") String id, @Query("count") int count);
@GET("getTopSongs")
Call<SubsonicResponse> getTopSongs(@QueryMap Map<String, String> params, @Query("artist") String artist, @Query("count") int count);
Call<ApiResponse> getTopSongs(@QueryMap Map<String, String> params, @Query("artist") String artist, @Query("count") int count);
}

View file

@ -4,9 +4,10 @@ import android.content.Context;
import android.util.Log;
import com.cappielloantonio.play.subsonic.Subsonic;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import com.cappielloantonio.play.subsonic.utils.CacheUtil;
import com.tickaroo.tikxml.retrofit.TikXmlConverterFactory;
import com.google.gson.GsonBuilder;
import java.util.concurrent.TimeUnit;
@ -15,6 +16,7 @@ import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class MediaAnnotationClient {
private static final String TAG = "BrowsingClient";
@ -29,29 +31,29 @@ public class MediaAnnotationClient {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(subsonic.getUrl())
.addConverterFactory(TikXmlConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder().setLenient().create()))
.client(getOkHttpClient())
.build();
this.mediaAnnotationService = retrofit.create(MediaAnnotationService.class);
}
public Call<SubsonicResponse> star(String id, String albumId, String artistId) {
public Call<ApiResponse> star(String id, String albumId, String artistId) {
Log.d(TAG, "star()");
return mediaAnnotationService.star(subsonic.getParams(), id, albumId, artistId);
}
public Call<SubsonicResponse> unstar(String id, String albumId, String artistId) {
public Call<ApiResponse> unstar(String id, String albumId, String artistId) {
Log.d(TAG, "unstar()");
return mediaAnnotationService.unstar(subsonic.getParams(), id, albumId, artistId);
}
public Call<SubsonicResponse> setRating(String id, int rating) {
public Call<ApiResponse> setRating(String id, int rating) {
Log.d(TAG, "setRating()");
return mediaAnnotationService.setRating(subsonic.getParams(), id, rating);
}
public Call<SubsonicResponse> scrobble(String id) {
public Call<ApiResponse> scrobble(String id) {
Log.d(TAG, "scrobble()");
return mediaAnnotationService.scrobble(subsonic.getParams(), id);
}

View file

@ -1,5 +1,6 @@
package com.cappielloantonio.play.subsonic.api.mediaannotation;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import java.util.Map;
@ -11,14 +12,14 @@ import retrofit2.http.QueryMap;
public interface MediaAnnotationService {
@GET("star")
Call<SubsonicResponse> star(@QueryMap Map<String, String> params, @Query("id") String id, @Query("albumId") String albumId, @Query("artistId") String artistId);
Call<ApiResponse> star(@QueryMap Map<String, String> params, @Query("id") String id, @Query("albumId") String albumId, @Query("artistId") String artistId);
@GET("unstar")
Call<SubsonicResponse> unstar(@QueryMap Map<String, String> params, @Query("id") String id, @Query("albumId") String albumId, @Query("artistId") String artistId);
Call<ApiResponse> unstar(@QueryMap Map<String, String> params, @Query("id") String id, @Query("albumId") String albumId, @Query("artistId") String artistId);
@GET("setRating")
Call<SubsonicResponse> setRating(@QueryMap Map<String, String> params, @Query("id") String id, @Query("rating") int rating);
Call<ApiResponse> setRating(@QueryMap Map<String, String> params, @Query("id") String id, @Query("rating") int rating);
@GET("scrobble")
Call<SubsonicResponse> scrobble(@QueryMap Map<String, String> params, @Query("id") String id);
Call<ApiResponse> scrobble(@QueryMap Map<String, String> params, @Query("id") String id);
}

View file

@ -4,9 +4,10 @@ import android.content.Context;
import android.util.Log;
import com.cappielloantonio.play.subsonic.Subsonic;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import com.cappielloantonio.play.subsonic.utils.CacheUtil;
import com.tickaroo.tikxml.retrofit.TikXmlConverterFactory;
import com.google.gson.GsonBuilder;
import java.util.concurrent.TimeUnit;
@ -15,6 +16,7 @@ import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class MediaLibraryScanningClient {
private static final String TAG = "SystemClient";
@ -29,19 +31,19 @@ public class MediaLibraryScanningClient {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(subsonic.getUrl())
.addConverterFactory(TikXmlConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder().setLenient().create()))
.client(getOkHttpClient())
.build();
this.mediaLibraryScanningService = retrofit.create(MediaLibraryScanningService.class);
}
public Call<SubsonicResponse> startScan() {
public Call<ApiResponse> startScan() {
Log.d(TAG, "startScan()");
return mediaLibraryScanningService.startScan(subsonic.getParams());
}
public Call<SubsonicResponse> getScanStatus() {
public Call<ApiResponse> getScanStatus() {
Log.d(TAG, "getScanStatus()");
return mediaLibraryScanningService.getScanStatus(subsonic.getParams());
}

View file

@ -1,6 +1,6 @@
package com.cappielloantonio.play.subsonic.api.medialibraryscanning;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import java.util.Map;
@ -10,8 +10,8 @@ import retrofit2.http.QueryMap;
public interface MediaLibraryScanningService {
@GET("startScan")
Call<SubsonicResponse> startScan(@QueryMap Map<String, String> params);
Call<ApiResponse> startScan(@QueryMap Map<String, String> params);
@GET("getScanStatus")
Call<SubsonicResponse> getScanStatus(@QueryMap Map<String, String> params);
Call<ApiResponse> getScanStatus(@QueryMap Map<String, String> params);
}

View file

@ -4,9 +4,10 @@ import android.content.Context;
import android.util.Log;
import com.cappielloantonio.play.subsonic.Subsonic;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import com.cappielloantonio.play.subsonic.utils.CacheUtil;
import com.tickaroo.tikxml.retrofit.TikXmlConverterFactory;
import com.google.gson.GsonBuilder;
import java.util.concurrent.TimeUnit;
@ -15,6 +16,7 @@ import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class MediaRetrievalClient {
private static final String TAG = "BrowsingClient";
@ -29,24 +31,24 @@ public class MediaRetrievalClient {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(subsonic.getUrl())
.addConverterFactory(TikXmlConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder().setLenient().create()))
.client(getOkHttpClient())
.build();
this.mediaRetrievalService = retrofit.create(MediaRetrievalService.class);
}
public Call<SubsonicResponse> stream(String id, Integer maxBitRate, String format) {
public Call<ApiResponse> stream(String id, Integer maxBitRate, String format) {
Log.d(TAG, "stream()");
return mediaRetrievalService.stream(subsonic.getParams(), id, maxBitRate, format);
}
public Call<SubsonicResponse> download(String id) {
public Call<ApiResponse> download(String id) {
Log.d(TAG, "download()");
return mediaRetrievalService.download(subsonic.getParams(), id);
}
public Call<SubsonicResponse> getLyrics(String artist, String title) {
public Call<ApiResponse> getLyrics(String artist, String title) {
Log.d(TAG, "getLyrics()");
return mediaRetrievalService.getLyrics(subsonic.getParams(), artist, title);
}

View file

@ -1,5 +1,6 @@
package com.cappielloantonio.play.subsonic.api.mediaretrieval;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import java.util.Map;
@ -11,11 +12,11 @@ import retrofit2.http.QueryMap;
public interface MediaRetrievalService {
@GET("stream")
Call<SubsonicResponse> stream(@QueryMap Map<String, String> params, @Query("id") String id, @Query("maxBitRate") Integer maxBitRate, @Query("format") String format);
Call<ApiResponse> stream(@QueryMap Map<String, String> params, @Query("id") String id, @Query("maxBitRate") Integer maxBitRate, @Query("format") String format);
@GET("download")
Call<SubsonicResponse> download(@QueryMap Map<String, String> params, @Query("id") String id);
Call<ApiResponse> download(@QueryMap Map<String, String> params, @Query("id") String id);
@GET("getLyrics")
Call<SubsonicResponse> getLyrics(@QueryMap Map<String, String> params, @Query("artist") String artist, @Query("title") String title);
Call<ApiResponse> getLyrics(@QueryMap Map<String, String> params, @Query("artist") String artist, @Query("title") String title);
}

View file

@ -4,9 +4,10 @@ import android.content.Context;
import android.util.Log;
import com.cappielloantonio.play.subsonic.Subsonic;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import com.cappielloantonio.play.subsonic.utils.CacheUtil;
import com.tickaroo.tikxml.retrofit.TikXmlConverterFactory;
import com.google.gson.GsonBuilder;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
@ -16,6 +17,7 @@ import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class PlaylistClient {
private static final String TAG = "BrowsingClient";
@ -30,34 +32,34 @@ public class PlaylistClient {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(subsonic.getUrl())
.addConverterFactory(TikXmlConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder().setLenient().create()))
.client(getOkHttpClient())
.build();
this.playlistService = retrofit.create(PlaylistService.class);
}
public Call<SubsonicResponse> getPlaylists() {
public Call<ApiResponse> getPlaylists() {
Log.d(TAG, "getPlaylists()");
return playlistService.getPlaylists(subsonic.getParams());
}
public Call<SubsonicResponse> getPlaylist(String id) {
public Call<ApiResponse> getPlaylist(String id) {
Log.d(TAG, "getPlaylist()");
return playlistService.getPlaylist(subsonic.getParams(), id);
}
public Call<SubsonicResponse> createPlaylist(String playlistId, String name, ArrayList<String> songsId) {
public Call<ApiResponse> createPlaylist(String playlistId, String name, ArrayList<String> songsId) {
Log.d(TAG, "createPlaylist()");
return playlistService.createPlaylist(subsonic.getParams(), playlistId, name, songsId);
}
public Call<SubsonicResponse> updatePlaylist(String playlistId, String name, boolean isPublic, ArrayList<String> songIdToAdd, ArrayList<Integer> songIndexToRemove) {
public Call<ApiResponse> updatePlaylist(String playlistId, String name, boolean isPublic, ArrayList<String> songIdToAdd, ArrayList<Integer> songIndexToRemove) {
Log.d(TAG, "updatePlaylist()");
return playlistService.updatePlaylist(subsonic.getParams(), playlistId, name, isPublic, songIdToAdd, songIndexToRemove);
}
public Call<SubsonicResponse> deletePlaylist(String id) {
public Call<ApiResponse> deletePlaylist(String id) {
Log.d(TAG, "deletePlaylist()");
return playlistService.deletePlaylist(subsonic.getParams(), id);
}

View file

@ -1,5 +1,6 @@
package com.cappielloantonio.play.subsonic.api.playlist;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import java.util.ArrayList;
@ -12,17 +13,17 @@ import retrofit2.http.QueryMap;
public interface PlaylistService {
@GET("getPlaylists")
Call<SubsonicResponse> getPlaylists(@QueryMap Map<String, String> params);
Call<ApiResponse> getPlaylists(@QueryMap Map<String, String> params);
@GET("getPlaylist")
Call<SubsonicResponse> getPlaylist(@QueryMap Map<String, String> params, @Query("id") String id);
Call<ApiResponse> getPlaylist(@QueryMap Map<String, String> params, @Query("id") String id);
@GET("createPlaylist")
Call<SubsonicResponse> createPlaylist(@QueryMap Map<String, String> params, @Query("playlistId") String playlistId, @Query("name") String name, @Query("songId") ArrayList<String> songsId);
Call<ApiResponse> createPlaylist(@QueryMap Map<String, String> params, @Query("playlistId") String playlistId, @Query("name") String name, @Query("songId") ArrayList<String> songsId);
@GET("updatePlaylist")
Call<SubsonicResponse> updatePlaylist(@QueryMap Map<String, String> params, @Query("playlistId") String playlistId, @Query("name") String name, @Query("public") boolean isPublic, @Query("songIdToAdd") ArrayList<String> songIdToAdd, @Query("songIndexToRemove") ArrayList<Integer> songIndexToRemove);
Call<ApiResponse> updatePlaylist(@QueryMap Map<String, String> params, @Query("playlistId") String playlistId, @Query("name") String name, @Query("public") boolean isPublic, @Query("songIdToAdd") ArrayList<String> songIdToAdd, @Query("songIndexToRemove") ArrayList<Integer> songIndexToRemove);
@GET("deletePlaylist")
Call<SubsonicResponse> deletePlaylist(@QueryMap Map<String, String> params, @Query("id") String id);
Call<ApiResponse> deletePlaylist(@QueryMap Map<String, String> params, @Query("id") String id);
}

View file

@ -4,9 +4,10 @@ import android.content.Context;
import android.util.Log;
import com.cappielloantonio.play.subsonic.Subsonic;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import com.cappielloantonio.play.subsonic.utils.CacheUtil;
import com.tickaroo.tikxml.retrofit.TikXmlConverterFactory;
import com.google.gson.GsonBuilder;
import java.util.concurrent.TimeUnit;
@ -15,6 +16,7 @@ import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class PodcastClient {
private static final String TAG = "SystemClient";
@ -29,27 +31,28 @@ public class PodcastClient {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(subsonic.getUrl())
.addConverterFactory(TikXmlConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder().setLenient().create()))
.client(getOkHttpClient())
.build();
this.podcastService = retrofit.create(PodcastService.class);
}
public Call<SubsonicResponse> getPodcasts(boolean includeEpisodes, String channelId) {
public Call<ApiResponse> getPodcasts(boolean includeEpisodes, String channelId) {
Log.d(TAG, "getPodcasts()");
return podcastService.getPodcasts(subsonic.getParams(), includeEpisodes, channelId);
}
public Call<SubsonicResponse> getNewestPodcasts(int count) {
public Call<ApiResponse> getNewestPodcasts(int count) {
Log.d(TAG, "getNewestPodcasts()");
return podcastService.getNewestPodcasts(subsonic.getParams(), count);
}
public Call<SubsonicResponse> refreshPodcasts() {
public Call<ApiResponse> refreshPodcasts() {
Log.d(TAG, "refreshPodcasts()");
return podcastService.refreshPodcasts(subsonic.getParams());
}
private OkHttpClient getOkHttpClient() {
CacheUtil cacheUtil = new CacheUtil(context, 60, 60 * 60 * 24 * 30);

View file

@ -1,5 +1,6 @@
package com.cappielloantonio.play.subsonic.api.podcast;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import java.util.Map;
@ -11,11 +12,11 @@ import retrofit2.http.QueryMap;
public interface PodcastService {
@GET("getPodcasts")
Call<SubsonicResponse> getPodcasts(@QueryMap Map<String, String> params, @Query("includeEpisodes") boolean includeEpisodes, @Query("id") String id);
Call<ApiResponse> getPodcasts(@QueryMap Map<String, String> params, @Query("includeEpisodes") boolean includeEpisodes, @Query("id") String id);
@GET("getNewestPodcasts")
Call<SubsonicResponse> getNewestPodcasts(@QueryMap Map<String, String> params, @Query("count") int count);
Call<ApiResponse> getNewestPodcasts(@QueryMap Map<String, String> params, @Query("count") int count);
@GET("refreshPodcasts")
Call<SubsonicResponse> refreshPodcasts(@QueryMap Map<String, String> params);
Call<ApiResponse> refreshPodcasts(@QueryMap Map<String, String> params);
}

View file

@ -4,9 +4,10 @@ import android.content.Context;
import android.util.Log;
import com.cappielloantonio.play.subsonic.Subsonic;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import com.cappielloantonio.play.subsonic.utils.CacheUtil;
import com.tickaroo.tikxml.retrofit.TikXmlConverterFactory;
import com.google.gson.GsonBuilder;
import java.util.concurrent.TimeUnit;
@ -15,6 +16,7 @@ import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class SearchingClient {
private static final String TAG = "BrowsingClient";
@ -29,19 +31,19 @@ public class SearchingClient {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(subsonic.getUrl())
.addConverterFactory(TikXmlConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder().setLenient().create()))
.client(getOkHttpClient())
.build();
this.searchingService = retrofit.create(SearchingService.class);
}
public Call<SubsonicResponse> search2(String query, int songCount, int albumCount, int artistCount) {
public Call<ApiResponse> search2(String query, int songCount, int albumCount, int artistCount) {
Log.d(TAG, "search2()");
return searchingService.search2(subsonic.getParams(), query, songCount, albumCount, artistCount);
}
public Call<SubsonicResponse> search3(String query, int songCount, int albumCount, int artistCount) {
public Call<ApiResponse> search3(String query, int songCount, int albumCount, int artistCount) {
Log.d(TAG, "search3()");
return searchingService.search3(subsonic.getParams(), query, songCount, albumCount, artistCount);
}

View file

@ -1,5 +1,6 @@
package com.cappielloantonio.play.subsonic.api.searching;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import java.util.Map;
@ -11,8 +12,8 @@ import retrofit2.http.QueryMap;
public interface SearchingService {
@GET("search2")
Call<SubsonicResponse> search2(@QueryMap Map<String, String> params, @Query("query") String query, @Query("songCount") int songCount, @Query("albumCount") int albumCount, @Query("artistCount") int artistCount);
Call<ApiResponse> search2(@QueryMap Map<String, String> params, @Query("query") String query, @Query("songCount") int songCount, @Query("albumCount") int albumCount, @Query("artistCount") int artistCount);
@GET("search3")
Call<SubsonicResponse> search3(@QueryMap Map<String, String> params, @Query("query") String query, @Query("songCount") int songCount, @Query("albumCount") int albumCount, @Query("artistCount") int artistCount);
Call<ApiResponse> search3(@QueryMap Map<String, String> params, @Query("query") String query, @Query("songCount") int songCount, @Query("albumCount") int albumCount, @Query("artistCount") int artistCount);
}

View file

@ -4,9 +4,10 @@ import android.content.Context;
import android.util.Log;
import com.cappielloantonio.play.subsonic.Subsonic;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import com.cappielloantonio.play.subsonic.utils.CacheUtil;
import com.tickaroo.tikxml.retrofit.TikXmlConverterFactory;
import com.google.gson.GsonBuilder;
import java.util.concurrent.TimeUnit;
@ -15,6 +16,7 @@ import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class SystemClient {
private static final String TAG = "SystemClient";
@ -29,19 +31,19 @@ public class SystemClient {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(subsonic.getUrl())
.addConverterFactory(TikXmlConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder().setLenient().create()))
.client(getOkHttpClient())
.build();
this.systemService = retrofit.create(SystemService.class);
}
public Call<SubsonicResponse> ping() {
public Call<ApiResponse> ping() {
Log.d(TAG, "ping()");
return systemService.ping(subsonic.getParams());
}
public Call<SubsonicResponse> getLicense() {
public Call<ApiResponse> getLicense() {
Log.d(TAG, "getLicense()");
return systemService.getLicense(subsonic.getParams());
}

View file

@ -1,6 +1,6 @@
package com.cappielloantonio.play.subsonic.api.system;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import java.util.Map;
@ -10,8 +10,8 @@ import retrofit2.http.QueryMap;
public interface SystemService {
@GET("ping")
Call<SubsonicResponse> ping(@QueryMap Map<String, String> params);
Call<ApiResponse> ping(@QueryMap Map<String, String> params);
@GET("getLicense")
Call<SubsonicResponse> getLicense(@QueryMap Map<String, String> params);
Call<ApiResponse> getLicense(@QueryMap Map<String, String> params);
}

View file

@ -0,0 +1,9 @@
package com.cappielloantonio.play.subsonic.base
import com.cappielloantonio.play.subsonic.models.SubsonicResponse
import com.google.gson.annotations.SerializedName
class ApiResponse {
@SerializedName("subsonic-response")
var subsonicResponse: SubsonicResponse? = null
}

View file

@ -1,48 +1,25 @@
package com.cappielloantonio.play.subsonic.models
import android.os.Parcelable
import com.tickaroo.tikxml.annotation.Attribute
import com.tickaroo.tikxml.annotation.Xml
import com.tickaroo.tikxml.converters.date.rfc3339.DateRfc3339TypeConverter
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
import java.util.*
@Parcelize
@Xml(name = "album")
open class AlbumID3 : Parcelable {
@Attribute
var id: String? = null
@Attribute
var name: String? = null
@Attribute
var artist: String? = null
@Attribute
var artistId: String? = null
@Attribute(name = "coverArt")
@SerializedName("coverArt")
var coverArtId: String? = null
@Attribute
var songCount = 0
@Attribute
var duration = 0
@Attribute
var playCount: Long? = null
@Attribute(converter = DateRfc3339TypeConverter::class)
var created: Date? = null
@Attribute(converter = DateRfc3339TypeConverter::class)
var starred: Date? = null
@Attribute
var year: Int? = null
@Attribute
var genre: String? = null
}

View file

@ -1,25 +1,11 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.Attribute
import com.tickaroo.tikxml.annotation.Xml
@Xml
class AlbumInfo {
@Attribute
var notes: String? = null
@Attribute
var musicBrainzId: String? = null
@Attribute
var lastFmUrl: String? = null
@Attribute
var smallImageUrl: String? = null
@Attribute
var mediumImageUrl: String? = null
@Attribute
var largeImageUrl: String? = null
}

View file

@ -1,10 +1,8 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.Element
import com.tickaroo.tikxml.annotation.Xml
import com.google.gson.annotations.SerializedName
@Xml
class AlbumList2 {
@Element
@SerializedName("album")
var albums: List<AlbumID3>? = null
}

View file

@ -1,13 +1,11 @@
package com.cappielloantonio.play.subsonic.models
import android.os.Parcelable
import com.tickaroo.tikxml.annotation.Element
import com.tickaroo.tikxml.annotation.Xml
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
@Parcelize
@Xml
class AlbumWithSongsID3 : AlbumID3(), Parcelable {
@Element(name = "song")
@SerializedName("song")
var songs: List<Child>? = null
}

View file

@ -1,27 +1,17 @@
package com.cappielloantonio.play.subsonic.models
import android.os.Parcelable
import com.tickaroo.tikxml.annotation.Attribute
import com.tickaroo.tikxml.annotation.Xml
import com.tickaroo.tikxml.converters.date.rfc3339.DateRfc3339TypeConverter
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
import java.util.*
@Parcelize
@Xml(name = "artist")
open class ArtistID3 : Parcelable {
@Attribute
var id: String? = null
@Attribute
var name: String? = null
@Attribute(name = "coverArt")
@SerializedName("coverArt")
var coverArtId: String? = null
@Attribute
var albumCount = 0
@Attribute(converter = DateRfc3339TypeConverter::class)
var starred: Date? = null
}

View file

@ -1,10 +1,9 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.Element
import com.tickaroo.tikxml.annotation.Xml
import com.google.gson.annotations.SerializedName
import java.util.*
@Xml
class ArtistInfo2 : ArtistInfoBase() {
@Element(name = "similarArtist")
var similarArtists: List<SimilarArtistID3>? = null
@SerializedName("similarArtist")
var similarArtists: List<SimilarArtistID3>? = emptyList()
}

View file

@ -1,25 +1,10 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.PropertyElement
import com.tickaroo.tikxml.annotation.Xml
@Xml
open class ArtistInfoBase {
@PropertyElement
var biography: String? = null
@PropertyElement
var musicBrainzId: String? = null
@PropertyElement
var lastFmUrl: String? = null
@PropertyElement
var smallImageUrl: String? = null
@PropertyElement
var mediumImageUrl: String? = null
@PropertyElement
var largeImageUrl: String? = null
}

View file

@ -1,13 +1,11 @@
package com.cappielloantonio.play.subsonic.models
import android.os.Parcelable
import com.tickaroo.tikxml.annotation.Element
import com.tickaroo.tikxml.annotation.Xml
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
@Parcelize
@Xml
class ArtistWithAlbumsID3 : ArtistID3(), Parcelable {
@Element(name = "album")
@SerializedName("album")
var albums: List<AlbumID3>? = null
}

View file

@ -1,11 +1,9 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.Element
import com.tickaroo.tikxml.annotation.Xml
import com.google.gson.annotations.SerializedName
@Xml
class ArtistsID3 {
@Element(name = "index")
@SerializedName("index")
var indices: List<IndexID3>? = null
var ignoredArticles: String? = null
}

View file

@ -3,137 +3,108 @@ package com.cappielloantonio.play.subsonic.models
import android.os.Parcelable
import androidx.room.ColumnInfo
import androidx.room.PrimaryKey
import com.tickaroo.tikxml.annotation.Attribute
import com.tickaroo.tikxml.annotation.Xml
import com.tickaroo.tikxml.converters.date.rfc3339.DateRfc3339TypeConverter
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
import java.util.*
@Parcelize
@Xml
open class Child(
@PrimaryKey
@ColumnInfo(name = "id")
@Attribute
open val id: String,
@ColumnInfo(name = "parent_id")
@Attribute(name = "parent")
@SerializedName("parent")
var parentId: String? = null,
@ColumnInfo(name = "is_dir")
@Attribute
var isDir: Boolean = false,
@ColumnInfo
@Attribute
var title: String? = null,
@ColumnInfo
@Attribute
var album: String? = null,
@ColumnInfo
@Attribute
var artist: String? = null,
@ColumnInfo
@Attribute
var track: Int? = null,
@ColumnInfo
@Attribute
var year: Int? = null,
@ColumnInfo
@Attribute(name = "genre")
@SerializedName("genre")
var genre: String? = null,
@ColumnInfo(name = "cover_art_id")
@Attribute(name = "coverArt")
@SerializedName("coverArt")
var coverArtId: String? = null,
@ColumnInfo
@Attribute
var size: Long? = null,
@ColumnInfo(name = "content_type")
@Attribute
var contentType: String? = null,
@ColumnInfo
@Attribute
var suffix: String? = null,
@ColumnInfo("transcoding_content_type")
@Attribute
var transcodedContentType: String? = null,
@ColumnInfo(name = "transcoded_suffix")
@Attribute
var transcodedSuffix: String? = null,
@ColumnInfo
@Attribute
var duration: Int? = null,
@ColumnInfo("bitrate")
@Attribute(name = "bitRate")
@SerializedName("bitRate")
var bitrate: Int? = null,
@ColumnInfo
@Attribute
var path: String? = null,
@ColumnInfo(name = "is_video")
@Attribute(name = "isVideo")
@SerializedName("isVideo")
var isVideo: Boolean = false,
@ColumnInfo(name = "user_rating")
@Attribute
var userRating: Int? = null,
@ColumnInfo(name = "average_rating")
@Attribute
var averageRating: Double? = null,
@ColumnInfo(name = "play_count")
@Attribute
var playCount: Long? = null,
@ColumnInfo(name = "disc_number")
@Attribute
var discNumber: Int? = null,
@ColumnInfo
@Attribute(converter = DateRfc3339TypeConverter::class)
var created: Date? = null,
@ColumnInfo
@Attribute(converter = DateRfc3339TypeConverter::class)
var starred: Date? = null,
@ColumnInfo(name = "album_id")
@Attribute
var albumId: String? = null,
@ColumnInfo(name = "artist_id")
@Attribute
var artistId: String? = null,
@ColumnInfo
@Attribute
var type: String? = null,
@ColumnInfo(name = "bookmark_position")
@Attribute
var bookmarkPosition: Long? = null,
@ColumnInfo(name = "original_width")
@Attribute
var originalWidth: Int? = null,
@ColumnInfo(name = "original_height")
@Attribute
var originalHeight: Int? = null
) : Parcelable

View file

@ -1,14 +1,7 @@
package com.cappielloantonio.play.subsonic.models
import com.cappielloantonio.play.subsonic.utils.converter.ErrorCodeConverter
import com.tickaroo.tikxml.annotation.Attribute
import com.tickaroo.tikxml.annotation.Xml
@Xml
class Error {
@Attribute(converter = ErrorCodeConverter::class)
var code: ErrorCode? = null
@Attribute
var message: String? = null
}

View file

@ -1,20 +1,13 @@
package com.cappielloantonio.play.subsonic.models
import android.os.Parcelable
import com.tickaroo.tikxml.annotation.Attribute
import com.tickaroo.tikxml.annotation.TextContent
import com.tickaroo.tikxml.annotation.Xml
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
@Parcelize
@Xml
class Genre : Parcelable {
@TextContent
@SerializedName("value")
var genre: String? = null
@Attribute
var songCount = 0
@Attribute
var albumCount = 0
}

View file

@ -1,10 +1,8 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.Element
import com.tickaroo.tikxml.annotation.Xml
import com.google.gson.annotations.SerializedName
@Xml
class Genres {
@Element
@SerializedName("genre")
var genres: List<Genre>? = null
}

View file

@ -1,11 +1,9 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.Element
import com.tickaroo.tikxml.annotation.Xml
import com.google.gson.annotations.SerializedName
@Xml
class IndexID3 {
@Element(name = "artist")
@SerializedName("artist")
var artists: List<ArtistID3>? = null
var name: String? = null
}

View file

@ -1,17 +1,7 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.Attribute
import com.tickaroo.tikxml.annotation.TextContent
import com.tickaroo.tikxml.annotation.Xml
@Xml(name = "lyrics")
class Lyrics {
@TextContent
var content: String? = null
@Attribute
var artist: String? = null
@Attribute
var title: String? = null
}

View file

@ -1,11 +1,6 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.Attribute
import com.tickaroo.tikxml.annotation.Xml
@Xml
class MediaType {
@Attribute
var value: String? = null
companion object {

View file

@ -1,13 +1,6 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.Attribute
import com.tickaroo.tikxml.annotation.Xml
@Xml
class MusicFolder {
@Attribute
var id = 0
@Attribute
var name: String? = null
}

View file

@ -1,10 +1,5 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.Element
import com.tickaroo.tikxml.annotation.Xml
@Xml
class MusicFolders {
@Element
var musicFolders: List<MusicFolder>? = null
}

View file

@ -1,10 +1,8 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.Element
import com.tickaroo.tikxml.annotation.Xml
import com.google.gson.annotations.SerializedName
@Xml
class NewestPodcasts {
@Element(name = "episode")
@SerializedName("episode")
var episodes: List<PodcastEpisode>? = null
}

View file

@ -1,9 +1,14 @@
package com.cappielloantonio.play.subsonic.models
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
@Parcelize
class NowPlayingEntry(override val id: String) : Child(id) {
class NowPlayingEntry(
// TODO
@SerializedName("_id")
override val id: String
) : Child(id) {
var username: String? = null
var minutesAgo = 0
var playerId = 0

View file

@ -5,60 +5,45 @@ import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.PrimaryKey
import com.tickaroo.tikxml.annotation.Attribute
import com.tickaroo.tikxml.annotation.Xml
import com.tickaroo.tikxml.converters.date.rfc3339.DateRfc3339TypeConverter
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
import java.util.*
@Parcelize
@Entity(tableName = "playlist")
@Xml
open class Playlist : Parcelable {
open class Playlist(
@PrimaryKey
@ColumnInfo(name = "id")
@Attribute
lateinit var id: String
open var id: String
) : Parcelable {
@ColumnInfo(name = "name")
@Attribute
var name: String? = null
@Ignore
@Attribute
var comment: String? = null
@Ignore
@Attribute
var owner: String? = null
@Ignore
@Attribute(name = "public")
@SerializedName("public")
var isUniversal: Boolean? = null
@Ignore
@Attribute
var songCount: Int = 0
@Ignore
@ColumnInfo(name = "duration")
@Attribute
var duration: Long = 0
@Ignore
@Attribute(converter = DateRfc3339TypeConverter::class)
var created: Date? = null
@Ignore
@Attribute(converter = DateRfc3339TypeConverter::class)
var changed: Date? = null
@Ignore
@ColumnInfo(name = "coverArt")
@Attribute
var coverArtId: String? = null
@Ignore
@Attribute
var allowedUsers: List<String>? = null
}

View file

@ -1,13 +1,14 @@
package com.cappielloantonio.play.subsonic.models
import android.os.Parcelable
import com.tickaroo.tikxml.annotation.Element
import com.tickaroo.tikxml.annotation.Xml
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
@Parcelize
@Xml
class PlaylistWithSongs : Playlist(), Parcelable {
@Element(name = "entry")
class PlaylistWithSongs(
@SerializedName("_id")
override var id: String
) : Playlist(id), Parcelable {
@SerializedName("entry")
var entries: List<Child>? = null
}

View file

@ -1,10 +1,8 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.Element
import com.tickaroo.tikxml.annotation.Xml
import com.google.gson.annotations.SerializedName
@Xml
class Playlists {
@Element(name = "playlist")
class Playlists(
@SerializedName("playlist")
var playlists: List<Playlist>? = null
}
)

View file

@ -1,38 +1,19 @@
package com.cappielloantonio.play.subsonic.models
import android.os.Parcelable
import com.tickaroo.tikxml.annotation.Attribute
import com.tickaroo.tikxml.annotation.Element
import com.tickaroo.tikxml.annotation.Xml
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
@Parcelize
@Xml
class PodcastChannel : Parcelable {
@Element(name = "episode")
@SerializedName("episode")
var episodes: List<PodcastEpisode>? = null
@Attribute
var id: String? = null
@Attribute
var url: String? = null
@Attribute
var title: String? = null
@Attribute
var description: String? = null
@Attribute
var coverArtId: String? = null
@Attribute
var originalImageUrl: String? = null
@Attribute
var status: String? = null
@Attribute
var errorMessage: String? = null
}

View file

@ -1,120 +1,54 @@
package com.cappielloantonio.play.subsonic.models
import android.os.Parcelable
import com.tickaroo.tikxml.annotation.Attribute
import com.tickaroo.tikxml.annotation.Xml
import com.tickaroo.tikxml.converters.date.rfc3339.DateRfc3339TypeConverter
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
import java.util.*
@Parcelize
@Xml
class PodcastEpisode : Parcelable {
@Attribute
var id: String? = null
@Attribute(name = "parent")
@SerializedName("parent")
var parentId: String? = null
@Attribute(name = "isDir")
@SerializedName("isDir")
var isDir = false
@Attribute
var title: String? = null
@Attribute
var album: String? = null
@Attribute
var artist: String? = null
@Attribute
var track: Int? = null
@Attribute
var year: Int? = null
@Attribute(name = "genre")
var genre: String? = null
@Attribute(name = "coverArt")
@SerializedName("coverArt")
var coverArtId: String? = null
@Attribute
var size: Long? = null
@Attribute
var contentType: String? = null
@Attribute
var suffix: String? = null
@Attribute
var transcodedContentType: String? = null
@Attribute
var transcodedSuffix: String? = null
@Attribute
var duration: Int? = null
@Attribute
var bitRate: Int? = null
@Attribute
var path: String? = null
@Attribute(name = "isVideo")
@SerializedName("isVideo")
var video: Boolean? = null
@Attribute
var userRating: Int? = null
@Attribute
var averageRating: Double? = null
@Attribute
var playCount: Long? = null
@Attribute
var discNumber: Int? = null
@Attribute(converter = DateRfc3339TypeConverter::class)
var created: Date? = null
@Attribute(converter = DateRfc3339TypeConverter::class)
var starred: Date? = null
@Attribute
var albumId: String? = null
@Attribute
var artistId: String? = null
@Attribute
var type: String? = null
@Attribute
var bookmarkPosition: Long? = null
@Attribute
var originalWidth: Int? = null
@Attribute
var originalHeight: Int? = null
@Attribute
var streamId: String? = null
@Attribute
var channelId: String? = null
@Attribute
var description: String? = null
@Attribute
var status: String? = null
@Attribute(converter = DateRfc3339TypeConverter::class)
var publishDate: Date? = null
}

View file

@ -1,11 +1,6 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.Attribute
import com.tickaroo.tikxml.annotation.Xml
@Xml
class PodcastStatus {
@Attribute
var value: String? = null
companion object {

View file

@ -1,10 +1,8 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.Element
import com.tickaroo.tikxml.annotation.Xml
import com.google.gson.annotations.SerializedName
@Xml
class Podcasts {
@Element(name = "channel")
@SerializedName("channel")
var channels: List<PodcastChannel>? = null
}

View file

@ -1,10 +1,6 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.Attribute
import com.tickaroo.tikxml.annotation.Xml
@Xml
class ResponseStatus(@param:Attribute val value: String) {
class ResponseStatus(val value: String) {
companion object {
@JvmField

View file

@ -1,13 +1,6 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.Attribute
import com.tickaroo.tikxml.annotation.Xml
@Xml
class ScanStatus {
@Attribute
var isScanning = false
@Attribute
var count: Long? = null
}

View file

@ -1,16 +1,14 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.Element
import com.tickaroo.tikxml.annotation.Xml
import com.google.gson.annotations.SerializedName
@Xml
class SearchResult2 {
@Element(name = "artist")
@SerializedName("artist")
var artists: List<Artist>? = null
@Element(name = "album")
@SerializedName("album")
var albums: List<Child>? = null
@Element(name = "song")
@SerializedName("song")
var songs: List<Child>? = null
}

View file

@ -1,16 +1,14 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.Element
import com.tickaroo.tikxml.annotation.Xml
import com.google.gson.annotations.SerializedName
@Xml
class SearchResult3 {
@Element(name = "artist")
@SerializedName("artist")
var artists: List<ArtistID3>? = null
@Element(name = "album")
@SerializedName("album")
var albums: List<AlbumID3>? = null
@Element(name = "song")
@SerializedName("song")
var songs: List<Child>? = null
}

View file

@ -1,22 +1,7 @@
package com.cappielloantonio.play.subsonic.models
import android.os.Parcelable
import com.tickaroo.tikxml.annotation.Attribute
import com.tickaroo.tikxml.annotation.Xml
import kotlinx.android.parcel.Parcelize
@Parcelize
@Xml(name = "similarArtist")
class SimilarArtistID3 : Parcelable {
@Attribute
var id: String? = null
@Attribute
var name: String? = null
@Attribute(name = "coverArt")
var coverArtId: String? = null
@Attribute
var albumCount = 0
}
class SimilarArtistID3 : ArtistID3(), Parcelable

View file

@ -1,10 +1,8 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.Element
import com.tickaroo.tikxml.annotation.Xml
import com.google.gson.annotations.SerializedName
@Xml
class SimilarSongs2 {
@Element(name = "song")
@SerializedName("song")
var songs: List<Child>? = null
}

View file

@ -1,10 +1,8 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.Element
import com.tickaroo.tikxml.annotation.Xml
import com.google.gson.annotations.SerializedName
@Xml
class Songs {
@Element(name = "song")
@SerializedName("song")
var songs: List<Child>? = null
}

View file

@ -1,16 +1,14 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.Element
import com.tickaroo.tikxml.annotation.Xml
import com.google.gson.annotations.SerializedName
@Xml
class Starred2 {
@Element(name = "artist")
@SerializedName("artist")
var artists: List<ArtistID3>? = null
@Element(name = "album")
@SerializedName("album")
var albums: List<AlbumID3>? = null
@Element(name = "song")
@SerializedName("song")
var songs: List<Child>? = null
}

View file

@ -1,54 +1,25 @@
package com.cappielloantonio.play.subsonic.models
import com.cappielloantonio.play.subsonic.utils.converter.ResponseStatusConverter
import com.tickaroo.tikxml.annotation.Attribute
import com.tickaroo.tikxml.annotation.Element
import com.tickaroo.tikxml.annotation.Xml
@Xml(name = "subsonic-response")
class SubsonicResponse {
@Element
var error: Error? = null
@Element(name = "scanStatus")
var scanStatus: ScanStatus? = null
@Element(name = "topSongs")
var topSongs: TopSongs? = null
@Element(name = "similarSongs2")
var similarSongs2: SimilarSongs2? = null
var similarSongs: SimilarSongs? = null
@Element(name = "artistInfo2")
var artistInfo2: ArtistInfo2? = null
var artistInfo: ArtistInfo? = null
@Element(name = "albumInfo")
var albumInfo: AlbumInfo? = null
@Element(name = "starred2")
var starred2: Starred2? = null
var starred: Starred? = null
var shares: Shares? = null
var playQueue: PlayQueue? = null
var bookmarks: Bookmarks? = null
var internetRadioStations: InternetRadioStations? = null
@Element(name = "newestPodcasts")
var newestPodcasts: NewestPodcasts? = null
var podcasts: Podcasts? = null
@Element(name = "lyrics")
var lyrics: Lyrics? = null
@Element(name = "songsByGenre")
var songsByGenre: Songs? = null
@Element(name = "randomSongs")
var randomSongs: Songs? = null
@Element
var albumList2: AlbumList2? = null
var albumList: AlbumList? = null
var chatMessages: ChatMessages? = null
@ -57,52 +28,24 @@ class SubsonicResponse {
var license: License? = null
var jukeboxPlaylist: JukeboxPlaylist? = null
var jukeboxStatus: JukeboxStatus? = null
@Element(name = "playlist")
var playlist: PlaylistWithSongs? = null
@Element
var playlists: Playlists? = null
@Element
var searchResult3: SearchResult3? = null
@Element
var searchResult2: SearchResult2? = null
var searchResult: SearchResult? = null
var nowPlaying: NowPlaying? = null
var videoInfo: VideoInfo? = null
var videos: Videos? = null
@Element(name = "song")
var song: Child? = null
@Element(name = "album")
var album: AlbumWithSongsID3? = null
@Element(name = "artist")
var artist: ArtistWithAlbumsID3? = null
@Element(name = "artists")
var artists: ArtistsID3? = null
@Element
var genres: Genres? = null
var directory: Directory? = null
var indexes: Indexes? = null
@Element
var musicFolders: MusicFolders? = null
@Attribute(converter = ResponseStatusConverter::class)
var status: ResponseStatus? = null
@Attribute
var status: String? = null
var version: String? = null
@Attribute
var type: String? = null
@Attribute
var serverVersion: String? = null
}

View file

@ -1,10 +1,8 @@
package com.cappielloantonio.play.subsonic.models
import com.tickaroo.tikxml.annotation.Element
import com.tickaroo.tikxml.annotation.Xml
import com.google.gson.annotations.SerializedName
@Xml
class TopSongs {
@Element(name = "song")
@SerializedName("song")
var songs: List<Child>? = null
}

View file

@ -1,16 +0,0 @@
package com.cappielloantonio.play.subsonic.utils.converter;
import com.cappielloantonio.play.subsonic.models.ErrorCode;
import com.tickaroo.tikxml.TypeConverter;
public class ErrorCodeConverter implements TypeConverter<ErrorCode> {
@Override
public ErrorCode read(String value) throws Exception {
return new ErrorCode(Integer.parseInt(value));
}
@Override
public String write(ErrorCode value) throws Exception {
return String.valueOf(value.getValue());
}
}

View file

@ -1,16 +0,0 @@
package com.cappielloantonio.play.subsonic.utils.converter;
import com.cappielloantonio.play.subsonic.models.ResponseStatus;
import com.tickaroo.tikxml.TypeConverter;
public class ResponseStatusConverter implements TypeConverter<ResponseStatus> {
@Override
public ResponseStatus read(String value) throws Exception {
return new ResponseStatus(value);
}
@Override
public String write(ResponseStatus value) throws Exception {
return value.getValue();
}
}

View file

@ -98,7 +98,7 @@ public class PlaylistChooserDialog extends DialogFragment implements ClickCallba
@Override
public void onPlaylistClick(Bundle bundle) {
Playlist playlist = requireArguments().getParcelable("playlist_object");
Playlist playlist = bundle.getParcelable("playlist_object");
playlistChooserViewModel.addSongToPlaylist(playlist.getId());
dismiss();
}

View file

@ -541,7 +541,7 @@ public class HomeFragment extends Fragment implements ClickCallback {
bind.homeMostPlayedAlbumsPlaceholder.placeholder.setVisibility(View.GONE);
if (bind != null)
bind.homeMostPlayedAlbumsSector.setVisibility(!albums.isEmpty() ? View.VISIBLE : View.GONE);
if (albums.size() < 5) reorder();
// if (albums.size() < 5) reorder();
mostPlayedAlbumAdapter.setItems(albums);
}
@ -714,19 +714,21 @@ public class HomeFragment extends Fragment implements ClickCallback {
public void reorder() {
if (bind != null) {
bind.homeLinearLayoutContainer.removeAllViews();
bind.homeLinearLayoutContainer.addView(bind.homeDiscoverSector);
// bind.homeLinearLayoutContainer.removeAllViews();
// bind.homeLinearLayoutContainer.addView(bind.homeDiscoverSector);
// bind.homeLinearLayoutContainer.addView(bind.homeSimilarTracksSector);
// bind.homeLinearLayoutContainer.addView(bind.homeRadioArtistSector);
// bind.homeLinearLayoutContainer.addView(bind.homeGridTracksSector);
// bind.homeLinearLayoutContainer.addView(bind.starredTracksSector);
// bind.homeLinearLayoutContainer.addView(bind.starredAlbumsSector);
// bind.homeLinearLayoutContainer.addView(bind.starredArtistsSector);
bind.homeLinearLayoutContainer.addView(bind.homeRecentlyAddedAlbumsSector);
bind.homeLinearLayoutContainer.addView(bind.homeFlashbackSector);
bind.homeLinearLayoutContainer.addView(bind.homeMostPlayedAlbumsSector);
bind.homeLinearLayoutContainer.addView(bind.homeRecentlyPlayedAlbumsSector);
bind.homeLinearLayoutContainer.addView(bind.homeNewestPodcastsSector);
// bind.homeLinearLayoutContainer.addView(bind.homeRecentlyAddedAlbumsSector);
// bind.homeLinearLayoutContainer.addView(bind.homeFlashbackSector);
// bind.homeLinearLayoutContainer.addView(bind.homeMostPlayedAlbumsSector);
// bind.homeLinearLayoutContainer.addView(bind.homeRecentlyPlayedAlbumsSector);
// bind.homeLinearLayoutContainer.addView(bind.homeNewestPodcastsSector);
}
}

View file

@ -3,17 +3,18 @@ package com.cappielloantonio.play.ui.fragment;
import android.content.ComponentName;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.media3.common.MediaMetadata;
import androidx.media3.common.Player;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.session.MediaBrowser;
import androidx.media3.session.MediaController;
import androidx.media3.session.SessionToken;
@ -33,9 +34,8 @@ import com.google.android.material.elevation.SurfaceColors;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
@OptIn(markerClass = UnstableApi.class)
public class PlayerBottomSheetFragment extends Fragment {
private static final String TAG = "PlayerBottomSheetFragment";
private FragmentPlayerBottomSheetBinding bind;
private PlayerBottomSheetViewModel playerBottomSheetViewModel;
@ -142,24 +142,24 @@ public class PlayerBottomSheetFragment extends Fragment {
}
private void setMetadata(MediaMetadata mediaMetadata) {
if (mediaMetadata.extras != null)
playerBottomSheetViewModel.setLiveMedia(getViewLifecycleOwner(), mediaMetadata.extras.getString("mediaType"), mediaMetadata.extras.getString("id"));
if (mediaMetadata.extras != null)
playerBottomSheetViewModel.setLiveArtist(getViewLifecycleOwner(), mediaMetadata.extras.getString("mediaType"), mediaMetadata.extras.getString("artistId"));
if (mediaMetadata.extras != null) {
playerBottomSheetViewModel.setLiveMedia(getViewLifecycleOwner(), mediaMetadata.extras.getString("type"), mediaMetadata.extras.getString("id"));
playerBottomSheetViewModel.setLiveArtist(getViewLifecycleOwner(), mediaMetadata.extras.getString("type"), mediaMetadata.extras.getString("artistId"));
bind.playerHeaderLayout.playerHeaderMediaTitleLabel.setText(MusicUtil.getReadableString(String.valueOf(mediaMetadata.title)));
bind.playerHeaderLayout.playerHeaderMediaArtistLabel.setText(MusicUtil.getReadableString(String.valueOf(mediaMetadata.artist)));
bind.playerHeaderLayout.playerHeaderMediaTitleLabel.setText(MusicUtil.getReadableString(mediaMetadata.extras.getString("title")));
bind.playerHeaderLayout.playerHeaderMediaArtistLabel.setText(MusicUtil.getReadableString(mediaMetadata.extras.getString("artist")));
if (mediaMetadata.extras != null) CustomGlideRequest.Builder
CustomGlideRequest.Builder
.from(requireContext(), mediaMetadata.extras.getString("coverArtId"), CustomGlideRequest.SONG_PIC, null)
.build()
.transform(new CenterCrop(), new RoundedCorners(CustomGlideRequest.CORNER_RADIUS))
.into(bind.playerHeaderLayout.playerHeaderMediaCoverImage);
}
}
private void setMediaControllerUI(MediaBrowser mediaBrowser) {
if (mediaBrowser.getMediaMetadata().extras != null) {
switch (mediaBrowser.getMediaMetadata().extras.getString("mediaType", Media.MEDIA_TYPE_MUSIC)) {
switch (mediaBrowser.getMediaMetadata().extras.getString("type", Media.MEDIA_TYPE_MUSIC)) {
case Media.MEDIA_TYPE_PODCAST:
bind.playerHeaderLayout.playerHeaderFastForwardMediaButton.setVisibility(View.VISIBLE);
bind.playerHeaderLayout.playerHeaderRewindMediaButton.setVisibility(View.VISIBLE);

View file

@ -27,6 +27,7 @@ import com.cappielloantonio.play.R;
import com.cappielloantonio.play.databinding.InnerFragmentPlayerControllerBinding;
import com.cappielloantonio.play.model.Media;
import com.cappielloantonio.play.service.MediaService;
import com.cappielloantonio.play.subsonic.models.Child;
import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.ui.dialog.RatingDialog;
import com.cappielloantonio.play.ui.fragment.pager.PlayerControllerHorizontalPager;
@ -155,7 +156,7 @@ public class PlayerControllerFragment extends Fragment {
private void setMediaInfo(MediaMetadata mediaMetadata) {
if (mediaMetadata.extras != null) {
String extension = mediaMetadata.extras.getString("extension", "Unknown format");
String extension = mediaMetadata.extras.getString("suffix", "Unknown format");
String bitrate = mediaMetadata.extras.getInt("bitrate", 0) != 0 ? mediaMetadata.extras.getInt("bitrate", 0) + "kbps" : "Original";
playerMediaExtension.setText(extension);
@ -190,7 +191,7 @@ public class PlayerControllerFragment extends Fragment {
initPlaybackSpeedButton(mediaBrowser);
if (mediaBrowser.getMediaMetadata().extras != null) {
switch (mediaBrowser.getMediaMetadata().extras.getString("mediaType", Media.MEDIA_TYPE_MUSIC)) {
switch (mediaBrowser.getMediaMetadata().extras.getString("type", Media.MEDIA_TYPE_MUSIC)) {
case Media.MEDIA_TYPE_PODCAST:
bind.getRoot().setShowShuffleButton(false);
bind.getRoot().setShowRewindButton(true);
@ -239,7 +240,7 @@ public class PlayerControllerFragment extends Fragment {
private void initMediaListenable() {
playerBottomSheetViewModel.getLiveMedia().observe(getViewLifecycleOwner(), media -> {
if (media != null) {
buttonFavorite.setChecked(Boolean.TRUE.equals(media.getStarred()));
buttonFavorite.setChecked(media.getStarred() != null);
buttonFavorite.setOnClickListener(v -> playerBottomSheetViewModel.setFavorite(requireContext(), media));
buttonFavorite.setOnLongClickListener(v -> {
Bundle bundle = new Bundle();

View file

@ -34,6 +34,8 @@ import com.paulrybitskyi.persistentsearchview.adapters.model.SuggestionItem;
import com.paulrybitskyi.persistentsearchview.listeners.OnSuggestionChangeListener;
import com.paulrybitskyi.persistentsearchview.utils.SuggestionCreationUtil;
import java.util.Collections;
@UnstableApi
public class SearchFragment extends Fragment implements ClickCallback {
private FragmentSearchBinding bind;
@ -179,14 +181,29 @@ public class SearchFragment extends Fragment implements ClickCallback {
private void performSearch(String query) {
searchViewModel.search(query).observe(getViewLifecycleOwner(), result -> {
if (bind != null) {
if (result.getArtists() != null) {
bind.searchArtistSector.setVisibility(!result.getArtists().isEmpty() ? View.VISIBLE : View.GONE);
artistAdapter.setItems(result.getArtists());
} else {
artistAdapter.setItems(Collections.emptyList());
bind.searchArtistSector.setVisibility(View.GONE);
}
if (result.getAlbums() != null) {
bind.searchAlbumSector.setVisibility(!result.getAlbums().isEmpty() ? View.VISIBLE : View.GONE);
albumAdapter.setItems(result.getAlbums());
} else {
albumAdapter.setItems(Collections.emptyList());
bind.searchAlbumSector.setVisibility(View.GONE);
}
if (result.getSongs() != null) {
bind.searchSongSector.setVisibility(!result.getSongs().isEmpty() ? View.VISIBLE : View.GONE);
songHorizontalAdapter.setItems(result.getSongs());
} else {
songHorizontalAdapter.setItems(Collections.emptyList());
bind.searchSongSector.setVisibility(View.GONE);
}
}
});

View file

@ -10,8 +10,6 @@ import com.cappielloantonio.play.ui.fragment.PlayerQueueFragment;
import java.util.HashMap;
public class PlayerControllerVerticalPager extends FragmentStateAdapter {
private static final String TAG = "PlayerControllerVerticalPager";
private final HashMap<Integer, Fragment> maps;
public PlayerControllerVerticalPager(@NonNull Fragment fragment) {

View file

@ -87,7 +87,37 @@ public class MappingUtil {
boolean isDownloaded = DownloadUtil.getDownloadTracker(context).isDownloaded(MusicUtil.getDownloadUri(media.getId()));
Bundle bundle = new Bundle();
bundle.putParcelable("child", media);
bundle.putString("id", media.getId());
bundle.putString("parentId", media.getParentId());
bundle.putBoolean("isDir", media.isDir());
bundle.putString("title", media.getTitle());
bundle.putString("album", media.getAlbum());
bundle.putString("artist", media.getArtist());
bundle.putInt("track", media.getTrack() != null ? media.getTrack() : 0);
bundle.putInt("year", media.getYear() != null ? media.getYear() : 0);
bundle.putString("genre", media.getGenre());
bundle.putString("coverArtId", media.getCoverArtId());
bundle.putLong("size", media.getSize() != null ? media.getSize() : 0);
bundle.putString("contentType", media.getContentType());
bundle.putString("suffix", media.getSuffix());
bundle.putString("transcodedContentType", media.getTranscodedContentType());
bundle.putString("transcodedSuffix", media.getTranscodedSuffix());
bundle.putInt("duration", media.getDuration() != null ? media.getDuration() : 0);
bundle.putInt("bitrate", media.getBitrate() != null ? media.getBitrate() : 0);
bundle.putString("path", media.getPath());
bundle.putBoolean("isVideo", media.isVideo());
bundle.putInt("userRating", media.getUserRating() != null ? media.getUserRating() : 0);
bundle.putDouble("averageRating", media.getAverageRating() != null ? media.getAverageRating() : 0);
bundle.putLong("playCount", media.getPlayCount() != null ? media.getTrack() : 0);
bundle.putInt("discNumber", media.getDiscNumber() != null ? media.getTrack() : 0);
bundle.putLong("created", media.getCreated() != null ? media.getCreated().getTime() : 0);
bundle.putLong("starred", media.getStarred() != null ? media.getStarred().getTime() : 0);
bundle.putString("albumId", media.getAlbumId());
bundle.putString("artistId", media.getArtistId());
bundle.putString("type", media.getType());
bundle.putLong("bookmarkPosition", media.getBookmarkPosition() != null ? media.getBookmarkPosition() : 0);
bundle.putInt("originalWidth", media.getOriginalWidth() != null ? media.getOriginalWidth() : 0);
bundle.putInt("originalHeight", media.getOriginalHeight() != null ? media.getOriginalHeight() : 0);
return new MediaItem.Builder()
.setMediaId(media.getId())

View file

@ -10,6 +10,7 @@ import androidx.lifecycle.MutableLiveData;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.interfaces.MediaCallback;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.AlbumID3;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
@ -59,18 +60,18 @@ public class AlbumCatalogueViewModel extends AndroidViewModel {
App.getSubsonicClientInstance(context, false)
.getAlbumSongListClient()
.getAlbumList2("alphabeticalByName", size, offset, null, null)
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull retrofit2.Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getAlbumList2() != null) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull retrofit2.Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getAlbumList2() != null) {
List<AlbumID3> albumList = new ArrayList<>();
albumList.addAll(response.body().getAlbumList2().getAlbums());
albumList.addAll(response.body().getSubsonicResponse().getAlbumList2().getAlbums());
callback.onLoadMedia(albumList);
}
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
callback.onError(new Exception(t.getMessage()));
}
});

View file

@ -9,6 +9,7 @@ import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.subsonic.base.ApiResponse;
import com.cappielloantonio.play.subsonic.models.ArtistID3;
import com.cappielloantonio.play.subsonic.models.IndexID3;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
@ -34,13 +35,13 @@ public class ArtistCatalogueViewModel extends AndroidViewModel {
App.getSubsonicClientInstance(context, false)
.getBrowsingClient()
.getArtists()
.enqueue(new Callback<SubsonicResponse>() {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<SubsonicResponse> call, @NonNull retrofit2.Response<SubsonicResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getArtists() != null) {
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull retrofit2.Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getArtists() != null) {
List<ArtistID3> artists = new ArrayList<>();
for (IndexID3 index : response.body().getArtists().getIndices()) {
for (IndexID3 index : response.body().getSubsonicResponse().getArtists().getIndices()) {
artists.addAll(index.getArtists());
}
@ -49,7 +50,7 @@ public class ArtistCatalogueViewModel extends AndroidViewModel {
}
@Override
public void onFailure(@NonNull Call<SubsonicResponse> call, @NonNull Throwable t) {
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});