Use a ViewModel for live updates

This commit is contained in:
Luna712 2023-11-03 18:56:40 -06:00
parent 8d69f9f245
commit d5b422da01
7 changed files with 153 additions and 80 deletions

View file

@ -92,6 +92,8 @@ import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appStri
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.inAppAuths import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.inAppAuths
import com.lagradost.cloudstream3.ui.APIRepository import com.lagradost.cloudstream3.ui.APIRepository
import com.lagradost.cloudstream3.ui.WatchType import com.lagradost.cloudstream3.ui.WatchType
import com.lagradost.cloudstream3.ui.account.AccountHelper
import com.lagradost.cloudstream3.ui.account.AccountViewModel
import com.lagradost.cloudstream3.ui.download.DOWNLOAD_NAVIGATE_TO import com.lagradost.cloudstream3.ui.download.DOWNLOAD_NAVIGATE_TO
import com.lagradost.cloudstream3.ui.home.HomeViewModel import com.lagradost.cloudstream3.ui.home.HomeViewModel
import com.lagradost.cloudstream3.ui.player.BasicLink import com.lagradost.cloudstream3.ui.player.BasicLink
@ -1610,4 +1612,9 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
false false
} }
} }
fun showAccountSelectLinear(context: Context) {
val viewModel = ViewModelProvider(this)[AccountViewModel::class.java]
AccountHelper.showAccountSelectLinear(context, viewModel, this)
}
} }

View file

@ -22,7 +22,8 @@ class AccountAdapter(
private val accounts: List<DataStoreHelper.Account>, private val accounts: List<DataStoreHelper.Account>,
private val accountSelectCallback: (DataStoreHelper.Account) -> Unit, private val accountSelectCallback: (DataStoreHelper.Account) -> Unit,
private val accountCreateCallback: (DataStoreHelper.Account) -> Unit, private val accountCreateCallback: (DataStoreHelper.Account) -> Unit,
private val accountEditCallback: (DataStoreHelper.Account) -> Unit private val accountEditCallback: (DataStoreHelper.Account) -> Unit,
private val accountDeleteCallback: () -> Unit
) : RecyclerView.Adapter<AccountAdapter.AccountViewHolder>() { ) : RecyclerView.Adapter<AccountAdapter.AccountViewHolder>() {
companion object { companion object {
@ -62,8 +63,11 @@ class AccountAdapter(
} else { } else {
root.setOnLongClickListener { root.setOnLongClickListener {
showAccountEditDialog(root.context, account, isNewAccount = false) { showAccountEditDialog(root.context, account, isNewAccount = false) {
accountEditCallback.invoke(it) if (it != null) {
accountEditCallback.invoke(it)
} else accountDeleteCallback.invoke()
} }
true true
} }
} }
@ -105,7 +109,9 @@ class AccountAdapter(
root.setOnClickListener { root.setOnClickListener {
showAccountEditDialog(root.context, account, isNewAccount = false) { showAccountEditDialog(root.context, account, isNewAccount = false) {
accountEditCallback.invoke(it) if (it != null) {
accountEditCallback.invoke(it)
} else accountDeleteCallback.invoke()
} }
} }
} }
@ -128,7 +134,9 @@ class AccountAdapter(
customImage = null, customImage = null,
defaultImageIndex = image defaultImageIndex = image
), isNewAccount = true) { ), isNewAccount = true) {
accountCreateCallback.invoke(it) if (it != null) {
accountCreateCallback.invoke(it)
}
} }
} }
} }

View file

