diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt index 80f42ac8..b5ab4769 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt @@ -555,6 +555,7 @@ enum class TvType { Documentary, AsianDrama, Live, + Others } // IN CASE OF FUTURE ANIME MOVIE OR SMTH diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt index b2b37b72..9d8b43b1 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt @@ -424,71 +424,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { override fun onCreate(savedInstanceState: Bundle?) { app.initClient(this) - - // Parallelize to speed up startup - ioSafe { - val settingsManager = PreferenceManager.getDefaultSharedPreferences(this@MainActivity) - if (settingsManager.getBoolean(getString(R.string.auto_update_plugins_key), true)) { - PluginManager.updateAllOnlinePluginsAndLoadThem(this@MainActivity) - } else { - PluginManager.loadAllOnlinePlugins(this@MainActivity) - } - - PluginManager.loadAllLocalPlugins(this@MainActivity) - } - -// ioSafe { -// val plugins = -// RepositoryParser.getRepoPlugins("https://raw.githubusercontent.com/recloudstream/TestPlugin/master/repo.json") -// ?: emptyList() -// plugins.map { -// println("Load plugin: ${it.name} ${it.url}") -// RepositoryParser.loadSiteTemp(applicationContext, it.url, it.name) -// } -// } - - // init accounts - ioSafe { - for (api in accountManagers) { - api.init() - } - } - - ioSafe { - inAppAuths.apmap { api -> - try { - api.initialize() - } catch (e: Exception) { - logError(e) - } - } - } - - SearchResultBuilder.updateCache(this) - - ioSafe { - initAll() - apis = allProviders - try { - getKey>(USER_PROVIDER_API)?.let { list -> - list.forEach { custom -> - allProviders.firstOrNull { it.javaClass.simpleName == custom.parentJavaClass } - ?.let { - allProviders.add(it.javaClass.newInstance().apply { - name = custom.name - lang = custom.lang - mainUrl = custom.url.trimEnd('/') - canBeOverridden = false - }) - } - } - } - apis = allProviders - APIHolder.apiMap = null - } catch (e: Exception) { - logError(e) - } - } + val settingsManager = PreferenceManager.getDefaultSharedPreferences(this) loadThemes(this) updateLocale() @@ -511,6 +447,65 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { changeStatusBarState(isEmulatorSettings()) + if (settingsManager.getBoolean(getString(R.string.auto_update_plugins_key), true)) { + PluginManager.updateAllOnlinePluginsAndLoadThem(this) + } else { + PluginManager.loadAllOnlinePlugins(this) + } + + PluginManager.loadAllLocalPlugins(this) + +// ioSafe { +// val plugins = +// RepositoryParser.getRepoPlugins("https://raw.githubusercontent.com/recloudstream/TestPlugin/master/repo.json") +// ?: emptyList() +// plugins.map { +// println("Load plugin: ${it.name} ${it.url}") +// RepositoryParser.loadSiteTemp(applicationContext, it.url, it.name) +// } +// } + + // init accounts + for (api in accountManagers) { + api.init() + } + + ioSafe { + inAppAuths.apmap { api -> + try { + api.initialize() + } catch (e: Exception) { + logError(e) + } + } + } + + SearchResultBuilder.updateCache(this) + + + initAll() + apis = allProviders + + try { + getKey>(USER_PROVIDER_API)?.let { list -> + list.forEach { custom -> + allProviders.firstOrNull { it.javaClass.simpleName == custom.parentJavaClass } + ?.let { + allProviders.add(it.javaClass.newInstance().apply { + name = custom.name + lang = custom.lang + mainUrl = custom.url.trimEnd('/') + canBeOverridden = false + }) + } + } + } + apis = allProviders + APIHolder.apiMap = null + } catch (e: Exception) { + logError(e) + } + // val navView: BottomNavigationView = findViewById(R.id.nav_view) setUpBackup() @@ -658,7 +653,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { handleAppIntent(intent) - ioSafe { + thread { runAutoUpdate() } 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 347a8d1a..3a5d99da 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 @@ -42,6 +42,7 @@ import com.lagradost.cloudstream3.ui.AutofitRecyclerView import com.lagradost.cloudstream3.ui.WatchType import com.lagradost.cloudstream3.ui.quicksearch.QuickSearchFragment import com.lagradost.cloudstream3.ui.result.START_ACTION_RESUME_LATEST +import com.lagradost.cloudstream3.ui.result.setLinearListLayout import com.lagradost.cloudstream3.ui.search.* import com.lagradost.cloudstream3.ui.search.SearchHelper.handleSearchClickCallback import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings @@ -251,6 +252,7 @@ class HomeFragment : Fragment() { movies: MaterialButton?, asian: MaterialButton?, livestream: MaterialButton?, + others: MaterialButton?, ): List>> { return listOf( Pair(anime, listOf(TvType.Anime, TvType.OVA, TvType.AnimeMovie)), @@ -260,6 +262,7 @@ class HomeFragment : Fragment() { Pair(movies, listOf(TvType.Movie, TvType.Torrent)), Pair(asian, listOf(TvType.AsianDrama)), Pair(livestream, listOf(TvType.Live)), + Pair(others, listOf(TvType.Others)), ) } @@ -294,10 +297,11 @@ class HomeFragment : Fragment() { val movies = dialog.findViewById(R.id.home_select_movies) val asian = dialog.findViewById(R.id.home_select_asian) val livestream = dialog.findViewById(R.id.home_select_livestreams) + val others = dialog.findViewById(R.id.home_select_others) val cancelBtt = dialog.findViewById(R.id.cancel_btt) val applyBtt = dialog.findViewById(R.id.apply_btt) - val pairList = getPairList(anime, cartoons, tvs, docs, movies, asian, livestream) + val pairList = getPairList(anime, cartoons, tvs, docs, movies, asian, livestream, others) cancelBtt?.setOnClickListener { dialog.dismissSafe() @@ -519,6 +523,16 @@ class HomeFragment : Fragment() { } } + home_main_poster_recyclerview?.adapter = + HomeChildItemAdapter( + mutableListOf(), + R.layout.home_result_big_grid, + nextFocusUp = home_main_poster_recyclerview.nextFocusUpId, + nextFocusDown = home_main_poster_recyclerview.nextFocusDownId + ) { callback -> + homeHandleSearch(callback) + } + home_main_poster_recyclerview.setLinearListLayout() observe(homeViewModel.randomItems) { items -> if (items.isNullOrEmpty()) { toggleMainVisibility(false) @@ -531,15 +545,7 @@ class HomeFragment : Fragment() { } val randomSize = items.size - home_main_poster_recyclerview?.adapter = - HomeChildItemAdapter( - items.toMutableList(), - R.layout.home_result_big_grid, - nextFocusUp = home_main_poster_recyclerview.nextFocusUpId, - nextFocusDown = home_main_poster_recyclerview.nextFocusDownId - ) { callback -> - homeHandleSearch(callback) - } + tempAdapter?.updateList(items) if (context?.isTvSettings() == false) { home_main_poster_recyclerview?.post { (home_main_poster_recyclerview?.layoutManager as CenterZoomLayoutManager?)?.let { manager -> @@ -813,6 +819,8 @@ class HomeFragment : Fragment() { homeHandleSearch(callback) } } + home_watch_child_recyclerview.setLinearListLayout() + home_bookmarked_child_recyclerview.setLinearListLayout() home_watch_child_recyclerview?.adapter = HomeChildItemAdapter( ArrayList(), @@ -901,6 +909,7 @@ class HomeFragment : Fragment() { }, { name -> homeViewModel.expand(name) }) + home_master_recycler.setLinearListLayout() home_master_recycler?.setMaxViewPoolSize(0, Int.MAX_VALUE) home_master_recycler.layoutManager = object : LinearLayoutManager(context) { override fun supportsPredictiveItemAnimations(): Boolean { 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 4f113eba..3fc1da24 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 @@ -10,6 +10,8 @@ import androidx.recyclerview.widget.ListUpdateCallback import androidx.recyclerview.widget.RecyclerView import com.lagradost.cloudstream3.HomePageList import com.lagradost.cloudstream3.R +import com.lagradost.cloudstream3.ui.result.LinearListLayout +import com.lagradost.cloudstream3.ui.result.setLinearListLayout import com.lagradost.cloudstream3.ui.search.SearchClickCallback import com.lagradost.cloudstream3.ui.search.SearchFragment.Companion.filterSearchResponse import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings @@ -153,6 +155,7 @@ class ParentItemAdapter( ).apply { isHorizontal = info.isHorizontalImages } + recyclerView.setLinearListLayout() } } @@ -167,7 +170,7 @@ class ParentItemAdapter( isHorizontal = info.isHorizontalImages hasNext = expand.hasNext } - + recyclerView.setLinearListLayout() title.text = info.name recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() { 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 9acae56b..075e6cf5 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 @@ -4,6 +4,7 @@ import android.annotation.SuppressLint import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.FrameLayout import android.widget.ImageView import android.widget.TextView import androidx.annotation.LayoutRes @@ -75,9 +76,12 @@ class EpisodeAdapter( } override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) { - if(holder.itemView.hasFocus()) { + if (holder.itemView.hasFocus()) { holder.itemView.clearFocus() } + //(holder.itemView as? FrameLayout?)?.descendantFocusability = + // ViewGroup.FOCUS_BLOCK_DESCENDANTS + if (holder is DownloadButtonViewHolder) { holder.downloadButton.dispose() } @@ -87,11 +91,20 @@ class EpisodeAdapter( if (holder is DownloadButtonViewHolder) { holder.downloadButton.dispose() mBoundViewHolders.remove(holder) + //(holder.itemView as? FrameLayout?)?.descendantFocusability = + // ViewGroup.FOCUS_BLOCK_DESCENDANTS } } override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) { if (holder is DownloadButtonViewHolder) { + //println("onViewAttachedToWindow = ${holder.absoluteAdapterPosition}") + //holder.itemView.post { + // if (holder.itemView.isAttachedToWindow) + // (holder.itemView as? FrameLayout?)?.descendantFocusability = + // ViewGroup.FOCUS_AFTER_DESCENDANTS + //} + holder.reattachDownloadButton() } } @@ -145,7 +158,6 @@ class EpisodeAdapter( ) : RecyclerView.ViewHolder(itemView), DownloadButtonViewHolder { override var downloadButton = EasyDownloadButton() - var episodeDownloadBar: ContentLoadingProgressBar? = null var episodeDownloadImage: ImageView? = null var localCard: ResultEpisode? = null @@ -217,17 +229,17 @@ class EpisodeAdapter( } } - parentView.setOnClickListener { + itemView.setOnClickListener { clickCallback.invoke(EpisodeClickEvent(ACTION_CLICK_DEFAULT, card)) } if (isTrueTv) { - parentView.isFocusable = true - parentView.isFocusableInTouchMode = true - parentView.touchscreenBlocksFocus = false + itemView.isFocusable = true + itemView.isFocusableInTouchMode = true + //itemView.touchscreenBlocksFocus = false } - parentView.setOnLongClickListener { + itemView.setOnLongClickListener { clickCallback.invoke(EpisodeClickEvent(ACTION_SHOW_OPTIONS, card)) return@setOnLongClickListener true @@ -242,6 +254,9 @@ class EpisodeAdapter( downloadButton.dispose() val card = localCard if (hasDownloadSupport && card != null) { + if (episodeDownloadBar == null || + episodeDownloadImage == null + ) return val downloadInfo = VideoDownloadManager.getDownloadFileInfoAndUpdateSettings( itemView.context, card.id diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/LinearListLayout.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/LinearListLayout.kt new file mode 100644 index 00000000..59a46264 --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/LinearListLayout.kt @@ -0,0 +1,129 @@ +package com.lagradost.cloudstream3.ui.result + +import android.content.Context +import android.view.View +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.lagradost.cloudstream3.mvvm.logError + +fun RecyclerView?.setLinearListLayout(isHorizontal: Boolean = true) { + if(this == null) return + this.layoutManager = + this.context?.let { LinearListLayout(it).apply { if (isHorizontal) setHorizontal() else setVertical() } } + ?: this.layoutManager +} + +class LinearListLayout(context: Context?) : + LinearLayoutManager(context) { + + fun setHorizontal() { + orientation = HORIZONTAL + } + + fun setVertical() { + orientation = VERTICAL + } + + private fun getCorrectParent(focused: View): View? { + var current: View? = focused + val last: ArrayList = arrayListOf(focused) + while (current != null && current !is RecyclerView) { + current = (current.parent as? View?)?.also { last.add(it) } + } + return last.getOrNull(last.count() - 2) + } + + private fun getPosition(view: View?): Int? { + return (view?.layoutParams as? RecyclerView.LayoutParams?)?.absoluteAdapterPosition + } + + private fun getViewFromPos(pos: Int): View? { + for (i in 0 until childCount) { + val child = getChildAt(i) + if ((child?.layoutParams as? RecyclerView.LayoutParams?)?.absoluteAdapterPosition == pos) { + return child + } + } + return null + //return recyclerView.children.firstOrNull { child -> (child.layoutParams as? RecyclerView.LayoutParams?)?.absoluteAdapterPosition == pos) } + } + + /* + private fun scrollTo(position: Int) { + val linearSmoothScroller = LinearSmoothScroller(recyclerView.context) + linearSmoothScroller.targetPosition = position + startSmoothScroll(linearSmoothScroller) + }*/ + + override fun onInterceptFocusSearch(focused: View, direction: Int): View? { + val dir = if (orientation == HORIZONTAL) { + if (direction == View.FOCUS_DOWN || direction == View.FOCUS_UP) return null + if (direction == View.FOCUS_RIGHT) 1 else -1 + } else { + if (direction == View.FOCUS_RIGHT || direction == View.FOCUS_LEFT) return null + if (direction == View.FOCUS_DOWN) 1 else -1 + } + + return try { + getPosition(getCorrectParent(focused))?.let { position -> + val lookfor = dir + position + //clamp(dir + position, 0, recyclerView.adapter?.itemCount ?: return null) + getViewFromPos(lookfor) ?: run { + scrollToPosition(lookfor) + null + } + } + } catch (e: Exception) { + logError(e) + null + } + } + + /*override fun onRequestChildFocus( + parent: RecyclerView, + state: RecyclerView.State, + child: View, + focused: View? + ): Boolean { + return super.onRequestChildFocus(parent, state, child, focused) + getPosition(getCorrectParent(focused ?: return true))?.let { + val startView = findFirstVisibleChildClosestToStart(true,true) + val endView = findFirstVisibleChildClosestToEnd(true,true) + val start = getPosition(startView) + val end = getPosition(endView) + fill(parent,LayoutState()) + + val helper = mOrientationHelper ?: return false + val laidOutArea: Int = abs( + helper.getDecoratedEnd(startView) + - helper.getDecoratedStart(endView) + ) + val itemRange: Int = abs( + (start + - end) + ) + 1 + + val avgSizePerRow = laidOutArea.toFloat() / itemRange + + return Math.round( + itemsBefore * avgSizePerRow + ((orientation.getStartAfterPadding() + - orientation.getDecoratedStart(startChild))) + ) + recyclerView.scrollToPosition(it) + } + return true*/ + + //return super.onRequestChildFocus(parent, state, child, focused) + /* if (focused == null || focused == child) { + return super.onRequestChildFocus(parent, state, child, focused) + } + + try { + val pos = getPosition(getCorrectParent(focused) ?: return true) + scrollToPosition(pos) + } catch (e: Exception) { + logError(e) + } + return true +}*/ +} \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt index eb23d3ea..5cb8f410 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt @@ -471,31 +471,6 @@ open class ResultFragment : ResultTrailerPlayer() { syncModel.addFromUrl(url) val api = getApiFromName(apiName) - if (media_route_button != null) { - val chromecastSupport = api.hasChromecastSupport - media_route_button?.alpha = if (chromecastSupport) 1f else 0.3f - if (!chromecastSupport) { - media_route_button?.setOnClickListener { - showToast(activity, R.string.no_chromecast_support_toast, Toast.LENGTH_LONG) - } - } - activity?.let { act -> - if (act.isCastApiAvailable()) { - try { - CastButtonFactory.setUpMediaRouteButton(act, media_route_button) - val castContext = CastContext.getSharedInstance(act.applicationContext) - media_route_button?.isGone = - castContext.castState == CastState.NO_DEVICES_AVAILABLE - // this shit leaks for some reason - //castContext.addCastStateListener { state -> - // media_route_button?.isGone = state == CastState.NO_DEVICES_AVAILABLE - //} - } catch (e: Exception) { - logError(e) - } - } - } - } result_episodes?.adapter = EpisodeAdapter( 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 750556ad..7f4e0ee0 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 @@ -5,23 +5,26 @@ import android.graphics.Rect import android.os.Bundle import android.view.View import android.view.ViewGroup +import android.widget.Toast import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.core.widget.NestedScrollView import com.discord.panels.OverlappingPanelsLayout import com.discord.panels.PanelsChildGestureRegionObserver +import com.google.android.gms.cast.framework.CastButtonFactory +import com.google.android.gms.cast.framework.CastContext +import com.google.android.gms.cast.framework.CastState import com.google.android.material.bottomsheet.BottomSheetDialog +import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.APIHolder.updateHasTrailers -import com.lagradost.cloudstream3.DubStatus -import com.lagradost.cloudstream3.LoadResponse -import com.lagradost.cloudstream3.R -import com.lagradost.cloudstream3.SearchResponse import com.lagradost.cloudstream3.mvvm.Some +import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.observe import com.lagradost.cloudstream3.ui.WatchType import com.lagradost.cloudstream3.ui.player.CSPlayerEvent import com.lagradost.cloudstream3.ui.search.SearchAdapter import com.lagradost.cloudstream3.ui.search.SearchHelper +import com.lagradost.cloudstream3.utils.AppUtils.isCastApiAvailable import com.lagradost.cloudstream3.utils.AppUtils.openBrowser import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog @@ -125,6 +128,8 @@ class ResultFragmentPhone : ResultFragment() { } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + val apiName = arguments?.getString(API_NAME_BUNDLE) ?: return + super.onViewCreated(view, savedInstanceState) player_open_source?.setOnClickListener { @@ -192,6 +197,37 @@ class ResultFragmentPhone : ResultFragment() { } //result_poster_blur_holder?.translationY = -scrollY.toFloat() }) + val api = APIHolder.getApiFromName(apiName) + + if (media_route_button != null) { + val chromecastSupport = api.hasChromecastSupport + media_route_button?.alpha = if (chromecastSupport) 1f else 0.3f + if (!chromecastSupport) { + media_route_button?.setOnClickListener { + CommonActivity.showToast( + activity, + R.string.no_chromecast_support_toast, + Toast.LENGTH_LONG + ) + } + } + activity?.let { act -> + if (act.isCastApiAvailable()) { + try { + CastButtonFactory.setUpMediaRouteButton(act, media_route_button) + val castContext = CastContext.getSharedInstance(act.applicationContext) + media_route_button?.isGone = + castContext.castState == CastState.NO_DEVICES_AVAILABLE + // this shit leaks for some reason + //castContext.addCastStateListener { state -> + // media_route_button?.isGone = state == CastState.NO_DEVICES_AVAILABLE + //} + } catch (e: Exception) { + logError(e) + } + } + } + } observe(viewModel.episodesCountText) { count -> result_episodes_text.setText(count) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentTv.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentTv.kt index 895f0724..0e3ee53e 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentTv.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentTv.kt @@ -3,6 +3,7 @@ package com.lagradost.cloudstream3.ui.result import android.app.Dialog import android.os.Bundle import android.view.View +import android.widget.LinearLayout import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.recyclerview.widget.RecyclerView @@ -15,10 +16,17 @@ import com.lagradost.cloudstream3.mvvm.Some import com.lagradost.cloudstream3.mvvm.observe import com.lagradost.cloudstream3.ui.search.SearchAdapter import com.lagradost.cloudstream3.ui.search.SearchHelper +import com.lagradost.cloudstream3.utils.AppUtils.setMaxViewPoolSize import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialogInstant import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe import com.lagradost.cloudstream3.utils.UIHelper.popCurrentPage +import kotlinx.android.synthetic.main.fragment_home.* +import kotlinx.android.synthetic.main.fragment_result.* import kotlinx.android.synthetic.main.fragment_result_tv.* +import kotlinx.android.synthetic.main.fragment_result_tv.result_episodes +import kotlinx.android.synthetic.main.fragment_result_tv.result_episodes_text +import kotlinx.android.synthetic.main.fragment_result_tv.result_play_movie +import kotlinx.android.synthetic.main.fragment_result_tv.result_root class ResultFragmentTv : ResultFragment() { override val resultLayout = R.layout.fragment_result_tv @@ -95,13 +103,21 @@ class ResultFragmentTv : ResultFragment() { result_recommendations_filter_selection?.isVisible = false } } + var loadingDialog: Dialog? = null var popupDialog: Dialog? = null override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + + result_episodes?.layoutManager = + //LinearListLayout(result_episodes ?: return, result_episodes?.context).apply { + LinearListLayout(result_episodes?.context).apply { + setHorizontal() + } (result_episodes?.adapter as EpisodeAdapter?)?.apply { layout = R.layout.result_episode_both_tv } + //result_episodes?.setMaxViewPoolSize(0, Int.MAX_VALUE) result_season_selection.setAdapter() result_range_selection.setAdapter() 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 cf12fab0..eed7a65c 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 @@ -197,6 +197,7 @@ fun LoadResponse.toResultData(repo: APIRepository): ResultData { TvType.Torrent -> R.string.torrent_singular TvType.AsianDrama -> R.string.asian_drama_singular TvType.Live -> R.string.live_singular + TvType.Others -> R.string.other_singular } ), yearText = txt(year?.toString()), @@ -549,6 +550,7 @@ class ResultViewModel2 : ViewModel() { TvType.Documentary -> "Documentaries" TvType.AsianDrama -> "AsianDrama" TvType.Live -> "LiveStreams" + TvType.Others -> "Others" } } 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 d05d8807..7616cb97 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 @@ -169,6 +169,7 @@ class SearchFragment : Fragment() { val asian = dialog.findViewById(R.id.home_select_asian) val livestream = dialog.findViewById(R.id.home_select_livestreams) + val other = dialog.findViewById(R.id.home_select_others) val cancelBtt = dialog.findViewById(R.id.cancel_btt) val applyBtt = dialog.findViewById(R.id.apply_btt) @@ -180,7 +181,8 @@ class SearchFragment : Fragment() { docs, movies, asian, - livestream + livestream, + other ) cancelBtt?.setOnClickListener { @@ -297,7 +299,8 @@ class SearchFragment : Fragment() { search_select_documentaries, search_select_movies, search_select_asian, - search_select_livestreams + search_select_livestreams, + search_select_others ) val settingsManager = context?.let { PreferenceManager.getDefaultSharedPreferences(it) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/PluginsFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/PluginsFragment.kt index 4d053606..8bc980ed 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/PluginsFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/PluginsFragment.kt @@ -112,7 +112,8 @@ class PluginsFragment : Fragment() { home_select_documentaries, home_select_movies, home_select_asian, - home_select_livestreams + home_select_livestreams, + home_select_others ) // Copy pasted code diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/PluginsViewModel.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/PluginsViewModel.kt index c83cc31d..9cb844fb 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/PluginsViewModel.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/PluginsViewModel.kt @@ -175,7 +175,10 @@ class PluginsViewModel : ViewModel() { // Perhaps can be optimized? private fun List.filterTvTypes(): List { if (tvTypes.isEmpty()) return this - return this.filter { it.plugin.second.tvTypes?.any { type -> tvTypes.contains(type) } == true } + return this.filter { + (it.plugin.second.tvTypes?.any { type -> tvTypes.contains(type) } == true) || + (tvTypes.contains("Others") && (it.plugin.second.tvTypes ?: emptyList()).isEmpty()) + } } private fun List.sortByQuery(query: String?): List { diff --git a/app/src/main/res/layout/fragment_plugins.xml b/app/src/main/res/layout/fragment_plugins.xml index 43576ca9..45255d6d 100644 --- a/app/src/main/res/layout/fragment_plugins.xml +++ b/app/src/main/res/layout/fragment_plugins.xml @@ -110,6 +110,12 @@ android:nextFocusLeft="@id/home_select_documentaries" android:text="@string/livestreams" /> + + diff --git a/app/src/main/res/layout/fragment_result.xml b/app/src/main/res/layout/fragment_result.xml index 35e78c7f..47f82f46 100644 --- a/app/src/main/res/layout/fragment_result.xml +++ b/app/src/main/res/layout/fragment_result.xml @@ -917,7 +917,7 @@ app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" android:descendantFocusability="afterDescendants" android:paddingBottom="100dp" - tools:listitem="@layout/result_episode" /> + tools:listitem="@layout/result_episode_both_tv" /> diff --git a/app/src/main/res/layout/fragment_search.xml b/app/src/main/res/layout/fragment_search.xml index fb1d6e41..cb816083 100644 --- a/app/src/main/res/layout/fragment_search.xml +++ b/app/src/main/res/layout/fragment_search.xml @@ -146,6 +146,12 @@ style="@style/RoundedSelectableButton" android:nextFocusLeft="@id/search_select_documentaries" android:text="@string/livestreams" /> + + diff --git a/app/src/main/res/layout/home_select_mainpage.xml b/app/src/main/res/layout/home_select_mainpage.xml index 99ee4fe2..d03234c1 100644 --- a/app/src/main/res/layout/home_select_mainpage.xml +++ b/app/src/main/res/layout/home_select_mainpage.xml @@ -104,6 +104,12 @@ android:nextFocusLeft="@id/home_select_documentaries" android:text="@string/livestreams" /> + + diff --git a/app/src/main/res/layout/result_episode.xml b/app/src/main/res/layout/result_episode.xml index 39521594..127cbd34 100644 --- a/app/src/main/res/layout/result_episode.xml +++ b/app/src/main/res/layout/result_episode.xml @@ -11,7 +11,6 @@ app:cardCornerRadius="@dimen/rounded_image_radius" app:cardBackgroundColor="@color/transparent" app:cardElevation="0dp" - android:foreground="@drawable/outline_drawable" android:layout_marginBottom="5dp"> Movie @@ -344,6 +345,7 @@ Documentary Asian Drama Livestream + Video Source error Remote error