Skip to content

Commit

Permalink
account switch
Browse files Browse the repository at this point in the history
  • Loading branch information
LagradOst committed Nov 8, 2021
1 parent 3a6814f commit a34c79e
Show file tree
Hide file tree
Showing 10 changed files with 268 additions and 26 deletions.
7 changes: 7 additions & 0 deletions app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.network.initRequestClient
import com.lagradost.cloudstream3.receivers.VideoDownloadRestartReceiver
import com.lagradost.cloudstream3.syncproviders.OAuth2Interface.Companion.OAuth2Apis
import com.lagradost.cloudstream3.syncproviders.OAuth2Interface.Companion.OAuth2accountApis
import com.lagradost.cloudstream3.syncproviders.OAuth2Interface.Companion.appString
import com.lagradost.cloudstream3.ui.APIRepository
import com.lagradost.cloudstream3.ui.download.DOWNLOAD_NAVIGATE_TO
Expand Down Expand Up @@ -371,6 +372,11 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
}

override fun onCreate(savedInstanceState: Bundle?) {
// init accounts
for (api in OAuth2accountApis) {
api.init(this)
}

val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)

val currentTheme = when (settingsManager.getString(getString(R.string.app_theme_key), "Black")) {
Expand Down Expand Up @@ -593,6 +599,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
}
APIRepository.dubStatusActive = getApiDubstatusSettings()