@ -12,6 +12,7 @@ import androidx.appcompat.app.AlertDialog
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.widget.doOnTextChanged import androidx.core.widget.doOnTextChanged
import androidx.lifecycle.LifecycleOwner
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialog
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKeys import com.lagradost.cloudstream3.AcraApplication.Companion.removeKeys
@ -20,6 +21,7 @@ import com.lagradost.cloudstream3.databinding.AccountEditDialogBinding
import com.lagradost.cloudstream3.databinding.AccountSelectLinearBinding import com.lagradost.cloudstream3.databinding.AccountSelectLinearBinding
import com.lagradost.cloudstream3.databinding.LockPinDialogBinding import com.lagradost.cloudstream3.databinding.LockPinDialogBinding
import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.mvvm.observe
import com.lagradost.cloudstream3.ui.result.setImage import com.lagradost.cloudstream3.ui.result.setImage
import com.lagradost.cloudstream3.ui.result.setLinearListLayout import com.lagradost.cloudstream3.ui.result.setLinearListLayout
import com.lagradost.cloudstream3.utils.AppUtils.setDefaultFocus import com.lagradost.cloudstream3.utils.AppUtils.setDefaultFocus
@ -35,7 +37,7 @@ object AccountHelper {
context: Context, context: Context,
account: DataStoreHelper.Account, account: DataStoreHelper.Account,
isNewAccount: Boolean, isNewAccount: Boolean,
callback: (DataStoreHelper.Account) -> Unit callback: (DataStoreHelper.Account?) -> Unit
) { ) {
val binding = AccountEditDialogBinding.inflate(LayoutInflater.from(context), null, false) val binding = AccountEditDialogBinding.inflate(LayoutInflater.from(context), null, false)
val builder = AlertDialog.Builder(context, R.style.AlertDialogCustom) val builder = AlertDialog.Builder(context, R.style.AlertDialogCustom)
@ -65,6 +67,7 @@ object AccountHelper {
// Update UI // Update UI
setAccount(getDefaultAccount(context), true) setAccount(getDefaultAccount(context), true)
callback.invoke(null)
dialog?.dismissSafe() dialog?.dismissSafe()
} }
@ -274,7 +277,11 @@ object AccountHelper {
}, 200) }, 200)
} }
fun showAccountSelectLinear(context: Context) { fun showAccountSelectLinear(
context: Context,
viewModel: AccountViewModel,
lifecycleOwner: LifecycleOwner
) {
fun onAccountUpdated(account: DataStoreHelper.Account) { fun onAccountUpdated(account: DataStoreHelper.Account) {
val currentAccounts = DataStoreHelper.accounts.toMutableList() val currentAccounts = DataStoreHelper.accounts.toMutableList()
@ -318,30 +325,38 @@ object AccountHelper {
recyclerView.addItemDecoration(AccountSelectLinearItemDecoration(itemWidth, itemHeight)) recyclerView.addItemDecoration(AccountSelectLinearItemDecoration(itemWidth, itemHeight))
recyclerView.setLinearListLayout(isHorizontal = true) recyclerView.setLinearListLayout(isHorizontal = true)
recyclerView.adapter = AccountAdapter(
getAccounts(context), lifecycleOwner.observe(viewModel.accountsLiveData) { liveAccounts ->
accountSelectCallback = { account -> recyclerView.adapter = AccountAdapter(
// Check if the selected account has a lock PIN set liveAccounts,
if (account.lockPin != null) { accountSelectCallback = { account ->
// Prompt for the lock pin // Check if the selected account has a lock PIN set
showPinInputDialog(context, account.lockPin, false) { pin -> if (account.lockPin != null) {
if (pin == null) return@showPinInputDialog // Prompt for the lock pin
// Pin is correct, unlock the profile showPinInputDialog(context, account.lockPin, false) { pin ->
if (pin == null) return@showPinInputDialog
// Pin is correct, unlock the profile
setAccount(account, true)
builder.dismissSafe()
}
} else {
// No lock PIN set, directly set the account
setAccount(account, true) setAccount(account, true)
builder.dismissSafe() builder.dismissSafe()
} }
} else { },
// No lock PIN set, directly set the account accountCreateCallback = {
setAccount(account, true) onAccountUpdated(it)
builder.dismissSafe() viewModel.updateAccounts(getAccounts(context))
},
accountEditCallback = {
onAccountUpdated(it)
viewModel.updateAccounts(getAccounts(context))
},
accountDeleteCallback = {
viewModel.updateAccounts(getAccounts(context))
} }
}, )
accountCreateCallback = { }
onAccountUpdated(it)
builder.dismissSafe()
},
// Editing is done using AccountSelectActivity
accountEditCallback = {}
)
} }
} }

View file

