From e886fde8b82641b5f9d2e82e9bc4b408ca3f2c89 Mon Sep 17 00:00:00 2001 From: LagradOst <11805592+LagradOst@users.noreply.github.com> Date: Thu, 21 Dec 2023 00:07:39 +0100 Subject: [PATCH] lib longhold --- app/build.gradle.kts | 2 +- .../lagradost/cloudstream3/MainActivity.kt | 111 +++++++++++++++--- .../cloudstream3/syncproviders/SyncAPI.kt | 10 +- .../syncproviders/providers/AniListApi.kt | 10 +- .../syncproviders/providers/MALApi.kt | 6 +- .../syncproviders/providers/SimklApi.kt | 13 +- .../lagradost/cloudstream3/ui/WatchType.kt | 23 ++++ .../ui/library/LibraryFragment.kt | 6 +- .../ui/result/ResultFragmentPhone.kt | 2 +- .../ui/result/ResultViewModel2.kt | 95 +++++++++++---- .../cloudstream3/ui/result/SyncViewModel.kt | 40 ++++++- .../cloudstream3/utils/DataStoreHelper.kt | 32 +++-- 12 files changed, 279 insertions(+), 71 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index bae407fa..9ecae616 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -60,7 +60,7 @@ android { targetSdk = 33 /* Android 14 is Fu*ked ^ https://developer.android.com/about/versions/14/behavior-changes-14#safer-dynamic-code-loading*/ versionCode = 63 - versionName = "4.3.0" + versionName = "4.3.1" resValue("string", "app_version", "${defaultConfig.versionName}${versionNameSuffix ?: ""}") resValue("string", "commit_hash", "git rev-parse --short HEAD".execute() ?: "") diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt index 6083f5ab..71a24ced 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt @@ -92,7 +92,9 @@ import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appStri import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appStringResumeWatching import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appStringSearch import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.inAppAuths +import com.lagradost.cloudstream3.syncproviders.SyncAPI import com.lagradost.cloudstream3.ui.APIRepository +import com.lagradost.cloudstream3.ui.SyncWatchType import com.lagradost.cloudstream3.ui.WatchType import com.lagradost.cloudstream3.ui.download.DOWNLOAD_NAVIGATE_TO import com.lagradost.cloudstream3.ui.home.HomeViewModel @@ -102,6 +104,7 @@ import com.lagradost.cloudstream3.ui.player.LinkGenerator import com.lagradost.cloudstream3.ui.result.LinearListLayout import com.lagradost.cloudstream3.ui.result.ResultViewModel2 import com.lagradost.cloudstream3.ui.result.START_ACTION_RESUME_LATEST +import com.lagradost.cloudstream3.ui.result.SyncViewModel import com.lagradost.cloudstream3.ui.result.setImage import com.lagradost.cloudstream3.ui.result.setText import com.lagradost.cloudstream3.ui.result.txt @@ -440,13 +443,30 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { } var lastPopup: SearchResponse? = null - fun loadPopup(result: SearchResponse) { + fun loadPopup(result: SearchResponse, load : Boolean = true) { lastPopup = result - viewModel.load( - this, result.url, result.apiName, false, if (getApiDubstatusSettings() - .contains(DubStatus.Dubbed) - ) DubStatus.Dubbed else DubStatus.Subbed, null - ) + val syncName = syncViewModel.syncName(result.apiName) + + // based on apiName we decide on if it is a local list or not, this is because + // we want to show a bit of extra UI to sync apis + if (result is SyncAPI.LibraryItem && syncName != null) { + isLocalList = false + syncViewModel.setSync(syncName, result.syncId) + syncViewModel.updateMetaAndUser() + } else { + isLocalList = true + syncViewModel.clear() + } + + if (load) { + viewModel.load( + this, result.url, result.apiName, false, if (getApiDubstatusSettings() + .contains(DubStatus.Dubbed) + ) DubStatus.Dubbed else DubStatus.Subbed, null + ) + }else { + viewModel.loadSmall(this,result) + } } override fun onColorSelected(dialogId: Int, color: Int) { @@ -734,10 +754,14 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { } lateinit var viewModel: ResultViewModel2 - + lateinit var syncViewModel : SyncViewModel + /** kinda dirty, however it signals that we should use the watch status as sync or not*/ + var isLocalList : Boolean = false override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? { viewModel = ViewModelProvider(this)[ResultViewModel2::class.java] + syncViewModel = + ViewModelProvider(this)[SyncViewModel::class.java] return super.onCreateView(name, context, attrs) } @@ -1235,13 +1259,48 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { builder.show().setDefaultFocus() } - observe(viewModel.watchStatus) { state -> + + fun setUserData(status : Resource?) { + if (isLocalList) return + bottomPreviewBinding?.apply { + when (status) { + is Resource.Success -> { + resultviewPreviewBookmark.isEnabled = true + resultviewPreviewBookmark.setText(status.value.status.stringRes) + resultviewPreviewBookmark.setIconResource(status.value.status.iconRes) + } + + is Resource.Failure -> { + resultviewPreviewBookmark.isEnabled = false + resultviewPreviewBookmark.setIconResource(R.drawable.ic_baseline_bookmark_border_24) + resultviewPreviewBookmark.text = status.errorString + } + + else -> { + resultviewPreviewBookmark.isEnabled = false + resultviewPreviewBookmark.setIconResource(R.drawable.ic_baseline_bookmark_border_24) + resultviewPreviewBookmark.setText(R.string.loading) + } + } + } + } + + fun setWatchStatus(state : WatchType?) { + if (!isLocalList || state == null) return + bottomPreviewBinding?.resultviewPreviewBookmark?.apply { setIconResource(state.iconRes) setText(state.stringRes) } } + observe(viewModel.watchStatus) { state -> + setWatchStatus(state) + } + observe(syncViewModel.userData) { status -> + setUserData(status) + } + observeNullable(viewModel.page) { resource -> if (resource == null) { hidePreviewPopupDialog() @@ -1281,17 +1340,37 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { d.posterImage ?: d.posterBackgroundImage ) + setUserData(syncViewModel.userData.value) + setWatchStatus(viewModel.watchStatus.value) + resultviewPreviewBookmark.setOnClickListener { //viewModel.updateWatchStatus(WatchType.PLANTOWATCH) - val value = viewModel.watchStatus.value ?: WatchType.NONE + if (isLocalList) { + val value = viewModel.watchStatus.value ?: WatchType.NONE - this@MainActivity.showBottomDialog( - WatchType.values().map { getString(it.stringRes) }.toList(), - value.ordinal, - this@MainActivity.getString(R.string.action_add_to_bookmarks), - showApply = false, - {}) { - viewModel.updateWatchStatus(WatchType.values()[it], this@MainActivity) + this@MainActivity.showBottomDialog( + WatchType.values().map { getString(it.stringRes) }.toList(), + value.ordinal, + this@MainActivity.getString(R.string.action_add_to_bookmarks), + showApply = false, + {}) { + viewModel.updateWatchStatus( + WatchType.values()[it], + this@MainActivity + ) + } + } else { + val value = (syncViewModel.userData.value as? Resource.Success)?.value?.status ?: SyncWatchType.NONE + + this@MainActivity.showBottomDialog( + SyncWatchType.values().map { getString(it.stringRes) }.toList(), + value.ordinal, + this@MainActivity.getString(R.string.action_add_to_bookmarks), + showApply = false, + {}) { + syncViewModel.setStatus(SyncWatchType.values()[it].internalId) + syncViewModel.publishUserData() + } } } 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 ed496326..045fdc94 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/SyncAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/SyncAPI.kt @@ -1,6 +1,8 @@ package com.lagradost.cloudstream3.syncproviders import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.ui.SyncWatchType +import com.lagradost.cloudstream3.ui.WatchType import com.lagradost.cloudstream3.ui.library.ListSorting import com.lagradost.cloudstream3.ui.result.UiText import me.xdrop.fuzzywuzzy.FuzzySearch @@ -61,7 +63,7 @@ interface SyncAPI : OAuth2API { ) : SearchResponse abstract class AbstractSyncStatus { - abstract var status: Int + abstract var status: SyncWatchType /** 1-10 */ abstract var score: Int? @@ -70,8 +72,9 @@ interface SyncAPI : OAuth2API { abstract var maxEpisodes: Int? } + data class SyncStatus( - override var status: Int, + override var status: SyncWatchType, /** 1-10 */ override var score: Int?, override var watchedEpisodes: Int?, @@ -166,5 +169,8 @@ interface SyncAPI : OAuth2API { override var posterHeaders: Map?, override var quality: SearchQuality?, override var id: Int? = null, + val plot : String? = null, + val rating: Int? = null, + val tags: List? = null, ) : SearchResponse } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/AniListApi.kt b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/AniListApi.kt index d0c88901..5c02e7f7 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/AniListApi.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/AniListApi.kt @@ -13,6 +13,7 @@ import com.lagradost.cloudstream3.syncproviders.AccountManager import com.lagradost.cloudstream3.syncproviders.AuthAPI import com.lagradost.cloudstream3.syncproviders.SyncAPI import com.lagradost.cloudstream3.syncproviders.SyncIdName +import com.lagradost.cloudstream3.ui.SyncWatchType import com.lagradost.cloudstream3.ui.library.ListSorting import com.lagradost.cloudstream3.ui.result.txt import com.lagradost.cloudstream3.utils.AppUtils.parseJson @@ -165,7 +166,7 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI { return SyncAPI.SyncStatus( score = data.score, watchedEpisodes = data.progress, - status = data.type?.value ?: return null, + status = SyncWatchType.fromInternalId(data.type?.value ?: return null), isFavorite = data.isFavourite, maxEpisodes = data.episodes, ) @@ -174,7 +175,7 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI { override suspend fun score(id: String, status: SyncAPI.AbstractSyncStatus): Boolean { return postDataAboutId( id.toIntOrNull() ?: return false, - fromIntToAnimeStatus(status.status), + fromIntToAnimeStatus(status.status.internalId), status.score, status.watchedEpisodes ).also { @@ -595,7 +596,7 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI { //@JsonProperty("source") val source: String, @JsonProperty("episodes") val episodes: Int, @JsonProperty("title") val title: Title, - //@JsonProperty("description") val description: String, + @JsonProperty("description") val description: String?, @JsonProperty("coverImage") val coverImage: CoverImage, @JsonProperty("synonyms") val synonyms: List, @JsonProperty("nextAiringEpisode") val nextAiringEpisode: SeasonNextAiringEpisode?, @@ -629,7 +630,8 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI { ?: this.media.coverImage.medium, null, null, - null + null, + plot = this.media.description ) } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/MALApi.kt b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/MALApi.kt index 02826401..fdbe763a 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/MALApi.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/MALApi.kt @@ -16,6 +16,7 @@ import com.lagradost.cloudstream3.syncproviders.AccountManager import com.lagradost.cloudstream3.syncproviders.AuthAPI import com.lagradost.cloudstream3.syncproviders.SyncAPI import com.lagradost.cloudstream3.syncproviders.SyncIdName +import com.lagradost.cloudstream3.ui.SyncWatchType import com.lagradost.cloudstream3.ui.library.ListSorting import com.lagradost.cloudstream3.ui.result.txt import com.lagradost.cloudstream3.utils.AppUtils.parseJson @@ -94,7 +95,7 @@ class MALApi(index: Int) : AccountManager(index), SyncAPI { override suspend fun score(id: String, status: SyncAPI.AbstractSyncStatus): Boolean { return setScoreRequest( id.toIntOrNull() ?: return false, - fromIntToAnimeStatus(status.status), + fromIntToAnimeStatus(status.status.internalId), status.score, status.watchedEpisodes ).also { @@ -245,7 +246,7 @@ class MALApi(index: Int) : AccountManager(index), SyncAPI { getDataAboutMalId(internalId)?.my_list_status //?: throw ErrorLoadingException("No my_list_status") return SyncAPI.SyncStatus( score = data?.score, - status = malStatusAsString.indexOf(data?.status), + status = SyncWatchType.fromInternalId(malStatusAsString.indexOf(data?.status)) , isFavorite = null, watchedEpisodes = data?.num_episodes_watched, ) @@ -442,6 +443,7 @@ class MALApi(index: Int) : AccountManager(index), SyncAPI { this.node.main_picture?.large ?: this.node.main_picture?.medium, null, null, + plot = this.node.synopsis, ) } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/SimklApi.kt b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/SimklApi.kt index 3a37a228..e0b13ba6 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/SimklApi.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/SimklApi.kt @@ -24,6 +24,7 @@ import com.lagradost.cloudstream3.syncproviders.AccountManager import com.lagradost.cloudstream3.syncproviders.AuthAPI import com.lagradost.cloudstream3.syncproviders.SyncAPI import com.lagradost.cloudstream3.syncproviders.SyncIdName +import com.lagradost.cloudstream3.ui.SyncWatchType import com.lagradost.cloudstream3.ui.library.ListSorting import com.lagradost.cloudstream3.ui.result.txt import com.lagradost.cloudstream3.utils.AppUtils.toJson @@ -671,7 +672,7 @@ class SimklApi(index: Int) : AccountManager(index), SyncAPI { this.movie.poster?.let { getPosterUrl(it) }, null, null, - movie.ids.simkl + movie.ids.simkl, ) } } @@ -779,7 +780,7 @@ class SimklApi(index: Int) : AccountManager(index), SyncAPI { } class SimklSyncStatus( - override var status: Int, + override var status: SyncWatchType, override var score: Int?, val oldScore: Int?, override var watchedEpisodes: Int?, @@ -826,7 +827,7 @@ class SimklApi(index: Int) : AccountManager(index), SyncAPI { if (foundItem != null) { return SimklSyncStatus( - status = foundItem.status?.let { SimklListStatusType.fromString(it)?.value } + status = foundItem.status?.let { SyncWatchType.fromInternalId(SimklListStatusType.fromString(it)?.value) } ?: return null, score = foundItem.user_rating, watchedEpisodes = foundItem.watched_episodes_count, @@ -838,7 +839,7 @@ class SimklApi(index: Int) : AccountManager(index), SyncAPI { ) } else { return SimklSyncStatus( - status = SimklListStatusType.None.value, + status = SyncWatchType.fromInternalId(SimklListStatusType.None.value) , score = 0, watchedEpisodes = 0, maxEpisodes = if (searchResult.type == "movie") 0 else searchResult.total_episodes, @@ -858,7 +859,7 @@ class SimklApi(index: Int) : AccountManager(index), SyncAPI { val builder = SimklScoreBuilder.Builder() .apiUrl(this.mainUrl) .score(status.score, simklStatus?.oldScore) - .status(status.status, (status as? SimklSyncStatus)?.oldStatus?.let { oldStatus -> + .status(status.status.internalId, (status as? SimklSyncStatus)?.oldStatus?.let { oldStatus -> SimklListStatusType.values().firstOrNull { it.originalName == oldStatus }?.value @@ -871,7 +872,7 @@ class SimklApi(index: Int) : AccountManager(index), SyncAPI { val episodes = simklStatus?.episodeConstructor?.getEpisodes() // All episodes if marked as completed - val watchedEpisodes = if (status.status == SimklListStatusType.Completed.value) { + val watchedEpisodes = if (status.status.internalId == SimklListStatusType.Completed.value) { episodes?.size } else { status.watchedEpisodes diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/WatchType.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/WatchType.kt index eb4eb666..426f1b4e 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/WatchType.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/WatchType.kt @@ -12,6 +12,29 @@ enum class WatchType(val internalId: Int, @StringRes val stringRes: Int, @Drawab PLANTOWATCH(4, R.string.type_plan_to_watch, R.drawable.ic_baseline_bookmark_24), NONE(5, R.string.type_none, R.drawable.ic_baseline_add_24); + companion object { + fun fromInternalId(id: Int?) = values().find { value -> value.internalId == id } ?: NONE + } +} + +enum class SyncWatchType(val internalId: Int, @StringRes val stringRes: Int, @DrawableRes val iconRes: Int) { + /* + -1 -> None + 0 -> Watching + 1 -> Completed + 2 -> OnHold + 3 -> Dropped + 4 -> PlanToWatch + 5 -> ReWatching + */ + NONE(-1, R.string.type_none, R.drawable.ic_baseline_add_24), + WATCHING(0, R.string.type_watching, R.drawable.ic_baseline_bookmark_24), + COMPLETED(1, R.string.type_completed, R.drawable.ic_baseline_bookmark_24), + ONHOLD(2, R.string.type_on_hold, R.drawable.ic_baseline_bookmark_24), + DROPPED(3, R.string.type_dropped, R.drawable.ic_baseline_bookmark_24), + PLANTOWATCH(4, R.string.type_plan_to_watch, R.drawable.ic_baseline_bookmark_24), + REWATCHING(5, R.string.type_plan_to_watch, R.drawable.ic_baseline_bookmark_24); + companion object { fun fromInternalId(id: Int?) = values().find { value -> value.internalId == id } ?: NONE } 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 c60c8ef0..a37fbcb3 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,6 +33,7 @@ import com.lagradost.cloudstream3.AcraApplication.Companion.getKey import com.lagradost.cloudstream3.AcraApplication.Companion.openBrowser import com.lagradost.cloudstream3.AcraApplication.Companion.setKey import com.lagradost.cloudstream3.CommonActivity +import com.lagradost.cloudstream3.MainActivity import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.databinding.FragmentLibraryBinding import com.lagradost.cloudstream3.mvvm.Resource @@ -293,11 +294,12 @@ class LibraryFragment : Fragment() { when (searchClickCallback.action) { SEARCH_ACTION_SHOW_METADATA -> { - activity?.showPluginSelectionDialog( + (activity as? MainActivity)?.loadPopup(searchClickCallback.card, load = false) + /*activity?.showPluginSelectionDialog( syncId, syncName, searchClickCallback.card.apiName - ) + )*/ } SEARCH_ACTION_LOAD -> { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt index 0541a40f..ad34309c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt @@ -851,7 +851,7 @@ open class ResultFragmentPhone : FullScreenPlayer() { val d = status.value resultSyncRating.value = d.score?.toFloat() ?: 0.0f - resultSyncCheck.setItemChecked(d.status + 1, true) + resultSyncCheck.setItemChecked(d.status.internalId + 1, true) val watchedEpisodes = d.watchedEpisodes ?: 0 currentSyncProgress = watchedEpisodes diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt index 101a65ef..e60c388b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt @@ -826,16 +826,15 @@ class ResultViewModel2 : ViewModel() { private val _selectPopup: MutableLiveData = MutableLiveData(null) val selectPopup: LiveData = _selectPopup - fun updateWatchStatus( status: WatchType, context: Context?, loadResponse: LoadResponse? = null, statusChangedCallback: ((statusChanged: Boolean) -> Unit)? = null ) { - val response = loadResponse ?: currentResponse ?: return - - val currentId = response.getId() + val (response,currentId) = loadResponse?.let { load -> + (load to load.getId()) + } ?: ((currentResponse ?: return) to (currentId ?: return)) val currentStatus = getResultWatchState(currentId) @@ -885,13 +884,17 @@ class ResultViewModel2 : ViewModel() { response.type, response.posterUrl, response.year, - response.syncData + response.syncData, + plot = response.plot, + tags = response.tags, + rating = response.rating ) ) } if (currentStatus != status) { MainActivity.bookmarksUpdatedEvent(true) + MainActivity.reloadLibraryEvent(true) } _watchStatus.postValue(status) @@ -926,7 +929,7 @@ class ResultViewModel2 : ViewModel() { val response = currentResponse ?: return if (response !is EpisodeResponse) return - val currentId = response.getId() + val currentId = currentId ?: return if (isSubscribed) { removeSubscribedData(currentId) @@ -969,7 +972,10 @@ class ResultViewModel2 : ViewModel() { response.type, response.posterUrl, response.year, - response.syncData + response.syncData, + plot = response.plot, + rating = response.rating, + tags = response.tags ) ) @@ -994,7 +1000,7 @@ class ResultViewModel2 : ViewModel() { val isFavorite = _favoriteStatus.value ?: return val response = currentResponse ?: return - val currentId = response.getId() + val currentId = currentId ?: return if (isFavorite) { removeFavoritesData(currentId) @@ -1036,7 +1042,10 @@ class ResultViewModel2 : ViewModel() { response.type, response.posterUrl, response.year, - response.syncData + response.syncData, + plot = response.plot, + rating = response.rating, + tags = response.tags ) ) @@ -1839,10 +1848,10 @@ class ResultViewModel2 : ViewModel() { this.japName ).filter { it.length > 2 } .distinct().map { - // this actually would be nice if we improved a bit as 3rd season == season 3 == III ect + // this actually would be nice if we improved a bit as 3rd season == season 3 == III ect // right now it just removes the dubbed status it.lowercase().replace(Regex("""\(?[ds]ub(bed)?\)?(\s|$)""") , "").trim() - }, + }, TrackerType.getTypes(this.type), this.year ) @@ -1936,6 +1945,7 @@ class ResultViewModel2 : ViewModel() { postSuccessful( value ?: return@launchSafe, + currentId ?: return@launchSafe, currentRepo ?: return@launchSafe, updateEpisodes ?: return@launchSafe, false @@ -2050,9 +2060,9 @@ class ResultViewModel2 : ViewModel() { } private fun postFavorites(loadResponse: LoadResponse) { - val id = loadResponse.getId() - val isFavorite = getFavoritesData(id) != null - _favoriteStatus.postValue(isFavorite) + val id = loadResponse.getId() + val isFavorite = getFavoritesData(id) != null + _favoriteStatus.postValue(isFavorite) } private fun postEpisodeRange(indexer: EpisodeIndexer?, range: EpisodeRange?) { @@ -2185,26 +2195,25 @@ class ResultViewModel2 : ViewModel() { private suspend fun postSuccessful( loadResponse: LoadResponse, + mainId : Int, apiRepository: APIRepository, updateEpisodes: Boolean, updateFillers: Boolean, ) { + currentId = mainId currentResponse = loadResponse postPage(loadResponse, apiRepository) postSubscription(loadResponse) postFavorites(loadResponse) + _watchStatus.postValue(getResultWatchState(mainId)) + if (updateEpisodes) - postEpisodes(loadResponse, updateFillers) + postEpisodes(loadResponse, mainId, updateFillers) } - private suspend fun postEpisodes(loadResponse: LoadResponse, updateFillers: Boolean) { + private suspend fun postEpisodes(loadResponse: LoadResponse, mainId : Int, updateFillers: Boolean) { _episodes.postValue(Resource.Loading()) - val mainId = loadResponse.getId() - currentId = mainId - - _watchStatus.postValue(getResultWatchState(mainId)) - if (updateFillers && loadResponse is AnimeLoadResponse) { updateFillers(loadResponse.name) } @@ -2561,6 +2570,49 @@ class ResultViewModel2 : ViewModel() { } } + data class LoadResponseFromSearch( + override var name: String, + override var url: String, + override var apiName: String, + override var type: TvType, + override var posterUrl: String?, + override var year: Int? = null, + override var plot: String? = null, + override var rating: Int? = null, + override var tags: List? = null, + override var duration: Int? = null, + override var trailers: MutableList = mutableListOf(), + override var recommendations: List? = null, + override var actors: List? = null, + override var comingSoon: Boolean = false, + override var syncData: MutableMap = mutableMapOf(), + override var posterHeaders: Map? = null, + override var backgroundPosterUrl: String? = null, + override var contentRating: String? = null, + ) : LoadResponse + + fun loadSmall(activity: Activity?, searchResponse : SearchResponse) = ioSafe { + val url = searchResponse.url + _page.postValue(Resource.Loading(url)) + _episodes.postValue(Resource.Loading()) + val api = APIHolder.getApiFromNameNull(searchResponse.apiName) ?: APIHolder.getApiFromUrlNull(searchResponse.url) ?: APIRepository.noneApi + val repo = APIRepository(api) + val response = LoadResponseFromSearch(name = searchResponse.name, url = searchResponse.url, apiName = api.name, type = searchResponse.type ?: TvType.Others, + posterUrl = searchResponse.posterUrl).apply { + if (searchResponse is SyncAPI.LibraryItem) { + this.plot = searchResponse.plot + this.rating = searchResponse.personalRating?.times(100) ?: searchResponse.rating + this.tags = searchResponse.tags + } + } + val mainId = searchResponse.id ?: response.getId() + + postSuccessful( + loadResponse = response, + mainId = mainId, + apiRepository = repo, updateEpisodes = false, updateFillers = false) + } + fun load( activity: Activity?, url: String, @@ -2646,6 +2698,7 @@ class ResultViewModel2 : ViewModel() { loadTrailers(data.value) postSuccessful( data.value, + mainId, updateEpisodes = true, updateFillers = showFillers, apiRepository = repo diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/SyncViewModel.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/SyncViewModel.kt index a3e2ed87..51d3f50c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/SyncViewModel.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/SyncViewModel.kt @@ -10,7 +10,9 @@ import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.SyncApis import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.aniListApi import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.malApi +import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.simklApi import com.lagradost.cloudstream3.syncproviders.SyncAPI +import com.lagradost.cloudstream3.ui.SyncWatchType import com.lagradost.cloudstream3.utils.Coroutines.ioSafe import com.lagradost.cloudstream3.utils.SyncUtil import java.util.* @@ -31,15 +33,15 @@ class SyncViewModel : ViewModel() { private val repos = SyncApis - private val _metaResponse: MutableLiveData> = - MutableLiveData() + private val _metaResponse: MutableLiveData?> = + MutableLiveData(null) - val metadata: LiveData> get() = _metaResponse + val metadata: LiveData?> = _metaResponse private val _userDataResponse: MutableLiveData?> = MutableLiveData(null) - val userData: LiveData?> get() = _userDataResponse + val userData: LiveData?> = _userDataResponse // prefix, id private val syncs = mutableMapOf() @@ -55,7 +57,7 @@ class SyncViewModel : ViewModel() { MutableLiveData(getMissing()) // pair of name idPrefix isSynced - val synced: LiveData> get() = _currentSynced + val synced: LiveData> = _currentSynced private fun getMissing(): List { return repos.map { @@ -169,7 +171,7 @@ class SyncViewModel : ViewModel() { if (which < -1 || which > 5) return // validate input val user = userData.value if (user is Resource.Success) { - user.value.status = which + user.value.status = SyncWatchType.fromInternalId(which) _userDataResponse.postValue(Resource.Success(user.value)) } } @@ -279,7 +281,33 @@ class SyncViewModel : ViewModel() { setEpisodesDelta(0) } + fun syncName(syncName: String) : String? { + // fix because of bad old data :pensive: + val realName = when(syncName) { + "MAL" -> malApi.idPrefix + "Simkl" -> simklApi.idPrefix + "AniList" -> aniListApi.idPrefix + else -> syncName + } + return repos.firstOrNull { it.idPrefix == realName }?.idPrefix + } + + fun setSync(syncName : String, syncId : String) { + syncs.clear() + syncs[syncName] = syncId + } + + fun clear() { + syncs.clear() + _metaResponse.postValue(null) + _currentSynced.postValue(getMissing()) + _userDataResponse.postValue(null) + } + fun updateMetaAndUser() { + _userDataResponse.postValue(Resource.Loading()) + _metaResponse.postValue(Resource.Loading()) + Log.i(TAG, "updateMetaAndUser") updateMetadata() updateUserData() 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 6babe273..04387d80 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/DataStoreHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/DataStoreHelper.kt @@ -209,7 +209,10 @@ object DataStoreHelper { @JsonProperty("year") open val year: Int?, @JsonProperty("syncData") open val syncData: Map?, @JsonProperty("quality") override var quality: SearchQuality?, - @JsonProperty("posterHeaders") override var posterHeaders: Map? + @JsonProperty("posterHeaders") override var posterHeaders: Map?, + @JsonProperty("plot") open val plot : String? = null, + @JsonProperty("rating") open val rating : Int? = null, + @JsonProperty("tags") open val tags : List? = null, ) : SearchResponse data class SubscribedData( @@ -225,8 +228,11 @@ object DataStoreHelper { override val year: Int?, override val syncData: Map? = null, override var quality: SearchQuality? = null, - override var posterHeaders: Map? = null - ) : LibrarySearchResponse(id, latestUpdatedTime, name, url, apiName, type, posterUrl, year, syncData, quality, posterHeaders) { + override var posterHeaders: Map? = null, + override val plot: String? = null, + override val rating: Int? = null, + override val tags: List? = null, + ) : LibrarySearchResponse(id, latestUpdatedTime, name, url, apiName, type, posterUrl, year, syncData, quality, posterHeaders, plot,rating,tags) { fun toLibraryItem(): SyncAPI.LibraryItem? { return SyncAPI.LibraryItem( name, @@ -236,7 +242,7 @@ object DataStoreHelper { null, null, latestUpdatedTime, - apiName, type, posterUrl, posterHeaders, quality, this.id + apiName, type, posterUrl, posterHeaders, quality, this.id, plot = this.plot, rating = this.rating, tags = this.tags ) } } @@ -253,8 +259,11 @@ object DataStoreHelper { override val year: Int?, override val syncData: Map? = null, override var quality: SearchQuality? = null, - override var posterHeaders: Map? = null - ) : LibrarySearchResponse(id, latestUpdatedTime, name, url, apiName, type, posterUrl, year, syncData, quality, posterHeaders) { + override var posterHeaders: Map? = null, + override val plot: String? = null, + override val rating: Int? = null, + override val tags: List? = null, + ) : LibrarySearchResponse(id, latestUpdatedTime, name, url, apiName, type, posterUrl, year, syncData, quality, posterHeaders, plot) { fun toLibraryItem(id: String): SyncAPI.LibraryItem { return SyncAPI.LibraryItem( name, @@ -264,7 +273,7 @@ object DataStoreHelper { null, null, latestUpdatedTime, - apiName, type, posterUrl, posterHeaders, quality, this.id + apiName, type, posterUrl, posterHeaders, quality, this.id, plot = this.plot, rating = this.rating, tags = this.tags ) } } @@ -281,8 +290,11 @@ object DataStoreHelper { override val year: Int?, override val syncData: Map? = null, override var quality: SearchQuality? = null, - override var posterHeaders: Map? = null - ) : LibrarySearchResponse(id, latestUpdatedTime, name, url, apiName, type, posterUrl, year, syncData, quality, posterHeaders) { + override var posterHeaders: Map? = null, + override val plot: String? = null, + override val rating: Int? = null, + override val tags: List? = null, + ) : LibrarySearchResponse(id, latestUpdatedTime, name, url, apiName, type, posterUrl, year, syncData, quality, posterHeaders,plot) { fun toLibraryItem(): SyncAPI.LibraryItem? { return SyncAPI.LibraryItem( name, @@ -292,7 +304,7 @@ object DataStoreHelper { null, null, latestUpdatedTime, - apiName, type, posterUrl, posterHeaders, quality, this.id + apiName, type, posterUrl, posterHeaders, quality, this.id, plot = this.plot, rating = this.rating, tags = this.tags ) } }