/*
val relativePath = (Environment.DIRECTORY_DOWNLOADS) + File.separatorChar
val displayName = "output.dex" //""output.dex"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,34 @@ import com.lagradost.cloudstream3.utils.AppUtils.splitQuery
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
import com.lagradost.cloudstream3.utils.DataStore.getKey
import com.lagradost.cloudstream3.utils.DataStore.getKeys
import com.lagradost.cloudstream3.utils.DataStore.removeKeys
import com.lagradost.cloudstream3.utils.DataStore.setKey
import com.lagradost.cloudstream3.utils.DataStore.toKotlinObject
import java.net.URL
import java.util.*
import java.util.concurrent.TimeUnit

class AniListApi(var accountId: String) : OAuth2Interface {
class AniListApi(index : Int) : OAuth2Interface.AccountManager(index) {
override val name: String
get() = "AniList"
override val key: String
get() = "6871"
override val redirectUrl: String
get() = "anilistlogin"

override fun logOut(context: Context) {
context.removeKeys(accountId)
}
override val idPrefix: String
get() = "anilist"

override fun loginInfo(context: Context): OAuth2Interface.LoginInfo? {
// context.getUser(true)?.
context.getKey<AniListUser>(accountId, ANILIST_USER_KEY)?.let { user ->
return OAuth2Interface.LoginInfo(profilePicture = user.picture, name = user.name)
return OAuth2Interface.LoginInfo(profilePicture = user.picture, name = user.name, accountIndex = accountIndex)
}
return null
}

override fun logOut(context: Context) {
context.removeAccountKeys()
}

override fun authenticate(context: Context) {
val request = "https://anilist.co/api/v2/oauth/authorize?client_id=$key&response_type=token"
context.openBrowser(request)
Expand All @@ -58,6 +59,7 @@ class AniListApi(var accountId: String) : OAuth2Interface {

val endTime = unixTime + expiresIn.toLong()

context.switchToNewAccount()
context.setKey(accountId, ANILIST_UNIXTIME_KEY, endTime)
context.setKey(accountId, ANILIST_TOKEN_KEY, token)
context.setKey(ANILIST_SHOULD_UPDATE_LIST, true)
Expand Down Expand Up @@ -552,7 +554,7 @@ class AniListApi(var accountId: String) : OAuth2Interface {
}
}

fun Context.getUser(setSettings: Boolean = true): AniListUser? {
private fun Context.getUser(setSettings: Boolean = true): AniListUser? {
val q = """
{
Viewer {
Expand Down Expand Up @@ -582,6 +584,7 @@ class AniListApi(var accountId: String) : OAuth2Interface {
)
if (setSettings) {
setKey(accountId, ANILIST_USER_KEY, user)
registerAccount()
}
/* // TODO FIX FAVS
for(i in u.favourites.anime.nodes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import com.lagradost.cloudstream3.utils.AppUtils.openBrowser
import com.lagradost.cloudstream3.utils.AppUtils.splitQuery
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
import com.lagradost.cloudstream3.utils.DataStore.getKey
import com.lagradost.cloudstream3.utils.DataStore.removeKeys
import com.lagradost.cloudstream3.utils.DataStore.setKey
import com.lagradost.cloudstream3.utils.DataStore.toKotlinObject
import java.net.URL
Expand All @@ -28,22 +27,24 @@ import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.*

class MALApi(var accountId: String) : OAuth2Interface {
class MALApi(index : Int) : OAuth2Interface.AccountManager(index) {
override val name: String
get() = "MAL"
override val key: String
get() = "1714d6f2f4f7cc19644384f8c4629910"
override val redirectUrl: String
get() = "mallogin"
override val idPrefix: String
get() = "mal"

override fun logOut(context: Context) {
context.removeKeys(accountId)
context.removeAccountKeys()
}

override fun loginInfo(context: Context): OAuth2Interface.LoginInfo? {
//context.getMalUser(true)?
context.getKey<MalUser>(accountId, MAL_USER_KEY)?.let { user ->
return OAuth2Interface.LoginInfo(profilePicture = user.picture, name = user.name)
return OAuth2Interface.LoginInfo(profilePicture = user.picture, name = user.name, accountIndex = accountIndex)
}
return null
}
Expand Down Expand Up @@ -84,6 +85,7 @@ class MALApi(var accountId: String) : OAuth2Interface {
}

if (res != "") {
context.switchToNewAccount()
context.storeToken(res)
context.getMalUser()
context.setKey(MAL_SHOULD_UPDATE_LIST, true)
Expand Down Expand Up @@ -383,7 +385,7 @@ class MALApi(var accountId: String) : OAuth2Interface {
}
}

fun Context.getMalUser(setSettings: Boolean = true): MalUser? {
private fun Context.getMalUser(setSettings: Boolean = true): MalUser? {
checkMalToken()
return try {
val res = get(
Expand All @@ -399,6 +401,7 @@ class MALApi(var accountId: String) : OAuth2Interface {
val user = mapper.readValue<MalUser>(res)
if (setSettings) {
setKey(accountId, MAL_USER_KEY, user)
registerAccount()
}
user
} catch (e: Exception) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,99 @@
package com.lagradost.cloudstream3.syncproviders

import android.content.Context
import com.lagradost.cloudstream3.utils.DataStore.getKey
import com.lagradost.cloudstream3.utils.DataStore.removeKeys
import com.lagradost.cloudstream3.utils.DataStore.setKey
import java.util.concurrent.TimeUnit

interface OAuth2Interface {
val key : String
val name : String
val redirectUrl : String
val key: String
val name: String
val redirectUrl: String

fun handleRedirect(context: Context, url : String)
fun handleRedirect(context: Context, url: String)
fun authenticate(context: Context)

fun loginInfo(context: Context) : LoginInfo?
fun loginInfo(context: Context): LoginInfo?
fun logOut(context: Context)

class LoginInfo(
val profilePicture : String?,
val name : String?,
val profilePicture: String?,
val name: String?,

val accountIndex: Int,
)

abstract class AccountManager(private val defIndex: Int) : OAuth2Interface {
// don't change this as all keys depend on it
open val idPrefix: String
get() {
throw(NotImplementedError())
}

var accountIndex = defIndex
protected val accountId get() = "${idPrefix}_account_$accountIndex"
private val accountActiveKey get() = "${idPrefix}_active"

// int array of all accounts indexes
private val accountsKey get() = "${idPrefix}_accounts"

protected fun Context.removeAccountKeys() {
this.removeKeys(accountId)
val accounts = getAccounts(this).toMutableList()
accounts.remove(accountIndex)
this.setKey(accountsKey, accounts.toIntArray())

init(this)
}

fun getAccounts(context: Context): IntArray {
return context.getKey(accountsKey, intArrayOf())!!
}

fun init(context: Context) {
accountIndex = context.getKey(accountActiveKey, defIndex)!!
val accounts = getAccounts(context)
if (accounts.isNotEmpty() && this.loginInfo(context) == null) {
accountIndex = accounts.first()
}
}

protected fun Context.switchToNewAccount() {
val accounts = getAccounts(this)
accountIndex = (accounts.maxOrNull() ?: 0) + 1
}

protected fun Context.registerAccount() {
this.setKey(accountActiveKey, accountIndex)
val accounts = getAccounts(this).toMutableList()
if (!accounts.contains(accountIndex)) {
accounts.add(accountIndex)
}

this.setKey(accountsKey, accounts.toIntArray())
}

fun changeAccount(context: Context, index: Int) {
accountIndex = index
context.setKey(accountActiveKey, index)
}
}

companion object {
val malApi = MALApi("mal_account_0")
val aniListApi = AniListApi("anilist_account_0")
val malApi = MALApi(0)
val aniListApi = AniListApi(0)

val OAuth2Apis
get() = listOf<OAuth2Interface>(
malApi, aniListApi
)

val OAuth2Apis get() = listOf(
malApi, aniListApi
)
// this needs init with context
val OAuth2accountApis
get() = listOf<AccountManager>(
malApi, aniListApi
)

const val appString = "cloudstreamapp"

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.lagradost.cloudstream3.ui.settings

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.syncproviders.OAuth2Interface
import com.lagradost.cloudstream3.utils.UIHelper.setImage

class AccountClickCallback(val action: Int, val view : View, val card: OAuth2Interface.LoginInfo)

class AccountAdapter(
val cardList: List<OAuth2Interface.LoginInfo>,
val layout: Int = R.layout.account_single,
private val clickCallback: (AccountClickCallback) -> Unit
) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return CardViewHolder(
LayoutInflater.from(parent.context).inflate(layout, parent, false), clickCallback
)
}

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is CardViewHolder -> {
holder.bind(cardList[position])
}
}
}

override fun getItemCount(): Int {
return cardList.size
}

override fun getItemId(position: Int): Long {
return cardList[position].accountIndex.toLong()
}

class CardViewHolder
constructor(itemView: View, private val clickCallback: (AccountClickCallback) -> Unit) :
RecyclerView.ViewHolder(itemView) {
private val pfp: ImageView = itemView.findViewById(R.id.account_profile_picture)!!
private val accountName: TextView = itemView.findViewById(R.id.account_name)!!

fun bind(card: OAuth2Interface.LoginInfo) {
// just in case name is null account index will show, should never happened
accountName.text = card.name ?: "%s %d".format(accountName.context.getString(R.string.account), card.accountIndex)
if(card.profilePicture.isNullOrEmpty()) {
pfp.isVisible = false
} else {
pfp.isVisible = true
pfp.setImage(card.profilePicture)
}

itemView.setOnClickListener {
clickCallback.invoke(AccountClickCallback(0, itemView, card))
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import androidx.appcompat.app.AlertDialog
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.RecyclerView
import com.hippo.unifile.UniFile
import com.lagradost.cloudstream3.APIHolder.apis
import com.lagradost.cloudstream3.APIHolder.getApiDubstatusSettings
Expand Down Expand Up @@ -119,7 +120,37 @@ class SettingsFragment : PreferenceFragmentCompat() {
Triple("🇹🇷", "Turkish", "tr")
).sortedBy { it.second } //ye, we go alphabetical, so ppl don't put their lang on top

private fun showLoginInfo(context: Context, api: OAuth2Interface, info: OAuth2Interface.LoginInfo) {
private fun showAccountSwitch(context: Context, api: OAuth2Interface.AccountManager) {
val builder =
AlertDialog.Builder(context, R.style.AlertDialogCustom).setView(R.layout.account_switch)
val dialog = builder.show()

val accounts = api.getAccounts(context)
dialog.findViewById<TextView>(R.id.account_add)?.setOnClickListener {
api.authenticate(it.context)
}

val ogIndex = api.accountIndex

val items = ArrayList<OAuth2Interface.LoginInfo>()

for (index in accounts) {
api.accountIndex = index
val accountInfo = api.loginInfo(context)
if (accountInfo != null) {
items.add(accountInfo)
}
}
api.accountIndex = ogIndex
val adapter = AccountAdapter(items, R.layout.account_single) {
dialog?.dismiss()
api.changeAccount(it.view.context, it.card.accountIndex)
}
val list = dialog.findViewById<RecyclerView>(R.id.account_list)
list?.adapter = adapter
}

private fun showLoginInfo(context: Context, api: OAuth2Interface.AccountManager, info: OAuth2Interface.LoginInfo) {
val builder =
AlertDialog.Builder(context, R.style.AlertDialogCustom).setView(R.layout.account_managment)
val dialog = builder.show()
Expand All @@ -134,6 +165,10 @@ class SettingsFragment : PreferenceFragmentCompat() {

dialog.findViewById<TextView>(R.id.account_name)?.text = info.name ?: context.getString(R.string.no_data)
dialog.findViewById<TextView>(R.id.account_site)?.text = api.name
dialog.findViewById<TextView>(R.id.account_switch_account)?.setOnClickListener {
dialog.dismiss()
showAccountSwitch(it.context, api)
}
}

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
Expand Down
Loading

0 comments on commit a34c79e

Please sign in to comment.