@ -4,6 +4,7 @@ import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.widget.ImageView import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.lagradost.cloudstream3.CommonActivity import com.lagradost.cloudstream3.CommonActivity
@ -11,6 +12,7 @@ import com.lagradost.cloudstream3.CommonActivity.loadThemes
import com.lagradost.cloudstream3.MainActivity import com.lagradost.cloudstream3.MainActivity
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.databinding.ActivityAccountSelectBinding import com.lagradost.cloudstream3.databinding.ActivityAccountSelectBinding
import com.lagradost.cloudstream3.mvvm.observe
import com.lagradost.cloudstream3.ui.account.AccountAdapter.Companion.VIEW_TYPE_EDIT_ACCOUNT import com.lagradost.cloudstream3.ui.account.AccountAdapter.Companion.VIEW_TYPE_EDIT_ACCOUNT
import com.lagradost.cloudstream3.ui.account.AccountAdapter.Companion.VIEW_TYPE_SELECT_ACCOUNT import com.lagradost.cloudstream3.ui.account.AccountAdapter.Companion.VIEW_TYPE_SELECT_ACCOUNT
import com.lagradost.cloudstream3.ui.account.AccountHelper.showPinInputDialog import com.lagradost.cloudstream3.ui.account.AccountHelper.showPinInputDialog
@ -23,11 +25,18 @@ class AccountSelectActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
// Are we editing and coming from MainActivity?
val isEditingFromMainActivity = intent.getBooleanExtra(
"isEditingFromMainActivity",
false
)
val accounts = getAccounts(this@AccountSelectActivity) val accounts = getAccounts(this@AccountSelectActivity)
// Don't show account selection if there is only // Don't show account selection if there is only
// one account that exists // one account that exists
if (accounts.count() <= 1) { if (!isEditingFromMainActivity && accounts.count() <= 1) {
navigateToMainActivity() navigateToMainActivity()
return return
} }
@ -42,61 +51,77 @@ class AccountSelectActivity : AppCompatActivity() {
val recyclerView: RecyclerView = binding.accountRecyclerView val recyclerView: RecyclerView = binding.accountRecyclerView
// Are we editing and coming from MainActivity? val viewModel = ViewModelProvider(this)[AccountViewModel::class.java]
val isEditingFromMainActivity = intent.getBooleanExtra(
"isEditingFromMainActivity",
false
)
val adapter = AccountAdapter( observe(viewModel.accountsLiveData) { liveAccounts ->
accounts, val adapter = AccountAdapter(
// Handle the selected account liveAccounts,
accountSelectCallback = { onAccountSelected(it) }, // Handle the selected account
accountCreateCallback = { onAccountUpdated(it) }, accountSelectCallback = { onAccountSelected(it) },
accountEditCallback = { accountCreateCallback = {
onAccountUpdated(it) onAccountUpdated(it)
// We came from MainActivity, return there viewModel.updateAccounts(
// and switch to the edited account getAccounts(binding.root.context)
if (isEditingFromMainActivity) { )
DataStoreHelper.setAccount(it, it.keyIndex != DataStoreHelper.selectedKeyIndex) },
navigateToMainActivity() accountEditCallback = {
onAccountUpdated(it)
viewModel.updateAccounts(
getAccounts(binding.root.context)
)
// We came from MainActivity, return there
// and switch to the edited account
if (isEditingFromMainActivity) {
DataStoreHelper.setAccount(
it,
it.keyIndex != DataStoreHelper.selectedKeyIndex
)
navigateToMainActivity()
}
},
accountDeleteCallback = {
viewModel.updateAccounts(
getAccounts(binding.root.context)
)
} }
} )
)
recyclerView.adapter = adapter recyclerView.adapter = adapter
var isEditing = false var isEditing = false
if (isEditingFromMainActivity) { if (isEditingFromMainActivity) {
binding.editAccountButton.setImageResource(R.drawable.ic_baseline_close_24) binding.editAccountButton.setImageResource(R.drawable.ic_baseline_close_24)
binding.title.setText(R.string.manage_accounts) binding.title.setText(R.string.manage_accounts)
adapter.viewType = VIEW_TYPE_EDIT_ACCOUNT adapter.viewType = VIEW_TYPE_EDIT_ACCOUNT
isEditing = true isEditing = true
adapter.notifyDataSetChanged() adapter.notifyDataSetChanged()
}
binding.editAccountButton.setOnClickListener {
isEditing = !isEditing
if (isEditing) {
(it as ImageView).setImageResource(R.drawable.ic_baseline_close_24)
binding.title.setText(R.string.manage_accounts)
adapter.viewType = VIEW_TYPE_EDIT_ACCOUNT
} else {
// We came from MainActivity, return there
// and resume it's state
if (isEditingFromMainActivity) {
navigateToMainActivity()
}
(it as ImageView).setImageResource(R.drawable.ic_baseline_edit_24)
binding.title.setText(R.string.select_an_account)
adapter.viewType = VIEW_TYPE_SELECT_ACCOUNT
} }
adapter.notifyDataSetChanged() binding.editAccountButton.setOnClickListener {
isEditing = !isEditing
if (isEditing) {
(it as ImageView).setImageResource(R.drawable.ic_baseline_close_24)
binding.title.setText(R.string.manage_accounts)
adapter.viewType = VIEW_TYPE_EDIT_ACCOUNT
} else {
// We came from MainActivity, return there
// and resume it's state
if (isEditingFromMainActivity) {
navigateToMainActivity()
}
(it as ImageView).setImageResource(R.drawable.ic_baseline_edit_24)
binding.title.setText(R.string.select_an_account)
adapter.viewType = VIEW_TYPE_SELECT_ACCOUNT
}
adapter.notifyDataSetChanged()
}
} }
if (isTvSettings()) { if (isTvSettings()) {
@ -137,8 +162,6 @@ class AccountSelectActivity : AppCompatActivity() {
DataStoreHelper.accounts = currentAccounts.toTypedArray() DataStoreHelper.accounts = currentAccounts.toTypedArray()
DataStoreHelper.currentHomePage = currentHomePage DataStoreHelper.currentHomePage = currentHomePage
this.recreate()
} }
private fun setAccount(account: DataStoreHelper.Account) { private fun setAccount(account: DataStoreHelper.Account) {

View file

@ -0,0 +1,21 @@
package com.lagradost.cloudstream3.ui.account
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.lagradost.cloudstream3.utils.DataStoreHelper
class AccountViewModel : ViewModel() {
private val _accountsLiveData = MutableLiveData<List<DataStoreHelper.Account>>()
val accountsLiveData: LiveData<List<DataStoreHelper.Account>> get() = _accountsLiveData
init {
// Default to using the getAccounts function to retrieve initial data
val initialAccounts = DataStoreHelper.accounts.toList()
_accountsLiveData.value = initialAccounts
}
fun updateAccounts(newAccounts: List<DataStoreHelper.Account>) {
_accountsLiveData.value = newAccounts
}
}

View file

@ -38,7 +38,6 @@ import com.lagradost.cloudstream3.mvvm.observe
import com.lagradost.cloudstream3.mvvm.observeNullable import com.lagradost.cloudstream3.mvvm.observeNullable
import com.lagradost.cloudstream3.ui.APIRepository.Companion.noneApi import com.lagradost.cloudstream3.ui.APIRepository.Companion.noneApi
import com.lagradost.cloudstream3.ui.APIRepository.Companion.randomApi import com.lagradost.cloudstream3.ui.APIRepository.Companion.randomApi
import com.lagradost.cloudstream3.ui.account.AccountHelper.showAccountSelectLinear
import com.lagradost.cloudstream3.ui.result.txt import com.lagradost.cloudstream3.ui.result.txt
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
@ -497,8 +496,9 @@ class HomeFragment : Fragment() {
homeApiFab.setOnClickListener(apiChangeClickListener) homeApiFab.setOnClickListener(apiChangeClickListener)
homeChangeApi.setOnClickListener(apiChangeClickListener) homeChangeApi.setOnClickListener(apiChangeClickListener)
homeSwitchAccount.setOnClickListener { v -> homeSwitchAccount.setOnClickListener { v ->
showAccountSelectLinear(v?.context ?: return@setOnClickListener) (CommonActivity.activity as MainActivity).showAccountSelectLinear(v?.context ?: return@setOnClickListener)
} }
homeRandom.setOnClickListener { homeRandom.setOnClickListener {
if (listHomepageItems.isNotEmpty()) { if (listHomepageItems.isNotEmpty()) {
activity.loadSearchResult(listHomepageItems.random()) activity.loadSearchResult(listHomepageItems.random())

View file

@ -27,7 +27,6 @@ import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.mvvm.debugException import com.lagradost.cloudstream3.mvvm.debugException
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.account.AccountHelper.showAccountSelectLinear
import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.selectHomepage import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.selectHomepage
import com.lagradost.cloudstream3.ui.result.FOCUS_SELF import com.lagradost.cloudstream3.ui.result.FOCUS_SELF
import com.lagradost.cloudstream3.ui.result.ResultViewModel2 import com.lagradost.cloudstream3.ui.result.ResultViewModel2
@ -479,7 +478,7 @@ class HomeParentItemAdapterPreview(
} }
homeAccount?.setOnClickListener { v -> homeAccount?.setOnClickListener { v ->
showAccountSelectLinear(v?.context ?: return@setOnClickListener) (activity as MainActivity).showAccountSelectLinear(v?.context ?: return@setOnClickListener)
} }
(binding as? FragmentHomeHeadTvBinding)?.apply { (binding as? FragmentHomeHeadTvBinding)?.apply {