mirror of
https://github.com/antebudimir/tempus.git
synced 2026-01-01 18:03:33 +00:00
Merge branch 'development' into fix-album-parse-empty-date-field
This commit is contained in:
commit
bdca5e16ed
27 changed files with 296 additions and 202 deletions
|
|
@ -8,18 +8,18 @@ import androidx.room.PrimaryKey
|
||||||
import com.cappielloantonio.tempo.subsonic.models.Child
|
import com.cappielloantonio.tempo.subsonic.models.Child
|
||||||
import com.cappielloantonio.tempo.util.Preferences
|
import com.cappielloantonio.tempo.util.Preferences
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
import java.util.*
|
import java.util.Date
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
@Entity(tableName = "chronology")
|
@Entity(tableName = "chronology")
|
||||||
class Chronology(@PrimaryKey override val id: String) : Child(id) {
|
class Chronology(
|
||||||
|
@PrimaryKey override val id: String,
|
||||||
@ColumnInfo(name = "timestamp")
|
@ColumnInfo(name = "timestamp")
|
||||||
var timestamp: Long = System.currentTimeMillis()
|
var timestamp: Long = System.currentTimeMillis(),
|
||||||
|
|
||||||
@ColumnInfo(name = "server")
|
@ColumnInfo(name = "server")
|
||||||
var server: String? = null
|
var server: String? = null,
|
||||||
|
) : Child(id) {
|
||||||
constructor(mediaItem: MediaItem) : this(mediaItem.mediaMetadata.extras!!.getString("id")!!) {
|
constructor(mediaItem: MediaItem) : this(mediaItem.mediaMetadata.extras!!.getString("id")!!) {
|
||||||
parentId = mediaItem.mediaMetadata.extras!!.getString("parentId")
|
parentId = mediaItem.mediaMetadata.extras!!.getString("parentId")
|
||||||
isDir = mediaItem.mediaMetadata.extras!!.getBoolean("isDir")
|
isDir = mediaItem.mediaMetadata.extras!!.getBoolean("isDir")
|
||||||
|
|
|
||||||
|
|
@ -10,19 +10,17 @@ import kotlinx.parcelize.Parcelize
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
@Entity(tableName = "download")
|
@Entity(tableName = "download")
|
||||||
class Download(@PrimaryKey override val id: String) : Child(id) {
|
class Download(
|
||||||
|
@PrimaryKey override val id: String,
|
||||||
@ColumnInfo(name = "playlist_id")
|
@ColumnInfo(name = "playlist_id")
|
||||||
var playlistId: String? = null
|
var playlistId: String? = null,
|
||||||
|
|
||||||
@ColumnInfo(name = "playlist_name")
|
@ColumnInfo(name = "playlist_name")
|
||||||
var playlistName: String? = null
|
var playlistName: String? = null,
|
||||||
|
|
||||||
@ColumnInfo(name = "download_state", defaultValue = "1")
|
@ColumnInfo(name = "download_state", defaultValue = "1")
|
||||||
var downloadState: Int = 0
|
var downloadState: Int = 0,
|
||||||
|
|
||||||
@ColumnInfo(name = "download_uri", defaultValue = "")
|
@ColumnInfo(name = "download_uri", defaultValue = "")
|
||||||
var downloadUri: String? = null
|
var downloadUri: String? = null,
|
||||||
|
) : Child(id) {
|
||||||
constructor(child: Child) : this(child.id) {
|
constructor(child: Child) : this(child.id) {
|
||||||
parentId = child.parentId
|
parentId = child.parentId
|
||||||
isDir = child.isDir
|
isDir = child.isDir
|
||||||
|
|
@ -62,5 +60,5 @@ class Download(@PrimaryKey override val id: String) : Child(id) {
|
||||||
@Keep
|
@Keep
|
||||||
data class DownloadStack(
|
data class DownloadStack(
|
||||||
var id: String,
|
var id: String,
|
||||||
var view: String?
|
var view: String?,
|
||||||
)
|
)
|
||||||
|
|
@ -10,20 +10,18 @@ import kotlinx.parcelize.Parcelize
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
@Entity(tableName = "queue")
|
@Entity(tableName = "queue")
|
||||||
class Queue(override val id: String) : Child(id) {
|
class Queue(
|
||||||
|
override val id: String,
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
@ColumnInfo(name = "track_order")
|
@ColumnInfo(name = "track_order")
|
||||||
var trackOrder: Int = 0
|
var trackOrder: Int = 0,
|
||||||
|
|
||||||
@ColumnInfo(name = "last_play")
|
@ColumnInfo(name = "last_play")
|
||||||
var lastPlay: Long = 0
|
var lastPlay: Long = 0,
|
||||||
|
|
||||||
@ColumnInfo(name = "playing_changed")
|
@ColumnInfo(name = "playing_changed")
|
||||||
var playingChanged: Long = 0
|
var playingChanged: Long = 0,
|
||||||
|
|
||||||
@ColumnInfo(name = "stream_id")
|
@ColumnInfo(name = "stream_id")
|
||||||
var streamId: String? = null
|
var streamId: String? = null,
|
||||||
|
) : Child(id) {
|
||||||
constructor(child: Child) : this(child.id) {
|
constructor(child: Child) : this(child.id) {
|
||||||
parentId = child.parentId
|
parentId = child.parentId
|
||||||
isDir = child.isDir
|
isDir = child.isDir
|
||||||
|
|
|
||||||
|
|
@ -4,38 +4,36 @@ import android.os.Parcelable
|
||||||
import androidx.annotation.Keep
|
import androidx.annotation.Keep
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
import java.time.Instant
|
import java.util.Date
|
||||||
import java.time.LocalDate
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
open class AlbumID3 : Parcelable {
|
open class AlbumID3(
|
||||||
var id: String? = null
|
var id: String? = null,
|
||||||
var name: String? = null
|
var name: String? = null,
|
||||||
var artist: String? = null
|
var artist: String? = null,
|
||||||
var artistId: String? = null
|
var artistId: String? = null,
|
||||||
@SerializedName("coverArt")
|
@SerializedName("coverArt")
|
||||||
var coverArtId: String? = null
|
var coverArtId: String? = null,
|
||||||
var songCount: Int? = 0
|
var songCount: Int? = 0,
|
||||||
var duration: Int? = 0
|
var duration: Int? = 0,
|
||||||
var playCount: Long? = 0
|
var playCount: Long? = 0,
|
||||||
var created: Date? = null
|
var created: Date? = null,
|
||||||
var starred: Date? = null
|
var starred: Date? = null,
|
||||||
var year: Int = 0
|
var year: Int = 0,
|
||||||
var genre: String? = null
|
var genre: String? = null,
|
||||||
var played: Date? = Date(0)
|
var played: Date? = Date(0),
|
||||||
var userRating: Int? = 0
|
var userRating: Int? = 0,
|
||||||
var recordLabels: List<RecordLabel>? = null
|
var recordLabels: List<RecordLabel>? = null,
|
||||||
var musicBrainzId: String? = null
|
var musicBrainzId: String? = null,
|
||||||
var genres: List<ItemGenre>? = null
|
var genres: List<ItemGenre>? = null,
|
||||||
var artists: List<ArtistID3>? = null
|
var artists: List<ArtistID3>? = null,
|
||||||
var displayArtist: String? = null
|
var displayArtist: String? = null,
|
||||||
var releaseTypes: List<String>? = null
|
var releaseTypes: List<String>? = null,
|
||||||
var moods: List<String>? = null
|
var moods: List<String>? = null,
|
||||||
var sortName: String? = null
|
var sortName: String? = null,
|
||||||
var originalReleaseDate: ItemDate? = null
|
var originalReleaseDate: ItemDate? = null,
|
||||||
var releaseDate: ItemDate? = null
|
var releaseDate: ItemDate? = null,
|
||||||
var isCompilation: Boolean? = null
|
var isCompilation: Boolean? = null,
|
||||||
var discTitles: List<DiscTitle>? = null
|
var discTitles: List<DiscTitle>? = null,
|
||||||
}
|
) : Parcelable
|
||||||
|
|
@ -7,7 +7,7 @@ import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
class AlbumWithSongsID3 : AlbumID3(), Parcelable {
|
class AlbumWithSongsID3(
|
||||||
@SerializedName("song")
|
@SerializedName("song")
|
||||||
var songs: List<Child>? = null
|
var songs: List<Child>? = null,
|
||||||
}
|
) : AlbumID3(), Parcelable
|
||||||
|
|
@ -7,10 +7,10 @@ import java.util.Date
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
class Artist : Parcelable {
|
class Artist(
|
||||||
var id: String? = null
|
var id: String? = null,
|
||||||
var name: String? = null
|
var name: String? = null,
|
||||||
var starred: Date? = null
|
var starred: Date? = null,
|
||||||
var userRating: Int? = null
|
var userRating: Int? = null,
|
||||||
var averageRating: Double? = null
|
var averageRating: Double? = null,
|
||||||
}
|
) : Parcelable
|
||||||
|
|
@ -4,15 +4,15 @@ import android.os.Parcelable
|
||||||
import androidx.annotation.Keep
|
import androidx.annotation.Keep
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
import java.util.*
|
import java.util.Date
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
open class ArtistID3 : Parcelable {
|
open class ArtistID3(
|
||||||
var id: String? = null
|
var id: String? = null,
|
||||||
var name: String? = null
|
var name: String? = null,
|
||||||
@SerializedName("coverArt")
|
@SerializedName("coverArt")
|
||||||
var coverArtId: String? = null
|
var coverArtId: String? = null,
|
||||||
var albumCount = 0
|
var albumCount: Int = 0,
|
||||||
var starred: Date? = null
|
var starred: Date? = null,
|
||||||
}
|
) : Parcelable
|
||||||
|
|
@ -7,7 +7,7 @@ import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
class ArtistWithAlbumsID3 : ArtistID3(), Parcelable {
|
class ArtistWithAlbumsID3(
|
||||||
@SerializedName("album")
|
@SerializedName("album")
|
||||||
var albums: List<AlbumID3>? = null
|
var albums: List<AlbumID3>? = null,
|
||||||
}
|
) : ArtistID3(), Parcelable
|
||||||
|
|
@ -8,15 +8,15 @@ import java.util.Date
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
class Directory : Parcelable {
|
class Directory(
|
||||||
@SerializedName("child")
|
@SerializedName("child")
|
||||||
var children: List<Child>? = null
|
var children: List<Child>? = null,
|
||||||
var id: String? = null
|
var id: String? = null,
|
||||||
@SerializedName("parent")
|
@SerializedName("parent")
|
||||||
var parentId: String? = null
|
var parentId: String? = null,
|
||||||
var name: String? = null
|
var name: String? = null,
|
||||||
var starred: Date? = null
|
var starred: Date? = null,
|
||||||
var userRating: Int? = null
|
var userRating: Int? = null,
|
||||||
var averageRating: Double? = null
|
var averageRating: Double? = null,
|
||||||
var playCount: Long? = null
|
var playCount: Long? = null,
|
||||||
}
|
) : Parcelable
|
||||||
|
|
@ -6,7 +6,7 @@ import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
open class DiscTitle : Parcelable {
|
open class DiscTitle(
|
||||||
var disc: Int? = null
|
var disc: Int? = null,
|
||||||
var title: String? = null
|
var title: String? = null,
|
||||||
}
|
) : Parcelable
|
||||||
|
|
@ -7,9 +7,9 @@ import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
class Genre : Parcelable {
|
class Genre(
|
||||||
@SerializedName("value")
|
@SerializedName("value")
|
||||||
var genre: String? = null
|
var genre: String? = null,
|
||||||
var songCount = 0
|
var songCount: Int = 0,
|
||||||
var albumCount = 0
|
var albumCount: Int = 0,
|
||||||
}
|
) : Parcelable
|
||||||
|
|
@ -6,9 +6,9 @@ import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
class InternetRadioStation : Parcelable {
|
class InternetRadioStation(
|
||||||
var id: String? = null
|
var id: String? = null,
|
||||||
var name: String? = null
|
var name: String? = null,
|
||||||
var streamUrl: String? = null
|
var streamUrl: String? = null,
|
||||||
var homePageUrl: String? = null
|
var homePageUrl: String? = null,
|
||||||
}
|
) : Parcelable
|
||||||
|
|
@ -9,11 +9,11 @@ import java.util.Locale
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
open class ItemDate : Parcelable {
|
open class ItemDate(
|
||||||
var year: Int? = null
|
var year: Int? = null,
|
||||||
var month: Int? = null
|
var month: Int? = null,
|
||||||
var day: Int? = null
|
var day: Int? = null,
|
||||||
|
) : Parcelable {
|
||||||
fun getFormattedDate(): String? {
|
fun getFormattedDate(): String? {
|
||||||
if (year == null && month == null && day == null) return null
|
if (year == null && month == null && day == null) return null
|
||||||
|
|
||||||
|
|
@ -22,8 +22,7 @@ open class ItemDate : Parcelable {
|
||||||
SimpleDateFormat("yyyy", Locale.getDefault())
|
SimpleDateFormat("yyyy", Locale.getDefault())
|
||||||
} else if (day == null) {
|
} else if (day == null) {
|
||||||
SimpleDateFormat("MMMM yyyy", Locale.getDefault())
|
SimpleDateFormat("MMMM yyyy", Locale.getDefault())
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
SimpleDateFormat("MMMM dd, yyyy", Locale.getDefault())
|
SimpleDateFormat("MMMM dd, yyyy", Locale.getDefault())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,6 @@ import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
open class ItemGenre : Parcelable {
|
open class ItemGenre(
|
||||||
var name: String? = null
|
var name: String? = null,
|
||||||
}
|
) : Parcelable
|
||||||
|
|
@ -6,7 +6,7 @@ import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
class MusicFolder : Parcelable {
|
class MusicFolder(
|
||||||
var id: String? = null
|
var id: String? = null,
|
||||||
var name: String? = null
|
var name: String? = null,
|
||||||
}
|
) : Parcelable
|
||||||
|
|
@ -8,10 +8,9 @@ import kotlinx.parcelize.Parcelize
|
||||||
@Parcelize
|
@Parcelize
|
||||||
class NowPlayingEntry(
|
class NowPlayingEntry(
|
||||||
@SerializedName("_id")
|
@SerializedName("_id")
|
||||||
override val id: String
|
override val id: String,
|
||||||
) : Child(id) {
|
var username: String? = null,
|
||||||
var username: String? = null
|
var minutesAgo: Int = 0,
|
||||||
var minutesAgo = 0
|
var playerId: Int = 0,
|
||||||
var playerId = 0
|
var playerName: String? = null,
|
||||||
var playerName: String? = null
|
) : Child(id)
|
||||||
}
|
|
||||||
|
|
@ -7,8 +7,9 @@ import androidx.room.Entity
|
||||||
import androidx.room.Ignore
|
import androidx.room.Ignore
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
|
import kotlinx.parcelize.IgnoredOnParcel
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
import java.util.*
|
import java.util.Date
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
|
|
@ -16,27 +17,56 @@ import java.util.*
|
||||||
open class Playlist(
|
open class Playlist(
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
@ColumnInfo(name = "id")
|
@ColumnInfo(name = "id")
|
||||||
open var id: String
|
open var id: String,
|
||||||
) : Parcelable {
|
|
||||||
@ColumnInfo(name = "name")
|
@ColumnInfo(name = "name")
|
||||||
var name: String? = null
|
var name: String? = null,
|
||||||
|
@ColumnInfo(name = "duration")
|
||||||
|
var duration: Long = 0,
|
||||||
|
@ColumnInfo(name = "coverArt")
|
||||||
|
var coverArtId: String? = null,
|
||||||
|
) : Parcelable {
|
||||||
@Ignore
|
@Ignore
|
||||||
|
@IgnoredOnParcel
|
||||||
var comment: String? = null
|
var comment: String? = null
|
||||||
@Ignore
|
@Ignore
|
||||||
|
@IgnoredOnParcel
|
||||||
var owner: String? = null
|
var owner: String? = null
|
||||||
@Ignore
|
@Ignore
|
||||||
|
@IgnoredOnParcel
|
||||||
@SerializedName("public")
|
@SerializedName("public")
|
||||||
var isUniversal: Boolean? = null
|
var isUniversal: Boolean? = null
|
||||||
@Ignore
|
@Ignore
|
||||||
|
@IgnoredOnParcel
|
||||||
var songCount: Int = 0
|
var songCount: Int = 0
|
||||||
@ColumnInfo(name = "duration")
|
|
||||||
var duration: Long = 0
|
|
||||||
@Ignore
|
@Ignore
|
||||||
|
@IgnoredOnParcel
|
||||||
var created: Date? = null
|
var created: Date? = null
|
||||||
@Ignore
|
@Ignore
|
||||||
|
@IgnoredOnParcel
|
||||||
var changed: Date? = null
|
var changed: Date? = null
|
||||||
@ColumnInfo(name = "coverArt")
|
|
||||||
var coverArtId: String? = null
|
|
||||||
@Ignore
|
@Ignore
|
||||||
|
@IgnoredOnParcel
|
||||||
var allowedUsers: List<String>? = null
|
var allowedUsers: List<String>? = null
|
||||||
|
@Ignore
|
||||||
|
constructor(
|
||||||
|
id: String,
|
||||||
|
name: String?,
|
||||||
|
comment: String?,
|
||||||
|
owner: String?,
|
||||||
|
isUniversal: Boolean?,
|
||||||
|
songCount: Int,
|
||||||
|
duration: Long,
|
||||||
|
created: Date?,
|
||||||
|
changed: Date?,
|
||||||
|
coverArtId: String?,
|
||||||
|
allowedUsers: List<String>?,
|
||||||
|
) : this(id, name, duration, coverArtId) {
|
||||||
|
this.comment = comment
|
||||||
|
this.owner = owner
|
||||||
|
this.isUniversal = isUniversal
|
||||||
|
this.songCount = songCount
|
||||||
|
this.created = created
|
||||||
|
this.changed = changed
|
||||||
|
this.allowedUsers = allowedUsers
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -9,8 +9,7 @@ import kotlinx.parcelize.Parcelize
|
||||||
@Parcelize
|
@Parcelize
|
||||||
class PlaylistWithSongs(
|
class PlaylistWithSongs(
|
||||||
@SerializedName("_id")
|
@SerializedName("_id")
|
||||||
override var id: String
|
override var id: String,
|
||||||
) : Playlist(id), Parcelable {
|
|
||||||
@SerializedName("entry")
|
@SerializedName("entry")
|
||||||
var entries: List<Child>? = null
|
var entries: List<Child>? = null,
|
||||||
}
|
) : Playlist(id), Parcelable
|
||||||
|
|
@ -6,5 +6,5 @@ import com.google.gson.annotations.SerializedName
|
||||||
@Keep
|
@Keep
|
||||||
class Playlists(
|
class Playlists(
|
||||||
@SerializedName("playlist")
|
@SerializedName("playlist")
|
||||||
var playlists: List<Playlist>? = null
|
var playlists: List<Playlist>? = null,
|
||||||
)
|
)
|
||||||
|
|
@ -3,20 +3,21 @@ package com.cappielloantonio.tempo.subsonic.models
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import androidx.annotation.Keep
|
import androidx.annotation.Keep
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
|
import kotlinx.parcelize.IgnoredOnParcel
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
class PodcastChannel : Parcelable {
|
class PodcastChannel(
|
||||||
@SerializedName("episode")
|
@SerializedName("episode")
|
||||||
var episodes: List<PodcastEpisode>? = null
|
var episodes: List<PodcastEpisode>? = null,
|
||||||
var id: String? = null
|
var id: String? = null,
|
||||||
var url: String? = null
|
var url: String? = null,
|
||||||
var title: String? = null
|
var title: String? = null,
|
||||||
var description: String? = null
|
var description: String? = null,
|
||||||
@SerializedName("coverArt")
|
@SerializedName("coverArt")
|
||||||
var coverArtId: String? = null
|
var coverArtId: String? = null,
|
||||||
var originalImageUrl: String? = null
|
var originalImageUrl: String? = null,
|
||||||
var status: String? = null
|
var status: String? = null,
|
||||||
var errorMessage: String? = null
|
var errorMessage: String? = null,
|
||||||
}
|
) : Parcelable
|
||||||
|
|
@ -3,37 +3,38 @@ package com.cappielloantonio.tempo.subsonic.models
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import androidx.annotation.Keep
|
import androidx.annotation.Keep
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
|
import kotlinx.parcelize.IgnoredOnParcel
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
class PodcastEpisode : Parcelable {
|
class PodcastEpisode(
|
||||||
var id: String? = null
|
var id: String? = null,
|
||||||
@SerializedName("parent")
|
@SerializedName("parent")
|
||||||
var parentId: String? = null
|
var parentId: String? = null,
|
||||||
var isDir = false
|
var isDir: Boolean = false,
|
||||||
var title: String? = null
|
var title: String? = null,
|
||||||
var album: String? = null
|
var album: String? = null,
|
||||||
var artist: String? = null
|
var artist: String? = null,
|
||||||
var year: Int? = null
|
var year: Int? = null,
|
||||||
var genre: String? = null
|
var genre: String? = null,
|
||||||
@SerializedName("coverArt")
|
@SerializedName("coverArt")
|
||||||
var coverArtId: String? = null
|
var coverArtId: String? = null,
|
||||||
var size: Long? = null
|
var size: Long? = null,
|
||||||
var contentType: String? = null
|
var contentType: String? = null,
|
||||||
var suffix: String? = null
|
var suffix: String? = null,
|
||||||
var duration: Int? = null
|
var duration: Int? = null,
|
||||||
@SerializedName("bitRate")
|
@SerializedName("bitRate")
|
||||||
var bitrate: Int? = null
|
var bitrate: Int? = null,
|
||||||
var path: String? = null
|
var path: String? = null,
|
||||||
var isVideo: Boolean = false
|
var isVideo: Boolean = false,
|
||||||
var created: Date? = null
|
var created: Date? = null,
|
||||||
var artistId: String? = null
|
var artistId: String? = null,
|
||||||
var type: String? = null
|
var type: String? = null,
|
||||||
var streamId: String? = null
|
var streamId: String? = null,
|
||||||
var channelId: String? = null
|
var channelId: String? = null,
|
||||||
var description: String? = null
|
var description: String? = null,
|
||||||
var status: String? = null
|
var status: String? = null,
|
||||||
var publishDate: Date? = null
|
var publishDate: Date? = null,
|
||||||
}
|
) : Parcelable
|
||||||
|
|
@ -2,10 +2,11 @@ package com.cappielloantonio.tempo.subsonic.models
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import androidx.annotation.Keep
|
import androidx.annotation.Keep
|
||||||
|
import kotlinx.parcelize.IgnoredOnParcel
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
open class RecordLabel : Parcelable {
|
open class RecordLabel(
|
||||||
var name: String? = null
|
var name: String? = null,
|
||||||
}
|
) : Parcelable
|
||||||
|
|
@ -3,20 +3,21 @@ package com.cappielloantonio.tempo.subsonic.models
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import androidx.annotation.Keep
|
import androidx.annotation.Keep
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
|
import kotlinx.parcelize.IgnoredOnParcel
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
import java.util.*
|
import java.util.Date
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
class Share : Parcelable {
|
data class Share(
|
||||||
@SerializedName("entry")
|
@SerializedName("entry")
|
||||||
var entries: List<Child>? = null
|
var entries: List<Child>? = null,
|
||||||
var id: String? = null
|
var id: String? = null,
|
||||||
var url: String? = null
|
var url: String? = null,
|
||||||
var description: String? = null
|
var description: String? = null,
|
||||||
var username: String? = null
|
var username: String? = null,
|
||||||
var created: Date? = null
|
var created: Date? = null,
|
||||||
var expires: Date? = null
|
var expires: Date? = null,
|
||||||
var lastVisited: Date? = null
|
var lastVisited: Date? = null,
|
||||||
var visitCount = 0
|
var visitCount: Int = 0
|
||||||
}
|
) : Parcelable
|
||||||
|
|
@ -14,16 +14,19 @@ import androidx.media3.common.*
|
||||||
import androidx.media3.common.util.UnstableApi
|
import androidx.media3.common.util.UnstableApi
|
||||||
import androidx.media3.exoplayer.DefaultLoadControl
|
import androidx.media3.exoplayer.DefaultLoadControl
|
||||||
import androidx.media3.exoplayer.ExoPlayer
|
import androidx.media3.exoplayer.ExoPlayer
|
||||||
|
import androidx.media3.exoplayer.source.MediaSource
|
||||||
import androidx.media3.exoplayer.source.TrackGroupArray
|
import androidx.media3.exoplayer.source.TrackGroupArray
|
||||||
import androidx.media3.exoplayer.trackselection.TrackSelectionArray
|
import androidx.media3.exoplayer.trackselection.TrackSelectionArray
|
||||||
import androidx.media3.session.*
|
import androidx.media3.session.*
|
||||||
import androidx.media3.session.MediaSession.ControllerInfo
|
import androidx.media3.session.MediaSession.ControllerInfo
|
||||||
import com.cappielloantonio.tempo.R
|
import com.cappielloantonio.tempo.R
|
||||||
|
import com.cappielloantonio.tempo.repository.QueueRepository
|
||||||
import com.cappielloantonio.tempo.ui.activity.MainActivity
|
import com.cappielloantonio.tempo.ui.activity.MainActivity
|
||||||
import com.cappielloantonio.tempo.util.AssetLinkUtil
|
import com.cappielloantonio.tempo.util.AssetLinkUtil
|
||||||
import com.cappielloantonio.tempo.util.Constants
|
import com.cappielloantonio.tempo.util.Constants
|
||||||
import com.cappielloantonio.tempo.util.DownloadUtil
|
import com.cappielloantonio.tempo.util.DownloadUtil
|
||||||
import com.cappielloantonio.tempo.util.DynamicMediaSourceFactory
|
import com.cappielloantonio.tempo.util.DynamicMediaSourceFactory
|
||||||
|
import com.cappielloantonio.tempo.util.MappingUtil
|
||||||
import com.cappielloantonio.tempo.util.Preferences
|
import com.cappielloantonio.tempo.util.Preferences
|
||||||
import com.cappielloantonio.tempo.util.ReplayGainUtil
|
import com.cappielloantonio.tempo.util.ReplayGainUtil
|
||||||
import com.cappielloantonio.tempo.widget.WidgetUpdateManager
|
import com.cappielloantonio.tempo.widget.WidgetUpdateManager
|
||||||
|
|
@ -84,6 +87,7 @@ class MediaService : MediaLibraryService() {
|
||||||
initializeCustomCommands()
|
initializeCustomCommands()
|
||||||
initializePlayer()
|
initializePlayer()
|
||||||
initializeMediaLibrarySession()
|
initializeMediaLibrarySession()
|
||||||
|
restorePlayerFromQueue()
|
||||||
initializePlayerListener()
|
initializePlayerListener()
|
||||||
initializeEqualizerManager()
|
initializeEqualizerManager()
|
||||||
|
|
||||||
|
|
@ -119,9 +123,9 @@ class MediaService : MediaLibraryService() {
|
||||||
val connectionResult = super.onConnect(session, controller)
|
val connectionResult = super.onConnect(session, controller)
|
||||||
val availableSessionCommands = connectionResult.availableSessionCommands.buildUpon()
|
val availableSessionCommands = connectionResult.availableSessionCommands.buildUpon()
|
||||||
|
|
||||||
shuffleCommands.forEach { commandButton ->
|
shuffleCommands.forEach {
|
||||||
// TODO: Aggiungere i comandi personalizzati
|
// TODO: Aggiungere i comandi personalizzati
|
||||||
// commandButton.sessionCommand?.let { availableSessionCommands.add(it) }
|
// it.sessionCommand?.let { availableSessionCommands.add(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
return MediaSession.ConnectionResult.accept(
|
return MediaSession.ConnectionResult.accept(
|
||||||
|
|
@ -226,7 +230,7 @@ class MediaService : MediaLibraryService() {
|
||||||
private fun initializePlayer() {
|
private fun initializePlayer() {
|
||||||
player = ExoPlayer.Builder(this)
|
player = ExoPlayer.Builder(this)
|
||||||
.setRenderersFactory(getRenderersFactory())
|
.setRenderersFactory(getRenderersFactory())
|
||||||
.setMediaSourceFactory(DynamicMediaSourceFactory(this))
|
.setMediaSourceFactory(getMediaSourceFactory())
|
||||||
.setAudioAttributes(AudioAttributes.DEFAULT, true)
|
.setAudioAttributes(AudioAttributes.DEFAULT, true)
|
||||||
.setHandleAudioBecomingNoisy(true)
|
.setHandleAudioBecomingNoisy(true)
|
||||||
.setWakeMode(C.WAKE_MODE_NETWORK)
|
.setWakeMode(C.WAKE_MODE_NETWORK)
|
||||||
|
|
@ -269,6 +273,33 @@ class MediaService : MediaLibraryService() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun restorePlayerFromQueue() {
|
||||||
|
if (player.mediaItemCount > 0) return
|
||||||
|
|
||||||
|
val queueRepository = QueueRepository()
|
||||||
|
val storedQueue = queueRepository.media
|
||||||
|
if (storedQueue.isNullOrEmpty()) return
|
||||||
|
|
||||||
|
val mediaItems = MappingUtil.mapMediaItems(storedQueue)
|
||||||
|
if (mediaItems.isEmpty()) return
|
||||||
|
|
||||||
|
val lastIndex = try {
|
||||||
|
queueRepository.lastPlayedMediaIndex
|
||||||
|
} catch (_: Exception) {
|
||||||
|
0
|
||||||
|
}.coerceIn(0, mediaItems.size - 1)
|
||||||
|
|
||||||
|
val lastPosition = try {
|
||||||
|
queueRepository.lastPlayedMediaTimestamp
|
||||||
|
} catch (_: Exception) {
|
||||||
|
0L
|
||||||
|
}.let { if (it < 0L) 0L else it }
|
||||||
|
|
||||||
|
player.setMediaItems(mediaItems, lastIndex, lastPosition)
|
||||||
|
player.prepare()
|
||||||
|
updateWidget()
|
||||||
|
}
|
||||||
|
|
||||||
private fun initializePlayerListener() {
|
private fun initializePlayerListener() {
|
||||||
player.addListener(object : Player.Listener {
|
player.addListener(object : Player.Listener {
|
||||||
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
|
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
|
||||||
|
|
@ -399,7 +430,7 @@ class MediaService : MediaLibraryService() {
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ignoreFuture(customLayout: ListenableFuture<SessionResult>) {
|
private fun ignoreFuture(@Suppress("UNUSED_PARAMETER") customLayout: ListenableFuture<SessionResult>) {
|
||||||
/* Do nothing. */
|
/* Do nothing. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -464,6 +495,7 @@ class MediaService : MediaLibraryService() {
|
||||||
|
|
||||||
private fun getRenderersFactory() = DownloadUtil.buildRenderersFactory(this, false)
|
private fun getRenderersFactory() = DownloadUtil.buildRenderersFactory(this, false)
|
||||||
|
|
||||||
|
private fun getMediaSourceFactory(): MediaSource.Factory = DynamicMediaSourceFactory(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val WIDGET_UPDATE_INTERVAL_MS = 1000L
|
private const val WIDGET_UPDATE_INTERVAL_MS = 1000L
|
||||||
|
|
|
||||||
|
|
@ -295,11 +295,6 @@ open class MediaLibrarySessionCallback(
|
||||||
args: Bundle
|
args: Bundle
|
||||||
): ListenableFuture<SessionResult> {
|
): ListenableFuture<SessionResult> {
|
||||||
|
|
||||||
val mediaItemId = args.getString(
|
|
||||||
MediaConstants.EXTRA_KEY_MEDIA_ID,
|
|
||||||
session.player.currentMediaItem?.mediaId
|
|
||||||
)
|
|
||||||
|
|
||||||
when (customCommand.customAction) {
|
when (customCommand.customAction) {
|
||||||
CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON -> {
|
CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON -> {
|
||||||
session.player.shuffleModeEnabled = true
|
session.player.shuffleModeEnabled = true
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import android.os.Binder
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.media3.cast.CastPlayer
|
import androidx.media3.cast.CastPlayer
|
||||||
import androidx.media3.cast.SessionAvailabilityListener
|
import androidx.media3.cast.SessionAvailabilityListener
|
||||||
import androidx.media3.common.AudioAttributes
|
import androidx.media3.common.AudioAttributes
|
||||||
|
|
@ -21,11 +22,13 @@ import androidx.media3.exoplayer.ExoPlayer
|
||||||
import androidx.media3.session.MediaLibraryService
|
import androidx.media3.session.MediaLibraryService
|
||||||
import androidx.media3.session.MediaSession.ControllerInfo
|
import androidx.media3.session.MediaSession.ControllerInfo
|
||||||
import com.cappielloantonio.tempo.repository.AutomotiveRepository
|
import com.cappielloantonio.tempo.repository.AutomotiveRepository
|
||||||
|
import com.cappielloantonio.tempo.repository.QueueRepository
|
||||||
import com.cappielloantonio.tempo.ui.activity.MainActivity
|
import com.cappielloantonio.tempo.ui.activity.MainActivity
|
||||||
import com.cappielloantonio.tempo.util.AssetLinkUtil
|
import com.cappielloantonio.tempo.util.AssetLinkUtil
|
||||||
import com.cappielloantonio.tempo.util.Constants
|
import com.cappielloantonio.tempo.util.Constants
|
||||||
import com.cappielloantonio.tempo.util.DownloadUtil
|
import com.cappielloantonio.tempo.util.DownloadUtil
|
||||||
import com.cappielloantonio.tempo.util.DynamicMediaSourceFactory
|
import com.cappielloantonio.tempo.util.DynamicMediaSourceFactory
|
||||||
|
import com.cappielloantonio.tempo.util.MappingUtil
|
||||||
import com.cappielloantonio.tempo.util.Preferences
|
import com.cappielloantonio.tempo.util.Preferences
|
||||||
import com.cappielloantonio.tempo.util.ReplayGainUtil
|
import com.cappielloantonio.tempo.util.ReplayGainUtil
|
||||||
import com.cappielloantonio.tempo.widget.WidgetUpdateManager
|
import com.cappielloantonio.tempo.widget.WidgetUpdateManager
|
||||||
|
|
@ -71,9 +74,10 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
||||||
|
|
||||||
initializeRepository()
|
initializeRepository()
|
||||||
initializePlayer()
|
initializePlayer()
|
||||||
initializeCastPlayer()
|
|
||||||
initializeMediaLibrarySession()
|
initializeMediaLibrarySession()
|
||||||
|
restorePlayerFromQueue()
|
||||||
initializePlayerListener()
|
initializePlayerListener()
|
||||||
|
initializeCastPlayer()
|
||||||
initializeEqualizerManager()
|
initializeEqualizerManager()
|
||||||
|
|
||||||
setPlayer(
|
setPlayer(
|
||||||
|
|
@ -143,12 +147,20 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
||||||
player.repeatMode = Preferences.getRepeatMode()
|
player.repeatMode = Preferences.getRepeatMode()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
private fun initializeCastPlayer() {
|
private fun initializeCastPlayer() {
|
||||||
if (GoogleApiAvailability.getInstance()
|
if (GoogleApiAvailability.getInstance()
|
||||||
.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS
|
.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS
|
||||||
) {
|
) {
|
||||||
castPlayer = CastPlayer(CastContext.getSharedInstance(this))
|
CastContext.getSharedInstance(this, ContextCompat.getMainExecutor(this))
|
||||||
castPlayer.setSessionAvailabilityListener(this)
|
.addOnSuccessListener { castContext ->
|
||||||
|
castPlayer = CastPlayer(castContext)
|
||||||
|
castPlayer.setSessionAvailabilityListener(this@MediaService)
|
||||||
|
|
||||||
|
if (castPlayer.isCastSessionAvailable && this::mediaLibrarySession.isInitialized) {
|
||||||
|
setPlayer(player, castPlayer)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,6 +178,33 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun restorePlayerFromQueue() {
|
||||||
|
if (player.mediaItemCount > 0) return
|
||||||
|
|
||||||
|
val queueRepository = QueueRepository()
|
||||||
|
val storedQueue = queueRepository.media
|
||||||
|
if (storedQueue.isNullOrEmpty()) return
|
||||||
|
|
||||||
|
val mediaItems = MappingUtil.mapMediaItems(storedQueue)
|
||||||
|
if (mediaItems.isEmpty()) return
|
||||||
|
|
||||||
|
val lastIndex = try {
|
||||||
|
queueRepository.lastPlayedMediaIndex
|
||||||
|
} catch (_: Exception) {
|
||||||
|
0
|
||||||
|
}.coerceIn(0, mediaItems.size - 1)
|
||||||
|
|
||||||
|
val lastPosition = try {
|
||||||
|
queueRepository.lastPlayedMediaTimestamp
|
||||||
|
} catch (_: Exception) {
|
||||||
|
0L
|
||||||
|
}.let { if (it < 0L) 0L else it }
|
||||||
|
|
||||||
|
player.setMediaItems(mediaItems, lastIndex, lastPosition)
|
||||||
|
player.prepare()
|
||||||
|
updateWidget()
|
||||||
|
}
|
||||||
|
|
||||||
private fun createLibrarySessionCallback(): MediaLibrarySessionCallback {
|
private fun createLibrarySessionCallback(): MediaLibrarySessionCallback {
|
||||||
return MediaLibrarySessionCallback(this, automotiveRepository)
|
return MediaLibrarySessionCallback(this, automotiveRepository)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,16 @@ package com.cappielloantonio.tempo.util;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
import com.google.android.gms.cast.framework.CastContext;
|
import com.google.android.gms.cast.framework.CastContext;
|
||||||
import com.google.android.gms.common.ConnectionResult;
|
import com.google.android.gms.common.ConnectionResult;
|
||||||
import com.google.android.gms.common.GoogleApiAvailability;
|
import com.google.android.gms.common.GoogleApiAvailability;
|
||||||
|
|
||||||
public class Flavors {
|
public class Flavors {
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public static void initializeCastContext(Context context) {
|
public static void initializeCastContext(Context context) {
|
||||||
if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS)
|
if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS)
|
||||||
CastContext.getSharedInstance(context);
|
CastContext.getSharedInstance(context, ContextCompat.getMainExecutor(context));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue