3
3
Fork 1
mirror of https://github.com/recloudstream/cloudstream.git synced 2024-08-15 01:53:11 +00:00

fix conflicts

This commit is contained in:
CranberrySoup 2023-09-22 14:33:04 +02:00
parent f8603a7874
commit 2c3bdafd45
10 changed files with 85 additions and 214 deletions

View file

@ -7,7 +7,6 @@ import android.content.DialogInterface
import android.content.Intent
import android.content.res.Configuration
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@ -23,9 +22,7 @@ import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.button.MaterialButton
import com.google.android.material.chip.Chip
import com.google.android.material.chip.ChipGroup
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.APIHolder.apis
import com.lagradost.cloudstream3.APIHolder.filterProviderByPreferredMedia
@ -47,15 +44,12 @@ import com.lagradost.cloudstream3.mvvm.observeNullable
import com.lagradost.cloudstream3.ui.APIRepository.Companion.noneApi
import com.lagradost.cloudstream3.ui.APIRepository.Companion.randomApi
import com.lagradost.cloudstream3.ui.WatchType
import com.lagradost.cloudstream3.ui.quicksearch.QuickSearchFragment
import com.lagradost.cloudstream3.ui.result.txt
import com.lagradost.cloudstream3.ui.search.*
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.isTvSettings
import com.lagradost.cloudstream3.utils.AppUtils.addProgramsToContinueWatching
import com.lagradost.cloudstream3.utils.AppUtils.isRecyclerScrollable
import com.lagradost.cloudstream3.utils.AppUtils.loadResult
import com.lagradost.cloudstream3.utils.AppUtils.loadSearchResult
import com.lagradost.cloudstream3.utils.AppUtils.ownHide
import com.lagradost.cloudstream3.utils.AppUtils.ownShow
@ -64,13 +58,12 @@ import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
import com.lagradost.cloudstream3.utils.DataStore.getKey
import com.lagradost.cloudstream3.utils.DataStore.setKey
import com.lagradost.cloudstream3.utils.DataStoreHelper
import com.lagradost.cloudstream3.utils.DataStoreHelper.currentHomePage
import com.lagradost.cloudstream3.utils.Event
import com.lagradost.cloudstream3.utils.SubtitleHelper.getFlagFromIso
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar
import com.lagradost.cloudstream3.utils.UIHelper.getSpanCount
import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIconsAndNoStringRes
import java.util.*
@ -523,7 +516,7 @@ class HomeFragment : Fragment() {
}
private fun reloadStored(unused: Unit = Unit) {
homeViewModel.loadResumeWatching()
homeViewModel.reloadStored()
val list = EnumSet.noneOf(WatchType::class.java)
getKey<IntArray>(HOME_BOOKMARK_VALUE_LIST)?.map { WatchType.fromInternalId(it) }?.let {
list.addAll(it)
@ -540,7 +533,7 @@ class HomeFragment : Fragment() {
}
private fun loadHomePage(forceReload: Boolean) {
val apiName = context?.getKey<String>(USER_SELECTED_HOMEPAGE_API)
val apiName = currentHomePage
if (homeViewModel.apiName.value != apiName || apiName == null || forceReload) {
//println("Caught home: " + homeViewModel.apiName.value + " at " + apiName)
@ -552,7 +545,7 @@ class HomeFragment : Fragment() {
if (callback.action == SEARCH_ACTION_FOCUSED) {
//focusCallback(callback.card)
} else {
handleSearchClickCallback(activity, callback)
handleSearchClickCallback(callback)
}
}

View file

@ -15,7 +15,6 @@ import android.view.animation.AlphaAnimation
import androidx.annotation.StringRes
import androidx.appcompat.widget.SearchView
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import com.google.android.material.tabs.TabLayoutMediator
import com.lagradost.cloudstream3.APIHolder
@ -93,12 +92,8 @@ class LibraryFragment : Fragment() {
override fun onDestroyView() {
binding = null
super.onDestroyView()
}
override fun onDestroyView() {
super.onDestroyView()
MainActivity.afterBackupRestoreEvent -= ::onNewSyncData
super.onDestroyView()
}
override fun onSaveInstanceState(outState: Bundle) {

View file

@ -12,9 +12,8 @@ import androidx.recyclerview.widget.RecyclerView
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.databinding.AccountManagmentBinding
import com.lagradost.cloudstream3.databinding.AccountSwitchBinding
import com.lagradost.cloudstream3.databinding.AddAccountInputBinding
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.syncproviders.*
import com.lagradost.cloudstream3.syncproviders.AccountManager
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.aniListApi
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.googleDriveApi
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.malApi
@ -22,6 +21,7 @@ import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.openSub
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.simklApi
import com.lagradost.cloudstream3.syncproviders.AuthAPI
import com.lagradost.cloudstream3.syncproviders.InAppAuthAPI
import com.lagradost.cloudstream3.syncproviders.InAppOAuth2API
import com.lagradost.cloudstream3.syncproviders.OAuth2API
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.getPref
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
@ -108,129 +108,12 @@ class SettingsAccount : PreferenceFragmentCompat() {
}
@UiThread
fun addAccount(activity: FragmentActivity?, api: AccountManager) {
fun addAccount(activity: FragmentActivity, api: AccountManager) {
try {
when (api) {
is OAuth2API -> {
api.authenticate(activity)
}
is InAppAuthAPI -> {
if (activity == null) return
val binding: AddAccountInputBinding =
AddAccountInputBinding.inflate(activity.layoutInflater, null, false)
val builder =
AlertDialog.Builder(activity, R.style.AlertDialogCustom)
.setView(binding.root)
val dialog = builder.show()
val visibilityMap = listOf(
binding.loginEmailInput to api.requiresEmail,
binding.loginPasswordInput to api.requiresPassword,
binding.loginServerInput to api.requiresServer,
binding.loginUsernameInput to api.requiresUsername
)
if (isTvSettings()) {
visibilityMap.forEach { (input, isVisible) ->
input.isVisible = isVisible
// Band-aid for weird FireTV behavior causing crashes because keyboard covers the screen
input.setOnEditorActionListener { textView, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_NEXT) {
val view = textView.focusSearch(FOCUS_DOWN)
return@setOnEditorActionListener view?.requestFocus(
FOCUS_DOWN
) == true
}
return@setOnEditorActionListener true
}
}
} else {
visibilityMap.forEach { (input, isVisible) ->
input.isVisible = isVisible
}
}
binding.loginEmailInput.isVisible = api.requiresEmail
binding.loginPasswordInput.isVisible = api.requiresPassword
binding.loginServerInput.isVisible = api.requiresServer
binding.loginUsernameInput.isVisible = api.requiresUsername
binding.createAccount.isGone = api.createAccountUrl.isNullOrBlank()
binding.createAccount.setOnClickListener {
openBrowser(
api.createAccountUrl ?: return@setOnClickListener,
activity
)
dialog.dismissSafe()
}
val displayedItems = listOf(
binding.loginUsernameInput,
binding.loginEmailInput,
binding.loginServerInput,
binding.loginPasswordInput
).filter { it.isVisible }
displayedItems.foldRight(displayedItems.firstOrNull()) { item, previous ->
item.id.let { previous?.nextFocusDownId = it }
previous?.id?.let { item.nextFocusUpId = it }
item
}
displayedItems.firstOrNull()?.let {
binding.createAccount.nextFocusDownId = it.id
it.nextFocusUpId = binding.createAccount.id
}
binding.applyBtt.id.let {
displayedItems.lastOrNull()?.nextFocusDownId = it
}
binding.text1.text = api.name
if (api.storesPasswordInPlainText) {
api.getLatestLoginData()?.let { data ->
binding.loginEmailInput.setText(data.email ?: "")
binding.loginServerInput.setText(data.server ?: "")
binding.loginUsernameInput.setText(data.username ?: "")
binding.loginPasswordInput.setText(data.password ?: "")
}
}
binding.applyBtt.setOnClickListener {
val loginData = InAppAuthAPI.LoginData(
username = if (api.requiresUsername) binding.loginUsernameInput.text?.toString() else null,
password = if (api.requiresPassword) binding.loginPasswordInput.text?.toString() else null,
email = if (api.requiresEmail) binding.loginEmailInput.text?.toString() else null,
server = if (api.requiresServer) binding.loginServerInput.text?.toString() else null,
)
ioSafe {
val isSuccessful = try {
api.login(loginData)
} catch (e: Exception) {
logError(e)
false
}
activity.runOnUiThread {
try {
showToast(
activity.getString(if (isSuccessful) R.string.authenticated_user else R.string.authenticated_user_fail)
.format(
api.name
)
)
} catch (e: Exception) {
logError(e) // format might fail
}
}
}
dialog.dismissSafe(activity)
}
binding.cancelBtt.setOnClickListener {
dialog.dismissSafe(activity)
}
}
is InAppOAuth2API -> InAppOAuth2DialogBuilder(api, activity).open()
is OAuth2API -> api.authenticate(activity)
is InAppAuthAPI -> InAppAuthDialogBuilder(api, activity).open()
else -> {
throw NotImplementedError("You are trying to add an account that has an unknown login method")
}
@ -269,7 +152,7 @@ class SettingsAccount : PreferenceFragmentCompat() {
if (info != null) {
showLoginInfo(activity, api, info)
} else {
addAccount(activity, api)
activity?.let { activity -> addAccount(activity, api) }
}
return@setOnPreferenceClickListener true
}

View file

@ -6,16 +6,17 @@ import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.core.view.isVisible
import androidx.fragment.app.FragmentActivity
import androidx.viewbinding.ViewBinding
import com.google.android.material.button.MaterialButton
import com.lagradost.cloudstream3.syncproviders.AuthAPI
import com.lagradost.cloudstream3.ui.settings.SettingsFragment
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
abstract class DialogBuilder(
abstract class DialogBuilder<T : ViewBinding>(
private val api: AuthAPI,
private val activity: FragmentActivity?,
private val themeResId: Int,
private val layoutResId: Int,
val binding: T,
) {
class CommonDialogItems(
private val dialog: AlertDialog,
@ -57,7 +58,7 @@ abstract class DialogBuilder(
return null
}
val dialogBuilder = AlertDialog.Builder(activity, themeResId).setView(layoutResId)
val dialogBuilder = AlertDialog.Builder(activity, themeResId).setView(binding.root)
val dialog = dialogBuilder.show()
setup(dialog)
@ -111,8 +112,8 @@ abstract class DialogBuilder(
val displayedItems = getVisibilityMap(dialog).keys.filter { it.isVisible }
displayedItems.foldRight(displayedItems.firstOrNull()) { item, previous ->
item?.id?.let { previous?.nextFocusDownId = it }
previous?.id?.let { item?.nextFocusUpId = it }
item.id.let { previous?.nextFocusDownId = it }
previous?.id?.let { item.nextFocusUpId = it }
item
}

View file

@ -8,30 +8,30 @@ import androidx.fragment.app.FragmentActivity
import com.lagradost.cloudstream3.AcraApplication
import com.lagradost.cloudstream3.CommonActivity
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.databinding.AddAccountInputBinding
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.syncproviders.InAppAuthAPI
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
import kotlinx.android.synthetic.main.add_account_input.*
class InAppAuthDialogBuilder(
private val api: InAppAuthAPI,
private val activity: FragmentActivity?,
) : DialogBuilder(
private val activity: FragmentActivity,
) : DialogBuilder<AddAccountInputBinding>(
api,
activity,
R.style.AlertDialogCustom,
R.layout.add_account_input,
AddAccountInputBinding.inflate(activity.layoutInflater),
) {
override fun onLogin(dialog: AlertDialog): Unit = with(dialog) {
if (activity == null) throw IllegalStateException("Login should be called after validation")
override fun onLogin(dialog: AlertDialog): Unit = with(binding) {
// if (activity == null) throw IllegalStateException("Login should be called after validation")
val loginData = InAppAuthAPI.LoginData(
username = if (api.requiresUsername) login_username_input?.text?.toString() else null,
password = if (api.requiresPassword) login_password_input?.text?.toString() else null,
email = if (api.requiresEmail) login_email_input?.text?.toString() else null,
server = if (api.requiresServer) login_server_input?.text?.toString() else null,
username = if (api.requiresUsername) loginUsernameInput.text?.toString() else null,
password = if (api.requiresPassword) loginPasswordInput.text?.toString() else null,
email = if (api.requiresEmail) loginEmailInput.text?.toString() else null,
server = if (api.requiresServer) loginServerInput.text?.toString() else null,
)
ioSafe {
@ -41,6 +41,9 @@ class InAppAuthDialogBuilder(
logError(e)
false
}
if (isSuccessful) {
dialog.dismissSafe()
}
activity.runOnUiThread {
try {
CommonActivity.showToast(
@ -58,43 +61,43 @@ class InAppAuthDialogBuilder(
}
override fun getCommonItems(dialog: AlertDialog) = with(dialog) {
CommonDialogItems(dialog, text1, apply_btt, cancel_btt, create_account,null)
override fun getCommonItems(dialog: AlertDialog) = with(binding) {
CommonDialogItems(dialog, text1, applyBtt, cancelBtt, createAccount,null)
}
override fun getVisibilityMap(dialog: AlertDialog): Map<View, Boolean> = with(dialog) {
override fun getVisibilityMap(dialog: AlertDialog): Map<View, Boolean> = with(binding) {
mapOf(
login_email_input to api.requiresEmail,
login_password_input to api.requiresPassword,
login_server_input to api.requiresServer,
login_username_input to api.requiresUsername
loginEmailInput to api.requiresEmail,
loginPasswordInput to api.requiresPassword,
loginServerInput to api.requiresServer,
loginUsernameInput to api.requiresUsername
)
}
override fun setupItems(dialog: AlertDialog): Unit = with(dialog) {
login_email_input?.isVisible = api.requiresEmail
login_password_input?.isVisible = api.requiresPassword
login_server_input?.isVisible = api.requiresServer
login_username_input?.isVisible = api.requiresUsername
override fun setupItems(dialog: AlertDialog): Unit = with(binding) {
loginEmailInput.isVisible = api.requiresEmail
loginPasswordInput.isVisible = api.requiresPassword
loginServerInput.isVisible = api.requiresServer
loginUsernameInput.isVisible = api.requiresUsername
create_account?.isGone = api.createAccountUrl.isNullOrBlank()
create_account?.setOnClickListener {
createAccount.isGone = api.createAccountUrl.isNullOrBlank()
createAccount.setOnClickListener {
AcraApplication.openBrowser(
api.createAccountUrl ?: return@setOnClickListener, activity
)
dismissSafe()
dialog.dismissSafe()
}
}
override fun handleStoresPasswordInPlainText(dialog: AlertDialog): Unit = with(dialog) {
override fun handleStoresPasswordInPlainText(dialog: AlertDialog): Unit = with(binding) {
if (!api.storesPasswordInPlainText) return
api.getLatestLoginData()?.let { data ->
login_email_input?.setText(data.email ?: "")
login_server_input?.setText(data.server ?: "")
login_username_input?.setText(data.username ?: "")
login_password_input?.setText(data.password ?: "")
loginEmailInput.setText(data.email ?: "")
loginServerInput.setText(data.server ?: "")
loginUsernameInput.setText(data.username ?: "")
loginPasswordInput.setText(data.password ?: "")
}
}
}

View file

@ -8,66 +8,65 @@ import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.fragment.app.FragmentActivity
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.databinding.AddAccountInputOauthBinding
import com.lagradost.cloudstream3.syncproviders.InAppOAuth2API
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
import kotlinx.android.synthetic.main.add_account_input_oauth.apply_btt
import kotlinx.android.synthetic.main.add_account_input_oauth.cancel_btt
import kotlinx.android.synthetic.main.add_account_input_oauth.info_button
import kotlinx.android.synthetic.main.add_account_input_oauth.login_client_id
import kotlinx.android.synthetic.main.add_account_input_oauth.login_client_secret
import kotlinx.android.synthetic.main.add_account_input_oauth.login_file_name
import kotlinx.android.synthetic.main.add_account_input_oauth.text1
class InAppOAuth2DialogBuilder(
private val api: InAppOAuth2API,
private val activity: FragmentActivity?,
) : DialogBuilder(api, activity, R.style.AlertDialogCustom, R.layout.add_account_input_oauth) {
override fun getCommonItems(dialog: AlertDialog) = with(dialog) {
CommonDialogItems(dialog, text1, apply_btt, cancel_btt, null, info_button)
private val activity: FragmentActivity,
) : DialogBuilder<AddAccountInputOauthBinding>(
api, activity, R.style.AlertDialogCustom,
AddAccountInputOauthBinding.inflate(activity.layoutInflater)
) {
override fun getCommonItems(dialog: AlertDialog) = with(binding) {
CommonDialogItems(dialog, text1, applyBtt, cancelBtt, null, infoButton)
}
override fun getVisibilityMap(dialog: AlertDialog): Map<View, Boolean> = with(dialog) {
override fun getVisibilityMap(dialog: AlertDialog): Map<View, Boolean> = with(binding) {
mapOf(
login_file_name to api.requiresFilename,
login_client_id to api.requiresClientId,
login_client_secret to api.requiresSecret,
loginFileName to api.requiresFilename,
loginClientId to api.requiresClientId,
loginClientSecret to api.requiresSecret,
)
}
override fun setupItems(dialog: AlertDialog): Unit = with(dialog) {
login_file_name?.isVisible = api.requiresFilename
login_client_id?.isVisible = api.requiresClientId
login_client_secret?.isVisible = api.requiresSecret
override fun setupItems(dialog: AlertDialog): Unit = with(binding) {
loginFileName.isVisible = api.requiresFilename
loginClientId.isVisible = api.requiresClientId
loginClientSecret.isVisible = api.requiresSecret
info_button?.isGone = api.infoUrl.isNullOrBlank()
info_button?.setOnClickListener {
infoButton.isGone = api.infoUrl.isNullOrBlank()
infoButton.setOnClickListener {
val customTabIntent = CustomTabsIntent.Builder().setShowTitle(true).build()
customTabIntent.launchUrl(context, Uri.parse(api.infoUrl))
customTabIntent.launchUrl(binding.root.context, Uri.parse(api.infoUrl))
}
}
override fun onLogin(dialog: AlertDialog): Unit = with(activity) {
if (this == null) throw IllegalStateException("Login should be called after validation")
override fun onLogin(dialog: AlertDialog): Unit = with(binding) {
// if (this == null) throw IllegalStateException("Login should be called after validation")
val clientId = dialog.login_client_id.text.toString().ifBlank {
getString(R.string.debug_gdrive_clientId)
val ctx = this.root.context
val clientId = loginClientId.text.toString().ifBlank {
ctx.getString(R.string.debug_gdrive_clientId)
}
val clientSecret = dialog.login_client_secret.text.toString().ifBlank {
getString(R.string.debug_gdrive_secret)
val clientSecret = loginClientSecret.text.toString().ifBlank {
ctx.getString(R.string.debug_gdrive_secret)
}
val syncFileName = dialog.login_file_name.text.toString().trim().ifBlank {
val syncFileName = loginFileName.text.toString().trim().ifBlank {
api.defaultFilenameValue
}
val redirectUrl = dialog.login_file_name.text.toString().trim().ifBlank {
val redirectUrl = loginFileName.text.toString().trim().ifBlank {
api.defaultRedirectUrl
}
ioSafe {
api.getAuthorizationToken(
this@with,
this@InAppOAuth2DialogBuilder.activity,
InAppOAuth2API.LoginData(
clientId = clientId,
secret = clientSecret,

View file

@ -53,7 +53,7 @@ class SetupFragmentLanguage : Fragment() {
val ctx = context ?: return@normalSafeApiCall
val settingsManager = PreferenceManager.getDefaultSharedPreferences(ctx)
.attachBackupListener(getSyncPrefs()).self
.attachBackupListener(ctx.getSyncPrefs()).self
val arrayAdapter =
ArrayAdapter<String>(ctx, R.layout.sort_bottom_single_choice)

View file

@ -45,7 +45,7 @@ class SetupFragmentLayout : Fragment() {
val ctx = context ?: return@normalSafeApiCall
val settingsManager = PreferenceManager.getDefaultSharedPreferences(ctx)
.attachBackupListener(getSyncPrefs()).self
.attachBackupListener(ctx.getSyncPrefs()).self
val prefNames = resources.getStringArray(R.array.app_layout)
val prefValues = resources.getIntArray(R.array.app_layout_values)

View file

@ -10,7 +10,6 @@ import androidx.core.util.forEach
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import androidx.preference.PreferenceManager
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.TvType
import com.lagradost.cloudstream3.databinding.FragmentSetupMediaBinding
@ -19,8 +18,6 @@ import com.lagradost.cloudstream3.utils.DataStoreHelper
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar
import com.lagradost.cloudstream3.utils.Scheduler.Companion.attachBackupListener
import com.lagradost.cloudstream3.utils.DataStore.getSyncPrefs
import com.lagradost.cloudstream3.utils.DataStore.removeKey
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar
class SetupFragmentMedia : Fragment() {
@ -49,7 +46,7 @@ class SetupFragmentMedia : Fragment() {
val ctx = context ?: return@normalSafeApiCall
val settingsManager = PreferenceManager.getDefaultSharedPreferences(ctx)
.attachBackupListener(getSyncPrefs()).self
.attachBackupListener(ctx.getSyncPrefs()).self
val arrayAdapter =
ArrayAdapter<String>(ctx, R.layout.sort_bottom_single_choice)

View file

@ -48,7 +48,7 @@ class SetupFragmentProviderLanguage : Fragment() {
val ctx = context ?: return@normalSafeApiCall
val settingsManager = PreferenceManager.getDefaultSharedPreferences(ctx)
.attachBackupListener(getSyncPrefs()).self
.attachBackupListener(ctx.getSyncPrefs()).self
val arrayAdapter =
ArrayAdapter<String>(ctx, R.layout.sort_bottom_single_choice)