Skip to content

Commit

Permalink
Fix #114, add artist refresh and loading indicator
Browse files Browse the repository at this point in the history
Centralise browse endpoint page type matching to MediaItemType.fromBrowseEndpointType (fixes #114)
Add pull refresh to artist page #88
Fix albums not loading
Add loading indicator and error display to artist page
  • Loading branch information
toasterofbread committed Aug 18, 2023
1 parent 056043b commit f5ed245
Show file tree
Hide file tree
Showing 16 changed files with 300 additions and 267 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import com.toasterofbread.spmp.model.mediaitem.PlaylistData
import com.toasterofbread.spmp.model.mediaitem.Song
import com.toasterofbread.spmp.model.mediaitem.SongData
import com.toasterofbread.spmp.model.mediaitem.artist.ArtistLayout
import com.toasterofbread.spmp.model.mediaitem.enums.MediaItemType
import com.toasterofbread.spmp.model.mediaitem.enums.PlaylistType
import com.toasterofbread.spmp.model.mediaitem.enums.SongType
import com.toasterofbread.spmp.resources.uilocalisation.LocalisedYoutubeString
Expand Down Expand Up @@ -80,7 +81,7 @@ suspend fun loadMediaItemData(
"isAudioOnly" to true,
"videoId" to item_id,
)
else if (item is Playlist && !item.id.startsWith("VL"))
else if (item is Playlist && !item.id.startsWith("VL") && !item.id.startsWith("MPREb_"))
mapOf(
"browseId" to "VL$item_id"
)
Expand Down Expand Up @@ -249,7 +250,7 @@ suspend fun processDefaultResponse(item: MediaItemData, response: Response, hl:
header_renderer.subtitle?.runs?.also { subtitle ->
if (item is MediaItem.DataWithArtist) {
val artist_run = subtitle.firstOrNull {
it.navigationEndpoint?.browseEndpoint?.getPageType() == "MUSIC_PAGE_TYPE_USER_CHANNEL"
it.navigationEndpoint?.browseEndpoint?.getMediaItemType() == MediaItemType.ARTIST
}
if (artist_run != null) {
item.artist = ArtistData(artist_run.navigationEndpoint!!.browseEndpoint!!.browseId).apply {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
package com.toasterofbread.spmp.api.model

import com.toasterofbread.spmp.model.mediaitem.AccountPlaylistRef
import com.toasterofbread.spmp.model.mediaitem.ArtistData
import com.toasterofbread.spmp.model.mediaitem.MediaItem
import com.toasterofbread.spmp.model.mediaitem.MediaItemData
import com.toasterofbread.spmp.model.mediaitem.PlaylistData
import com.toasterofbread.spmp.model.mediaitem.PlaylistRef
import com.toasterofbread.spmp.model.mediaitem.SongData
import com.toasterofbread.spmp.model.mediaitem.enums.MediaItemType
import com.toasterofbread.spmp.ui.component.mediaitemlayout.MediaItemLayout

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,22 @@ data class MusicResponsiveListItemRenderer(

if (video_id == null) {
val page_type = navigationEndpoint?.browseEndpoint?.getPageType()
when (page_type) {
"MUSIC_PAGE_TYPE_ALBUM", "MUSIC_PAGE_TYPE_PLAYLIST" -> {
when (
page_type?.let { type ->
MediaItemType.fromBrowseEndpointType(type)
}
) {
MediaItemType.PLAYLIST_ACC -> {
video_is_main = false
playlist = PlaylistData(navigationEndpoint!!.browseEndpoint!!.browseId).apply {
playlist_type = PlaylistType.fromTypeString(page_type)
playlist_type = PlaylistType.fromBrowseEndpointType(page_type)
}
}
"MUSIC_PAGE_TYPE_ARTIST", "MUSIC_PAGE_TYPE_USER_CHANNEL" -> {
MediaItemType.ARTIST -> {
video_is_main = false
artist = ArtistData(navigationEndpoint!!.browseEndpoint!!.browseId)
}
else -> {}
}
}

Expand Down Expand Up @@ -68,13 +73,9 @@ data class MusicResponsiveListItemRenderer(
}

val browse_endpoint = run.navigationEndpoint.browseEndpoint
when (browse_endpoint?.getPageType()) {
"MUSIC_PAGE_TYPE_ARTIST", "MUSIC_PAGE_TYPE_USER_CHANNEL" -> {
if (artist == null) {
artist = ArtistData(browse_endpoint.browseId)
artist.title = run.text
}
}
if (artist == null && browse_endpoint?.getMediaItemType() == MediaItemType.ARTIST) {
artist = ArtistData(browse_endpoint.browseId)
artist.title = run.text
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,20 +73,20 @@ class MusicTwoRowItemRenderer(
val browse_id = navigationEndpoint.browseEndpoint!!.browseId
val page_type = navigationEndpoint.browseEndpoint.getPageType()!!

item = when (page_type) {
"MUSIC_PAGE_TYPE_ALBUM", "MUSIC_PAGE_TYPE_PLAYLIST", "MUSIC_PAGE_TYPE_AUDIOBOOK", "MUSIC_PAGE_TYPE_PODCAST_SHOW_DETAIL_PAGE" -> {
item = when (MediaItemType.fromBrowseEndpointType(page_type)) {
MediaItemType.PLAYLIST_ACC -> {
if (Playlist.formatYoutubeId(browse_id).startsWith("RDAT") && !Settings.get<Boolean>(Settings.KEY_FEED_SHOW_RADIOS)) {
return null
}

PlaylistData(browse_id).also { data ->
data.playlist_type = PlaylistType.fromTypeString(page_type)
data.playlist_type = PlaylistType.fromBrowseEndpointType(page_type)
data.artist = getArtist(data)
// is_editable = menu?.menuRenderer?.items
// ?.any { it.menuNavigationItemRenderer?.icon?.iconType == "DELETE" } == true
}
}
"MUSIC_PAGE_TYPE_ARTIST" -> ArtistData(browse_id)
MediaItemType.ARTIST -> ArtistData(browse_id)
else -> throw NotImplementedError("$page_type ($browse_id)")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import com.toasterofbread.spmp.model.mediaitem.ArtistData
import com.toasterofbread.spmp.model.mediaitem.PlaylistData
import com.toasterofbread.spmp.model.mediaitem.Song
import com.toasterofbread.spmp.model.mediaitem.db.loadMediaItemValue
import com.toasterofbread.spmp.model.mediaitem.enums.MediaItemType

data class YoutubeiNextResponse(
val contents: Contents
Expand Down Expand Up @@ -69,7 +70,10 @@ data class YoutubeiNextResponse(
suspend fun getArtist(host_item: Song, db: Database): Result<ArtistData?> {
// Get artist ID directly
for (run in longBylineText.runs!! + title.runs!!) {
if (run.browse_endpoint_type != "MUSIC_PAGE_TYPE_ARTIST" && run.browse_endpoint_type != "MUSIC_PAGE_TYPE_USER_CHANNEL") {
val page_type = run.browse_endpoint_type?.let { type ->
MediaItemType.fromBrowseEndpointType(type)
}
if (page_type != MediaItemType.ARTIST) {
continue
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,17 +200,8 @@ sealed class MediaItemData: MediaItem {
get() = thumbnail_provider.asMediaItemProperty(super.ThumbnailProvider) { thumbnail_provider = it }

companion object {
fun fromBrowseEndpointType(page_type: String, id: String): MediaItemData {
return when (page_type) {
"MUSIC_PAGE_TYPE_PLAYLIST", "MUSIC_PAGE_TYPE_ALBUM", "MUSIC_PAGE_TYPE_AUDIOBOOK" ->
PlaylistData(id).apply { playlist_type = PlaylistTypeEnum.fromTypeString(page_type) }
"MUSIC_PAGE_TYPE_ARTIST", "MUSIC_PAGE_TYPE_USER_CHANNEL" ->
ArtistData(id)
"MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE" ->
SongData(id)
else -> throw NotImplementedError("page_type=$page_type, id=$page_type")
}
}
fun fromBrowseEndpointType(page_type: String, id: String): MediaItemData =
MediaItemType.fromBrowseEndpointType(page_type).referenceFromId(id).getEmptyData()
}

open fun saveToDatabase(db: Database, apply_to_item: MediaItem = this) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ sealed interface Playlist: MediaItem.WithArtist {
},
clearItems = { from_index ->
playlistItemQueries.clearItems(id, from_index)
}
},
prerequisite = Loaded
)
val ItemCount: Property<Int?>
get() = property_rememberer.rememberSingleProperty(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,10 @@ open class ListProperty<T, Q: Any>(
)

if (prerequisite != null) {
val pr: Boolean by prerequisite.observe(db)
return remember {
derivedStateOf {
if (!pr) null
else value_state.value
}
val prerequisite_state: State<Boolean> = prerequisite.observe(db)
return derivedStateOf {
if (!prerequisite_state.value) null
else value_state.value
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,12 @@ import androidx.compose.material.icons.filled.Person
import androidx.compose.material.icons.filled.PlaylistPlay
import androidx.compose.ui.graphics.vector.ImageVector
import com.toasterofbread.spmp.model.mediaitem.AccountPlaylistRef
import com.toasterofbread.spmp.model.mediaitem.Artist
import com.toasterofbread.spmp.model.mediaitem.ArtistRef
import com.toasterofbread.spmp.model.mediaitem.LocalPlaylistRef
import com.toasterofbread.spmp.model.mediaitem.MediaItem
import com.toasterofbread.spmp.model.mediaitem.PlaylistData
import com.toasterofbread.spmp.model.mediaitem.Song
import com.toasterofbread.spmp.model.mediaitem.SongRef
import com.toasterofbread.spmp.resources.getString

fun MediaItem.getType(): MediaItemType =
when(this) {
is Song -> MediaItemType.SONG
is Artist -> MediaItemType.ARTIST
is AccountPlaylistRef -> MediaItemType.PLAYLIST_ACC
is LocalPlaylistRef -> MediaItemType.PLAYLIST_LOC
is PlaylistData ->
if (isLocalPlaylist()) MediaItemType.PLAYLIST_LOC
else MediaItemType.PLAYLIST_ACC
else -> throw NotImplementedError(this::class.toString())
}

enum class MediaItemType {
SONG, ARTIST, PLAYLIST_ACC, PLAYLIST_LOC;

Expand Down Expand Up @@ -65,11 +50,28 @@ enum class MediaItemType {
}

companion object {
fun fromBrowseEndpointType(page_type: String): MediaItemType? {
return when (page_type) {
"MUSIC_PAGE_TYPE_PLAYLIST", "MUSIC_PAGE_TYPE_ALBUM", "MUSIC_PAGE_TYPE_AUDIOBOOK" -> PLAYLIST_ACC
"MUSIC_PAGE_TYPE_ARTIST", "MUSIC_PAGE_TYPE_USER_CHANNEL" -> ARTIST
else -> null
fun fromBrowseEndpointType(page_type: String): MediaItemType {
// Remove "MUSIC_PAGE_TYPE_" prefix
val type_name: String = page_type.substring(16)

if (type_name.startsWith("ARTIST")) {
return ARTIST
}
if (type_name.startsWith("PODCAST")) {
return PLAYLIST_ACC
}

return when (type_name) {
"PLAYLIST",
"ALBUM",
"AUDIOBOOK",
"RADIO" ->
PLAYLIST_ACC
"USER_CHANNEL" ->
ARTIST
"NON_MUSIC_AUDIO_TRACK_PAGE" ->
SONG
else -> throw NotImplementedError(page_type)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ enum class PlaylistType {
LOCAL, PLAYLIST, ALBUM, AUDIOBOOK, PODCAST, RADIO;

companion object {
fun fromTypeString(type: String): PlaylistType {
fun fromBrowseEndpointType(type: String): PlaylistType {
return when (type) {
"MUSIC_PAGE_TYPE_PLAYLIST" -> PLAYLIST
"MUSIC_PAGE_TYPE_ALBUM" -> ALBUM
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.toasterofbread.spmp.model.mediaitem.loader
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
Expand Down Expand Up @@ -69,7 +70,7 @@ internal object MediaItemLoader: ListenerLoader<String, MediaItemData>() {
}

@Composable
fun MediaItem.loadDataOnChange(db: Database): State<Boolean> {
fun MediaItem.loadDataOnChange(db: Database, load: Boolean = true, onLoadFailed: ((Throwable?) -> Unit)? = null): State<Boolean> {
val loading_state = remember(this) { mutableStateOf(false) }

DisposableEffect(this) {
Expand All @@ -86,6 +87,7 @@ fun MediaItem.loadDataOnChange(db: Database): State<Boolean> {
}
override fun onLoadFailed(key: String, error: Throwable) {
if (key == id) {
onLoadFailed?.invoke(error)
loading_state.value = false
}
}
Expand All @@ -98,8 +100,11 @@ fun MediaItem.loadDataOnChange(db: Database): State<Boolean> {
}
}

LaunchedEffect(this) {
loadData(db)
LaunchedEffect(this, load) {
if (load) {
onLoadFailed?.invoke(null)
loadData(db)
}
}

return loading_state
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import com.toasterofbread.spmp.model.YoutubeMusicAuthInfo
import com.toasterofbread.spmp.model.mediaitem.Artist
import com.toasterofbread.spmp.model.mediaitem.ArtistData
import com.toasterofbread.spmp.model.mediaitem.MediaItemThumbnailProvider
import com.toasterofbread.spmp.model.mediaitem.enums.MediaItemType
import com.toasterofbread.spmp.platform.WebViewLogin
import com.toasterofbread.spmp.platform.composable.PlatformAlertDialog
import com.toasterofbread.spmp.platform.isWebViewLoginSupported
Expand Down Expand Up @@ -241,7 +242,7 @@ data class YTAccountMenuResponse(val actions: List<Action>) {
for (section in getSections()) {
for (item in section.multiPageMenuSectionRenderer.items) {
val browse_endpoint = item.compactLinkRenderer.navigationEndpoint?.browseEndpoint
if (browse_endpoint?.getPageType() == "MUSIC_PAGE_TYPE_USER_CHANNEL") {
if (browse_endpoint?.getMediaItemType() == MediaItemType.ARTIST) {
return browse_endpoint.browseId
}
}
Expand Down
Loading

0 comments on commit f5ed245

Please sign in to comment.