From 6893d4d48af6ab3986dc40e19a8535383e466d59 Mon Sep 17 00:00:00 2001 From: gechoto <124326167+gechoto@users.noreply.github.com> Date: Sat, 5 Oct 2024 21:19:41 +0200 Subject: [PATCH 1/5] feat: add support for premium exclusive albums --- innertube/src/main/java/com/zionhuang/innertube/YouTube.kt | 6 +++--- .../com/zionhuang/innertube/models/NavigationEndpoint.kt | 4 ++++ .../java/com/zionhuang/innertube/pages/ArtistItemsPage.kt | 2 +- .../main/java/com/zionhuang/innertube/pages/ArtistPage.kt | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt b/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt index 4b386cfe0..1fc0bb381 100644 --- a/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt +++ b/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt @@ -179,7 +179,7 @@ object YouTube { } suspend fun albumSongs(playlistId: String): Result> = runCatching { - var response = innerTube.browse(WEB_REMIX, "VL$playlistId").body() + var response = innerTube.browse(WEB_REMIX, "VL$playlistId", setLogin = true).body() val songs = response.contents?.twoColumnBrowseResultsRenderer ?.secondaryContents?.sectionListRenderer ?.contents?.firstOrNull() @@ -205,7 +205,7 @@ object YouTube { } suspend fun artist(browseId: String): Result = runCatching { - val response = innerTube.browse(WEB_REMIX, browseId).body() + val response = innerTube.browse(WEB_REMIX, browseId, setLogin = true).body() ArtistPage( artist = ArtistItem( id = browseId, @@ -224,7 +224,7 @@ object YouTube { } suspend fun artistItems(endpoint: BrowseEndpoint): Result = runCatching { - val response = innerTube.browse(WEB_REMIX, endpoint.browseId, endpoint.params).body() + val response = innerTube.browse(WEB_REMIX, endpoint.browseId, endpoint.params, setLogin = true).body() val gridRenderer = response.contents?.singleColumnBrowseResultsRenderer?.tabs?.firstOrNull() ?.tabRenderer?.content?.sectionListRenderer?.contents?.firstOrNull() ?.gridRenderer diff --git a/innertube/src/main/java/com/zionhuang/innertube/models/NavigationEndpoint.kt b/innertube/src/main/java/com/zionhuang/innertube/models/NavigationEndpoint.kt index 83e4f3351..9229f3e5e 100644 --- a/innertube/src/main/java/com/zionhuang/innertube/models/NavigationEndpoint.kt +++ b/innertube/src/main/java/com/zionhuang/innertube/models/NavigationEndpoint.kt @@ -18,4 +18,8 @@ data class NavigationEndpoint( ?: searchEndpoint ?: queueAddEndpoint ?: shareEntityEndpoint + + val anyWatchEndpoint: WatchEndpoint? + get() = watchEndpoint + ?: watchPlaylistEndpoint } diff --git a/innertube/src/main/java/com/zionhuang/innertube/pages/ArtistItemsPage.kt b/innertube/src/main/java/com/zionhuang/innertube/pages/ArtistItemsPage.kt index 61cc4f4ed..109ec5d04 100644 --- a/innertube/src/main/java/com/zionhuang/innertube/pages/ArtistItemsPage.kt +++ b/innertube/src/main/java/com/zionhuang/innertube/pages/ArtistItemsPage.kt @@ -54,7 +54,7 @@ data class ArtistItemsPage( browseId = renderer.navigationEndpoint.browseEndpoint?.browseId ?: return null, playlistId = renderer.thumbnailOverlay?.musicItemThumbnailOverlayRenderer ?.content?.musicPlayButtonRenderer?.playNavigationEndpoint - ?.watchPlaylistEndpoint?.playlistId ?: return null, + ?.anyWatchEndpoint?.playlistId ?: return null, title = renderer.title.runs?.firstOrNull()?.text ?: return null, artists = null, year = renderer.subtitle?.runs?.lastOrNull()?.text?.toIntOrNull(), diff --git a/innertube/src/main/java/com/zionhuang/innertube/pages/ArtistPage.kt b/innertube/src/main/java/com/zionhuang/innertube/pages/ArtistPage.kt index 8e5fffbaa..0b65e2686 100644 --- a/innertube/src/main/java/com/zionhuang/innertube/pages/ArtistPage.kt +++ b/innertube/src/main/java/com/zionhuang/innertube/pages/ArtistPage.kt @@ -123,7 +123,7 @@ data class ArtistPage( browseId = renderer.navigationEndpoint.browseEndpoint?.browseId ?: return null, playlistId = renderer.thumbnailOverlay?.musicItemThumbnailOverlayRenderer?.content ?.musicPlayButtonRenderer?.playNavigationEndpoint - ?.watchPlaylistEndpoint?.playlistId ?: return null, + ?.anyWatchEndpoint?.playlistId ?: return null, title = renderer.title.runs?.firstOrNull()?.text ?: return null, artists = null, year = renderer.subtitle?.runs?.lastOrNull()?.text?.toIntOrNull(), From 9706ecc4fcb6559dd56038ab0f1cdd8b7c5e8529 Mon Sep 17 00:00:00 2001 From: gechoto <124326167+gechoto@users.noreply.github.com> Date: Sun, 6 Oct 2024 02:25:47 +0200 Subject: [PATCH 2/5] fix: load premium exclusive albums also in `artistItemsContinuation` --- innertube/src/main/java/com/zionhuang/innertube/YouTube.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt b/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt index 1fc0bb381..62469920a 100644 --- a/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt +++ b/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt @@ -254,7 +254,7 @@ object YouTube { } suspend fun artistItemsContinuation(continuation: String): Result = runCatching { - val response = innerTube.browse(WEB_REMIX, continuation = continuation).body() + val response = innerTube.browse(WEB_REMIX, continuation = continuation, setLogin = true).body() ArtistItemsContinuationPage( items = response.continuationContents?.musicPlaylistShelfContinuation?.contents?.mapNotNull { ArtistItemsContinuationPage.fromMusicResponsiveListItemRenderer(it.musicResponsiveListItemRenderer) From 5d1cb486724c6c296680a94698f96cf85a6f356f Mon Sep 17 00:00:00 2001 From: gechoto <124326167+gechoto@users.noreply.github.com> Date: Sat, 12 Oct 2024 03:56:33 +0200 Subject: [PATCH 3/5] add `useLoginOnArtistPage` preference --- app/src/main/java/com/zionhuang/music/App.kt | 5 +++++ .../music/constants/PreferenceKeys.kt | 1 + .../ui/screens/settings/PrivacySettings.kt | 18 ++++++++++++++++++ app/src/main/res/values/strings.xml | 2 ++ .../java/com/zionhuang/innertube/YouTube.kt | 9 +++++---- 5 files changed, 31 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/zionhuang/music/App.kt b/app/src/main/java/com/zionhuang/music/App.kt index 6fcfc0228..4072c3bfb 100644 --- a/app/src/main/java/com/zionhuang/music/App.kt +++ b/app/src/main/java/com/zionhuang/music/App.kt @@ -21,6 +21,7 @@ import com.zionhuang.music.constants.ProxyEnabledKey import com.zionhuang.music.constants.ProxyTypeKey import com.zionhuang.music.constants.ProxyUrlKey import com.zionhuang.music.constants.SYSTEM_DEFAULT +import com.zionhuang.music.constants.UseLoginOnArtistPage import com.zionhuang.music.constants.VisitorDataKey import com.zionhuang.music.extensions.toEnum import com.zionhuang.music.extensions.toInetSocketAddress @@ -71,6 +72,10 @@ class App : Application(), ImageLoaderFactory { } } + if (dataStore[UseLoginOnArtistPage] == true) { + YouTube.useLoginOnArtistPage = true + } + GlobalScope.launch { dataStore.data .map { it[VisitorDataKey] } diff --git a/app/src/main/java/com/zionhuang/music/constants/PreferenceKeys.kt b/app/src/main/java/com/zionhuang/music/constants/PreferenceKeys.kt index 09680e619..734241fc2 100644 --- a/app/src/main/java/com/zionhuang/music/constants/PreferenceKeys.kt +++ b/app/src/main/java/com/zionhuang/music/constants/PreferenceKeys.kt @@ -50,6 +50,7 @@ val MaxSongCacheSizeKey = intPreferencesKey("maxSongCacheSize") val PauseListenHistoryKey = booleanPreferencesKey("pauseListenHistory") val PauseSearchHistoryKey = booleanPreferencesKey("pauseSearchHistory") +val UseLoginOnArtistPage = booleanPreferencesKey("useLoginOnArtistPage") val DisableScreenshotKey = booleanPreferencesKey("disableScreenshot") val DiscordTokenKey = stringPreferencesKey("discordToken") diff --git a/app/src/main/java/com/zionhuang/music/ui/screens/settings/PrivacySettings.kt b/app/src/main/java/com/zionhuang/music/ui/screens/settings/PrivacySettings.kt index c2b025574..85d9cede9 100644 --- a/app/src/main/java/com/zionhuang/music/ui/screens/settings/PrivacySettings.kt +++ b/app/src/main/java/com/zionhuang/music/ui/screens/settings/PrivacySettings.kt @@ -25,12 +25,14 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.navigation.NavController +import com.zionhuang.innertube.YouTube import com.zionhuang.music.LocalDatabase import com.zionhuang.music.LocalPlayerAwareWindowInsets import com.zionhuang.music.R import com.zionhuang.music.constants.DisableScreenshotKey import com.zionhuang.music.constants.PauseListenHistoryKey import com.zionhuang.music.constants.PauseSearchHistoryKey +import com.zionhuang.music.constants.UseLoginOnArtistPage import com.zionhuang.music.ui.component.DefaultDialog import com.zionhuang.music.ui.component.IconButton import com.zionhuang.music.ui.component.PreferenceEntry @@ -48,6 +50,7 @@ fun PrivacySettings( val database = LocalDatabase.current val (pauseListenHistory, onPauseListenHistoryChange) = rememberPreference(key = PauseListenHistoryKey, defaultValue = false) val (pauseSearchHistory, onPauseSearchHistoryChange) = rememberPreference(key = PauseSearchHistoryKey, defaultValue = false) + val (useLoginOnArtistPage, onUseLoginOnArtistPageChange) = rememberPreference(key = UseLoginOnArtistPage, defaultValue = false) val (disableScreenshot, onDisableScreenshotChange) = rememberPreference(key = DisableScreenshotKey, defaultValue = false) var showClearListenHistoryDialog by remember { mutableStateOf(false) } @@ -155,6 +158,21 @@ fun PrivacySettings( onClick = { showClearSearchHistoryDialog = true } ) + PreferenceGroupTitle( + title = stringResource(R.string.account) + ) + + SwitchPreference( + title = { Text(stringResource(R.string.use_login_on_artist_page)) }, + description = stringResource(R.string.use_login_on_artist_page_desc), + icon = { Icon(painterResource(R.drawable.person), null) }, + checked = useLoginOnArtistPage, + onCheckedChange = { + YouTube.useLoginOnArtistPage = it + onUseLoginOnArtistPageChange(it) + } + ) + PreferenceGroupTitle( title = stringResource(R.string.misc) ) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 187474d75..adae55f63 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -299,6 +299,8 @@ Pause search history Clear search history Are you sure you want to clear all search history? + Use login on artist pages + Shows premium-only albums if you are logged in with a Premium account Disable screenshot When this option is on, screenshots and the app\'s view in Recents are disabled. Enable LrcLib lyrics provider diff --git a/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt b/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt index 62469920a..bc16e26ec 100644 --- a/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt +++ b/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt @@ -82,6 +82,7 @@ object YouTube { set(value) { innerTube.proxy = value } + var useLoginOnArtistPage: Boolean = false suspend fun searchSuggestions(query: String): Result = runCatching { val response = innerTube.getSearchSuggestions(WEB_REMIX, query).body() @@ -179,7 +180,7 @@ object YouTube { } suspend fun albumSongs(playlistId: String): Result> = runCatching { - var response = innerTube.browse(WEB_REMIX, "VL$playlistId", setLogin = true).body() + var response = innerTube.browse(WEB_REMIX, "VL$playlistId", setLogin = useLoginOnArtistPage).body() val songs = response.contents?.twoColumnBrowseResultsRenderer ?.secondaryContents?.sectionListRenderer ?.contents?.firstOrNull() @@ -205,7 +206,7 @@ object YouTube { } suspend fun artist(browseId: String): Result = runCatching { - val response = innerTube.browse(WEB_REMIX, browseId, setLogin = true).body() + val response = innerTube.browse(WEB_REMIX, browseId, setLogin = useLoginOnArtistPage).body() ArtistPage( artist = ArtistItem( id = browseId, @@ -224,7 +225,7 @@ object YouTube { } suspend fun artistItems(endpoint: BrowseEndpoint): Result = runCatching { - val response = innerTube.browse(WEB_REMIX, endpoint.browseId, endpoint.params, setLogin = true).body() + val response = innerTube.browse(WEB_REMIX, endpoint.browseId, endpoint.params, setLogin = useLoginOnArtistPage).body() val gridRenderer = response.contents?.singleColumnBrowseResultsRenderer?.tabs?.firstOrNull() ?.tabRenderer?.content?.sectionListRenderer?.contents?.firstOrNull() ?.gridRenderer @@ -254,7 +255,7 @@ object YouTube { } suspend fun artistItemsContinuation(continuation: String): Result = runCatching { - val response = innerTube.browse(WEB_REMIX, continuation = continuation, setLogin = true).body() + val response = innerTube.browse(WEB_REMIX, continuation = continuation, setLogin = useLoginOnArtistPage).body() ArtistItemsContinuationPage( items = response.continuationContents?.musicPlaylistShelfContinuation?.contents?.mapNotNull { ArtistItemsContinuationPage.fromMusicResponsiveListItemRenderer(it.musicResponsiveListItemRenderer) From eca5bb817fe3553777e6dff76c55e4bc6616a651 Mon Sep 17 00:00:00 2001 From: gechoto <124326167+gechoto@users.noreply.github.com> Date: Sun, 13 Oct 2024 03:02:16 +0200 Subject: [PATCH 4/5] show premium-only albums and audiobooks also in search results & rename option --- app/src/main/java/com/zionhuang/music/App.kt | 6 +++--- .../zionhuang/music/constants/PreferenceKeys.kt | 2 +- .../music/ui/screens/settings/PrivacySettings.kt | 14 +++++++------- app/src/main/res/values/strings.xml | 4 ++-- .../main/java/com/zionhuang/innertube/InnerTube.kt | 4 +++- .../main/java/com/zionhuang/innertube/YouTube.kt | 14 +++++++++----- .../com/zionhuang/innertube/models/Endpoint.kt | 4 +++- .../com/zionhuang/innertube/pages/SearchPage.kt | 2 +- .../zionhuang/innertube/pages/SearchSummaryPage.kt | 2 +- 9 files changed, 30 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/com/zionhuang/music/App.kt b/app/src/main/java/com/zionhuang/music/App.kt index 4072c3bfb..fe609d1a4 100644 --- a/app/src/main/java/com/zionhuang/music/App.kt +++ b/app/src/main/java/com/zionhuang/music/App.kt @@ -21,7 +21,7 @@ import com.zionhuang.music.constants.ProxyEnabledKey import com.zionhuang.music.constants.ProxyTypeKey import com.zionhuang.music.constants.ProxyUrlKey import com.zionhuang.music.constants.SYSTEM_DEFAULT -import com.zionhuang.music.constants.UseLoginOnArtistPage +import com.zionhuang.music.constants.UseLoginForBrowse import com.zionhuang.music.constants.VisitorDataKey import com.zionhuang.music.extensions.toEnum import com.zionhuang.music.extensions.toInetSocketAddress @@ -72,8 +72,8 @@ class App : Application(), ImageLoaderFactory { } } - if (dataStore[UseLoginOnArtistPage] == true) { - YouTube.useLoginOnArtistPage = true + if (dataStore[UseLoginForBrowse] == true) { + YouTube.useLoginForBrowse = true } GlobalScope.launch { diff --git a/app/src/main/java/com/zionhuang/music/constants/PreferenceKeys.kt b/app/src/main/java/com/zionhuang/music/constants/PreferenceKeys.kt index 734241fc2..254889a26 100644 --- a/app/src/main/java/com/zionhuang/music/constants/PreferenceKeys.kt +++ b/app/src/main/java/com/zionhuang/music/constants/PreferenceKeys.kt @@ -50,7 +50,7 @@ val MaxSongCacheSizeKey = intPreferencesKey("maxSongCacheSize") val PauseListenHistoryKey = booleanPreferencesKey("pauseListenHistory") val PauseSearchHistoryKey = booleanPreferencesKey("pauseSearchHistory") -val UseLoginOnArtistPage = booleanPreferencesKey("useLoginOnArtistPage") +val UseLoginForBrowse = booleanPreferencesKey("useLoginForBrowse") val DisableScreenshotKey = booleanPreferencesKey("disableScreenshot") val DiscordTokenKey = stringPreferencesKey("discordToken") diff --git a/app/src/main/java/com/zionhuang/music/ui/screens/settings/PrivacySettings.kt b/app/src/main/java/com/zionhuang/music/ui/screens/settings/PrivacySettings.kt index 85d9cede9..6e1a485b9 100644 --- a/app/src/main/java/com/zionhuang/music/ui/screens/settings/PrivacySettings.kt +++ b/app/src/main/java/com/zionhuang/music/ui/screens/settings/PrivacySettings.kt @@ -32,7 +32,7 @@ import com.zionhuang.music.R import com.zionhuang.music.constants.DisableScreenshotKey import com.zionhuang.music.constants.PauseListenHistoryKey import com.zionhuang.music.constants.PauseSearchHistoryKey -import com.zionhuang.music.constants.UseLoginOnArtistPage +import com.zionhuang.music.constants.UseLoginForBrowse import com.zionhuang.music.ui.component.DefaultDialog import com.zionhuang.music.ui.component.IconButton import com.zionhuang.music.ui.component.PreferenceEntry @@ -50,7 +50,7 @@ fun PrivacySettings( val database = LocalDatabase.current val (pauseListenHistory, onPauseListenHistoryChange) = rememberPreference(key = PauseListenHistoryKey, defaultValue = false) val (pauseSearchHistory, onPauseSearchHistoryChange) = rememberPreference(key = PauseSearchHistoryKey, defaultValue = false) - val (useLoginOnArtistPage, onUseLoginOnArtistPageChange) = rememberPreference(key = UseLoginOnArtistPage, defaultValue = false) + val (useLoginForBrowse, onUseLoginForBrowseChange) = rememberPreference(key = UseLoginForBrowse, defaultValue = false) val (disableScreenshot, onDisableScreenshotChange) = rememberPreference(key = DisableScreenshotKey, defaultValue = false) var showClearListenHistoryDialog by remember { mutableStateOf(false) } @@ -163,13 +163,13 @@ fun PrivacySettings( ) SwitchPreference( - title = { Text(stringResource(R.string.use_login_on_artist_page)) }, - description = stringResource(R.string.use_login_on_artist_page_desc), + title = { Text(stringResource(R.string.use_login_for_browse)) }, + description = stringResource(R.string.use_login_for_browse_desc), icon = { Icon(painterResource(R.drawable.person), null) }, - checked = useLoginOnArtistPage, + checked = useLoginForBrowse, onCheckedChange = { - YouTube.useLoginOnArtistPage = it - onUseLoginOnArtistPageChange(it) + YouTube.useLoginForBrowse = it + onUseLoginForBrowseChange(it) } ) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index adae55f63..899bc4887 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -299,8 +299,8 @@ Pause search history Clear search history Are you sure you want to clear all search history? - Use login on artist pages - Shows premium-only albums if you are logged in with a Premium account + Use login for browsing content + Shows premium-only albums if you are logged in with a Premium account Disable screenshot When this option is on, screenshots and the app\'s view in Recents are disabled. Enable LrcLib lyrics provider diff --git a/innertube/src/main/java/com/zionhuang/innertube/InnerTube.kt b/innertube/src/main/java/com/zionhuang/innertube/InnerTube.kt index b41ffba18..11697b2fb 100644 --- a/innertube/src/main/java/com/zionhuang/innertube/InnerTube.kt +++ b/innertube/src/main/java/com/zionhuang/innertube/InnerTube.kt @@ -47,6 +47,8 @@ class InnerTube { httpClient = createClient() } + var useLoginForBrowse: Boolean = false + @OptIn(ExperimentalSerializationApi::class) private fun createClient() = HttpClient(OkHttp) { expectSuccess = true @@ -107,7 +109,7 @@ class InnerTube { params: String? = null, continuation: String? = null, ) = httpClient.post("search") { - ytClient(client) + ytClient(client, setLogin = useLoginForBrowse) setBody( SearchBody( context = client.toContext(locale, visitorData), diff --git a/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt b/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt index bc16e26ec..820c2a07b 100644 --- a/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt +++ b/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt @@ -82,7 +82,11 @@ object YouTube { set(value) { innerTube.proxy = value } - var useLoginOnArtistPage: Boolean = false + var useLoginForBrowse: Boolean + get() = innerTube.useLoginForBrowse + set(value) { + innerTube.useLoginForBrowse = value + } suspend fun searchSuggestions(query: String): Result = runCatching { val response = innerTube.getSearchSuggestions(WEB_REMIX, query).body() @@ -180,7 +184,7 @@ object YouTube { } suspend fun albumSongs(playlistId: String): Result> = runCatching { - var response = innerTube.browse(WEB_REMIX, "VL$playlistId", setLogin = useLoginOnArtistPage).body() + var response = innerTube.browse(WEB_REMIX, "VL$playlistId", setLogin = useLoginForBrowse).body() val songs = response.contents?.twoColumnBrowseResultsRenderer ?.secondaryContents?.sectionListRenderer ?.contents?.firstOrNull() @@ -206,7 +210,7 @@ object YouTube { } suspend fun artist(browseId: String): Result = runCatching { - val response = innerTube.browse(WEB_REMIX, browseId, setLogin = useLoginOnArtistPage).body() + val response = innerTube.browse(WEB_REMIX, browseId, setLogin = useLoginForBrowse).body() ArtistPage( artist = ArtistItem( id = browseId, @@ -225,7 +229,7 @@ object YouTube { } suspend fun artistItems(endpoint: BrowseEndpoint): Result = runCatching { - val response = innerTube.browse(WEB_REMIX, endpoint.browseId, endpoint.params, setLogin = useLoginOnArtistPage).body() + val response = innerTube.browse(WEB_REMIX, endpoint.browseId, endpoint.params, setLogin = useLoginForBrowse).body() val gridRenderer = response.contents?.singleColumnBrowseResultsRenderer?.tabs?.firstOrNull() ?.tabRenderer?.content?.sectionListRenderer?.contents?.firstOrNull() ?.gridRenderer @@ -255,7 +259,7 @@ object YouTube { } suspend fun artistItemsContinuation(continuation: String): Result = runCatching { - val response = innerTube.browse(WEB_REMIX, continuation = continuation, setLogin = useLoginOnArtistPage).body() + val response = innerTube.browse(WEB_REMIX, continuation = continuation, setLogin = useLoginForBrowse).body() ArtistItemsContinuationPage( items = response.continuationContents?.musicPlaylistShelfContinuation?.contents?.mapNotNull { ArtistItemsContinuationPage.fromMusicResponsiveListItemRenderer(it.musicResponsiveListItemRenderer) diff --git a/innertube/src/main/java/com/zionhuang/innertube/models/Endpoint.kt b/innertube/src/main/java/com/zionhuang/innertube/models/Endpoint.kt index a5ec77638..ff2ed8d63 100644 --- a/innertube/src/main/java/com/zionhuang/innertube/models/Endpoint.kt +++ b/innertube/src/main/java/com/zionhuang/innertube/models/Endpoint.kt @@ -2,6 +2,7 @@ package com.zionhuang.innertube.models import com.zionhuang.innertube.models.BrowseEndpoint.BrowseEndpointContextSupportedConfigs.BrowseEndpointContextMusicConfig.Companion.MUSIC_PAGE_TYPE_ALBUM import com.zionhuang.innertube.models.BrowseEndpoint.BrowseEndpointContextSupportedConfigs.BrowseEndpointContextMusicConfig.Companion.MUSIC_PAGE_TYPE_ARTIST +import com.zionhuang.innertube.models.BrowseEndpoint.BrowseEndpointContextSupportedConfigs.BrowseEndpointContextMusicConfig.Companion.MUSIC_PAGE_TYPE_AUDIOBOOK import com.zionhuang.innertube.models.BrowseEndpoint.BrowseEndpointContextSupportedConfigs.BrowseEndpointContextMusicConfig.Companion.MUSIC_PAGE_TYPE_PLAYLIST import kotlinx.serialization.Serializable @@ -43,7 +44,8 @@ data class BrowseEndpoint( val isArtistEndpoint: Boolean get() = browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType == MUSIC_PAGE_TYPE_ARTIST val isAlbumEndpoint: Boolean - get() = browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType == MUSIC_PAGE_TYPE_ALBUM + get() = browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType == MUSIC_PAGE_TYPE_ALBUM || + browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType == MUSIC_PAGE_TYPE_AUDIOBOOK val isPlaylistEndpoint: Boolean get() = browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType == MUSIC_PAGE_TYPE_PLAYLIST diff --git a/innertube/src/main/java/com/zionhuang/innertube/pages/SearchPage.kt b/innertube/src/main/java/com/zionhuang/innertube/pages/SearchPage.kt index 478a227ea..dc9dbafef 100644 --- a/innertube/src/main/java/com/zionhuang/innertube/pages/SearchPage.kt +++ b/innertube/src/main/java/com/zionhuang/innertube/pages/SearchPage.kt @@ -64,7 +64,7 @@ object SearchPage { renderer.isAlbum -> { AlbumItem( browseId = renderer.navigationEndpoint?.browseEndpoint?.browseId ?: return null, - playlistId = renderer.overlay?.musicItemThumbnailOverlayRenderer?.content?.musicPlayButtonRenderer?.playNavigationEndpoint?.watchPlaylistEndpoint?.playlistId ?: return null, + playlistId = renderer.overlay?.musicItemThumbnailOverlayRenderer?.content?.musicPlayButtonRenderer?.playNavigationEndpoint?.anyWatchEndpoint?.playlistId ?: return null, title = renderer.flexColumns.firstOrNull() ?.musicResponsiveListItemFlexColumnRenderer?.text?.runs ?.firstOrNull()?.text ?: return null, diff --git a/innertube/src/main/java/com/zionhuang/innertube/pages/SearchSummaryPage.kt b/innertube/src/main/java/com/zionhuang/innertube/pages/SearchSummaryPage.kt index 53f9c7522..69386fee5 100644 --- a/innertube/src/main/java/com/zionhuang/innertube/pages/SearchSummaryPage.kt +++ b/innertube/src/main/java/com/zionhuang/innertube/pages/SearchSummaryPage.kt @@ -83,7 +83,7 @@ data class SearchSummaryPage( renderer.onTap.browseEndpoint?.isAlbumEndpoint == true -> { AlbumItem( browseId = renderer.onTap.browseEndpoint.browseId, - playlistId = renderer.buttons.firstOrNull()?.buttonRenderer?.command?.watchPlaylistEndpoint?.playlistId ?: return null, + playlistId = renderer.buttons.firstOrNull()?.buttonRenderer?.command?.anyWatchEndpoint?.playlistId ?: return null, title = renderer.title.runs?.firstOrNull()?.text ?: return null, artists = subtitle?.getOrNull(1)?.oddElements()?.map { Artist( From a5e570653399dca1513d23a71fa633d7b741c5e7 Mon Sep 17 00:00:00 2001 From: gechoto <124326167+gechoto@users.noreply.github.com> Date: Thu, 17 Oct 2024 22:56:57 +0200 Subject: [PATCH 5/5] Use login for all `browse` requests if `useLoginForBrowse` option is enabled --- app/src/main/res/values/strings.xml | 2 +- .../src/main/java/com/zionhuang/innertube/InnerTube.kt | 2 +- .../src/main/java/com/zionhuang/innertube/YouTube.kt | 9 ++++----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 899bc4887..fe88c7127 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -300,7 +300,7 @@ Clear search history Are you sure you want to clear all search history? Use login for browsing content - Shows premium-only albums if you are logged in with a Premium account + This can influence what content you see and for example shows premium-only albums if you are logged in with a Premium account Disable screenshot When this option is on, screenshots and the app\'s view in Recents are disabled. Enable LrcLib lyrics provider diff --git a/innertube/src/main/java/com/zionhuang/innertube/InnerTube.kt b/innertube/src/main/java/com/zionhuang/innertube/InnerTube.kt index 11697b2fb..ae0775f1d 100644 --- a/innertube/src/main/java/com/zionhuang/innertube/InnerTube.kt +++ b/innertube/src/main/java/com/zionhuang/innertube/InnerTube.kt @@ -156,7 +156,7 @@ class InnerTube { continuation: String? = null, setLogin: Boolean = false, ) = httpClient.post("browse") { - ytClient(client, setLogin) + ytClient(client, setLogin = setLogin || useLoginForBrowse) setBody( BrowseBody( context = client.toContext(locale, visitorData), diff --git a/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt b/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt index 820c2a07b..797c3a940 100644 --- a/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt +++ b/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt @@ -184,7 +184,7 @@ object YouTube { } suspend fun albumSongs(playlistId: String): Result> = runCatching { - var response = innerTube.browse(WEB_REMIX, "VL$playlistId", setLogin = useLoginForBrowse).body() + var response = innerTube.browse(WEB_REMIX, "VL$playlistId").body() val songs = response.contents?.twoColumnBrowseResultsRenderer ?.secondaryContents?.sectionListRenderer ?.contents?.firstOrNull() @@ -199,7 +199,6 @@ object YouTube { response = innerTube.browse( client = WEB_REMIX, continuation = continuation, - setLogin = true ).body() songs += response.continuationContents?.musicPlaylistShelfContinuation?.contents?.mapNotNull { AlbumPage.fromMusicResponsiveListItemRenderer(it.musicResponsiveListItemRenderer) @@ -210,7 +209,7 @@ object YouTube { } suspend fun artist(browseId: String): Result = runCatching { - val response = innerTube.browse(WEB_REMIX, browseId, setLogin = useLoginForBrowse).body() + val response = innerTube.browse(WEB_REMIX, browseId).body() ArtistPage( artist = ArtistItem( id = browseId, @@ -229,7 +228,7 @@ object YouTube { } suspend fun artistItems(endpoint: BrowseEndpoint): Result = runCatching { - val response = innerTube.browse(WEB_REMIX, endpoint.browseId, endpoint.params, setLogin = useLoginForBrowse).body() + val response = innerTube.browse(WEB_REMIX, endpoint.browseId, endpoint.params).body() val gridRenderer = response.contents?.singleColumnBrowseResultsRenderer?.tabs?.firstOrNull() ?.tabRenderer?.content?.sectionListRenderer?.contents?.firstOrNull() ?.gridRenderer @@ -259,7 +258,7 @@ object YouTube { } suspend fun artistItemsContinuation(continuation: String): Result = runCatching { - val response = innerTube.browse(WEB_REMIX, continuation = continuation, setLogin = useLoginForBrowse).body() + val response = innerTube.browse(WEB_REMIX, continuation = continuation).body() ArtistItemsContinuationPage( items = response.continuationContents?.musicPlaylistShelfContinuation?.contents?.mapNotNull { ArtistItemsContinuationPage.fromMusicResponsiveListItemRenderer(it.musicResponsiveListItemRenderer)