Unprivated function to allow nginx plugin to use it

This commit is contained in:
Blatzar 2022-08-17 18:14:36 +02:00
parent 4546370dc4
commit 8b321bbd5e
5 changed files with 184 additions and 230 deletions

View file

@ -1,7 +1,9 @@
package com.lagradost.cloudstream3
import android.app.Activity
import android.app.Application
import android.content.Context
import android.content.ContextWrapper
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.google.auto.service.AutoService
@ -89,6 +91,10 @@ class AcraApplication : Application() {
}
companion object {
/** Use to get activity from Context */
tailrec fun Context.getActivity(): Activity? = this as? Activity
?: (this as? ContextWrapper)?.baseContext?.getActivity()
private var _context: WeakReference<Context>? = null
var context
get() = _context?.get()

View file

@ -12,7 +12,6 @@ abstract class AccountManager(private val defIndex: Int) : AuthAPI {
val aniListApi = AniListApi(0)
val openSubtitlesApi = OpenSubtitlesApi(0)
val indexSubtitlesApi = IndexSubtitleApi()
//val nginxApi = NginxApi(0) // TODO: fix
// used to login via app intent
val OAuth2Apis

View file

@ -1,60 +0,0 @@
// package com.lagradost.cloudstream3.syncproviders.providers
// import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
// import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
// import com.lagradost.cloudstream3.R
// import com.lagradost.cloudstream3.movieproviders.NginxProvider
// import com.lagradost.cloudstream3.syncproviders.AuthAPI
// import com.lagradost.cloudstream3.syncproviders.InAppAuthAPI
// import com.lagradost.cloudstream3.syncproviders.InAppAuthAPIManager
// class NginxApi(index: Int) : InAppAuthAPIManager(index) {
// override val name = "Nginx"
// override val idPrefix = "nginx"
// override val icon = R.drawable.nginx
// override val requiresUsername = true
// override val requiresPassword = true
// override val requiresServer = true
// override val createAccountUrl = "https://www.sarlays.com/use-nginx-with-cloudstream/"
// companion object {
// const val NGINX_USER_KEY: String = "nginx_user"
// }
// override fun getLatestLoginData(): InAppAuthAPI.LoginData? {
// return getKey(accountId, NGINX_USER_KEY)
// }
// override fun loginInfo(): AuthAPI.LoginInfo? {
// val data = getLatestLoginData() ?: return null
// return AuthAPI.LoginInfo(name = data.username ?: data.server, accountIndex = accountIndex)
// }
// override suspend fun login(data: InAppAuthAPI.LoginData): Boolean {
// if (data.server.isNullOrBlank()) return false // we require a server
// switchToNewAccount()
// setKey(accountId, NGINX_USER_KEY, data)
// registerAccount()
// initialize()
// return true
// }
// override fun logOut() {
// removeAccountKeys()
// initializeData()
// }
// private fun initializeData() {
// val data = getLatestLoginData() ?: run {
// NginxProvider.overrideUrl = null
// NginxProvider.loginCredentials = null
// return
// }
// NginxProvider.overrideUrl = data.server?.removeSuffix("/")
// NginxProvider.loginCredentials = "${data.username ?: ""}:${data.password ?: ""}"
// }
// override suspend fun initialize() {
// initializeData()
// }
// }

View file

@ -1,6 +1,6 @@
package com.lagradost.cloudstream3.ui.settings
import android.content.Context
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Bundle
@ -36,185 +36,189 @@ import kotlinx.android.synthetic.main.account_switch.*
import kotlinx.android.synthetic.main.add_account_input.*
class SettingsAccount : PreferenceFragmentCompat() {
companion object {
/** Used by nginx plugin too */
fun showLoginInfo(activity: Activity?, api: AccountManager, info: AuthAPI.LoginInfo) {
val builder =
AlertDialog.Builder(activity ?: return, R.style.AlertDialogCustom)
.setView(R.layout.account_managment)
val dialog = builder.show()
dialog.account_main_profile_picture_holder?.isVisible =
dialog.account_main_profile_picture?.setImage(info.profilePicture) == true
dialog.account_logout?.setOnClickListener {
api.logOut()
dialog.dismissSafe(activity)
}
(info.name ?: activity.getString(R.string.no_data)).let {
dialog.findViewById<TextView>(R.id.account_name)?.text = it
}
dialog.account_site?.text = api.name
dialog.account_switch_account?.setOnClickListener {
dialog.dismissSafe(activity)
showAccountSwitch(activity, api)
}
}
private fun showAccountSwitch(activity: Activity, api: AccountManager) {
val accounts = api.getAccounts() ?: return
val builder =
AlertDialog.Builder(activity, R.style.AlertDialogCustom)
.setView(R.layout.account_switch)
val dialog = builder.show()
dialog.account_add?.setOnClickListener {
addAccount(activity, api)
dialog?.dismissSafe(activity)
}
val ogIndex = api.accountIndex
val items = ArrayList<AuthAPI.LoginInfo>()
for (index in accounts) {
api.accountIndex = index
val accountInfo = api.loginInfo()
if (accountInfo != null) {
items.add(accountInfo)
}
}
api.accountIndex = ogIndex
val adapter = AccountAdapter(items, R.layout.account_single) {
dialog?.dismissSafe(activity)
api.changeAccount(it.card.accountIndex)
}
val list = dialog.findViewById<RecyclerView>(R.id.account_list)
list?.adapter = adapter
}
@UiThread
private fun addAccount(activity: Activity?, api: AccountManager) {
try {
when (api) {
is OAuth2API -> {
api.authenticate()
}
is InAppAuthAPI -> {
val builder =
AlertDialog.Builder(activity ?: return, R.style.AlertDialogCustom)
.setView(R.layout.add_account_input)
val dialog = builder.show()
val visibilityMap = mapOf(
dialog.login_email_input to api.requiresEmail,
dialog.login_password_input to api.requiresPassword,
dialog.login_server_input to api.requiresServer,
dialog.login_username_input to api.requiresUsername
)
if (activity.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
}
}
dialog.login_email_input?.isVisible = api.requiresEmail
dialog.login_password_input?.isVisible = api.requiresPassword
dialog.login_server_input?.isVisible = api.requiresServer
dialog.login_username_input?.isVisible = api.requiresUsername
dialog.create_account?.isGone = api.createAccountUrl.isNullOrBlank()
dialog.create_account?.setOnClickListener {
val i = Intent(Intent.ACTION_VIEW)
i.data = Uri.parse(api.createAccountUrl)
try {
activity.startActivity(i)
} catch (e: Exception) {
logError(e)
}
}
dialog.text1?.text = api.name
if (api.storesPasswordInPlainText) {
api.getLatestLoginData()?.let { data ->
dialog.login_email_input?.setText(data.email ?: "")
dialog.login_server_input?.setText(data.server ?: "")
dialog.login_username_input?.setText(data.username ?: "")
dialog.login_password_input?.setText(data.password ?: "")
}
}
dialog.apply_btt?.setOnClickListener {
val loginData = InAppAuthAPI.LoginData(
username = if (api.requiresUsername) dialog.login_username_input?.text?.toString() else null,
password = if (api.requiresPassword) dialog.login_password_input?.text?.toString() else null,
email = if (api.requiresEmail) dialog.login_email_input?.text?.toString() else null,
server = if (api.requiresServer) dialog.login_server_input?.text?.toString() else null,
)
ioSafe {
val isSuccessful = try {
api.login(loginData)
} catch (e: Exception) {
logError(e)
false
}
activity.runOnUiThread {
try {
showToast(
activity,
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)
}
dialog.cancel_btt?.setOnClickListener {
dialog.dismissSafe(activity)
}
}
else -> {
throw NotImplementedError("You are trying to add an account that has an unknown login method")
}
}
} catch (e: Exception) {
logError(e)
}
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setUpToolbar(R.string.category_account)
}
private fun showLoginInfo(api: AccountManager, info: AuthAPI.LoginInfo) {
val builder =
AlertDialog.Builder(context ?: return, R.style.AlertDialogCustom)
.setView(R.layout.account_managment)
val dialog = builder.show()
dialog.account_main_profile_picture_holder?.isVisible =
dialog.account_main_profile_picture?.setImage(info.profilePicture) == true
dialog.account_logout?.setOnClickListener {
api.logOut()
dialog.dismissSafe(activity)
}
(info.name ?: context?.getString(R.string.no_data))?.let {
dialog.findViewById<TextView>(R.id.account_name)?.text = it
}
dialog.account_site?.text = api.name
dialog.account_switch_account?.setOnClickListener {
dialog.dismissSafe(activity)
showAccountSwitch(it.context, api)
}
}
@UiThread
private fun addAccount(api: AccountManager) {
try {
when (api) {
is OAuth2API -> {
api.authenticate()
}
is InAppAuthAPI -> {
val builder =
AlertDialog.Builder(context ?: return, R.style.AlertDialogCustom)
.setView(R.layout.add_account_input)
val dialog = builder.show()
val visibilityMap = mapOf(
dialog.login_email_input to api.requiresEmail,
dialog.login_password_input to api.requiresPassword,
dialog.login_server_input to api.requiresServer,
dialog.login_username_input to api.requiresUsername
)
if (context?.isTvSettings() == true) {
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
}
}
dialog.login_email_input?.isVisible = api.requiresEmail
dialog.login_password_input?.isVisible = api.requiresPassword
dialog.login_server_input?.isVisible = api.requiresServer
dialog.login_username_input?.isVisible = api.requiresUsername
dialog.create_account?.isGone = api.createAccountUrl.isNullOrBlank()
dialog.create_account?.setOnClickListener {
val i = Intent(Intent.ACTION_VIEW)
i.data = Uri.parse(api.createAccountUrl)
try {
startActivity(i)
} catch (e: Exception) {
logError(e)
}
}
dialog.text1?.text = api.name
if (api.storesPasswordInPlainText) {
api.getLatestLoginData()?.let { data ->
dialog.login_email_input?.setText(data.email ?: "")
dialog.login_server_input?.setText(data.server ?: "")
dialog.login_username_input?.setText(data.username ?: "")
dialog.login_password_input?.setText(data.password ?: "")
}
}
dialog.apply_btt?.setOnClickListener {
val loginData = InAppAuthAPI.LoginData(
username = if (api.requiresUsername) dialog.login_username_input?.text?.toString() else null,
password = if (api.requiresPassword) dialog.login_password_input?.text?.toString() else null,
email = if (api.requiresEmail) dialog.login_email_input?.text?.toString() else null,
server = if (api.requiresServer) dialog.login_server_input?.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)
}
dialog.cancel_btt?.setOnClickListener {
dialog.dismissSafe(activity)
}
}
else -> {
throw NotImplementedError("You are trying to add an account that has an unknown login method")
}
}
} catch (e: Exception) {
logError(e)
}
}
private fun showAccountSwitch(context: Context, api: AccountManager) {
val accounts = api.getAccounts() ?: return
val builder =
AlertDialog.Builder(context, R.style.AlertDialogCustom).setView(R.layout.account_switch)
val dialog = builder.show()
dialog.account_add?.setOnClickListener {
addAccount(api)
dialog?.dismissSafe(activity)
}
val ogIndex = api.accountIndex
val items = ArrayList<AuthAPI.LoginInfo>()
for (index in accounts) {
api.accountIndex = index
val accountInfo = api.loginInfo()
if (accountInfo != null) {
items.add(accountInfo)
}
}
api.accountIndex = ogIndex
val adapter = AccountAdapter(items, R.layout.account_single) {
dialog?.dismissSafe(activity)
api.changeAccount(it.card.accountIndex)
}
val list = dialog.findViewById<RecyclerView>(R.id.account_list)
list?.adapter = adapter
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
hideKeyboard()
setPreferencesFromResource(R.xml.settings_account, rootKey)
// TODO: fix
val syncApis =
listOf(
R.string.mal_key to malApi,
R.string.anilist_key to aniListApi,
R.string.opensubtitles_key to openSubtitlesApi,
//R.string.nginx_key to nginxApi,
)
for ((key, api) in syncApis) {
@ -224,9 +228,9 @@ class SettingsAccount : PreferenceFragmentCompat() {
setOnPreferenceClickListener {
val info = api.loginInfo()
if (info != null) {
showLoginInfo(api, info)
showLoginInfo(activity, api, info)
} else {
addAccount(api)
addAccount(activity, api)
}
return@setOnPreferenceClickListener true
}

View file

@ -101,7 +101,12 @@ class PluginAdapter(
try {
plugin.openSettings!!.invoke(itemView.context)
} catch (e: Throwable) {
Log.e("PluginAdapter", "Failed to open ${metadata.name} settings: ${Log.getStackTraceString(e)}")
Log.e(
"PluginAdapter",
"Failed to open ${metadata.name} settings: ${
Log.getStackTraceString(e)
}"
)
}
}