forked from recloudstream/cloudstream
Merge remote-tracking branch 'origin/master'
# Conflicts: # app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt
This commit is contained in:
commit
d64bf911e8
25 changed files with 368 additions and 129 deletions
|
@ -555,6 +555,7 @@ enum class TvType {
|
||||||
Documentary,
|
Documentary,
|
||||||
AsianDrama,
|
AsianDrama,
|
||||||
Live,
|
Live,
|
||||||
|
Others
|
||||||
}
|
}
|
||||||
|
|
||||||
// IN CASE OF FUTURE ANIME MOVIE OR SMTH
|
// IN CASE OF FUTURE ANIME MOVIE OR SMTH
|
||||||
|
|
|
@ -424,71 +424,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
app.initClient(this)
|
app.initClient(this)
|
||||||
|
val settingsManager = PreferenceManager.getDefaultSharedPreferences(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<Array<SettingsGeneral.CustomSite>>(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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
loadThemes(this)
|
loadThemes(this)
|
||||||
updateLocale()
|
updateLocale()
|
||||||
|
@ -511,6 +447,65 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
||||||
|
|
||||||
changeStatusBarState(isEmulatorSettings())
|
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<Array<SettingsGeneral.CustomSite>>(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)
|
// val navView: BottomNavigationView = findViewById(R.id.nav_view)
|
||||||
setUpBackup()
|
setUpBackup()
|
||||||
|
|
||||||
|
@ -658,7 +653,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
||||||
|
|
||||||
handleAppIntent(intent)
|
handleAppIntent(intent)
|
||||||
|
|
||||||
ioSafe {
|
thread {
|
||||||
runAutoUpdate()
|
runAutoUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ import com.lagradost.cloudstream3.ui.AutofitRecyclerView
|
||||||
import com.lagradost.cloudstream3.ui.WatchType
|
import com.lagradost.cloudstream3.ui.WatchType
|
||||||
import com.lagradost.cloudstream3.ui.quicksearch.QuickSearchFragment
|
import com.lagradost.cloudstream3.ui.quicksearch.QuickSearchFragment
|
||||||
import com.lagradost.cloudstream3.ui.result.START_ACTION_RESUME_LATEST
|
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.*
|
||||||
import com.lagradost.cloudstream3.ui.search.SearchHelper.handleSearchClickCallback
|
import com.lagradost.cloudstream3.ui.search.SearchHelper.handleSearchClickCallback
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
|
||||||
|
@ -251,6 +252,7 @@ class HomeFragment : Fragment() {
|
||||||
movies: MaterialButton?,
|
movies: MaterialButton?,
|
||||||
asian: MaterialButton?,
|
asian: MaterialButton?,
|
||||||
livestream: MaterialButton?,
|
livestream: MaterialButton?,
|
||||||
|
others: MaterialButton?,
|
||||||
): List<Pair<MaterialButton?, List<TvType>>> {
|
): List<Pair<MaterialButton?, List<TvType>>> {
|
||||||
return listOf(
|
return listOf(
|
||||||
Pair(anime, listOf(TvType.Anime, TvType.OVA, TvType.AnimeMovie)),
|
Pair(anime, listOf(TvType.Anime, TvType.OVA, TvType.AnimeMovie)),
|
||||||
|
@ -260,6 +262,7 @@ class HomeFragment : Fragment() {
|
||||||
Pair(movies, listOf(TvType.Movie, TvType.Torrent)),
|
Pair(movies, listOf(TvType.Movie, TvType.Torrent)),
|
||||||
Pair(asian, listOf(TvType.AsianDrama)),
|
Pair(asian, listOf(TvType.AsianDrama)),
|
||||||
Pair(livestream, listOf(TvType.Live)),
|
Pair(livestream, listOf(TvType.Live)),
|
||||||
|
Pair(others, listOf(TvType.Others)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,10 +297,11 @@ class HomeFragment : Fragment() {
|
||||||
val movies = dialog.findViewById<MaterialButton>(R.id.home_select_movies)
|
val movies = dialog.findViewById<MaterialButton>(R.id.home_select_movies)
|
||||||
val asian = dialog.findViewById<MaterialButton>(R.id.home_select_asian)
|
val asian = dialog.findViewById<MaterialButton>(R.id.home_select_asian)
|
||||||
val livestream = dialog.findViewById<MaterialButton>(R.id.home_select_livestreams)
|
val livestream = dialog.findViewById<MaterialButton>(R.id.home_select_livestreams)
|
||||||
|
val others = dialog.findViewById<MaterialButton>(R.id.home_select_others)
|
||||||
val cancelBtt = dialog.findViewById<MaterialButton>(R.id.cancel_btt)
|
val cancelBtt = dialog.findViewById<MaterialButton>(R.id.cancel_btt)
|
||||||
val applyBtt = dialog.findViewById<MaterialButton>(R.id.apply_btt)
|
val applyBtt = dialog.findViewById<MaterialButton>(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 {
|
cancelBtt?.setOnClickListener {
|
||||||
dialog.dismissSafe()
|
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 ->
|
observe(homeViewModel.randomItems) { items ->
|
||||||
if (items.isNullOrEmpty()) {
|
if (items.isNullOrEmpty()) {
|
||||||
toggleMainVisibility(false)
|
toggleMainVisibility(false)
|
||||||
|
@ -531,15 +545,7 @@ class HomeFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
val randomSize = items.size
|
val randomSize = items.size
|
||||||
home_main_poster_recyclerview?.adapter =
|
tempAdapter?.updateList(items)
|
||||||
HomeChildItemAdapter(
|
|
||||||
items.toMutableList(),
|
|
||||||
R.layout.home_result_big_grid,
|
|
||||||
nextFocusUp = home_main_poster_recyclerview.nextFocusUpId,
|
|
||||||
nextFocusDown = home_main_poster_recyclerview.nextFocusDownId
|
|
||||||
) { callback ->
|
|
||||||
homeHandleSearch(callback)
|
|
||||||
}
|
|
||||||
if (context?.isTvSettings() == false) {
|
if (context?.isTvSettings() == false) {
|
||||||
home_main_poster_recyclerview?.post {
|
home_main_poster_recyclerview?.post {
|
||||||
(home_main_poster_recyclerview?.layoutManager as CenterZoomLayoutManager?)?.let { manager ->
|
(home_main_poster_recyclerview?.layoutManager as CenterZoomLayoutManager?)?.let { manager ->
|
||||||
|
@ -813,6 +819,8 @@ class HomeFragment : Fragment() {
|
||||||
homeHandleSearch(callback)
|
homeHandleSearch(callback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
home_watch_child_recyclerview.setLinearListLayout()
|
||||||
|
home_bookmarked_child_recyclerview.setLinearListLayout()
|
||||||
|
|
||||||
home_watch_child_recyclerview?.adapter = HomeChildItemAdapter(
|
home_watch_child_recyclerview?.adapter = HomeChildItemAdapter(
|
||||||
ArrayList(),
|
ArrayList(),
|
||||||
|
@ -901,6 +909,7 @@ class HomeFragment : Fragment() {
|
||||||
}, { name ->
|
}, { name ->
|
||||||
homeViewModel.expand(name)
|
homeViewModel.expand(name)
|
||||||
})
|
})
|
||||||
|
home_master_recycler.setLinearListLayout()
|
||||||
home_master_recycler?.setMaxViewPoolSize(0, Int.MAX_VALUE)
|
home_master_recycler?.setMaxViewPoolSize(0, Int.MAX_VALUE)
|
||||||
home_master_recycler.layoutManager = object : LinearLayoutManager(context) {
|
home_master_recycler.layoutManager = object : LinearLayoutManager(context) {
|
||||||
override fun supportsPredictiveItemAnimations(): Boolean {
|
override fun supportsPredictiveItemAnimations(): Boolean {
|
||||||
|
|
|
@ -10,6 +10,8 @@ import androidx.recyclerview.widget.ListUpdateCallback
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.lagradost.cloudstream3.HomePageList
|
import com.lagradost.cloudstream3.HomePageList
|
||||||
import com.lagradost.cloudstream3.R
|
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.SearchClickCallback
|
||||||
import com.lagradost.cloudstream3.ui.search.SearchFragment.Companion.filterSearchResponse
|
import com.lagradost.cloudstream3.ui.search.SearchFragment.Companion.filterSearchResponse
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
||||||
|
@ -153,6 +155,7 @@ class ParentItemAdapter(
|
||||||
).apply {
|
).apply {
|
||||||
isHorizontal = info.isHorizontalImages
|
isHorizontal = info.isHorizontalImages
|
||||||
}
|
}
|
||||||
|
recyclerView.setLinearListLayout()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,7 +170,7 @@ class ParentItemAdapter(
|
||||||
isHorizontal = info.isHorizontalImages
|
isHorizontal = info.isHorizontalImages
|
||||||
hasNext = expand.hasNext
|
hasNext = expand.hasNext
|
||||||
}
|
}
|
||||||
|
recyclerView.setLinearListLayout()
|
||||||
title.text = info.name
|
title.text = info.name
|
||||||
|
|
||||||
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import android.annotation.SuppressLint
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.FrameLayout
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.annotation.LayoutRes
|
import androidx.annotation.LayoutRes
|
||||||
|
@ -78,6 +79,9 @@ class EpisodeAdapter(
|
||||||
if (holder.itemView.hasFocus()) {
|
if (holder.itemView.hasFocus()) {
|
||||||
holder.itemView.clearFocus()
|
holder.itemView.clearFocus()
|
||||||
}
|
}
|
||||||
|
//(holder.itemView as? FrameLayout?)?.descendantFocusability =
|
||||||
|
// ViewGroup.FOCUS_BLOCK_DESCENDANTS
|
||||||
|
|
||||||
if (holder is DownloadButtonViewHolder) {
|
if (holder is DownloadButtonViewHolder) {
|
||||||
holder.downloadButton.dispose()
|
holder.downloadButton.dispose()
|
||||||
}
|
}
|
||||||
|
@ -87,11 +91,20 @@ class EpisodeAdapter(
|
||||||
if (holder is DownloadButtonViewHolder) {
|
if (holder is DownloadButtonViewHolder) {
|
||||||
holder.downloadButton.dispose()
|
holder.downloadButton.dispose()
|
||||||
mBoundViewHolders.remove(holder)
|
mBoundViewHolders.remove(holder)
|
||||||
|
//(holder.itemView as? FrameLayout?)?.descendantFocusability =
|
||||||
|
// ViewGroup.FOCUS_BLOCK_DESCENDANTS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {
|
override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {
|
||||||
if (holder is DownloadButtonViewHolder) {
|
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()
|
holder.reattachDownloadButton()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,7 +158,6 @@ class EpisodeAdapter(
|
||||||
) : RecyclerView.ViewHolder(itemView), DownloadButtonViewHolder {
|
) : RecyclerView.ViewHolder(itemView), DownloadButtonViewHolder {
|
||||||
override var downloadButton = EasyDownloadButton()
|
override var downloadButton = EasyDownloadButton()
|
||||||
|
|
||||||
|
|
||||||
var episodeDownloadBar: ContentLoadingProgressBar? = null
|
var episodeDownloadBar: ContentLoadingProgressBar? = null
|
||||||
var episodeDownloadImage: ImageView? = null
|
var episodeDownloadImage: ImageView? = null
|
||||||
var localCard: ResultEpisode? = null
|
var localCard: ResultEpisode? = null
|
||||||
|
@ -217,17 +229,17 @@ class EpisodeAdapter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parentView.setOnClickListener {
|
itemView.setOnClickListener {
|
||||||
clickCallback.invoke(EpisodeClickEvent(ACTION_CLICK_DEFAULT, card))
|
clickCallback.invoke(EpisodeClickEvent(ACTION_CLICK_DEFAULT, card))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isTrueTv) {
|
if (isTrueTv) {
|
||||||
parentView.isFocusable = true
|
itemView.isFocusable = true
|
||||||
parentView.isFocusableInTouchMode = true
|
itemView.isFocusableInTouchMode = true
|
||||||
parentView.touchscreenBlocksFocus = false
|
//itemView.touchscreenBlocksFocus = false
|
||||||
}
|
}
|
||||||
|
|
||||||
parentView.setOnLongClickListener {
|
itemView.setOnLongClickListener {
|
||||||
clickCallback.invoke(EpisodeClickEvent(ACTION_SHOW_OPTIONS, card))
|
clickCallback.invoke(EpisodeClickEvent(ACTION_SHOW_OPTIONS, card))
|
||||||
|
|
||||||
return@setOnLongClickListener true
|
return@setOnLongClickListener true
|
||||||
|
@ -242,6 +254,9 @@ class EpisodeAdapter(
|
||||||
downloadButton.dispose()
|
downloadButton.dispose()
|
||||||
val card = localCard
|
val card = localCard
|
||||||
if (hasDownloadSupport && card != null) {
|
if (hasDownloadSupport && card != null) {
|
||||||
|
if (episodeDownloadBar == null ||
|
||||||
|
episodeDownloadImage == null
|
||||||
|
) return
|
||||||
val downloadInfo = VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(
|
val downloadInfo = VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(
|
||||||
itemView.context,
|
itemView.context,
|
||||||
card.id
|
card.id
|
||||||
|
|
|
@ -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<View> = 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
|
||||||
|
}*/
|
||||||
|
}
|
|
@ -471,31 +471,6 @@ open class ResultFragment : ResultTrailerPlayer() {
|
||||||
syncModel.addFromUrl(url)
|
syncModel.addFromUrl(url)
|
||||||
|
|
||||||
val api = getApiFromName(apiName)
|
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 =
|
result_episodes?.adapter =
|
||||||
EpisodeAdapter(
|
EpisodeAdapter(
|
||||||
|
|
|
@ -5,23 +5,26 @@ import android.graphics.Rect
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.core.view.isGone
|
import androidx.core.view.isGone
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.widget.NestedScrollView
|
import androidx.core.widget.NestedScrollView
|
||||||
import com.discord.panels.OverlappingPanelsLayout
|
import com.discord.panels.OverlappingPanelsLayout
|
||||||
import com.discord.panels.PanelsChildGestureRegionObserver
|
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.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
|
import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.APIHolder.updateHasTrailers
|
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.Some
|
||||||
|
import com.lagradost.cloudstream3.mvvm.logError
|
||||||
import com.lagradost.cloudstream3.mvvm.observe
|
import com.lagradost.cloudstream3.mvvm.observe
|
||||||
import com.lagradost.cloudstream3.ui.WatchType
|
import com.lagradost.cloudstream3.ui.WatchType
|
||||||
import com.lagradost.cloudstream3.ui.player.CSPlayerEvent
|
import com.lagradost.cloudstream3.ui.player.CSPlayerEvent
|
||||||
import com.lagradost.cloudstream3.ui.search.SearchAdapter
|
import com.lagradost.cloudstream3.ui.search.SearchAdapter
|
||||||
import com.lagradost.cloudstream3.ui.search.SearchHelper
|
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.AppUtils.openBrowser
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog
|
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog
|
||||||
|
@ -125,6 +128,8 @@ class ResultFragmentPhone : ResultFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
val apiName = arguments?.getString(API_NAME_BUNDLE) ?: return
|
||||||
|
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
player_open_source?.setOnClickListener {
|
player_open_source?.setOnClickListener {
|
||||||
|
@ -192,6 +197,37 @@ class ResultFragmentPhone : ResultFragment() {
|
||||||
}
|
}
|
||||||
//result_poster_blur_holder?.translationY = -scrollY.toFloat()
|
//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 ->
|
observe(viewModel.episodesCountText) { count ->
|
||||||
result_episodes_text.setText(count)
|
result_episodes_text.setText(count)
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.lagradost.cloudstream3.ui.result
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.widget.LinearLayout
|
||||||
import androidx.core.view.isGone
|
import androidx.core.view.isGone
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
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.mvvm.observe
|
||||||
import com.lagradost.cloudstream3.ui.search.SearchAdapter
|
import com.lagradost.cloudstream3.ui.search.SearchAdapter
|
||||||
import com.lagradost.cloudstream3.ui.search.SearchHelper
|
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.SingleSelectionHelper.showBottomDialogInstant
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
|
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.popCurrentPage
|
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.*
|
||||||
|
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() {
|
class ResultFragmentTv : ResultFragment() {
|
||||||
override val resultLayout = R.layout.fragment_result_tv
|
override val resultLayout = R.layout.fragment_result_tv
|
||||||
|
@ -95,13 +103,21 @@ class ResultFragmentTv : ResultFragment() {
|
||||||
result_recommendations_filter_selection?.isVisible = false
|
result_recommendations_filter_selection?.isVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var loadingDialog: Dialog? = null
|
var loadingDialog: Dialog? = null
|
||||||
var popupDialog: Dialog? = null
|
var popupDialog: Dialog? = null
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
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 {
|
(result_episodes?.adapter as EpisodeAdapter?)?.apply {
|
||||||
layout = R.layout.result_episode_both_tv
|
layout = R.layout.result_episode_both_tv
|
||||||
}
|
}
|
||||||
|
//result_episodes?.setMaxViewPoolSize(0, Int.MAX_VALUE)
|
||||||
|
|
||||||
result_season_selection.setAdapter()
|
result_season_selection.setAdapter()
|
||||||
result_range_selection.setAdapter()
|
result_range_selection.setAdapter()
|
||||||
|
|
|
@ -197,6 +197,7 @@ fun LoadResponse.toResultData(repo: APIRepository): ResultData {
|
||||||
TvType.Torrent -> R.string.torrent_singular
|
TvType.Torrent -> R.string.torrent_singular
|
||||||
TvType.AsianDrama -> R.string.asian_drama_singular
|
TvType.AsianDrama -> R.string.asian_drama_singular
|
||||||
TvType.Live -> R.string.live_singular
|
TvType.Live -> R.string.live_singular
|
||||||
|
TvType.Others -> R.string.other_singular
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
yearText = txt(year?.toString()),
|
yearText = txt(year?.toString()),
|
||||||
|
@ -549,6 +550,7 @@ class ResultViewModel2 : ViewModel() {
|
||||||
TvType.Documentary -> "Documentaries"
|
TvType.Documentary -> "Documentaries"
|
||||||
TvType.AsianDrama -> "AsianDrama"
|
TvType.AsianDrama -> "AsianDrama"
|
||||||
TvType.Live -> "LiveStreams"
|
TvType.Live -> "LiveStreams"
|
||||||
|
TvType.Others -> "Others"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -169,6 +169,7 @@ class SearchFragment : Fragment() {
|
||||||
val asian = dialog.findViewById<MaterialButton>(R.id.home_select_asian)
|
val asian = dialog.findViewById<MaterialButton>(R.id.home_select_asian)
|
||||||
val livestream =
|
val livestream =
|
||||||
dialog.findViewById<MaterialButton>(R.id.home_select_livestreams)
|
dialog.findViewById<MaterialButton>(R.id.home_select_livestreams)
|
||||||
|
val other = dialog.findViewById<MaterialButton>(R.id.home_select_others)
|
||||||
val cancelBtt = dialog.findViewById<MaterialButton>(R.id.cancel_btt)
|
val cancelBtt = dialog.findViewById<MaterialButton>(R.id.cancel_btt)
|
||||||
val applyBtt = dialog.findViewById<MaterialButton>(R.id.apply_btt)
|
val applyBtt = dialog.findViewById<MaterialButton>(R.id.apply_btt)
|
||||||
|
|
||||||
|
@ -180,7 +181,8 @@ class SearchFragment : Fragment() {
|
||||||
docs,
|
docs,
|
||||||
movies,
|
movies,
|
||||||
asian,
|
asian,
|
||||||
livestream
|
livestream,
|
||||||
|
other
|
||||||
)
|
)
|
||||||
|
|
||||||
cancelBtt?.setOnClickListener {
|
cancelBtt?.setOnClickListener {
|
||||||
|
@ -297,7 +299,8 @@ class SearchFragment : Fragment() {
|
||||||
search_select_documentaries,
|
search_select_documentaries,
|
||||||
search_select_movies,
|
search_select_movies,
|
||||||
search_select_asian,
|
search_select_asian,
|
||||||
search_select_livestreams
|
search_select_livestreams,
|
||||||
|
search_select_others
|
||||||
)
|
)
|
||||||
|
|
||||||
val settingsManager = context?.let { PreferenceManager.getDefaultSharedPreferences(it) }
|
val settingsManager = context?.let { PreferenceManager.getDefaultSharedPreferences(it) }
|
||||||
|
|
|
@ -112,7 +112,8 @@ class PluginsFragment : Fragment() {
|
||||||
home_select_documentaries,
|
home_select_documentaries,
|
||||||
home_select_movies,
|
home_select_movies,
|
||||||
home_select_asian,
|
home_select_asian,
|
||||||
home_select_livestreams
|
home_select_livestreams,
|
||||||
|
home_select_others
|
||||||
)
|
)
|
||||||
|
|
||||||
// Copy pasted code
|
// Copy pasted code
|
||||||
|
|
|
@ -175,7 +175,10 @@ class PluginsViewModel : ViewModel() {
|
||||||
// Perhaps can be optimized?
|
// Perhaps can be optimized?
|
||||||
private fun List<PluginViewData>.filterTvTypes(): List<PluginViewData> {
|
private fun List<PluginViewData>.filterTvTypes(): List<PluginViewData> {
|
||||||
if (tvTypes.isEmpty()) return this
|
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<PluginViewData>.sortByQuery(query: String?): List<PluginViewData> {
|
private fun List<PluginViewData>.sortByQuery(query: String?): List<PluginViewData> {
|
||||||
|
|
|
@ -110,6 +110,12 @@
|
||||||
android:nextFocusLeft="@id/home_select_documentaries"
|
android:nextFocusLeft="@id/home_select_documentaries"
|
||||||
android:text="@string/livestreams" />
|
android:text="@string/livestreams" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/home_select_others"
|
||||||
|
style="@style/RoundedSelectableButton"
|
||||||
|
android:nextFocusLeft="@id/home_select_livestreams"
|
||||||
|
android:text="@string/others" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</HorizontalScrollView>
|
</HorizontalScrollView>
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
|
@ -917,7 +917,7 @@
|
||||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
android:descendantFocusability="afterDescendants"
|
android:descendantFocusability="afterDescendants"
|
||||||
android:paddingBottom="100dp"
|
android:paddingBottom="100dp"
|
||||||
tools:listitem="@layout/result_episode" />
|
tools:listitem="@layout/result_episode_both_tv" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
|
@ -146,6 +146,12 @@
|
||||||
style="@style/RoundedSelectableButton"
|
style="@style/RoundedSelectableButton"
|
||||||
android:nextFocusLeft="@id/search_select_documentaries"
|
android:nextFocusLeft="@id/search_select_documentaries"
|
||||||
android:text="@string/livestreams" />
|
android:text="@string/livestreams" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/search_select_others"
|
||||||
|
style="@style/RoundedSelectableButton"
|
||||||
|
android:nextFocusLeft="@id/search_select_livestreams"
|
||||||
|
android:text="@string/others" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</HorizontalScrollView>
|
</HorizontalScrollView>
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,12 @@
|
||||||
android:nextFocusLeft="@id/home_select_documentaries"
|
android:nextFocusLeft="@id/home_select_documentaries"
|
||||||
android:text="@string/livestreams" />
|
android:text="@string/livestreams" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/home_select_others"
|
||||||
|
style="@style/RoundedSelectableButton"
|
||||||
|
android:nextFocusLeft="@id/home_select_livestreams"
|
||||||
|
android:text="@string/others" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</HorizontalScrollView>
|
</HorizontalScrollView>
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
app:cardCornerRadius="@dimen/rounded_image_radius"
|
app:cardCornerRadius="@dimen/rounded_image_radius"
|
||||||
app:cardBackgroundColor="@color/transparent"
|
app:cardBackgroundColor="@color/transparent"
|
||||||
app:cardElevation="0dp"
|
app:cardElevation="0dp"
|
||||||
android:foreground="@drawable/outline_drawable"
|
|
||||||
android:layout_marginBottom="5dp">
|
android:layout_marginBottom="5dp">
|
||||||
<!--
|
<!--
|
||||||
android:nextFocusLeft="@id/result_episode_download"
|
android:nextFocusLeft="@id/result_episode_download"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
android:foreground="@drawable/outline_drawable"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<include android:visibility="gone" layout="@layout/result_episode" />
|
<include android:visibility="gone" layout="@layout/result_episode" />
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:foreground="@drawable/outline_drawable"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<include
|
<include
|
||||||
tools:visibility="visible"
|
tools:visibility="visible"
|
||||||
|
|
|
@ -6,19 +6,18 @@
|
||||||
android:nextFocusRight="@id/result_episode_download"
|
android:nextFocusRight="@id/result_episode_download"
|
||||||
android:id="@+id/episode_holder_large"
|
android:id="@+id/episode_holder_large"
|
||||||
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:cardCornerRadius="@dimen/rounded_image_radius"
|
app:cardCornerRadius="@dimen/rounded_image_radius"
|
||||||
app:cardBackgroundColor="?attr/boxItemBackground"
|
app:cardBackgroundColor="?attr/boxItemBackground"
|
||||||
|
|
||||||
android:foreground="@drawable/outline_drawable"
|
|
||||||
android:layout_marginBottom="10dp">
|
android:layout_marginBottom="10dp">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
||||||
android:padding="10dp"
|
android:padding="10dp"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
app:cardCornerRadius="@dimen/rounded_image_radius"
|
app:cardCornerRadius="@dimen/rounded_image_radius"
|
||||||
app:cardBackgroundColor="?attr/boxItemBackground"
|
app:cardBackgroundColor="?attr/boxItemBackground"
|
||||||
|
|
||||||
android:foreground="@drawable/outline_drawable"
|
|
||||||
android:layout_marginBottom="10dp">
|
android:layout_marginBottom="10dp">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
app:cardCornerRadius="@dimen/rounded_image_radius"
|
app:cardCornerRadius="@dimen/rounded_image_radius"
|
||||||
app:cardBackgroundColor="@color/transparent"
|
app:cardBackgroundColor="@color/transparent"
|
||||||
app:cardElevation="0dp"
|
app:cardElevation="0dp"
|
||||||
android:foreground="@drawable/outline_drawable"
|
|
||||||
android:layout_marginBottom="5dp">
|
android:layout_marginBottom="5dp">
|
||||||
|
|
||||||
<androidx.core.widget.ContentLoadingProgressBar
|
<androidx.core.widget.ContentLoadingProgressBar
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
<string name="type_re_watching">Ponowne oglądanie</string>
|
<string name="type_re_watching">Ponowne oglądanie</string>
|
||||||
|
|
||||||
<string name="play_movie_button">Odtwórz film</string>
|
<string name="play_movie_button">Odtwórz film</string>
|
||||||
<string name="play_livestream_button">Odtwórz Livestream</string>
|
<string name="play_livestream_button">Odtwórz transmisję na żywo</string>
|
||||||
<string name="play_torrent_button">Otwórz torrent</string>
|
<string name="play_torrent_button">Otwórz torrent</string>
|
||||||
<string name="pick_source">Źródła</string>
|
<string name="pick_source">Źródła</string>
|
||||||
<string name="pick_subtitle">Napisy</string>
|
<string name="pick_subtitle">Napisy</string>
|
||||||
|
@ -60,7 +60,7 @@
|
||||||
<string name="download_canceled">Anulowano pobieranie</string>
|
<string name="download_canceled">Anulowano pobieranie</string>
|
||||||
<string name="download_done">Zakończono pobieranie</string>
|
<string name="download_done">Zakończono pobieranie</string>
|
||||||
|
|
||||||
<string name="stream">Streamuj</string>
|
<string name="stream">Stream</string>
|
||||||
<string name="error_loading_links_toast">Błąd przy ładowaniu linków</string>
|
<string name="error_loading_links_toast">Błąd przy ładowaniu linków</string>
|
||||||
<string name="download_storage_text">Pamięć wewnętrzna</string>
|
<string name="download_storage_text">Pamięć wewnętrzna</string>
|
||||||
|
|
||||||
|
@ -236,7 +236,7 @@
|
||||||
<string name="ova">OVA</string>
|
<string name="ova">OVA</string>
|
||||||
<string name="asian_drama">Filmy azjatyckie</string>
|
<string name="asian_drama">Filmy azjatyckie</string>
|
||||||
|
|
||||||
<string name="livestreams">Livestreamy</string>
|
<string name="livestreams">Transmisje na żywo</string>
|
||||||
<string name="movies_singular">Film</string>
|
<string name="movies_singular">Film</string>
|
||||||
<string name="tv_series_singular">Serial telewizyjny</string>
|
<string name="tv_series_singular">Serial telewizyjny</string>
|
||||||
<string name="cartoons_singular">Kreskówka</string>
|
<string name="cartoons_singular">Kreskówka</string>
|
||||||
|
@ -396,4 +396,37 @@
|
||||||
<string name="app_layout_subtext">Dostosuj wygląd aplikacji do urządzenia</string>
|
<string name="app_layout_subtext">Dostosuj wygląd aplikacji do urządzenia</string>
|
||||||
<string name="preferred_media_subtext">Preferowany rodzaj filmów</string>
|
<string name="preferred_media_subtext">Preferowany rodzaj filmów</string>
|
||||||
<string name="setup_done">Gotowe</string>
|
<string name="setup_done">Gotowe</string>
|
||||||
|
<string name="extras">Dodatki</string>
|
||||||
|
<string name="trailer">Zwiastun</string>
|
||||||
|
<string name="play_with_app_name">Odtwórz w CloudStream</string>
|
||||||
|
<string name="live_singular">Transmisja na żywo</string>
|
||||||
|
<string name="network_adress_example">Link to streamu</string>
|
||||||
|
<string name="referer">Odsyłacz</string>
|
||||||
|
<string name="crash_reporting_title">Przekazywanie błędów</string>
|
||||||
|
<string name="automatic_plugin_updates">Automatyczne aktualizacje rozszerzeń</string>
|
||||||
|
<string name="extensions">Rozszerzenia</string>
|
||||||
|
<string name="add_repository">Dodaj repozytorium</string>
|
||||||
|
<string name="repository_name_hint">Nazwa repozytorium</string>
|
||||||
|
<string name="repository_url_hint">Adres url repozytorium</string>
|
||||||
|
<string name="plugin_loaded">Rozszerzenie załadowane</string>
|
||||||
|
<string name="plugin_deleted">Rozszerzenie usunięte</string>
|
||||||
|
<string name="plugin_load_fail">Błąd ładowania %s</string>
|
||||||
|
<string name="is_adult">+18</string>
|
||||||
|
<string name="batch_download_start_format">Zaczęto pobieranie %d %s</string>
|
||||||
|
<string name="batch_download_finish_format">Pobrano %d %s</string>
|
||||||
|
<string name="batch_download_nothing_to_download_format">Wszystkie %s już pobrane</string>
|
||||||
|
<string name="batch_download">Pobierz wszystko</string>
|
||||||
|
<string name="plugin_singular">rozszerzenie</string>
|
||||||
|
<string name="plugin">rozszerzenia</string>
|
||||||
|
<string name="delete_repository_plugins">Ta akcja usunie także wszystkie rozszerzenia z repozytorium</string>
|
||||||
|
<string name="delete_repository">Usuń repozytorium</string>
|
||||||
|
<string name="setup_extensions_subtext">Pobierz strony które Cię interesują</string>
|
||||||
|
<string name="plugins_downloaded">Pobrano: %d</string>
|
||||||
|
<string name="plugins_disabled">Wyłączono: %d</string>
|
||||||
|
<string name="plugins_not_downloaded">Nie pobrano: %d</string>
|
||||||
|
<string name="blank_repo_message">Dodaj repozytorium aby zainstalować rozszerzenia</string>
|
||||||
|
<string name="sync_score">Ocenione</string>
|
||||||
|
<string name="sync_score_format">%d na 10</string>
|
||||||
|
<string name="others">Inne</string>
|
||||||
|
<string name="other_singular">Wideo</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -333,6 +333,7 @@
|
||||||
<string name="ova">OVA</string>
|
<string name="ova">OVA</string>
|
||||||
<string name="asian_drama">Asian Dramas</string>
|
<string name="asian_drama">Asian Dramas</string>
|
||||||
<string name="livestreams">Livestreams</string>
|
<string name="livestreams">Livestreams</string>
|
||||||
|
<string name="others">Others</string>
|
||||||
|
|
||||||
<!--singular-->
|
<!--singular-->
|
||||||
<string name="movies_singular">Movie</string>
|
<string name="movies_singular">Movie</string>
|
||||||
|
@ -344,6 +345,7 @@
|
||||||
<string name="documentaries_singular">Documentary</string>
|
<string name="documentaries_singular">Documentary</string>
|
||||||
<string name="asian_drama_singular">Asian Drama</string>
|
<string name="asian_drama_singular">Asian Drama</string>
|
||||||
<string name="live_singular">Livestream</string>
|
<string name="live_singular">Livestream</string>
|
||||||
|
<string name="other_singular">Video</string>
|
||||||
|
|
||||||
<string name="source_error">Source error</string>
|
<string name="source_error">Source error</string>
|
||||||
<string name="remote_error">Remote error</string>
|
<string name="remote_error">Remote error</string>
|
||||||
|
|
Loading…
Reference in a new issue