mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
sflix mirror and phone layout UI update
This commit is contained in:
parent
b3cbedcd3a
commit
37d402d7b3
14 changed files with 164 additions and 70 deletions
|
@ -114,7 +114,7 @@ dependencies {
|
|||
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||
|
||||
implementation "androidx.leanback:leanback-paging:1.1.0-alpha09"
|
||||
// implementation "androidx.leanback:leanback-paging:1.1.0-alpha09"
|
||||
|
||||
// Exoplayer
|
||||
implementation 'com.google.android.exoplayer:exoplayer:2.15.1'
|
||||
|
@ -153,5 +153,5 @@ dependencies {
|
|||
implementation "com.github.tachiyomiorg:unifile:17bec43"
|
||||
|
||||
// debugImplementation because LeakCanary should only run in debug builds.
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'
|
||||
// debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'
|
||||
}
|
|
@ -31,7 +31,7 @@
|
|||
<activity
|
||||
android:exported="true"
|
||||
android:name=".MainActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|keyboard|keyboardHidden|navigation"
|
||||
android:configChanges="screenSize|smallestScreenSize|screenLayout|keyboard|keyboardHidden|navigation"
|
||||
android:label="@string/app_name"
|
||||
android:resizeableActivity="true"
|
||||
android:supportsPictureInPicture="true">
|
||||
|
|
|
@ -85,6 +85,5 @@ class AcraApplication : Application() {
|
|||
private set(value) {
|
||||
_context = WeakReference(value)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -49,7 +49,9 @@ object APIHolder {
|
|||
VfSerieProvider(),
|
||||
AsianLoadProvider(),
|
||||
|
||||
SflixProvider(),
|
||||
SflixProvider("https://sflix.to","Sflix"),
|
||||
SflixProvider("https://dopebox.to","Dopebox"),
|
||||
|
||||
ZoroProvider()
|
||||
)
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ import androidx.navigation.findNavController
|
|||
import androidx.navigation.ui.setupWithNavController
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.google.android.gms.cast.framework.*
|
||||
import com.google.android.material.navigationrail.NavigationRailView
|
||||
import com.jaredrummler.android.colorpicker.ColorPickerDialogListener
|
||||
import com.lagradost.cloudstream3.APIHolder.apis
|
||||
import com.lagradost.cloudstream3.APIHolder.getApiDubstatusSettings
|
||||
|
@ -51,8 +52,6 @@ import com.lagradost.cloudstream3.utils.UIHelper.requestRW
|
|||
import com.lagradost.cloudstream3.utils.UIHelper.shouldShowPIPMode
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.toPx
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
import kotlinx.android.synthetic.main.activity_main.cast_mini_controller_holder
|
||||
import kotlinx.android.synthetic.main.activity_main_tv.*
|
||||
import kotlinx.android.synthetic.main.fragment_result.*
|
||||
import java.util.*
|
||||
import kotlin.concurrent.thread
|
||||
|
@ -84,7 +83,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
|||
updateLocale() // android fucks me by chaining lang when rotating the phone
|
||||
}
|
||||
|
||||
private var mCastSession: CastSession? = null
|
||||
//private var mCastSession: CastSession? = null
|
||||
lateinit var mSessionManager: SessionManager
|
||||
private val mSessionManagerListener: SessionManagerListener<Session> by lazy { SessionManagerListenerImpl() }
|
||||
|
||||
|
@ -123,7 +122,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
|||
super.onResume()
|
||||
try {
|
||||
if (isCastApiAvailable()) {
|
||||
mCastSession = mSessionManager.currentCastSession
|
||||
//mCastSession = mSessionManager.currentCastSession
|
||||
mSessionManager.addSessionManagerListener(mSessionManagerListener)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
@ -136,7 +135,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
|||
try {
|
||||
if (isCastApiAvailable()) {
|
||||
mSessionManager.removeSessionManagerListener(mSessionManagerListener)
|
||||
mCastSession = null
|
||||
//mCastSession = null
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logError(e)
|
||||
|
@ -448,7 +447,8 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
|||
.setPopUpTo(navController.graph.startDestination, false)
|
||||
.build()*/
|
||||
nav_view?.setupWithNavController(navController)
|
||||
nav_rail_view?.setupWithNavController(navController)
|
||||
val navRail = findViewById<NavigationRailView?>(R.id.nav_rail_view)
|
||||
navRail?.setupWithNavController(navController)
|
||||
navController.addOnDestinationChangedListener { _, destination, _ ->
|
||||
this.hideKeyboard()
|
||||
// nav_view.hideKeyboard()
|
||||
|
@ -473,7 +473,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
|||
).contains(destination.id)
|
||||
|
||||
nav_view?.isVisible = isNavVisible
|
||||
nav_rail_view?.isVisible = isNavVisible
|
||||
navRail?.isVisible = isNavVisible
|
||||
}
|
||||
|
||||
/*nav_view.setOnNavigationItemSelectedListener { item ->
|
||||
|
@ -496,7 +496,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
|||
|
||||
val rippleColor = ColorStateList.valueOf(getResourceColor(R.attr.colorPrimary, 0.1f))
|
||||
nav_view?.itemRippleColor = rippleColor
|
||||
nav_rail_view?.itemRippleColor = rippleColor
|
||||
navRail?.itemRippleColor = rippleColor
|
||||
|
||||
if (!checkWrite()) {
|
||||
requestRW()
|
||||
|
|
|
@ -13,11 +13,11 @@ import org.jsoup.Jsoup
|
|||
import org.jsoup.nodes.Element
|
||||
import java.net.URI
|
||||
|
||||
class SflixProvider : MainAPI() {
|
||||
class SflixProvider(private val providerUrl: String, private val providerName: String) : MainAPI() {
|
||||
override val mainUrl: String
|
||||
get() = "https://sflix.to"
|
||||
get() = providerUrl
|
||||
override val name: String
|
||||
get() = "Sflix"
|
||||
get() = providerName
|
||||
|
||||
override val hasQuickSearch: Boolean
|
||||
get() = false
|
||||
|
|
|
@ -119,46 +119,6 @@ class HomeFragment : Fragment() {
|
|||
home_main_holder.isVisible = visible
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun chooseRandomMainPage() {
|
||||
val home = currentHomePage
|
||||
if (home != null && home.items.isNotEmpty()) {
|
||||
val currentList =
|
||||
home.items.shuffled().filter { !it.list.isNullOrEmpty() }.flatMap { it.list }.distinctBy { it.url }
|
||||
.toList()
|
||||
|
||||
if (currentList.isNullOrEmpty()) {
|
||||
toggleMainVisibility(false)
|
||||
} else {
|
||||
val randomItems = currentList.shuffled()
|
||||
val randomSize = randomItems.size
|
||||
home_main_poster_recyclerview.adapter =
|
||||
HomeChildItemAdapter(randomItems, R.layout.home_result_big_grid) { callback ->
|
||||
handleSearchClickCallback(activity, callback)
|
||||
}
|
||||
home_main_poster_recyclerview.post {
|
||||
(home_main_poster_recyclerview.layoutManager as CenterZoomLayoutManager?)?.let { manager ->
|
||||
|
||||
manager.updateSize(forceUpdate = true)
|
||||
if (randomSize > 2) {
|
||||
manager.scrollToPosition(randomSize / 2)
|
||||
manager.snap { dx ->
|
||||
home_main_poster_recyclerview?.post {
|
||||
// this is the best I can do, fuck android for not including instant scroll
|
||||
home_main_poster_recyclerview?.smoothScrollBy(dx, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
toggleMainVisibility(true)
|
||||
}
|
||||
} else {
|
||||
toggleMainVisibility(false)
|
||||
}
|
||||
}
|
||||
|
||||
private fun fixGrid() {
|
||||
val compactView = activity?.getGridIsCompact() ?: false
|
||||
val spanCountLandscape = if (compactView) 2 else 6
|
||||
|
@ -239,6 +199,40 @@ class HomeFragment : Fragment() {
|
|||
}
|
||||
}
|
||||
|
||||
observe(homeViewModel.randomItems) { items ->
|
||||
if (items.isNullOrEmpty()) {
|
||||
toggleMainVisibility(false)
|
||||
} else {
|
||||
val tempAdapter = home_main_poster_recyclerview.adapter as HomeChildItemAdapter?
|
||||
// no need to reload if it has the same data
|
||||
if (tempAdapter != null && tempAdapter.cardList == items) {
|
||||
toggleMainVisibility(true)
|
||||
return@observe
|
||||
}
|
||||
|
||||
val randomSize = items.size
|
||||
home_main_poster_recyclerview.adapter =
|
||||
HomeChildItemAdapter(items, R.layout.home_result_big_grid) { callback ->
|
||||
handleSearchClickCallback(activity, callback)
|
||||
}
|
||||
home_main_poster_recyclerview.post {
|
||||
(home_main_poster_recyclerview.layoutManager as CenterZoomLayoutManager?)?.let { manager ->
|
||||
manager.updateSize(forceUpdate = true)
|
||||
if (randomSize > 2) {
|
||||
manager.scrollToPosition(randomSize / 2)
|
||||
manager.snap { dx ->
|
||||
home_main_poster_recyclerview?.post {
|
||||
// this is the best I can do, fuck android for not including instant scroll
|
||||
home_main_poster_recyclerview?.smoothScrollBy(dx, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
toggleMainVisibility(true)
|
||||
}
|
||||
}
|
||||
|
||||
observe(homeViewModel.page) { data ->
|
||||
when (data) {
|
||||
is Resource.Success -> {
|
||||
|
@ -256,7 +250,6 @@ class HomeFragment : Fragment() {
|
|||
}
|
||||
|
||||
home_master_recycler?.adapter?.notifyDataSetChanged()
|
||||
chooseRandomMainPage()
|
||||
|
||||
home_loading.visibility = View.GONE
|
||||
home_loading_error.visibility = View.GONE
|
||||
|
|
|
@ -39,6 +39,9 @@ class HomeViewModel : ViewModel() {
|
|||
private val _page = MutableLiveData<Resource<HomePageResponse>>()
|
||||
val page: LiveData<Resource<HomePageResponse>> = _page
|
||||
|
||||
private val _randomItems = MutableLiveData<List<SearchResponse>?>(null)
|
||||
val randomItems: LiveData<List<SearchResponse>?> = _randomItems
|
||||
|
||||
private fun autoloadRepo(): APIRepository {
|
||||
return APIRepository(apis.first { it.hasMainPage })
|
||||
}
|
||||
|
@ -142,7 +145,29 @@ class HomeViewModel : ViewModel() {
|
|||
_apiName.postValue(repo?.name)
|
||||
if (repo?.hasMainPage == true) {
|
||||
_page.postValue(Resource.Loading())
|
||||
_page.postValue(repo?.getMainPage())
|
||||
_randomItems.postValue(null)
|
||||
|
||||
val data = repo?.getMainPage()
|
||||
when (data) {
|
||||
is Resource.Success -> {
|
||||
val home = data.value
|
||||
if (home.items.isNotEmpty()) {
|
||||
val currentList =
|
||||
home.items.shuffled().filter { !it.list.isNullOrEmpty() }.flatMap { it.list }
|
||||
.distinctBy { it.url }
|
||||
.toList()
|
||||
|
||||
if (!currentList.isNullOrEmpty()) {
|
||||
val randomItems = currentList.shuffled()
|
||||
|
||||
_randomItems.postValue(randomItems)
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
_page.postValue(data)
|
||||
} else {
|
||||
_page.postValue(Resource.Success(HomePageResponse(emptyList())))
|
||||
}
|
||||
|
@ -152,8 +177,8 @@ class HomeViewModel : ViewModel() {
|
|||
val api = getApiFromNameNull(preferredApiName)
|
||||
if (preferredApiName == noneApi.name)
|
||||
loadAndCancel(noneApi)
|
||||
else if(preferredApiName == randomApi.name || api == null) {
|
||||
var validAPIs = AppUtils.filterProviderByPreferredMedia(apis, currentPrefMedia)
|
||||
else if (preferredApiName == randomApi.name || api == null) {
|
||||
val validAPIs = AppUtils.filterProviderByPreferredMedia(apis, currentPrefMedia)
|
||||
val apiRandom = validAPIs.random()
|
||||
loadAndCancel(apiRandom)
|
||||
context?.setKey(HOMEPAGE_API, apiRandom.name)
|
||||
|
|
63
app/src/main/res/layout-land/activity_main.xml
Normal file
63
app/src/main/res/layout-land/activity_main.xml
Normal file
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
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:id="@+id/homeRoot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|keyboard|navigation"
|
||||
android:paddingTop="0dp">
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent">
|
||||
<com.google.android.material.navigationrail.NavigationRailView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/nav_rail_view"
|
||||
android:background="?attr/primaryGrayBackground"
|
||||
app:itemTextColor="@color/item_select_color"
|
||||
app:itemIconTint="@color/item_select_color"
|
||||
app:menuGravity="center"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:labelVisibilityMode="unlabeled"
|
||||
app:menu="@menu/bottom_nav_menu">
|
||||
|
||||
</com.google.android.material.navigationrail.NavigationRailView>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/nav_host_fragment"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:defaultNavHost="true"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toRightOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/cast_mini_controller_holder"
|
||||
app:navGraph="@navigation/mobile_navigation"
|
||||
app:layout_constraintStart_toEndOf="@id/nav_rail_view"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
<LinearLayout
|
||||
app:layout_constraintStart_toEndOf="@+id/nav_rail_view"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
tools:layout_height="100dp"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/cast_mini_controller_holder"
|
||||
>
|
||||
<!--com.google.android.gms.cast.framework.media.widget.MiniControllerFragment-->
|
||||
<fragment
|
||||
app:customCastBackgroundColor="?attr/primaryGrayBackground"
|
||||
app:castControlButtons="@array/cast_mini_controller_control_buttons"
|
||||
android:id="@+id/cast_mini_controller"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
class="com.lagradost.cloudstream3.ui.MyMiniControllerFragment"
|
||||
tools:ignore="FragmentTagUsage">
|
||||
</fragment>
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</FrameLayout>
|
|
@ -31,11 +31,12 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:defaultNavHost="true"
|
||||
app:layout_constraintBottom_toTopOf="@+id/nav_view"
|
||||
app:layout_constraintBottom_toTopOf="@+id/cast_mini_controller_holder"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:navGraph="@navigation/mobile_navigation"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
<LinearLayout
|
||||
tools:layout_height="100dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toTopOf="@+id/nav_view"
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
app:menuGravity="center"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:labelVisibilityMode="labeled"
|
||||
app:labelVisibilityMode="unlabeled"
|
||||
app:menu="@menu/bottom_nav_menu">
|
||||
|
||||
</com.google.android.material.navigationrail.NavigationRailView>
|
||||
|
@ -30,17 +30,21 @@
|
|||
android:id="@+id/nav_host_fragment"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:defaultNavHost="true"
|
||||
app:layout_constraintLeft_toRightOf="@+id/nav_view"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toRightOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/cast_mini_controller_holder"
|
||||
app:navGraph="@navigation/mobile_navigation"
|
||||
app:layout_constraintStart_toEndOf="@id/nav_rail_view"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/nav_rail_view"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
tools:layout_height="100dp"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toTopOf="@+id/nav_view"
|
||||
android:id="@+id/cast_mini_controller_holder"
|
||||
>
|
||||
<!--com.google.android.gms.cast.framework.media.widget.MiniControllerFragment-->
|
||||
|
|
|
@ -301,6 +301,8 @@
|
|||
</FrameLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:paddingHorizontal="5dp"
|
||||
android:clipToPadding="false"
|
||||
android:descendantFocusability="afterDescendants"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
android:id="@+id/home_watch_child_recyclerview"
|
||||
|
@ -358,6 +360,8 @@
|
|||
</FrameLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:paddingHorizontal="5dp"
|
||||
android:clipToPadding="false"
|
||||
android:descendantFocusability="afterDescendants"
|
||||
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
|
|
|
@ -32,6 +32,9 @@
|
|||
</FrameLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:paddingHorizontal="5dp"
|
||||
android:clipToPadding="false"
|
||||
|
||||
android:descendantFocusability="afterDescendants"
|
||||
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
|
|
|
@ -135,9 +135,9 @@
|
|||
<style name="OverlayPrimaryColorRed">
|
||||
<item name="colorPrimary">@color/colorPrimaryRed</item>
|
||||
<item name="android:colorPrimary">@color/colorPrimaryRed</item>
|
||||
<item name="colorPrimaryDark">#D53333</item>
|
||||
<item name="colorAccent">#F53B3B</item>
|
||||
<item name="colorOnPrimary">#EC3838</item>
|
||||
<item name="colorPrimaryDark">#B62B2B</item>
|
||||
<item name="colorAccent">@color/colorPrimaryRed</item> <!--#F53B3B-->
|
||||
<item name="colorOnPrimary">@color/colorPrimaryRed</item> <!--#EC3838-->
|
||||
<!-- Needed for leanback fuckery -->
|
||||
<item name="android:colorAccent">@color/colorPrimaryRed</item>
|
||||
</style>
|
||||
|
|
Loading…
Reference in a new issue