mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
Merge branch 'master' of https://github.com/recloudstream/cloudstream into favorites-button-tv
This commit is contained in:
commit
e64d46f0a0
14 changed files with 236 additions and 36 deletions
|
@ -51,7 +51,7 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://developer.android.com/about/versions/14/behavior-changes-14#safer-dynamic-code-loading
|
// https://developer.android.com/about/versions/14/behavior-changes-14#safer-dynamic-code-loading
|
||||||
compileSdk = 33 // android 14 is fucked
|
compileSdk = 34 // android 14 is fucked
|
||||||
buildToolsVersion = "34.0.0"
|
buildToolsVersion = "34.0.0"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
|
@ -157,7 +157,7 @@ dependencies {
|
||||||
implementation("androidx.test.ext:junit-ktx:1.1.5")
|
implementation("androidx.test.ext:junit-ktx:1.1.5")
|
||||||
testImplementation("org.json:json:20230618")
|
testImplementation("org.json:json:20230618")
|
||||||
|
|
||||||
implementation("androidx.core:core-ktx:1.10.1") // need 34 for higher
|
implementation("androidx.core:core-ktx:1.12.0") // need 34 for higher
|
||||||
implementation("androidx.appcompat:appcompat:1.6.1") // need target 32 for 1.5.0
|
implementation("androidx.appcompat:appcompat:1.6.1") // need target 32 for 1.5.0
|
||||||
|
|
||||||
// dont change this to 1.6.0 it looks ugly af
|
// dont change this to 1.6.0 it looks ugly af
|
||||||
|
@ -165,10 +165,10 @@ dependencies {
|
||||||
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
|
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
|
||||||
|
|
||||||
// need 34 for higher
|
// need 34 for higher
|
||||||
implementation("androidx.navigation:navigation-fragment-ktx:2.6.0")
|
implementation("androidx.navigation:navigation-fragment-ktx:2.7.4")
|
||||||
implementation("androidx.navigation:navigation-ui-ktx:2.6.0")
|
implementation("androidx.navigation:navigation-ui-ktx:2.7.4")
|
||||||
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.1")
|
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2")
|
||||||
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1")
|
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")
|
||||||
|
|
||||||
testImplementation("junit:junit:4.13.2")
|
testImplementation("junit:junit:4.13.2")
|
||||||
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
||||||
|
|
|
@ -19,6 +19,7 @@ import com.lagradost.cloudstream3.databinding.FragmentSearchBinding
|
||||||
import com.lagradost.cloudstream3.databinding.FragmentSearchTvBinding
|
import com.lagradost.cloudstream3.databinding.FragmentSearchTvBinding
|
||||||
import com.lagradost.cloudstream3.databinding.HomeResultGridBinding
|
import com.lagradost.cloudstream3.databinding.HomeResultGridBinding
|
||||||
import com.lagradost.cloudstream3.databinding.HomepageParentBinding
|
import com.lagradost.cloudstream3.databinding.HomepageParentBinding
|
||||||
|
import com.lagradost.cloudstream3.databinding.HomepageParentEmulatorBinding
|
||||||
import com.lagradost.cloudstream3.databinding.HomepageParentTvBinding
|
import com.lagradost.cloudstream3.databinding.HomepageParentTvBinding
|
||||||
import com.lagradost.cloudstream3.databinding.PlayerCustomLayoutBinding
|
import com.lagradost.cloudstream3.databinding.PlayerCustomLayoutBinding
|
||||||
import com.lagradost.cloudstream3.databinding.PlayerCustomLayoutTvBinding
|
import com.lagradost.cloudstream3.databinding.PlayerCustomLayoutTvBinding
|
||||||
|
@ -119,8 +120,9 @@ class ExampleInstrumentedTest {
|
||||||
// testAllLayouts<HomeScrollViewBinding>(activity, R.layout.home_scroll_view, R.layout.home_scroll_view_tv)
|
// testAllLayouts<HomeScrollViewBinding>(activity, R.layout.home_scroll_view, R.layout.home_scroll_view_tv)
|
||||||
// testAllLayouts<HomeScrollViewTvBinding>(activity, R.layout.home_scroll_view, R.layout.home_scroll_view_tv)
|
// testAllLayouts<HomeScrollViewTvBinding>(activity, R.layout.home_scroll_view, R.layout.home_scroll_view_tv)
|
||||||
|
|
||||||
testAllLayouts<HomepageParentTvBinding>(activity, R.layout.homepage_parent_tv, R.layout.homepage_parent)
|
testAllLayouts<HomepageParentTvBinding>(activity, R.layout.homepage_parent_tv, R.layout.homepage_parent_emulator, R.layout.homepage_parent)
|
||||||
testAllLayouts<HomepageParentBinding>(activity, R.layout.homepage_parent_tv, R.layout.homepage_parent)
|
testAllLayouts<HomepageParentEmulatorBinding>(activity, R.layout.homepage_parent_tv, R.layout.homepage_parent_emulator, R.layout.homepage_parent)
|
||||||
|
testAllLayouts<HomepageParentBinding>(activity, R.layout.homepage_parent_tv, R.layout.homepage_parent_emulator, R.layout.homepage_parent)
|
||||||
|
|
||||||
testAllLayouts<FragmentLibraryTvBinding>(activity, R.layout.fragment_library_tv, R.layout.fragment_library)
|
testAllLayouts<FragmentLibraryTvBinding>(activity, R.layout.fragment_library_tv, R.layout.fragment_library)
|
||||||
testAllLayouts<FragmentLibraryBinding>(activity, R.layout.fragment_library_tv, R.layout.fragment_library)
|
testAllLayouts<FragmentLibraryBinding>(activity, R.layout.fragment_library_tv, R.layout.fragment_library)
|
||||||
|
|
|
@ -662,7 +662,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
||||||
val isAtHome =
|
val isAtHome =
|
||||||
navController?.currentDestination?.matchDestination(R.id.navigation_home) == true
|
navController?.currentDestination?.matchDestination(R.id.navigation_home) == true
|
||||||
|
|
||||||
if (isAtHome && isTrueTvSettings()) {
|
if (isAtHome && isTvSettings()) {
|
||||||
showConfirmExitDialog()
|
showConfirmExitDialog()
|
||||||
} else {
|
} else {
|
||||||
super.onBackPressed()
|
super.onBackPressed()
|
||||||
|
|
|
@ -8,7 +8,7 @@ import com.lagradost.cloudstream3.syncproviders.SyncIdName
|
||||||
import com.lagradost.cloudstream3.ui.WatchType
|
import com.lagradost.cloudstream3.ui.WatchType
|
||||||
import com.lagradost.cloudstream3.ui.library.ListSorting
|
import com.lagradost.cloudstream3.ui.library.ListSorting
|
||||||
import com.lagradost.cloudstream3.ui.result.txt
|
import com.lagradost.cloudstream3.ui.result.txt
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
|
||||||
import com.lagradost.cloudstream3.utils.Coroutines.ioWork
|
import com.lagradost.cloudstream3.utils.Coroutines.ioWork
|
||||||
import com.lagradost.cloudstream3.utils.DataStoreHelper.getAllFavorites
|
import com.lagradost.cloudstream3.utils.DataStoreHelper.getAllFavorites
|
||||||
import com.lagradost.cloudstream3.utils.DataStoreHelper.getAllSubscriptions
|
import com.lagradost.cloudstream3.utils.DataStoreHelper.getAllSubscriptions
|
||||||
|
@ -71,14 +71,14 @@ class LocalList : SyncAPI {
|
||||||
}?.distinctBy { it.first } ?: return null
|
}?.distinctBy { it.first } ?: return null
|
||||||
|
|
||||||
val list = ioWork {
|
val list = ioWork {
|
||||||
val isTv = isTvSettings()
|
val isTrueTv = isTrueTvSettings()
|
||||||
|
|
||||||
val baseMap = WatchType.values().filter { it != WatchType.NONE }.associate {
|
val baseMap = WatchType.values().filter { it != WatchType.NONE }.associate {
|
||||||
// None is not something to display
|
// None is not something to display
|
||||||
it.stringRes to emptyList<SyncAPI.LibraryItem>()
|
it.stringRes to emptyList<SyncAPI.LibraryItem>()
|
||||||
} + mapOf(
|
} + mapOf(
|
||||||
R.string.favorites_list_name to emptyList()
|
R.string.favorites_list_name to emptyList()
|
||||||
) + if (!isTv) {
|
) + if (!isTrueTv) {
|
||||||
mapOf(
|
mapOf(
|
||||||
R.string.subscription_list_name to emptyList()
|
R.string.subscription_list_name to emptyList()
|
||||||
)
|
)
|
||||||
|
@ -96,8 +96,8 @@ class LocalList : SyncAPI {
|
||||||
it.toLibraryItem()
|
it.toLibraryItem()
|
||||||
})
|
})
|
||||||
|
|
||||||
// Don't show subscriptions or favorites on TV
|
// Don't show subscriptions on TV
|
||||||
val result = if (isTv) {
|
val result = if (isTrueTv) {
|
||||||
baseMap + watchStatusMap + favoritesMap
|
baseMap + watchStatusMap + favoritesMap
|
||||||
} else {
|
} else {
|
||||||
val subscriptionsMap = mapOf(R.string.subscription_list_name to getAllSubscriptions().mapNotNull {
|
val subscriptionsMap = mapOf(R.string.subscription_list_name to getAllSubscriptions().mapNotNull {
|
||||||
|
|
|
@ -15,7 +15,8 @@ import com.lagradost.cloudstream3.ui.result.FOCUS_SELF
|
||||||
import com.lagradost.cloudstream3.ui.result.setLinearListLayout
|
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.isEmulatorSettings
|
||||||
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.isRecyclerScrollable
|
import com.lagradost.cloudstream3.utils.AppUtils.isRecyclerScrollable
|
||||||
|
|
||||||
class LoadClickCallback(
|
class LoadClickCallback(
|
||||||
|
@ -34,11 +35,13 @@ open class ParentItemAdapter(
|
||||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
|
|
||||||
val root = LayoutInflater.from(parent.context).inflate(
|
val layoutResId = when {
|
||||||
if (isTvSettings()) R.layout.homepage_parent_tv else R.layout.homepage_parent,
|
isTrueTvSettings() -> R.layout.homepage_parent_tv
|
||||||
parent,
|
parent.context.isEmulatorSettings() -> R.layout.homepage_parent_emulator
|
||||||
false
|
else -> R.layout.homepage_parent
|
||||||
)
|
}
|
||||||
|
|
||||||
|
val root = LayoutInflater.from(parent.context).inflate(layoutResId, parent, false)
|
||||||
|
|
||||||
val binding = HomepageParentBinding.bind(root)
|
val binding = HomepageParentBinding.bind(root)
|
||||||
|
|
||||||
|
@ -234,7 +237,7 @@ open class ParentItemAdapter(
|
||||||
})
|
})
|
||||||
|
|
||||||
//(recyclerView.adapter as HomeChildItemAdapter).notifyDataSetChanged()
|
//(recyclerView.adapter as HomeChildItemAdapter).notifyDataSetChanged()
|
||||||
if (!isTvSettings()) {
|
if (!isTrueTvSettings()) {
|
||||||
title.setOnClickListener {
|
title.setOnClickListener {
|
||||||
moreInfoClickCallback.invoke(expand)
|
moreInfoClickCallback.invoke(expand)
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ import com.lagradost.cloudstream3.ui.result.setLinearListLayout
|
||||||
import com.lagradost.cloudstream3.ui.search.SEARCH_ACTION_LOAD
|
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.SEARCH_ACTION_SHOW_METADATA
|
||||||
import com.lagradost.cloudstream3.ui.search.SearchClickCallback
|
import com.lagradost.cloudstream3.ui.search.SearchClickCallback
|
||||||
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmulatorSettings
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
||||||
import com.lagradost.cloudstream3.utils.DataStoreHelper
|
import com.lagradost.cloudstream3.utils.DataStoreHelper
|
||||||
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog
|
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog
|
||||||
|
@ -81,6 +82,28 @@ class HomeParentItemAdapterPreview(
|
||||||
parent,
|
parent,
|
||||||
false
|
false
|
||||||
) else FragmentHomeHeadBinding.inflate(inflater, parent, false)
|
) else FragmentHomeHeadBinding.inflate(inflater, parent, false)
|
||||||
|
|
||||||
|
if (binding is FragmentHomeHeadTvBinding && parent.context.isEmulatorSettings()) {
|
||||||
|
binding.homeBookmarkParentItemMoreInfo.isVisible = true
|
||||||
|
|
||||||
|
val marginInDp = 50
|
||||||
|
val density = binding.horizontalScrollChips.context.resources.displayMetrics.density
|
||||||
|
val marginInPixels = (marginInDp * density).toInt()
|
||||||
|
|
||||||
|
val params = binding.horizontalScrollChips.layoutParams as ViewGroup.MarginLayoutParams
|
||||||
|
params.marginEnd = marginInPixels
|
||||||
|
binding.horizontalScrollChips.layoutParams = params
|
||||||
|
binding.homeWatchParentItemTitle.setCompoundDrawablesWithIntrinsicBounds(
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
parent.context,
|
||||||
|
R.drawable.ic_baseline_arrow_forward_24
|
||||||
|
),
|
||||||
|
null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
HeaderViewHolder(
|
HeaderViewHolder(
|
||||||
binding,
|
binding,
|
||||||
viewModel,
|
viewModel,
|
||||||
|
@ -553,12 +576,19 @@ class HomeParentItemAdapterPreview(
|
||||||
resumeHolder.isVisible = resumeWatching.isNotEmpty()
|
resumeHolder.isVisible = resumeWatching.isNotEmpty()
|
||||||
resumeAdapter.updateList(resumeWatching)
|
resumeAdapter.updateList(resumeWatching)
|
||||||
|
|
||||||
if (binding is FragmentHomeHeadBinding) {
|
if (
|
||||||
binding.homeWatchParentItemTitle.setOnClickListener {
|
binding is FragmentHomeHeadBinding ||
|
||||||
|
binding is FragmentHomeHeadTvBinding &&
|
||||||
|
binding.root.context.isEmulatorSettings()
|
||||||
|
) {
|
||||||
|
val title = (binding as? FragmentHomeHeadBinding)?.homeWatchParentItemTitle
|
||||||
|
?: (binding as? FragmentHomeHeadTvBinding)?.homeWatchParentItemTitle
|
||||||
|
|
||||||
|
title?.setOnClickListener {
|
||||||
viewModel.popup(
|
viewModel.popup(
|
||||||
HomeViewModel.ExpandableHomepageList(
|
HomeViewModel.ExpandableHomepageList(
|
||||||
HomePageList(
|
HomePageList(
|
||||||
binding.homeWatchParentItemTitle.text.toString(),
|
title.text.toString(),
|
||||||
resumeWatching,
|
resumeWatching,
|
||||||
false
|
false
|
||||||
), 1, false
|
), 1, false
|
||||||
|
@ -576,8 +606,15 @@ class HomeParentItemAdapterPreview(
|
||||||
bookmarkHolder.isVisible = visible
|
bookmarkHolder.isVisible = visible
|
||||||
bookmarkAdapter.updateList(list)
|
bookmarkAdapter.updateList(list)
|
||||||
|
|
||||||
if (binding is FragmentHomeHeadBinding) {
|
if (
|
||||||
binding.homeBookmarkParentItemTitle.setOnClickListener {
|
binding is FragmentHomeHeadBinding ||
|
||||||
|
binding is FragmentHomeHeadTvBinding &&
|
||||||
|
binding.root.context.isEmulatorSettings()
|
||||||
|
) {
|
||||||
|
val title = (binding as? FragmentHomeHeadBinding)?.homeBookmarkParentItemTitle
|
||||||
|
?: (binding as? FragmentHomeHeadTvBinding)?.homeBookmarkParentItemTitle
|
||||||
|
|
||||||
|
title?.setOnClickListener {
|
||||||
val items = toggleList.map { it.first }.filter { it.isChecked }
|
val items = toggleList.map { it.first }.filter { it.isChecked }
|
||||||
if (items.isEmpty()) return@setOnClickListener // we don't want to show an empty dialog
|
if (items.isEmpty()) return@setOnClickListener // we don't want to show an empty dialog
|
||||||
val textSum = items
|
val textSum = items
|
||||||
|
|
|
@ -575,6 +575,7 @@ class ResultFragmentTv : Fragment() {
|
||||||
observeNullable(viewModel.movie) { data ->
|
observeNullable(viewModel.movie) { data ->
|
||||||
binding?.apply {
|
binding?.apply {
|
||||||
resultPlayMovie.isVisible = data is Resource.Success
|
resultPlayMovie.isVisible = data is Resource.Success
|
||||||
|
resultPlaySeries.isVisible = data == null
|
||||||
seriesHolder.isVisible = data == null
|
seriesHolder.isVisible = data == null
|
||||||
resultEpisodesShow.isVisible = data == null
|
resultEpisodesShow.isVisible = data == null
|
||||||
|
|
||||||
|
@ -804,12 +805,14 @@ class ResultFragmentTv : Fragment() {
|
||||||
R.drawable.profile_bg_red,
|
R.drawable.profile_bg_red,
|
||||||
R.drawable.profile_bg_teal
|
R.drawable.profile_bg_teal
|
||||||
).random()
|
).random()
|
||||||
|
//Change poster crop area to 20% from Top
|
||||||
|
backgroundPoster.cropYCenterOffsetPct = 0.20F
|
||||||
|
|
||||||
backgroundPoster.setImage(
|
backgroundPoster.setImage(
|
||||||
d.posterBackgroundImage ?: UiImage.Drawable(error),
|
d.posterBackgroundImage ?: UiImage.Drawable(error),
|
||||||
radius = 0,
|
radius = 0,
|
||||||
errorImageDrawable = error
|
errorImageDrawable = error
|
||||||
)
|
)
|
||||||
|
|
||||||
resultComingSoon.isVisible = d.comingSoon
|
resultComingSoon.isVisible = d.comingSoon
|
||||||
resultDataHolder.isGone = d.comingSoon
|
resultDataHolder.isGone = d.comingSoon
|
||||||
UIHelper.populateChips(resultTag, d.tags)
|
UIHelper.populateChips(resultTag, d.tags)
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
package com.lagradost.cloudstream3.utils
|
||||||
|
//Reference: https://stackoverflow.com/a/29055283
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Matrix
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.util.AttributeSet
|
||||||
|
|
||||||
|
class PercentageCropImageView : androidx.appcompat.widget.AppCompatImageView {
|
||||||
|
private var mCropYCenterOffsetPct: Float? = null
|
||||||
|
private var mCropXCenterOffsetPct: Float? = null
|
||||||
|
constructor(context: Context?) : super(context!!)
|
||||||
|
constructor(context: Context?, attrs: AttributeSet?) : super(context!!, attrs)
|
||||||
|
constructor(
|
||||||
|
context: Context?, attrs: AttributeSet?,
|
||||||
|
defStyle: Int
|
||||||
|
) : super(context!!, attrs, defStyle)
|
||||||
|
|
||||||
|
var cropYCenterOffsetPct: Float
|
||||||
|
get() = mCropYCenterOffsetPct!!
|
||||||
|
set(cropYCenterOffsetPct) {
|
||||||
|
require(cropYCenterOffsetPct <= 1.0) { "Value too large: Must be <= 1.0" }
|
||||||
|
mCropYCenterOffsetPct = cropYCenterOffsetPct
|
||||||
|
}
|
||||||
|
var cropXCenterOffsetPct: Float
|
||||||
|
get() = mCropXCenterOffsetPct!!
|
||||||
|
set(cropXCenterOffsetPct) {
|
||||||
|
require(cropXCenterOffsetPct <= 1.0) { "Value too large: Must be <= 1.0" }
|
||||||
|
mCropXCenterOffsetPct = cropXCenterOffsetPct
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun myConfigureBounds() {
|
||||||
|
if (this.scaleType == ScaleType.MATRIX) {
|
||||||
|
|
||||||
|
val d = this.drawable
|
||||||
|
if (d != null) {
|
||||||
|
val dWidth = d.intrinsicWidth
|
||||||
|
val dHeight = d.intrinsicHeight
|
||||||
|
val m = Matrix()
|
||||||
|
val vWidth = width - this.paddingLeft - this.paddingRight
|
||||||
|
val vHeight = height - this.paddingTop - this.paddingBottom
|
||||||
|
val scale: Float
|
||||||
|
var dx = 0f
|
||||||
|
var dy = 0f
|
||||||
|
if (dWidth * vHeight > vWidth * dHeight) {
|
||||||
|
val cropXCenterOffsetPct =
|
||||||
|
if (mCropXCenterOffsetPct != null) mCropXCenterOffsetPct!!.toFloat() else 0.5f
|
||||||
|
scale = vHeight.toFloat() / dHeight.toFloat()
|
||||||
|
dx = (vWidth - dWidth * scale) * cropXCenterOffsetPct
|
||||||
|
} else {
|
||||||
|
val cropYCenterOffsetPct =
|
||||||
|
if (mCropYCenterOffsetPct != null) mCropYCenterOffsetPct!!.toFloat() else 0f
|
||||||
|
scale = vWidth.toFloat() / dWidth.toFloat()
|
||||||
|
dy = (vHeight - dHeight * scale) * cropYCenterOffsetPct
|
||||||
|
}
|
||||||
|
m.setScale(scale, scale)
|
||||||
|
m.postTranslate((dx + 0.5f).toInt().toFloat(), (dy + 0.5f).toInt().toFloat())
|
||||||
|
this.imageMatrix = m
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// These 3 methods call configureBounds in ImageView.java class, which
|
||||||
|
// adjusts the matrix in a call to center_crop (android's built-in
|
||||||
|
// scaling and centering crop method). We also want to trigger
|
||||||
|
// in the same place, but using our own matrix, which is then set
|
||||||
|
// directly at line 588 of ImageView.java and then copied over
|
||||||
|
// as the draw matrix at line 942 of ImageView.java
|
||||||
|
override fun setFrame(l: Int, t: Int, r: Int, b: Int): Boolean {
|
||||||
|
val changed = super.setFrame(l, t, r, b)
|
||||||
|
myConfigureBounds()
|
||||||
|
return changed
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setImageDrawable(d: Drawable?) {
|
||||||
|
super.setImageDrawable(d)
|
||||||
|
myConfigureBounds()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setImageResource(resId: Int) {
|
||||||
|
super.setImageResource(resId)
|
||||||
|
myConfigureBounds()
|
||||||
|
}
|
||||||
|
// In case you can change the ScaleType in code you have to call redraw()
|
||||||
|
//fullsizeImageView.setScaleType(ScaleType.FIT_CENTER);
|
||||||
|
//fullsizeImageView.redraw();
|
||||||
|
fun redraw() {
|
||||||
|
val d = this.drawable
|
||||||
|
if (d != null) {
|
||||||
|
// Force toggle to recalculate our bounds
|
||||||
|
setImageDrawable(null)
|
||||||
|
setImageDrawable(d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -178,9 +178,10 @@ object UIHelper {
|
||||||
fun Activity?.navigate(@IdRes navigation: Int, arguments: Bundle? = null) {
|
fun Activity?.navigate(@IdRes navigation: Int, arguments: Bundle? = null) {
|
||||||
try {
|
try {
|
||||||
if (this is FragmentActivity) {
|
if (this is FragmentActivity) {
|
||||||
(supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as? NavHostFragment?)?.navController?.navigate(
|
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as? NavHostFragment?
|
||||||
navigation, arguments
|
navHostFragment?.navController?.let {
|
||||||
)
|
it.navigate(navigation, arguments)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (t: Throwable) {
|
} catch (t: Throwable) {
|
||||||
logError(t)
|
logError(t)
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
android:layout_margin="5dp"
|
android:layout_margin="5dp"
|
||||||
android:foreground="@drawable/outline_drawable"
|
android:foreground="@drawable/outline_drawable"
|
||||||
app:cardBackgroundColor="@color/transparent"
|
app:cardBackgroundColor="@color/transparent"
|
||||||
|
android:focusable="true"
|
||||||
app:cardCornerRadius="@dimen/rounded_image_radius"
|
app:cardCornerRadius="@dimen/rounded_image_radius"
|
||||||
app:cardElevation="0dp">
|
app:cardElevation="0dp">
|
||||||
|
|
||||||
|
|
|
@ -232,7 +232,9 @@
|
||||||
android:layout_marginStart="@dimen/navbar_width"
|
android:layout_marginStart="@dimen/navbar_width"
|
||||||
android:layout_marginEnd="0dp"
|
android:layout_marginEnd="0dp"
|
||||||
android:padding="12dp"
|
android:padding="12dp"
|
||||||
android:text="@string/continue_watching" />
|
android:text="@string/continue_watching"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
app:drawableTint="?attr/white" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/home_watch_child_recyclerview"
|
android:id="@+id/home_watch_child_recyclerview"
|
||||||
|
@ -258,7 +260,15 @@
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible">
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/home_bookmark_parent_item_title"
|
||||||
|
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?android:attr/selectableItemBackground">
|
||||||
|
|
||||||
<HorizontalScrollView
|
<HorizontalScrollView
|
||||||
|
android:id="@+id/horizontal_scroll_chips"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fadingEdge="horizontal"
|
android:fadingEdge="horizontal"
|
||||||
|
@ -344,6 +354,18 @@
|
||||||
</com.google.android.material.chip.ChipGroup>
|
</com.google.android.material.chip.ChipGroup>
|
||||||
</HorizontalScrollView>
|
</HorizontalScrollView>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/home_bookmark_parent_item_more_info"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:layout_marginEnd="12dp"
|
||||||
|
android:contentDescription="@string/home_more_info"
|
||||||
|
android:src="@drawable/ic_baseline_arrow_forward_24"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:drawableTint="?attr/white" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/home_bookmarked_child_recyclerview"
|
android:id="@+id/home_bookmarked_child_recyclerview"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|
|
@ -140,6 +140,7 @@
|
||||||
android:layout_gravity="end"
|
android:layout_gravity="end"
|
||||||
android:background="@drawable/player_button_tv_attr_no_bg"
|
android:background="@drawable/player_button_tv_attr_no_bg"
|
||||||
android:contentDescription="@string/account"
|
android:contentDescription="@string/account"
|
||||||
|
android:focusable="true"
|
||||||
android:nextFocusLeft="@id/home_preview_search_button"
|
android:nextFocusLeft="@id/home_preview_search_button"
|
||||||
android:nextFocusRight="@id/home_switch_account"
|
android:nextFocusRight="@id/home_switch_account"
|
||||||
android:nextFocusDown="@id/home_change_api"
|
android:nextFocusDown="@id/home_change_api"
|
||||||
|
|
|
@ -130,14 +130,15 @@ https://developer.android.com/design/ui/tv/samples/jet-fit
|
||||||
android:layout_height="250dp"
|
android:layout_height="250dp"
|
||||||
android:visibility="visible">
|
android:visibility="visible">
|
||||||
|
|
||||||
<ImageView
|
<com.lagradost.cloudstream3.utils.PercentageCropImageView
|
||||||
android:id="@+id/background_poster"
|
android:id="@+id/background_poster"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="275dp"
|
android:layout_height="275dp"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:alpha="0.8"
|
android:alpha="0.8"
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="matrix"
|
||||||
tools:src="@drawable/profile_bg_dark_blue" />
|
tools:src="@drawable/profile_bg_dark_blue" >
|
||||||
|
</com.lagradost.cloudstream3.utils.PercentageCropImageView>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -417,6 +418,7 @@ https://developer.android.com/design/ui/tv/samples/jet-fit
|
||||||
android:fadingEdgeLength="30dp"
|
android:fadingEdgeLength="30dp"
|
||||||
android:foreground="@drawable/outline_drawable"
|
android:foreground="@drawable/outline_drawable"
|
||||||
android:maxLines="7"
|
android:maxLines="7"
|
||||||
|
android:focusable="true"
|
||||||
android:nextFocusUp="@id/result_back"
|
android:nextFocusUp="@id/result_back"
|
||||||
android:nextFocusDown="@id/result_bookmark_button"
|
android:nextFocusDown="@id/result_bookmark_button"
|
||||||
android:padding="5dp"
|
android:padding="5dp"
|
||||||
|
|
35
app/src/main/res/layout/homepage_parent_emulator.xml
Normal file
35
app/src/main/res/layout/homepage_parent_emulator.xml
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/home_child_more_info"
|
||||||
|
style="@style/WatchHeaderText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/navbar_width"
|
||||||
|
android:layout_marginEnd="0dp"
|
||||||
|
android:padding="12dp"
|
||||||
|
tools:text="@string/continue_watching"
|
||||||
|
app:drawableRightCompat="@drawable/ic_baseline_arrow_forward_24"
|
||||||
|
app:drawableTint="?attr/white"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:contentDescription="@string/home_more_info"/>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/home_child_recyclerview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:descendantFocusability="afterDescendants"
|
||||||
|
android:nextFocusUp="@id/home_child_more_info"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingStart="@dimen/navbar_width"
|
||||||
|
android:paddingEnd="5dp"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
tools:listitem="@layout/home_result_grid" />
|
||||||
|
</LinearLayout>
|
Loading…
Add table
Add a link
Reference in a new issue