Skip to content

Commit

Permalink
Fix #64
Browse files Browse the repository at this point in the history
Fix #64
Replace several error throws with warning messages
Simplify LocalisedYoutubeString
  • Loading branch information
toasterofbread committed Jul 14, 2023
1 parent c8ef09f commit 79aed35
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 116 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ import com.toasterofbread.spmp.model.mediaitem.enums.MediaItemType
import com.toasterofbread.spmp.model.mediaitem.enums.SongType
import com.toasterofbread.spmp.resources.uilocalisation.LocalisedYoutubeString
import com.toasterofbread.spmp.ui.component.MediaItemLayout
import com.toasterofbread.spmp.ui.layout.mainpage.FilterChip
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.Request
import okio.use
import java.time.Duration

private val CACHE_LIFETIME = Duration.ofDays(1)
Expand All @@ -33,29 +35,23 @@ suspend fun getHomeFeed(
allow_cached: Boolean = true,
params: String? = null,
continuation: String? = null
): Result<Triple<List<MediaItemLayout>, String?, List<Pair<Int, String>>?>> = withContext(Dispatchers.IO) {
): Result<Triple<List<MediaItemLayout>, String?, List<FilterChip>?>> = withContext(Dispatchers.IO) {
val hl = SpMp.data_language
val suffix = params ?: ""
val rows_cache_key = "feed_rows$suffix"
val ctoken_cache_key = "feed_ctoken$suffix"
val chips_cache_key = "feed_chips$suffix"

if (allow_cached && continuation == null) {
val cached_rows = Cache.get(rows_cache_key)
if (cached_rows != null) {
Cache.get(rows_cache_key)?.use { cached_rows ->
val rows = Api.klaxon.parseArray<MediaItemLayout>(cached_rows)!!
cached_rows.close()

val ctoken = Cache.get(ctoken_cache_key)?.run {
val ctoken = readText()
close()
ctoken
val ctoken = Cache.get(ctoken_cache_key)?.use {
it.readText()
}

val chips = Cache.get(chips_cache_key)?.run {
val chips: List<List<Any>> = Api.klaxon.parseArray(this)!!
close()
chips.map { Pair(it[0] as Int, it[1] as String) }
val chips: List<FilterChip>? = Cache.get(chips_cache_key)?.use {
Api.klaxon.parseArray(it)!!
}

return@withContext Result.success(Triple(rows, ctoken, chips))
Expand Down Expand Up @@ -154,14 +150,14 @@ suspend fun getHomeFeed(
if (continuation == null) {
Cache.set(rows_cache_key, Api.klaxon.toJsonString(rows).reader(), CACHE_LIFETIME)
Cache.set(ctoken_cache_key, ctoken?.reader(), CACHE_LIFETIME)
Cache.set(chips_cache_key, chips?.let { Api.klaxon.toJsonString(it.map { chip -> listOf(chip.first, chip.second) }).reader() }, CACHE_LIFETIME)
Cache.set(chips_cache_key, Api.klaxon.toJsonString(chips).reader(), CACHE_LIFETIME)
}

return@runCatching Triple(rows, ctoken, chips)
}
}

private fun processRows(rows: List<YoutubeiShelf>, hl: String): List<MediaItemLayout> {
private suspend fun processRows(rows: List<YoutubeiShelf>, hl: String): List<MediaItemLayout> {
val ret = mutableListOf<MediaItemLayout>()
for (row in rows) {
if (!row.implemented) {
Expand Down Expand Up @@ -199,8 +195,8 @@ private fun processRows(rows: List<YoutubeiShelf>, hl: String): List<MediaItemLa
val browse_endpoint = header.title?.runs?.first()?.navigationEndpoint?.browseEndpoint
if (browse_endpoint == null) {
add(
LocalisedYoutubeString.homeFeed(header.title!!.first_text),
header.subtitle?.first_text?.let { LocalisedYoutubeString.homeFeed(it) }
LocalisedYoutubeString.Type.HOME_FEED.create(header.title!!.first_text),
header.subtitle?.first_text?.let { LocalisedYoutubeString.Type.HOME_FEED.create(it) }
)
continue
}
Expand All @@ -216,7 +212,7 @@ private fun processRows(rows: List<YoutubeiShelf>, hl: String): List<MediaItemLa

if (view_more_page_title_key != null) {
add(
LocalisedYoutubeString.app(view_more_page_title_key),
LocalisedYoutubeString.Type.APP.create(view_more_page_title_key),
null,
view_more = MediaItemLayout.ViewMore(list_page_browse_id = browse_endpoint.browseId),
type = when(browse_endpoint.browseId) {
Expand All @@ -227,12 +223,14 @@ private fun processRows(rows: List<YoutubeiShelf>, hl: String): List<MediaItemLa
continue
}

val page_type = browse_endpoint.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType
val page_type = browse_endpoint.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType!!

val media_item: MediaItem = when (page_type) {
"MUSIC_PAGE_TYPE_ARTIST", "MUSIC_PAGE_TYPE_USER_CHANNEL" -> Artist.fromId(browse_endpoint.browseId)
"MUSIC_PAGE_TYPE_PLAYLIST" -> AccountPlaylist.fromId(browse_endpoint.browseId).editPlaylistData { supplyTitle(header.title.first_text) }
else -> throw NotImplementedError(browse_endpoint.toString())
val media_item = MediaItemType.fromBrowseEndpointType(page_type)!!.fromId(browse_endpoint.browseId).apply {
editData {
header.title.runs?.getOrNull(0)?.also { title ->
supplyTitle(title.text)
}
}
}

val thumbnail_source =
Expand All @@ -242,8 +240,8 @@ private fun processRows(rows: List<YoutubeiShelf>, hl: String): List<MediaItemLa
?: MediaItemLayout.ThumbnailSource(media_item = media_item)

add(
LocalisedYoutubeString.raw(header.title.first_text),
header.subtitle?.first_text?.let { LocalisedYoutubeString.homeFeed(it) },
LocalisedYoutubeString.Type.RAW.create(header.title.first_text),
header.subtitle?.first_text?.let { LocalisedYoutubeString.Type.HOME_FEED.create(it) },
view_more = MediaItemLayout.ViewMore(media_item = media_item),
thumbnail_source = thumbnail_source,
media_item_type = media_item.type
Expand All @@ -270,10 +268,10 @@ data class YoutubeiBrowseResponse(
else contents?.singleColumnBrowseResultsRenderer?.tabs?.firstOrNull()?.tabRenderer?.content?.sectionListRenderer?.contents ?: emptyList()
}

fun getHeaderChips(): List<Pair<Int, String>>? =
fun getHeaderChips(): List<FilterChip>? =
contents?.singleColumnBrowseResultsRenderer?.tabs?.first()?.tabRenderer?.content?.sectionListRenderer?.header?.chipCloudRenderer?.chips?.map {
Pair(
LocalisedYoutubeString.filterChip(it.chipCloudChipRenderer.text!!.first_text) ?: throw NotImplementedError(it.chipCloudChipRenderer.text.first_text),
FilterChip(
LocalisedYoutubeString.Type.FILTER_CHIP.create(it.chipCloudChipRenderer.text!!.first_text),
it.chipCloudChipRenderer.navigationEndpoint.browseEndpoint!!.params!!
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ suspend fun loadBrowseId(browse_id: String, params: String? = null): Result<List
view_more?.layout_type = MediaItemLayout.Type.LIST

ret.add(MediaItemLayout(
row.value.title?.text?.let { LocalisedYoutubeString.raw(it) },
row.value.title?.text?.let { LocalisedYoutubeString.Type.RAW.create(it) },
null,
if (row.index == 0) MediaItemLayout.Type.NUMBERED_LIST else MediaItemLayout.Type.GRID,
row.value.getMediaItems(hl).toMutableList(),
Expand Down Expand Up @@ -212,7 +212,7 @@ suspend fun processDefaultResponse(item: MediaItem, data: MediaItemData, respons
}

val layout_title = row.value.title?.text?.let {
if (item is Artist && item.is_own_channel) LocalisedYoutubeString.ownChannel(it)
if (item is Artist && item.is_own_channel) LocalisedYoutubeString.Type.OWN_CHANNEL.create(it)
else LocalisedYoutubeString.mediaItemPage(it, item.type)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ suspend fun searchYoutubeMusic(query: String, params: String?): Result<SearchRes
if (card != null) {
category_layouts.add(Pair(
MediaItemLayout(
LocalisedYoutubeString.searchPage(card.header.musicCardShelfHeaderBasicRenderer!!.title!!.first_text),
LocalisedYoutubeString.Type.SEARCH_PAGE.create(card.header.musicCardShelfHeaderBasicRenderer!!.title!!.first_text),
null,
items = mutableListOf(card.getMediaItem()),
type = MediaItemLayout.Type.CARD
Expand All @@ -128,7 +128,7 @@ suspend fun searchYoutubeMusic(query: String, params: String?): Result<SearchRes
val search_params = if (category.index == 0) null else chips[category.index - 1].chipCloudChipRenderer.navigationEndpoint.searchEndpoint!!.params

category_layouts.add(Pair(
MediaItemLayout(LocalisedYoutubeString.searchPage(shelf.title!!.first_text), null, items = items),
MediaItemLayout(LocalisedYoutubeString.Type.SEARCH_PAGE.create(shelf.title!!.first_text), null, items = items),
search_params?.let {
val item = items.firstOrNull() ?: return@let null
SearchFilter(when (item) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,9 @@ fun getYoutubeFilterChipsLocalisations(getLanguage: (String) -> Int): YoutubeUIL
en to "Focus",
ja to "フォーカス"
)
add(
en to "Podcasts",
ja to "ポッドキャスト"
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import com.toasterofbread.spmp.model.Settings
import com.toasterofbread.spmp.model.mediaitem.enums.MediaItemType
import com.toasterofbread.spmp.resources.getString

class LocalisedYoutubeString(
class LocalisedYoutubeString private constructor(
val key: String,
val type: Type,
@Suppress("MemberVisibilityCanBePrivate")
val source_language: Int? = null
) {
private var localised: Pair<String, YoutubeUILocalisation.StringID?>? = null
Expand All @@ -18,7 +19,11 @@ class LocalisedYoutubeString(
HOME_FEED,
OWN_CHANNEL,
ARTIST_PAGE,
SEARCH_PAGE
SEARCH_PAGE,
FILTER_CHIP;

fun create(key: String, source_language: Int? = current_source_language): LocalisedYoutubeString =
LocalisedYoutubeString(key, this, source_language)
}

init {
Expand All @@ -27,60 +32,52 @@ class LocalisedYoutubeString(
}
}

private fun getLocalised() {
private fun getLocalised(): Pair<String, YoutubeUILocalisation.StringID?> {
if (localised == null) {
localised = when (type) {
Type.RAW -> Pair(key, null)
Type.APP -> Pair(getString(key), null)
Type.HOME_FEED -> {
val localisation = SpMp.yt_ui_localisation.localiseHomeFeedString(key, source_language!!)
if (localisation != null) {
localisation
} else {
println("WARNING: Using raw key '$key' as home feed string")
Pair(key, null)
}
// TODO
val data = SpMp.yt_ui_localisation

val strings = when (type) {
Type.RAW -> {
localised = Pair(key, null)
return localised!!
}
Type.APP -> {
localised = Pair(getString(key), null)
return localised!!
}
Type.OWN_CHANNEL -> SpMp.yt_ui_localisation.localiseOwnChannelString(key, source_language!!)
Type.ARTIST_PAGE -> SpMp.yt_ui_localisation.localiseArtistPageString(key, source_language!!)
Type.SEARCH_PAGE -> SpMp.yt_ui_localisation.localiseSearchPageString(key, source_language!!)
Type.HOME_FEED -> data.HOME_FEED_STRINGS
Type.OWN_CHANNEL -> data.OWN_CHANNEL_STRINGS
Type.ARTIST_PAGE -> data.ARTIST_PAGE_STRINGS
Type.SEARCH_PAGE -> data.SEARCH_PAGE_STRINGS
Type.FILTER_CHIP -> data.FILTER_CHIPS
}

localised = data.getLocalised(key, strings, source_language!!)

if (localised == null) {
println("WARNING: Localised string key '$key' of type $type has not been implemented. Source lang: ${SpMp.getLanguageCode(source_language!!)}")
localised = Pair(key, null)
SpMp.Log.warning("String key '$key' of type $type has not been localised (source lang=${SpMp.getLanguageCode(source_language)})")
}
}

return localised!!
}

fun getString(): String {
getLocalised()
return localised!!.first
return getLocalised().first
}

fun getID(): YoutubeUILocalisation.StringID? {
getLocalised()
return localised!!.second
return getLocalised().second
}

companion object {
private val current_source_language: Int get() = Settings.KEY_LANG_DATA.get()

fun temp(string: String): LocalisedYoutubeString = LocalisedYoutubeString("$string // TEMP", Type.RAW, current_source_language)

fun raw(string: String): LocalisedYoutubeString = LocalisedYoutubeString(string, Type.RAW, current_source_language)
fun app(key: String): LocalisedYoutubeString = LocalisedYoutubeString(key, Type.APP, current_source_language)
fun homeFeed(key: String): LocalisedYoutubeString = LocalisedYoutubeString(key, Type.HOME_FEED, current_source_language)
fun ownChannel(key: String): LocalisedYoutubeString = LocalisedYoutubeString(key, Type.OWN_CHANNEL, current_source_language)
fun artistPage(key: String): LocalisedYoutubeString = LocalisedYoutubeString(key, Type.ARTIST_PAGE, current_source_language)
fun searchPage(key: String): LocalisedYoutubeString = LocalisedYoutubeString(key, Type.SEARCH_PAGE, current_source_language)

fun filterChip(key: String): Int? = SpMp.yt_ui_localisation.getFilterChipIndex(key, current_source_language)
fun filterChip(index: Int): String = SpMp.yt_ui_localisation.getFilterChip(index)

fun mediaItemPage(key: String, item_type: MediaItemType): LocalisedYoutubeString =
when (item_type) {
MediaItemType.ARTIST, MediaItemType.PLAYLIST_BROWSEPARAMS -> artistPage(key)
MediaItemType.ARTIST, MediaItemType.PLAYLIST_BROWSEPARAMS -> Type.ARTIST_PAGE.create(key)
else -> throw NotImplementedError(item_type.name)
}
}
Expand Down Expand Up @@ -120,13 +117,13 @@ class YoutubeUILocalisation(languages: List<String>) {
check(it != -1)
}

private val HOME_FEED_STRINGS: LocalisationSet = getYoutubeHomeFeedLocalisations { getLanguage(it, languages) }
private val OWN_CHANNEL_STRINGS: LocalisationSet = getYoutubeOwnChannelLocalisations { getLanguage(it, languages) }
private val ARTIST_PAGE_STRINGS: LocalisationSet = getYoutubeArtistPageLocalisations { getLanguage(it, languages) }
private val SEARCH_PAGE_STRINGS: LocalisationSet = getYoutubeSearchPageLocalisations { getLanguage(it, languages) }
private val FILTER_CHIPS: LocalisationSet = getYoutubeFilterChipsLocalisations { getLanguage(it, languages) }
internal val HOME_FEED_STRINGS: LocalisationSet = getYoutubeHomeFeedLocalisations { getLanguage(it, languages) }
internal val OWN_CHANNEL_STRINGS: LocalisationSet = getYoutubeOwnChannelLocalisations { getLanguage(it, languages) }
internal val ARTIST_PAGE_STRINGS: LocalisationSet = getYoutubeArtistPageLocalisations { getLanguage(it, languages) }
internal val SEARCH_PAGE_STRINGS: LocalisationSet = getYoutubeSearchPageLocalisations { getLanguage(it, languages) }
internal val FILTER_CHIPS: LocalisationSet = getYoutubeFilterChipsLocalisations { getLanguage(it, languages) }

private fun getLocalised(string: String, localisations: LocalisationSet, source_language: Int): Pair<String, StringID?>? {
internal fun getLocalised(string: String, localisations: LocalisationSet, source_language: Int): Pair<String, StringID?>? {
val target: Int = Settings.KEY_LANG_UI.get()

for (localisation in localisations.items.withIndex()) {
Expand All @@ -139,21 +136,4 @@ class YoutubeUILocalisation(languages: List<String>) {

return null
}

fun localiseHomeFeedString(string: String, source_language: Int): Pair<String, StringID?>? = getLocalised(string, HOME_FEED_STRINGS, source_language)
fun localiseOwnChannelString(string: String, source_language: Int): Pair<String, StringID?>? = getLocalised(string, OWN_CHANNEL_STRINGS, source_language)
fun localiseArtistPageString(string: String, source_language: Int): Pair<String, StringID?>? = getLocalised(string, ARTIST_PAGE_STRINGS, source_language)
fun localiseSearchPageString(string: String, source_language: Int): Pair<String, StringID?>? = getLocalised(string, SEARCH_PAGE_STRINGS, source_language)

fun getFilterChipIndex(string: String, source_language: Int): Int? {
val index = FILTER_CHIPS.items.indexOfFirst { it[source_language]?.first == string }
if (index == -1) {
return null
}
return index
}
fun getFilterChip(index: Int): String {
val chip = FILTER_CHIPS.items.elementAt(index)[Settings.KEY_LANG_UI.get()]!!
return chip.second ?: chip.first
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.toasterofbread.spmp.ui.layout.mainpage

import com.toasterofbread.spmp.resources.uilocalisation.LocalisedYoutubeString

data class FilterChip(
val text: LocalisedYoutubeString,
val params: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ fun MainPage(
feed_load_state: MutableState<FeedLoadState>,
feed_load_error: Throwable?,
can_continue_feed: Boolean,
getFilterChips: () -> List<Pair<Int, String>>?,
getFilterChips: () -> List<FilterChip>?,
getSelectedFilterChip: () -> Int?,
pill_menu: PillMenu,
loadFeed: (filter_chip: Int?, continuation: Boolean) -> Unit
Expand Down
Loading

0 comments on commit 79aed35

Please sign in to comment.