From 7cd6dd3fe68a0841e479780484b4d59ef1c4e5c3 Mon Sep 17 00:00:00 2001 From: Blatzar <46196380+Blatzar@users.noreply.github.com> Date: Sat, 21 Jan 2023 13:14:17 +0100 Subject: [PATCH] WIP local list support --- .../syncproviders/AccountManager.kt | 3 +- .../cloudstream3/syncproviders/SyncAPI.kt | 7 +- .../syncproviders/providers/LocalList.kt | 72 +++++++++++++++++++ .../ui/library/LibraryFragment.kt | 14 ++-- .../ui/library/ViewpagerAdapter.kt | 1 + .../cloudstream3/utils/DataStoreHelper.kt | 19 ++++- 6 files changed, 108 insertions(+), 8 deletions(-) create mode 100644 app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/LocalList.kt diff --git a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/AccountManager.kt b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/AccountManager.kt index 2bc39b54..997d1c51 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/AccountManager.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/AccountManager.kt @@ -12,6 +12,7 @@ abstract class AccountManager(private val defIndex: Int) : AuthAPI { val aniListApi = AniListApi(0) val openSubtitlesApi = OpenSubtitlesApi(0) val indexSubtitlesApi = IndexSubtitleApi() + val localListApi = LocalList() // used to login via app intent val OAuth2Apis @@ -28,7 +29,7 @@ abstract class AccountManager(private val defIndex: Int) : AuthAPI { // used for active syncing val SyncApis get() = listOf( - SyncRepo(malApi), SyncRepo(aniListApi) + SyncRepo(malApi), SyncRepo(aniListApi), SyncRepo(localListApi) ) val inAppAuths diff --git a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/SyncAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/SyncAPI.kt index 5f6b02a8..a52745dd 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/SyncAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/SyncAPI.kt @@ -7,12 +7,17 @@ enum class SyncIdName { Anilist, MyAnimeList, Trakt, - Imdb + Imdb, + LocalList } interface SyncAPI : OAuth2API { val mainUrl: String + /** + * Allows certain providers to open pages from + * library links. + **/ val syncIdName: SyncIdName /** diff --git a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/LocalList.kt b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/LocalList.kt new file mode 100644 index 00000000..d3dc5314 --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/LocalList.kt @@ -0,0 +1,72 @@ +package com.lagradost.cloudstream3.syncproviders.providers + +import com.lagradost.cloudstream3.R +import com.lagradost.cloudstream3.syncproviders.AuthAPI +import com.lagradost.cloudstream3.syncproviders.SyncAPI +import com.lagradost.cloudstream3.syncproviders.SyncIdName +import com.lagradost.cloudstream3.ui.library.LibraryItem +import com.lagradost.cloudstream3.utils.Coroutines.ioWork +import com.lagradost.cloudstream3.utils.DataStoreHelper.getAllWatchStateIds +import com.lagradost.cloudstream3.utils.DataStoreHelper.getBookmarkedData +import com.lagradost.cloudstream3.utils.DataStoreHelper.getResultWatchState + +class LocalList : SyncAPI { + override val name = "Local" + override val icon: Int = R.drawable.ic_baseline_storage_24 + override val requiresLogin = false + override val createAccountUrl: Nothing? = null + override val idPrefix = "local" + + override fun loginInfo(): AuthAPI.LoginInfo? { + return null + } + + override fun logOut() { + + } + + override val key: String = "" + override val redirectUrl = "" + override suspend fun handleRedirect(url: String): Boolean { + return true + } + + override fun authenticate() { + } + + override val mainUrl = "" + override val syncIdName = SyncIdName.LocalList + override suspend fun score(id: String, status: SyncAPI.SyncStatus): Boolean { + return true + } + + override suspend fun getStatus(id: String): SyncAPI.SyncStatus? { + return null + } + + override suspend fun getResult(id: String): SyncAPI.SyncResult? { + return null + } + + override suspend fun search(name: String): List? { + return null + } + + override suspend fun getPersonalLibrary(): List { + val watchStatusIds = ioWork { + getAllWatchStateIds()?.map { id -> + Pair(id, getResultWatchState(id)) + } + }?.distinctBy { it.first } ?: return emptyList() + + return ioWork { + watchStatusIds.mapNotNull { + getBookmarkedData(it.first)?.toLibraryItem(it.second) + } + } + } + + override fun getIdFromUrl(url: String): String { + return url + } +} \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/library/LibraryFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/library/LibraryFragment.kt index cbc48d41..2009afba 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/library/LibraryFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/library/LibraryFragment.kt @@ -33,9 +33,13 @@ enum class LibraryOpenerType { } /** Used to store how the user wants to open said poster */ -class LibraryOpener( +data class LibraryOpener( val openType: LibraryOpenerType, - val data: String?, + val providerData: ProviderLibraryData?, +) + +data class ProviderLibraryData( + val apiName: String ) class LibraryFragment : Fragment() { @@ -121,8 +125,8 @@ class LibraryFragment : Fragment() { savedSelection == null -> -1 // If provider savedSelection.openType == LibraryOpenerType.Provider - && savedSelection.data != null -> { - availableProviders.indexOf(savedSelection.data).takeIf { it != -1 } + && savedSelection.providerData?.apiName != null -> { + availableProviders.indexOf(savedSelection.providerData.apiName).takeIf { it != -1 } ?.plus(baseOptions.size) ?: -1 } // Else base option @@ -144,7 +148,7 @@ class LibraryFragment : Fragment() { } else { LibraryOpener( LibraryOpenerType.Provider, - items[it] + ProviderLibraryData(items[it]) ) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/library/ViewpagerAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/library/ViewpagerAdapter.kt index f4f8369c..cab6066e 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/library/ViewpagerAdapter.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/library/ViewpagerAdapter.kt @@ -42,6 +42,7 @@ data class Page( data class LibraryItem( override val name: String, override val url: String, + /** Unique unchanging string used for data storage */ val syncId: String, val listName: String, val episodesCompleted: Int?, diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/DataStoreHelper.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/DataStoreHelper.kt index 46c29e3f..bd40586a 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/DataStoreHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/DataStoreHelper.kt @@ -1,6 +1,7 @@ package com.lagradost.cloudstream3.utils import com.fasterxml.jackson.annotation.JsonProperty +import com.lagradost.cloudstream3.APIHolder.capitalize import com.lagradost.cloudstream3.AcraApplication.Companion.getKey import com.lagradost.cloudstream3.AcraApplication.Companion.getKeys import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey @@ -10,7 +11,10 @@ import com.lagradost.cloudstream3.DubStatus import com.lagradost.cloudstream3.SearchQuality import com.lagradost.cloudstream3.SearchResponse import com.lagradost.cloudstream3.TvType +import com.lagradost.cloudstream3.syncproviders.SyncIdName +import com.lagradost.cloudstream3.syncproviders.providers.LocalList import com.lagradost.cloudstream3.ui.WatchType +import com.lagradost.cloudstream3.ui.library.LibraryItem const val VIDEO_POS_DUR = "video_pos_dur" const val RESULT_WATCH_STATE = "result_watch_state" @@ -49,7 +53,20 @@ object DataStoreHelper { @JsonProperty("year") val year: Int?, @JsonProperty("quality") override var quality: SearchQuality? = null, @JsonProperty("posterHeaders") override var posterHeaders: Map? = null, - ) : SearchResponse + ) : SearchResponse { + fun toLibraryItem(state: WatchType): LibraryItem { + return LibraryItem( + name, + url, + url, + state.name.lowercase().capitalize(), + null, + null, + null, + apiName, type, posterUrl, posterHeaders, quality, id + ) + } + } data class ResumeWatchingResult( @JsonProperty("name") override val name: String,