diff --git a/app/build.gradle b/app/build.gradle index f948335b..66d38ebd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,8 +13,8 @@ android { applicationId "com.lagradost.cloudstream3" minSdkVersion 21 targetSdkVersion 30 - versionCode 8 - versionName "1.1.6" + versionCode 9 + versionName "1.1.7" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt index af91f206..accc6353 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt @@ -56,7 +56,7 @@ object APIHolder { } fun LoadResponse.getId(): Int { - return url.replace(getApiFromName(apiName).mainUrl, "").hashCode() + return url.replace(getApiFromName(apiName).mainUrl, "").replace("/", "").hashCode() } fun Activity.getApiSettings(): HashSet { @@ -86,7 +86,7 @@ abstract class MainAPI { open val hasMainPage = false open val hasQuickSearch = false - open fun getMainPage() : HomePageResponse? { + open fun getMainPage(): HomePageResponse? { return null } @@ -189,6 +189,7 @@ interface SearchResponse { val type: TvType val posterUrl: String? val year: Int? + val id: Int? } data class AnimeSearchResponse( @@ -204,6 +205,7 @@ data class AnimeSearchResponse( val dubStatus: EnumSet?, val dubEpisodes: Int?, val subEpisodes: Int?, + override val id: Int? = null, ) : SearchResponse data class MovieSearchResponse( @@ -214,6 +216,7 @@ data class MovieSearchResponse( override val posterUrl: String?, override val year: Int?, + override val id: Int? = null, ) : SearchResponse data class TvSeriesSearchResponse( @@ -225,6 +228,7 @@ data class TvSeriesSearchResponse( override val posterUrl: String?, override val year: Int?, val episodes: Int?, + override val id: Int? = null, ) : SearchResponse interface LoadResponse { diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt index f7995288..b53b5649 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt @@ -13,7 +13,6 @@ import androidx.navigation.NavOptions import androidx.navigation.findNavController import androidx.navigation.fragment.NavHostFragment import com.google.android.gms.cast.framework.CastButtonFactory -import com.google.android.material.bottomnavigation.BottomNavigationView import com.lagradost.cloudstream3.APIHolder.apis import com.lagradost.cloudstream3.utils.UIHelper.checkWrite import com.lagradost.cloudstream3.utils.UIHelper.getResourceColor @@ -31,6 +30,7 @@ import com.lagradost.cloudstream3.utils.AppUtils.loadResult import com.lagradost.cloudstream3.utils.DataStore.getKey import com.lagradost.cloudstream3.utils.DataStore.removeKey import com.lagradost.cloudstream3.utils.DataStoreHelper.setViewPos +import com.lagradost.cloudstream3.utils.Event import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.fragment_result.* @@ -59,6 +59,8 @@ class MainActivity : AppCompatActivity() { var isInPlayer: Boolean = false var canShowPipMode: Boolean = false var isInPIPMode: Boolean = false + + val backEvent = Event() lateinit var navOptions: NavOptions } @@ -110,8 +112,10 @@ class MainActivity : AppCompatActivity() { .setCustomAnimations(R.anim.enter_anim, R.anim.exit_anim, R.anim.pop_enter, R.anim.pop_exit) .remove(currentFragment) .commitAllowingStateLoss() + backEvent.invoke(true) return true } + backEvent.invoke(false) return false } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeChildItemAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeChildItemAdapter.kt index cedd613c..5714f488 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeChildItemAdapter.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeChildItemAdapter.kt @@ -10,11 +10,14 @@ import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.bumptech.glide.load.model.GlideUrl import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.ui.search.SEARCH_ACTION_LOAD +import com.lagradost.cloudstream3.ui.search.SEARCH_ACTION_SHOW_METADATA +import com.lagradost.cloudstream3.ui.search.SearchClickCallback import kotlinx.android.synthetic.main.home_result_grid.view.* class HomeChildItemAdapter( - var cardList: List, - private val clickCallback: (SearchResponse) -> Unit + var cardList: List, + private val clickCallback: (SearchClickCallback) -> Unit ) : RecyclerView.Adapter() { @@ -38,7 +41,7 @@ class HomeChildItemAdapter( } class CardViewHolder - constructor(itemView: View, private val clickCallback: (SearchResponse) -> Unit) : + constructor(itemView: View, private val clickCallback: (SearchClickCallback) -> Unit) : RecyclerView.ViewHolder(itemView) { val cardView: ImageView = itemView.imageView private val cardText: TextView = itemView.imageText @@ -52,50 +55,51 @@ class HomeChildItemAdapter( //val imageTextProvider: TextView? = itemView.imageTextProvider private val bg: CardView = itemView.backgroundCard - fun bind(card: Any) { - if (card is SearchResponse) { // GENERIC + fun bind(card: SearchResponse) { + textType?.text = when (card.type) { + TvType.Anime -> "Anime" + TvType.Movie -> "Movie" + TvType.ONA -> "ONA" + TvType.TvSeries -> "TV" + } + // search_result_lang?.visibility = View.GONE - textType?.text = when (card.type) { - TvType.Anime -> "Anime" - TvType.Movie -> "Movie" - TvType.ONA -> "ONA" - TvType.TvSeries -> "TV" - } - // search_result_lang?.visibility = View.GONE + textIsDub?.visibility = View.GONE + textIsSub?.visibility = View.GONE - textIsDub?.visibility = View.GONE - textIsSub?.visibility = View.GONE + cardText.text = card.name - cardText.text = card.name + //imageTextProvider.text = card.apiName + if (!card.posterUrl.isNullOrEmpty()) { - //imageTextProvider.text = card.apiName - if (!card.posterUrl.isNullOrEmpty()) { + val glideUrl = + GlideUrl(card.posterUrl) - val glideUrl = - GlideUrl(card.posterUrl) + Glide.with(cardView.context) + .load(glideUrl) + .into(cardView) - Glide.with(cardView.context) - .load(glideUrl) - .into(cardView) + } - } + bg.setOnClickListener { + clickCallback.invoke(SearchClickCallback(SEARCH_ACTION_LOAD, it, card)) + } - bg.setOnClickListener { - clickCallback.invoke(card) - // (activity as AppCompatActivity).loadResult(card.url, card.slug, card.apiName) - } + bg.setOnLongClickListener { + clickCallback.invoke(SearchClickCallback(SEARCH_ACTION_SHOW_METADATA, it, card)) + return@setOnLongClickListener true + } - when (card) { - is AnimeSearchResponse -> { - if (card.dubStatus?.size == 1) { - //search_result_lang?.visibility = View.VISIBLE - if (card.dubStatus.contains(DubStatus.Dubbed)) { - textIsDub?.visibility = View.VISIBLE - //search_result_lang?.setColorFilter(ContextCompat.getColor(activity, R.color.dubColor)) - } else if (card.dubStatus.contains(DubStatus.Subbed)) { - //search_result_lang?.setColorFilter(ContextCompat.getColor(activity, R.color.subColor)) - textIsSub?.visibility = View.VISIBLE - } + when (card) { + is AnimeSearchResponse -> { + if (card.dubStatus?.size == 1) { + //search_result_lang?.visibility = View.VISIBLE + if (card.dubStatus.contains(DubStatus.Dubbed)) { + textIsDub?.visibility = View.VISIBLE + //search_result_lang?.setColorFilter(ContextCompat.getColor(activity, R.color.dubColor)) + } else if (card.dubStatus.contains(DubStatus.Subbed)) { + //search_result_lang?.setColorFilter(ContextCompat.getColor(activity, R.color.subColor)) + textIsSub?.visibility = View.VISIBLE } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt index 25c9b594..2670aa51 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt @@ -17,26 +17,33 @@ import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.bumptech.glide.load.model.GlideUrl import com.google.android.material.bottomsheet.BottomSheetDialog +import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.APIHolder.apis -import com.lagradost.cloudstream3.AnimeSearchResponse -import com.lagradost.cloudstream3.HomePageResponse -import com.lagradost.cloudstream3.R -import com.lagradost.cloudstream3.SearchResponse +import com.lagradost.cloudstream3.MainActivity.Companion.backEvent import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar import com.lagradost.cloudstream3.utils.UIHelper.getGridIsCompact import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIconsAndNoStringRes import com.lagradost.cloudstream3.mvvm.Resource import com.lagradost.cloudstream3.mvvm.observe import com.lagradost.cloudstream3.ui.AutofitRecyclerView +import com.lagradost.cloudstream3.ui.WatchType import com.lagradost.cloudstream3.ui.result.START_ACTION_RESUME_LATEST +import com.lagradost.cloudstream3.ui.search.SEARCH_ACTION_LOAD +import com.lagradost.cloudstream3.ui.search.SEARCH_ACTION_SHOW_METADATA import com.lagradost.cloudstream3.ui.search.SearchAdapter +import com.lagradost.cloudstream3.ui.search.SearchHelper.handleSearchClickCallback import com.lagradost.cloudstream3.utils.AppUtils.loadSearchResult import com.lagradost.cloudstream3.utils.DataStore.getKey +import com.lagradost.cloudstream3.utils.DataStore.removeKey import com.lagradost.cloudstream3.utils.DataStore.setKey +import com.lagradost.cloudstream3.utils.DataStoreHelper.setResultWatchState import com.lagradost.cloudstream3.utils.Event import com.lagradost.cloudstream3.utils.HOMEPAGE_API +import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIcons import kotlinx.android.synthetic.main.fragment_home.* +const val HOME_BOOKMARK_VALUE = "home_bookmarked_last" + class HomeFragment : Fragment() { private lateinit var homeViewModel: HomeViewModel @@ -142,6 +149,28 @@ class HomeFragment : Fragment() { fixGrid() } + override fun onResume() { + backEvent += ::handleBack + super.onResume() + } + + override fun onStop() { + backEvent -= ::handleBack + super.onStop() + } + + private fun reloadStored() { + context?.let { ctx -> + homeViewModel.loadStoredData(ctx, WatchType.fromInternalId(ctx.getKey(HOME_BOOKMARK_VALUE))) + } + } + + private fun handleBack(poppedFragment: Boolean) { + if (poppedFragment) { + reloadStored() + } + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) fixGrid() @@ -225,9 +254,7 @@ class HomeFragment : Fragment() { } } - val adapter: RecyclerView.Adapter = ParentItemAdapter(listOf(), { card -> - activity.loadSearchResult(card) - }, { item -> + fun loadHomepageList(item: HomePageList) { val bottomSheetDialogBuilder = BottomSheetDialog(view.context) bottomSheetDialogBuilder.setContentView(R.layout.home_episodes_expanded) val title = bottomSheetDialogBuilder.findViewById(R.id.home_expanded_text)!! @@ -242,9 +269,11 @@ class HomeFragment : Fragment() { // Span settings recycle.spanCount = currentSpan - recycle.adapter = SearchAdapter(item.list, recycle) { card -> - bottomSheetDialogBuilder.dismiss() - activity.loadSearchResult(card) + recycle.adapter = SearchAdapter(item.list, recycle) { callback -> + handleSearchClickCallback(activity, callback) + if (callback.action == SEARCH_ACTION_LOAD) { + bottomSheetDialogBuilder.dismiss() + } } val spanListener = { span: Int -> @@ -261,13 +290,66 @@ class HomeFragment : Fragment() { (recycle.adapter as SearchAdapter).notifyDataSetChanged() bottomSheetDialogBuilder.show() + } + + val adapter: RecyclerView.Adapter = ParentItemAdapter(listOf(), { callback -> + handleSearchClickCallback(activity, callback) + }, { item -> + loadHomepageList(item) }) + observe(homeViewModel.availableWatchStatusTypes) { availableWatchStatusTypes -> + context?.setKey(HOME_BOOKMARK_VALUE, availableWatchStatusTypes.first.internalId) + home_bookmark_select?.setOnClickListener { + it.popupMenuNoIcons(availableWatchStatusTypes.second.map { type -> + Pair( + type.internalId, + type.stringRes + ) + }) { + homeViewModel.loadStoredData(it.context, WatchType.fromInternalId(this.itemId)) + } + } + home_bookmarked_parent_item_title?.text = getString(availableWatchStatusTypes.first.stringRes) + } + + observe(homeViewModel.bookmarks) { bookmarks -> + home_bookmarked_holder.visibility = if (bookmarks.isNotEmpty()) View.VISIBLE else View.GONE + (home_bookmarked_child_recyclerview?.adapter as HomeChildItemAdapter?)?.cardList = bookmarks + home_bookmarked_child_recyclerview?.adapter?.notifyDataSetChanged() + + home_bookmarked_child_more_info.setOnClickListener { + loadHomepageList( + HomePageList( + home_bookmarked_parent_item_title?.text?.toString() ?: getString(R.string.error_bookmarks_text), + bookmarks + ) + ) + } + } + + home_bookmarked_child_recyclerview.adapter = HomeChildItemAdapter(ArrayList()) { callback -> + if (callback.action == SEARCH_ACTION_SHOW_METADATA) { + val id = callback.card.id + if (id != null) { + callback.view.popupMenuNoIcons(listOf(Pair(0, R.string.action_remove_from_bookmarks))) { + if (itemId == 0) { + activity?.setResultWatchState(id, WatchType.NONE.internalId) + reloadStored() + } + } + } + } else { + handleSearchClickCallback(activity, callback) + } + } + context?.fixPaddingStatusbar(home_root) home_master_recycler.adapter = adapter home_master_recycler.layoutManager = GridLayoutManager(context, 1) + reloadStored() homeViewModel.load(context?.getKey(HOMEPAGE_API)) } } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapter.kt index e2618ef9..65790c6f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapter.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapter.kt @@ -9,11 +9,12 @@ import androidx.recyclerview.widget.RecyclerView import com.lagradost.cloudstream3.HomePageList import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.SearchResponse +import com.lagradost.cloudstream3.ui.search.SearchClickCallback import kotlinx.android.synthetic.main.homepage_parent.view.* class ParentItemAdapter( var items: List, - private val clickCallback: (SearchResponse) -> Unit, + private val clickCallback: (SearchClickCallback) -> Unit, private val moreInfoClickCallback: (HomePageList) -> Unit, ) : RecyclerView.Adapter() { override fun onCreateViewHolder(parent: ViewGroup, i: Int): ParentViewHolder { @@ -38,7 +39,7 @@ class ParentItemAdapter( class ParentViewHolder constructor( itemView: View, - private val clickCallback: (SearchResponse) -> Unit, + private val clickCallback: (SearchClickCallback) -> Unit, private val moreInfoClickCallback: (HomePageList) -> Unit ) : RecyclerView.ViewHolder(itemView) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeViewModel.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeViewModel.kt index 51e4d7b8..fbbfd1d3 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeViewModel.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeViewModel.kt @@ -33,15 +33,17 @@ class HomeViewModel : ViewModel() { return APIRepository(apis.first { it.hasMainPage }) } - private val availableWatchStatusTypes = MutableLiveData>>() - private val bookmarks = MutableLiveData>() + private val _availableWatchStatusTypes = MutableLiveData>>() + val availableWatchStatusTypes: LiveData>> = _availableWatchStatusTypes + private val _bookmarks = MutableLiveData>() + val bookmarks: LiveData> = _bookmarks fun loadStoredData(context: Context, preferredWatchStatus: WatchType?) = viewModelScope.launch { val watchStatusIds = withContext(Dispatchers.IO) { context.getAllWatchStateIds().map { id -> Pair(id, context.getResultWatchState(id)) } - } + }.distinctBy { it.first } val length = WatchType.values().size val currentWatchTypes = HashSet() @@ -52,21 +54,28 @@ class HomeViewModel : ViewModel() { } } + currentWatchTypes.remove(WatchType.NONE) + if (currentWatchTypes.size <= 0) { - bookmarks.postValue(ArrayList()) + _bookmarks.postValue(ArrayList()) return@launch } - val watchStatus = preferredWatchStatus ?: currentWatchTypes.first() - availableWatchStatusTypes.postValue( + val watchPrefNotNull = preferredWatchStatus ?: currentWatchTypes.first() + val watchStatus = + if (currentWatchTypes.contains(watchPrefNotNull)) watchPrefNotNull else currentWatchTypes.first() + _availableWatchStatusTypes.postValue( Pair( watchStatus, currentWatchTypes.sortedBy { it.internalId }.toList() ) ) val list = withContext(Dispatchers.IO) { - watchStatusIds.map { context.getBookmarkedData(it.first) } + watchStatusIds.filter { it.second == watchStatus } + .mapNotNull { context.getBookmarkedData(it.first) } + .sortedBy { -it.latestUpdatedTime } } + _bookmarks.postValue(list) } fun load(api: MainAPI?) = viewModelScope.launch { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt index 472ccf61..84b5c6cf 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt @@ -117,7 +117,7 @@ class EpisodeAdapter( class EpisodeCardViewHolder constructor( itemView: View, - val hasDownloadSupport: Boolean, + private val hasDownloadSupport: Boolean, private val clickCallback: (EpisodeClickEvent) -> Unit, private val downloadClickCallback: (DownloadClickEvent) -> Unit, ) : RecyclerView.ViewHolder(itemView), DownloadButtonViewHolder { @@ -129,8 +129,8 @@ class EpisodeAdapter( private val episodeProgress: ContentLoadingProgressBar? = itemView.episode_progress private val episodePoster: ImageView? = itemView.episode_poster - val episodeDownloadBar: ContentLoadingProgressBar = itemView.result_episode_progress_downloaded - val episodeDownloadImage: ImageView = itemView.result_episode_download + private val episodeDownloadBar: ContentLoadingProgressBar = itemView.result_episode_progress_downloaded + private val episodeDownloadImage: ImageView = itemView.result_episode_download private val episodeHolder = itemView.episode_holder diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchAdaptor.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchAdaptor.kt index c835a0aa..3dda63f6 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchAdaptor.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchAdaptor.kt @@ -1,5 +1,6 @@ package com.lagradost.cloudstream3.ui.search +import android.app.Activity import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -24,12 +25,16 @@ import kotlinx.android.synthetic.main.search_result_compact.view.imageView import kotlinx.android.synthetic.main.search_result_grid.view.* import kotlin.math.roundToInt +const val SEARCH_ACTION_LOAD = 0 +const val SEARCH_ACTION_SHOW_METADATA = 1 + +class SearchClickCallback(val action: Int, val view: View, val card: SearchResponse) + class SearchAdapter( var cardList: List, private val resView: AutofitRecyclerView, - private val clickCallback: (SearchResponse) -> Unit, -) : - RecyclerView.Adapter() { + private val clickCallback: (SearchClickCallback) -> Unit, +) : RecyclerView.Adapter() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { val layout = parent.context.getGridFormatId() @@ -54,7 +59,11 @@ class SearchAdapter( } class CardViewHolder - constructor(itemView: View, private val clickCallback: (SearchResponse) -> Unit, resView: AutofitRecyclerView) : + constructor( + itemView: View, + private val clickCallback: (SearchClickCallback) -> Unit, + resView: AutofitRecyclerView + ) : RecyclerView.ViewHolder(itemView) { val cardView: ImageView = itemView.imageView private val cardText: TextView = itemView.imageText @@ -105,7 +114,12 @@ class SearchAdapter( } bg.setOnClickListener { - clickCallback.invoke(card) + clickCallback.invoke(SearchClickCallback(SEARCH_ACTION_LOAD, it, card)) + } + + bg.setOnLongClickListener { + clickCallback.invoke(SearchClickCallback(SEARCH_ACTION_SHOW_METADATA, it, card)) + return@setOnLongClickListener true } when (card) { @@ -121,7 +135,6 @@ class SearchAdapter( } } } - } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt index 33aab033..89500368 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt @@ -9,7 +9,6 @@ import android.view.ViewGroup import android.view.WindowManager import android.view.inputmethod.InputMethodManager import android.widget.ImageView -import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.appcompat.widget.SearchView import androidx.fragment.app.Fragment @@ -24,11 +23,9 @@ import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar import com.lagradost.cloudstream3.utils.UIHelper.getGridIsCompact import com.lagradost.cloudstream3.mvvm.Resource import com.lagradost.cloudstream3.mvvm.observe -import com.lagradost.cloudstream3.utils.AppUtils.loadSearchResult import kotlinx.android.synthetic.main.fragment_search.* class SearchFragment : Fragment() { - private lateinit var searchViewModel: SearchViewModel override fun onCreateView( @@ -77,8 +74,8 @@ class SearchFragment : Fragment() { SearchAdapter( ArrayList(), cardSpace, - ) { card -> - activity.loadSearchResult(card) + ) { callback -> + SearchHelper.handleSearchClickCallback(activity, callback) } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchHelper.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchHelper.kt new file mode 100644 index 00000000..bc2ce06c --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchHelper.kt @@ -0,0 +1,21 @@ +package com.lagradost.cloudstream3.ui.search + +import android.app.Activity +import android.widget.Toast +import com.lagradost.cloudstream3.utils.AppUtils.loadSearchResult + +object SearchHelper { + fun handleSearchClickCallback(activity: Activity?, callback: SearchClickCallback) { + val card = callback.card + when (callback.action) { + SEARCH_ACTION_LOAD -> { + activity.loadSearchResult(card) + } + SEARCH_ACTION_SHOW_METADATA -> { + activity?.let { act -> + Toast.makeText(act, callback.card.name, Toast.LENGTH_SHORT).show() + } + } + } + } +} \ No newline at end of file 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 cd9b1d31..a03b4a06 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/DataStoreHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/DataStoreHelper.kt @@ -6,6 +6,7 @@ import com.lagradost.cloudstream3.TvType import com.lagradost.cloudstream3.ui.WatchType import com.lagradost.cloudstream3.utils.DataStore.getKey import com.lagradost.cloudstream3.utils.DataStore.getKeys +import com.lagradost.cloudstream3.utils.DataStore.removeKey import com.lagradost.cloudstream3.utils.DataStore.setKey const val VIDEO_POS_DUR = "video_pos_dur" @@ -27,9 +28,9 @@ object DataStoreHelper { } data class BookmarkedData( - val parentId: Int, - val bookmarkedTime : Long, - val latestUpdatedTime : Long, + override val id: Int?, + val bookmarkedTime: Long, + val latestUpdatedTime: Long, override val name: String, override val url: String, override val apiName: String, @@ -42,17 +43,19 @@ object DataStoreHelper { fun Context.getAllWatchStateIds(): List { val folder = "$currentAccount/$RESULT_WATCH_STATE" - return getKeys(folder).mapNotNull { it.removePrefix(folder).toIntOrNull() } + return getKeys(folder).mapNotNull { + it.removePrefix("$folder/").toIntOrNull() + } } fun Context.setBookmarkedData(id: Int?, data: BookmarkedData) { if (id == null) return - setKey("$currentAccount/$RESULT_WATCH_STATE", id.toString(), data) + setKey("$currentAccount/$RESULT_WATCH_STATE_DATA", id.toString(), data) } fun Context.getBookmarkedData(id: Int?): BookmarkedData? { if (id == null) return null - return getKey("$currentAccount/$RESULT_WATCH_STATE", id.toString()) + return getKey("$currentAccount/$RESULT_WATCH_STATE_DATA", id.toString()) } fun Context.setViewPos(id: Int?, pos: Long, dur: Long) { @@ -66,7 +69,13 @@ object DataStoreHelper { fun Context.setResultWatchState(id: Int?, status: Int) { if (id == null) return - setKey("$currentAccount/$RESULT_WATCH_STATE", id.toString(), status) + val folder = "$currentAccount/$RESULT_WATCH_STATE" + if (status == WatchType.NONE.internalId) { + removeKey(folder, id.toString()) + removeKey("$currentAccount/$RESULT_WATCH_STATE_DATA", id.toString()) + } else { + setKey(folder, id.toString(), status) + } } fun Context.getResultWatchState(id: Int): WatchType { diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 78c3bb93..ed2cdbe9 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -207,6 +207,8 @@ @@ -217,6 +219,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> Background blur Background Shadow Filter Bookmarks + Bookmarks + Remove \ No newline at end of file