mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
More work on local list support
This commit is contained in:
parent
7cd6dd3fe6
commit
019e9a0c4f
11 changed files with 143 additions and 109 deletions
|
@ -1,7 +1,8 @@
|
|||
package com.lagradost.cloudstream3.syncproviders
|
||||
|
||||
import com.lagradost.cloudstream3.*
|
||||
import com.lagradost.cloudstream3.ui.library.LibraryItem
|
||||
import com.lagradost.cloudstream3.ui.library.ListSorting
|
||||
import me.xdrop.fuzzywuzzy.FuzzySearch
|
||||
|
||||
enum class SyncIdName {
|
||||
Anilist,
|
||||
|
@ -37,9 +38,9 @@ interface SyncAPI : OAuth2API {
|
|||
|
||||
suspend fun search(name: String): List<SyncSearchResult>?
|
||||
|
||||
suspend fun getPersonalLibrary(): List<LibraryItem>?
|
||||
suspend fun getPersonalLibrary(): LibraryMetadata?
|
||||
|
||||
fun getIdFromUrl(url : String) : String
|
||||
fun getIdFromUrl(url: String): String
|
||||
|
||||
data class SyncSearchResult(
|
||||
override val name: String,
|
||||
|
@ -59,7 +60,7 @@ interface SyncAPI : OAuth2API {
|
|||
val score: Int?,
|
||||
val watchedEpisodes: Int?,
|
||||
var isFavorite: Boolean? = null,
|
||||
var maxEpisodes : Int? = null,
|
||||
var maxEpisodes: Int? = null,
|
||||
)
|
||||
|
||||
data class SyncResult(
|
||||
|
@ -80,9 +81,9 @@ interface SyncAPI : OAuth2API {
|
|||
var genres: List<String>? = null,
|
||||
var synonyms: List<String>? = null,
|
||||
var trailers: List<String>? = null,
|
||||
var isAdult : Boolean? = null,
|
||||
var isAdult: Boolean? = null,
|
||||
var posterUrl: String? = null,
|
||||
var backgroundPosterUrl : String? = null,
|
||||
var backgroundPosterUrl: String? = null,
|
||||
|
||||
/** In unixtime */
|
||||
var startDate: Long? = null,
|
||||
|
@ -93,4 +94,53 @@ interface SyncAPI : OAuth2API {
|
|||
var prevSeason: SyncSearchResult? = null,
|
||||
var actors: List<ActorData>? = null,
|
||||
)
|
||||
|
||||
|
||||
data class Page(
|
||||
val title: String, var items: List<LibraryItem>
|
||||
) {
|
||||
fun sort(method: ListSorting?, query: String? = null) {
|
||||
items = when (method) {
|
||||
ListSorting.Query ->
|
||||
if (query != null) {
|
||||
items.sortedBy {
|
||||
-FuzzySearch.partialRatio(
|
||||
query.lowercase(), it.name.lowercase()
|
||||
)
|
||||
}
|
||||
} else items
|
||||
ListSorting.RatingHigh -> items.sortedBy { -(it.personalRating ?: 0) }
|
||||
ListSorting.RatingLow -> items.sortedBy { (it.personalRating ?: 0) }
|
||||
ListSorting.AlphabeticalA -> items.sortedBy { it.name }
|
||||
ListSorting.AlphabeticalZ -> items.sortedBy { it.name }.reversed()
|
||||
else -> items
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class LibraryMetadata(
|
||||
/** List of all available pages, useful to show empty pages
|
||||
* if the user has no entry on that page */
|
||||
val allListNames: List<String>,
|
||||
/** Not necessarily sorted list of all library items, will be grouped by listName */
|
||||
val allLibraryItems: List<LibraryItem>
|
||||
)
|
||||
|
||||
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?,
|
||||
val episodesTotal: Int?,
|
||||
/** Out of 100 */
|
||||
val personalRating: Int?,
|
||||
override val apiName: String,
|
||||
override var type: TvType?,
|
||||
override var posterUrl: String?,
|
||||
override var posterHeaders: Map<String, String>?,
|
||||
override var quality: SearchQuality?,
|
||||
override var id: Int? = null,
|
||||
) : SearchResponse
|
||||
}
|
|
@ -4,7 +4,6 @@ import com.lagradost.cloudstream3.ErrorLoadingException
|
|||
import com.lagradost.cloudstream3.mvvm.Resource
|
||||
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
||||
import com.lagradost.cloudstream3.mvvm.safeApiCall
|
||||
import com.lagradost.cloudstream3.ui.library.LibraryItem
|
||||
|
||||
class SyncRepo(private val repo: SyncAPI) {
|
||||
val idPrefix = repo.idPrefix
|
||||
|
@ -30,7 +29,7 @@ class SyncRepo(private val repo: SyncAPI) {
|
|||
return safeApiCall { repo.search(query) ?: throw ErrorLoadingException() }
|
||||
}
|
||||
|
||||
suspend fun getPersonalLibrary(): Resource<List<LibraryItem>> {
|
||||
suspend fun getPersonalLibrary(): Resource<SyncAPI.LibraryMetadata> {
|
||||
return safeApiCall { repo.getPersonalLibrary() ?: throw ErrorLoadingException() }
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ 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.library.LibraryItem
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.splitQuery
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.toJson
|
||||
|
@ -598,8 +597,8 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
|
|||
@JsonProperty("private") val private: Boolean,
|
||||
@JsonProperty("media") val media: Media
|
||||
) {
|
||||
fun toLibraryItem(listName: String?): LibraryItem? {
|
||||
return LibraryItem(
|
||||
fun toLibraryItem(listName: String?): SyncAPI.LibraryItem? {
|
||||
return SyncAPI.LibraryItem(
|
||||
// English title first
|
||||
this.media.title.english ?: this.media.title.romaji
|
||||
?: this.media.synonyms.firstOrNull()
|
||||
|
@ -612,7 +611,8 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
|
|||
this.score,
|
||||
"AniList",
|
||||
TvType.Anime,
|
||||
this.media.coverImage.extraLarge ?: this.media.coverImage.large ?: this.media.coverImage.medium,
|
||||
this.media.coverImage.extraLarge ?: this.media.coverImage.large
|
||||
?: this.media.coverImage.medium,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
|
@ -653,14 +653,17 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun getPersonalLibrary(): List<LibraryItem>? {
|
||||
return getAniListAnimeListSmart()?.map {
|
||||
it.entries.mapNotNull { entry ->
|
||||
entry.toLibraryItem(
|
||||
entry.status ?: it.status
|
||||
)
|
||||
}
|
||||
}?.flatten()
|
||||
override suspend fun getPersonalLibrary(): SyncAPI.LibraryMetadata {
|
||||
return SyncAPI.LibraryMetadata(
|
||||
emptyList(),
|
||||
getAniListAnimeListSmart()?.map {
|
||||
it.entries.mapNotNull { entry ->
|
||||
entry.toLibraryItem(
|
||||
entry.status ?: it.status
|
||||
)
|
||||
}
|
||||
}?.flatten() ?: emptyList()
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun getFullAniListList(): FullAnilistList? {
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package com.lagradost.cloudstream3.syncproviders.providers
|
||||
|
||||
import com.lagradost.cloudstream3.AcraApplication
|
||||
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.ui.WatchType
|
||||
import com.lagradost.cloudstream3.ui.result.txt
|
||||
import com.lagradost.cloudstream3.utils.Coroutines.ioWork
|
||||
import com.lagradost.cloudstream3.utils.DataStoreHelper.getAllWatchStateIds
|
||||
import com.lagradost.cloudstream3.utils.DataStoreHelper.getBookmarkedData
|
||||
|
@ -17,8 +19,12 @@ class LocalList : SyncAPI {
|
|||
override val createAccountUrl: Nothing? = null
|
||||
override val idPrefix = "local"
|
||||
|
||||
override fun loginInfo(): AuthAPI.LoginInfo? {
|
||||
return null
|
||||
override fun loginInfo(): AuthAPI.LoginInfo {
|
||||
return AuthAPI.LoginInfo(
|
||||
null,
|
||||
null,
|
||||
0
|
||||
)
|
||||
}
|
||||
|
||||
override fun logOut() {
|
||||
|
@ -52,18 +58,29 @@ class LocalList : SyncAPI {
|
|||
return null
|
||||
}
|
||||
|
||||
override suspend fun getPersonalLibrary(): List<LibraryItem> {
|
||||
override suspend fun getPersonalLibrary(): SyncAPI.LibraryMetadata? {
|
||||
val watchStatusIds = ioWork {
|
||||
getAllWatchStateIds()?.map { id ->
|
||||
Pair(id, getResultWatchState(id))
|
||||
}
|
||||
}?.distinctBy { it.first } ?: return emptyList()
|
||||
}?.distinctBy { it.first } ?: return null
|
||||
|
||||
return ioWork {
|
||||
val list = ioWork {
|
||||
watchStatusIds.mapNotNull {
|
||||
getBookmarkedData(it.first)?.toLibraryItem(it.second)
|
||||
}
|
||||
}
|
||||
|
||||
return SyncAPI.LibraryMetadata(
|
||||
WatchType.values().mapNotNull {
|
||||
// None is not something to display
|
||||
if (it == WatchType.NONE) return@mapNotNull null
|
||||
|
||||
// Dirty hack for context!
|
||||
txt(it.stringRes).asStringNull(AcraApplication.context)
|
||||
},
|
||||
list
|
||||
)
|
||||
}
|
||||
|
||||
override fun getIdFromUrl(url: String): String {
|
||||
|
|
|
@ -14,7 +14,6 @@ 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.library.LibraryItem
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.splitQuery
|
||||
import com.lagradost.cloudstream3.utils.DataStore.toKotlinObject
|
||||
|
@ -386,8 +385,8 @@ class MALApi(index: Int) : AccountManager(index), SyncAPI {
|
|||
@JsonProperty("node") val node: Node,
|
||||
@JsonProperty("list_status") val list_status: ListStatus?,
|
||||
) {
|
||||
fun toLibraryItem(): LibraryItem {
|
||||
return LibraryItem(
|
||||
fun toLibraryItem(): SyncAPI.LibraryItem {
|
||||
return SyncAPI.LibraryItem(
|
||||
this.node.title,
|
||||
"https://myanimelist.net/anime/${this.node.id}/",
|
||||
this.node.id.toString(),
|
||||
|
@ -445,8 +444,11 @@ class MALApi(index: Int) : AccountManager(index), SyncAPI {
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun getPersonalLibrary(): List<LibraryItem>? {
|
||||
return getMalAnimeListSmart()?.map { it.toLibraryItem() }
|
||||
override suspend fun getPersonalLibrary(): SyncAPI.LibraryMetadata {
|
||||
return SyncAPI.LibraryMetadata(
|
||||
emptyList(),
|
||||
getMalAnimeListSmart()?.map { it.toLibraryItem() } ?: emptyList()
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun getMalAnimeList(): Array<Data> {
|
||||
|
|
|
@ -15,6 +15,7 @@ import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
|
|||
import com.lagradost.cloudstream3.R
|
||||
import com.lagradost.cloudstream3.mvvm.debugAssert
|
||||
import com.lagradost.cloudstream3.mvvm.observe
|
||||
import com.lagradost.cloudstream3.syncproviders.SyncAPI
|
||||
import com.lagradost.cloudstream3.syncproviders.SyncIdName
|
||||
import com.lagradost.cloudstream3.ui.result.txt
|
||||
import com.lagradost.cloudstream3.ui.search.SEARCH_ACTION_LOAD
|
||||
|
@ -126,7 +127,8 @@ class LibraryFragment : Fragment() {
|
|||
// If provider
|
||||
savedSelection.openType == LibraryOpenerType.Provider
|
||||
&& savedSelection.providerData?.apiName != null -> {
|
||||
availableProviders.indexOf(savedSelection.providerData.apiName).takeIf { it != -1 }
|
||||
availableProviders.indexOf(savedSelection.providerData.apiName)
|
||||
.takeIf { it != -1 }
|
||||
?.plus(baseOptions.size) ?: -1
|
||||
}
|
||||
// Else base option
|
||||
|
@ -167,7 +169,7 @@ class LibraryFragment : Fragment() {
|
|||
|
||||
viewpager?.setPageTransformer(LibraryScrollTransformer())
|
||||
viewpager?.adapter =
|
||||
viewpager.adapter ?: ViewpagerAdapter(emptyList(), { isScrollingDown: Boolean ->
|
||||
viewpager.adapter ?: ViewpagerAdapter(mutableListOf(), { isScrollingDown: Boolean ->
|
||||
if (isScrollingDown) {
|
||||
sort_fab?.shrink()
|
||||
} else {
|
||||
|
@ -177,11 +179,11 @@ class LibraryFragment : Fragment() {
|
|||
|
||||
// To prevent future accidents
|
||||
debugAssert({
|
||||
searchClickCallback.card !is LibraryItem
|
||||
searchClickCallback.card !is SyncAPI.LibraryItem
|
||||
}, {
|
||||
"searchClickCallback ${searchClickCallback.card} is not a LibraryItem"
|
||||
})
|
||||
val syncId = (searchClickCallback.card as LibraryItem).syncId
|
||||
val syncId = (searchClickCallback.card as SyncAPI.LibraryItem).syncId
|
||||
|
||||
println("SEARCH CLICK $searchClickCallback")
|
||||
when (searchClickCallback.action) {
|
||||
|
@ -200,7 +202,8 @@ class LibraryFragment : Fragment() {
|
|||
|
||||
observe(libraryViewModel.pages) { pages ->
|
||||
(viewpager.adapter as? ViewpagerAdapter)?.pages = pages
|
||||
viewpager.adapter?.notifyItemChanged(viewpager?.currentItem ?: 0)
|
||||
// Using notifyItemRangeChanged keeps the animations when sorting
|
||||
viewpager.adapter?.notifyItemRangeChanged(0, viewpager.adapter?.itemCount ?: 0)
|
||||
|
||||
TabLayoutMediator(
|
||||
library_tab_layout,
|
||||
|
|
|
@ -7,6 +7,7 @@ import androidx.lifecycle.ViewModel
|
|||
import com.lagradost.cloudstream3.R
|
||||
import com.lagradost.cloudstream3.mvvm.Resource
|
||||
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.SyncApis
|
||||
import com.lagradost.cloudstream3.syncproviders.SyncAPI
|
||||
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
||||
|
||||
enum class ListSorting(@StringRes val stringRes: Int) {
|
||||
|
@ -20,8 +21,8 @@ enum class ListSorting(@StringRes val stringRes: Int) {
|
|||
}
|
||||
|
||||
class LibraryViewModel : ViewModel() {
|
||||
private val _pages: MutableLiveData<List<Page>> = MutableLiveData(emptyList())
|
||||
val pages: LiveData<List<Page>> = _pages
|
||||
private val _pages: MutableLiveData<List<SyncAPI.Page>> = MutableLiveData(emptyList())
|
||||
val pages: LiveData<List<SyncAPI.Page>> = _pages
|
||||
|
||||
private val _currentApiName: MutableLiveData<String> = MutableLiveData("")
|
||||
val currentApiName: LiveData<String> = _currentApiName
|
||||
|
@ -65,15 +66,22 @@ class LibraryViewModel : ViewModel() {
|
|||
fun loadPages() {
|
||||
ioSafe {
|
||||
currentSyncApi?.let { repo ->
|
||||
val list = (repo.getPersonalLibrary() as? Resource.Success)?.value
|
||||
val pages = (list ?: emptyList()).groupBy { it.listName }.map {
|
||||
Page(
|
||||
_currentApiName.postValue(repo.name)
|
||||
val library = (repo.getPersonalLibrary() as? Resource.Success)?.value ?: return@let
|
||||
|
||||
val listSubset = library.allLibraryItems.groupBy { it.listName }
|
||||
val allLists = library.allListNames.associateWith { emptyList<SyncAPI.LibraryItem>() }
|
||||
|
||||
val filledLists = allLists + listSubset
|
||||
|
||||
val pages = filledLists.map {
|
||||
SyncAPI.Page(
|
||||
it.key,
|
||||
it.value
|
||||
)
|
||||
}
|
||||
println("PAGES $pages")
|
||||
_pages.postValue(pages)
|
||||
_currentApiName.postValue(repo.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,16 +6,17 @@ import android.view.ViewGroup
|
|||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.lagradost.cloudstream3.R
|
||||
import com.lagradost.cloudstream3.syncproviders.SyncAPI
|
||||
import com.lagradost.cloudstream3.ui.search.SearchClickCallback
|
||||
import com.lagradost.cloudstream3.ui.search.SearchResultBuilder
|
||||
import com.lagradost.cloudstream3.utils.AppUtils
|
||||
import kotlinx.android.synthetic.main.search_result_grid_expanded.view.*
|
||||
|
||||
class PageAdapter(
|
||||
override val items: MutableList<LibraryItem>,
|
||||
override val items: MutableList<SyncAPI.LibraryItem>,
|
||||
val clickCallback: (SearchClickCallback) -> Unit
|
||||
) :
|
||||
AppUtils.DiffAdapter<LibraryItem>(items) {
|
||||
AppUtils.DiffAdapter<SyncAPI.LibraryItem>(items) {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
return LibraryItemViewHolder(
|
||||
|
@ -33,7 +34,7 @@ class PageAdapter(
|
|||
}
|
||||
|
||||
inner class LibraryItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
fun bind(item: LibraryItem, position: Int) {
|
||||
fun bind(item: SyncAPI.LibraryItem, position: Int) {
|
||||
SearchResultBuilder.bind(
|
||||
this@PageAdapter.clickCallback,
|
||||
item,
|
||||
|
|
|
@ -4,62 +4,16 @@ import android.os.Build
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.widget.NestedScrollView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.RecyclerView.OnFlingListener
|
||||
import androidx.recyclerview.widget.RecyclerView.OnScrollListener
|
||||
import com.lagradost.cloudstream3.R
|
||||
import com.lagradost.cloudstream3.SearchQuality
|
||||
import com.lagradost.cloudstream3.SearchResponse
|
||||
import com.lagradost.cloudstream3.TvType
|
||||
import com.lagradost.cloudstream3.syncproviders.SyncAPI
|
||||
import com.lagradost.cloudstream3.ui.search.SearchClickCallback
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.getSpanCount
|
||||
import kotlinx.android.synthetic.main.library_viewpager_page.view.*
|
||||
import me.xdrop.fuzzywuzzy.FuzzySearch
|
||||
|
||||
data class Page(
|
||||
val title: String, var items: List<LibraryItem>
|
||||
) {
|
||||
fun sort(method: ListSorting?, query: String? = null) {
|
||||
items = when (method) {
|
||||
ListSorting.Query ->
|
||||
if (query != null) {
|
||||
items.sortedBy {
|
||||
-FuzzySearch.partialRatio(
|
||||
query.lowercase(), it.name.lowercase()
|
||||
)
|
||||
}
|
||||
} else items
|
||||
ListSorting.RatingHigh -> items.sortedBy { -(it.personalRating ?: 0) }
|
||||
ListSorting.RatingLow -> items.sortedBy { (it.personalRating ?: 0) }
|
||||
ListSorting.AlphabeticalA -> items.sortedBy { it.name }
|
||||
ListSorting.AlphabeticalZ -> items.sortedBy { it.name }.reversed()
|
||||
else -> items
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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?,
|
||||
val episodesTotal: Int?,
|
||||
/** Out of 100 */
|
||||
val personalRating: Int?,
|
||||
override val apiName: String,
|
||||
override var type: TvType?,
|
||||
override var posterUrl: String?,
|
||||
override var posterHeaders: Map<String, String>?,
|
||||
override var quality: SearchQuality?,
|
||||
override var id: Int? = null,
|
||||
) : SearchResponse
|
||||
|
||||
|
||||
class ViewpagerAdapter(
|
||||
var pages: List<Page>,
|
||||
var pages: List<SyncAPI.Page>,
|
||||
val scrollCallback: (isScrollingDown: Boolean) -> Unit,
|
||||
val clickCallback: (SearchClickCallback) -> Unit
|
||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
|
@ -80,7 +34,7 @@ class ViewpagerAdapter(
|
|||
|
||||
inner class PageViewHolder(private val itemViewTest: View) :
|
||||
RecyclerView.ViewHolder(itemViewTest) {
|
||||
fun bind(page: Page) {
|
||||
fun bind(page: SyncAPI.Page) {
|
||||
if (itemViewTest.page_recyclerview?.adapter == null) {
|
||||
itemViewTest.page_recyclerview?.adapter = PageAdapter(page.items.toMutableList(), clickCallback)
|
||||
itemView.page_recyclerview?.spanCount =
|
||||
|
|
|
@ -277,18 +277,14 @@ object AppUtils {
|
|||
}
|
||||
|
||||
fun updateList(newList: List<T>) {
|
||||
val time = measureTimeMillis {
|
||||
val diffResult = DiffUtil.calculateDiff(
|
||||
GenericDiffCallback(this.items, newList)
|
||||
)
|
||||
|
||||
val diffResult = DiffUtil.calculateDiff(
|
||||
GenericDiffCallback(this.items, newList)
|
||||
)
|
||||
items.clear()
|
||||
items.addAll(newList)
|
||||
|
||||
items.clear()
|
||||
items.addAll(newList)
|
||||
|
||||
diffResult.dispatchUpdatesTo(this)
|
||||
}
|
||||
println("TIME TAKEn $time")
|
||||
diffResult.dispatchUpdatesTo(this)
|
||||
}
|
||||
|
||||
inner class GenericDiffCallback(
|
||||
|
|
|
@ -11,10 +11,8 @@ 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.syncproviders.SyncAPI
|
||||
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"
|
||||
|
@ -54,8 +52,8 @@ object DataStoreHelper {
|
|||
@JsonProperty("quality") override var quality: SearchQuality? = null,
|
||||
@JsonProperty("posterHeaders") override var posterHeaders: Map<String, String>? = null,
|
||||
) : SearchResponse {
|
||||
fun toLibraryItem(state: WatchType): LibraryItem {
|
||||
return LibraryItem(
|
||||
fun toLibraryItem(state: WatchType): SyncAPI.LibraryItem {
|
||||
return SyncAPI.LibraryItem(
|
||||
name,
|
||||
url,
|
||||
url,
|
||||
|
@ -86,6 +84,9 @@ object DataStoreHelper {
|
|||
@JsonProperty("posterHeaders") override var posterHeaders: Map<String, String>? = null,
|
||||
) : SearchResponse
|
||||
|
||||
/**
|
||||
* A datastore wide account for future implementations of a multiple account system
|
||||
**/
|
||||
private var currentAccount: String = "0" //TODO ACCOUNT IMPLEMENTATION
|
||||
|
||||
fun getAllWatchStateIds(): List<Int>? {
|
||||
|
|
Loading…
Reference in a new issue