204 lines
7.6 KiB
Kotlin
204 lines
7.6 KiB
Kotlin
package org.mosad.teapod.ui.activity.main.fragments
|
|
|
|
import android.os.Bundle
|
|
import android.view.LayoutInflater
|
|
import android.view.View
|
|
import android.view.ViewGroup
|
|
import androidx.core.view.isVisible
|
|
import androidx.fragment.app.Fragment
|
|
import androidx.lifecycle.lifecycleScope
|
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
import kotlinx.coroutines.Deferred
|
|
import kotlinx.coroutines.async
|
|
import kotlinx.coroutines.launch
|
|
import kotlinx.coroutines.runBlocking
|
|
import org.mosad.teapod.BuildConfig
|
|
import org.mosad.teapod.R
|
|
import org.mosad.teapod.databinding.FragmentAccountBinding
|
|
import org.mosad.teapod.parser.crunchyroll.Benefits
|
|
import org.mosad.teapod.parser.crunchyroll.Crunchyroll
|
|
import org.mosad.teapod.parser.crunchyroll.Profile
|
|
import org.mosad.teapod.parser.crunchyroll.supportedLocals
|
|
import org.mosad.teapod.preferences.EncryptedPreferences
|
|
import org.mosad.teapod.preferences.Preferences
|
|
import org.mosad.teapod.ui.activity.main.MainActivity
|
|
import org.mosad.teapod.ui.components.LoginModalBottomSheet
|
|
import org.mosad.teapod.util.DataTypes.Theme
|
|
import org.mosad.teapod.util.showFragment
|
|
import org.mosad.teapod.util.toDisplayString
|
|
import java.util.*
|
|
|
|
class AccountFragment : Fragment() {
|
|
|
|
private lateinit var binding: FragmentAccountBinding
|
|
private var profile: Deferred<Profile> = lifecycleScope.async {
|
|
Crunchyroll.profile()
|
|
}
|
|
private var benefits: Deferred<Benefits> = lifecycleScope.async {
|
|
Crunchyroll.benefits()
|
|
}
|
|
|
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
|
binding = FragmentAccountBinding.inflate(inflater, container, false)
|
|
return binding.root
|
|
}
|
|
|
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
super.onViewCreated(view, savedInstanceState)
|
|
|
|
binding.textAccountLogin.text = EncryptedPreferences.login
|
|
|
|
// load account status and tier (async) info before anything else
|
|
lifecycleScope.launch {
|
|
benefits.await().apply {
|
|
this.items.firstOrNull { it.benefit == "cr_premium" }?.let {
|
|
binding.textAccountSubscription.text = getString(R.string.account_premium)
|
|
}
|
|
|
|
this.items.firstOrNull { it.benefit == "cr_fan_pack" }?.let {
|
|
binding.textAccountSubscriptionDesc.text =
|
|
getString(R.string.account_tier, getString(R.string.account_tier_mega_fan))
|
|
}
|
|
}
|
|
}
|
|
|
|
// add preferred subtitles
|
|
lifecycleScope.launch {
|
|
binding.textSettingsContentLanguageDesc.text = Locale.forLanguageTag(
|
|
profile.await().preferredContentSubtitleLanguage
|
|
).displayLanguage
|
|
}
|
|
binding.switchSecondary.isChecked = Preferences.preferSubbed
|
|
binding.switchAutoplay.isChecked = Preferences.autoplay
|
|
binding.textThemeSelected.text = when (Preferences.theme) {
|
|
Theme.DARK -> getString(R.string.theme_dark)
|
|
else -> getString(R.string.theme_light)
|
|
}
|
|
|
|
binding.linearDevSettings.isVisible = Preferences.devSettings
|
|
binding.switchUpdatePlayhead.isChecked = Preferences.updatePlayhead
|
|
|
|
binding.textInfoAboutDesc.text = getString(R.string.info_about_desc, BuildConfig.VERSION_NAME, getString(R.string.build_time))
|
|
|
|
initActions()
|
|
}
|
|
|
|
private fun initActions() {
|
|
binding.linearAccountLogin.setOnClickListener {
|
|
showLoginDialog()
|
|
}
|
|
|
|
binding.linearSettingsContentLanguage.setOnClickListener {
|
|
showContentLanguageSelection()
|
|
}
|
|
|
|
binding.switchSecondary.setOnClickListener {
|
|
Preferences.savePreferSecondary(requireContext(), binding.switchSecondary.isChecked)
|
|
}
|
|
|
|
binding.switchAutoplay.setOnClickListener {
|
|
Preferences.saveAutoplay(requireContext(), binding.switchAutoplay.isChecked)
|
|
}
|
|
|
|
binding.linearTheme.setOnClickListener {
|
|
showThemeDialog()
|
|
}
|
|
|
|
binding.linearInfo.setOnClickListener {
|
|
activity?.showFragment(AboutFragment())
|
|
}
|
|
|
|
binding.switchUpdatePlayhead.setOnClickListener {
|
|
Preferences.saveUpdatePlayhead(requireContext(), binding.switchUpdatePlayhead.isChecked)
|
|
}
|
|
|
|
binding.linearExportData.setOnClickListener {
|
|
// unused
|
|
}
|
|
|
|
binding.linearImportData.setOnClickListener {
|
|
// unused
|
|
}
|
|
}
|
|
|
|
private fun showLoginDialog() {
|
|
val loginModal = LoginModalBottomSheet().apply {
|
|
login = EncryptedPreferences.login
|
|
password = ""
|
|
positiveAction = {
|
|
EncryptedPreferences.saveCredentials(login, password, requireContext())
|
|
|
|
// TODO only dismiss if login was successful
|
|
this.dismiss()
|
|
}
|
|
negativeAction = {
|
|
this.dismiss()
|
|
}
|
|
}
|
|
activity?.let { loginModal.show(it.supportFragmentManager, LoginModalBottomSheet.TAG) }
|
|
}
|
|
|
|
private fun showContentLanguageSelection() {
|
|
// we should be able to use the index of supportedLocals for language selection, items is GUI only
|
|
val items = supportedLocals.map {
|
|
it.toDisplayString(getString(R.string.settings_content_language_none))
|
|
}.toTypedArray()
|
|
|
|
var initialSelection: Int
|
|
// profile should be completed here, therefore blocking
|
|
runBlocking {
|
|
initialSelection = supportedLocals.indexOf(Locale.forLanguageTag(
|
|
profile.await().preferredContentSubtitleLanguage))
|
|
if (initialSelection < 0) initialSelection = supportedLocals.lastIndex
|
|
}
|
|
|
|
MaterialAlertDialogBuilder(requireContext())
|
|
.setTitle(R.string.settings_content_language)
|
|
.setSingleChoiceItems(items, initialSelection){ dialog, which ->
|
|
updatePrefContentLanguage(supportedLocals[which])
|
|
dialog.dismiss()
|
|
}
|
|
.show()
|
|
}
|
|
|
|
@kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
private fun updatePrefContentLanguage(preferredLocale: Locale) {
|
|
lifecycleScope.launch {
|
|
Crunchyroll.postPrefSubLanguage(preferredLocale.toLanguageTag())
|
|
|
|
}.invokeOnCompletion {
|
|
// update the local preferred content language
|
|
Preferences.savePreferredLocal(requireContext(), preferredLocale)
|
|
|
|
// update profile since the language selection might have changed
|
|
profile = lifecycleScope.async { Crunchyroll.profile() }
|
|
profile.invokeOnCompletion {
|
|
// update language once loading profile is completed
|
|
binding.textSettingsContentLanguageDesc.text = Locale.forLanguageTag(
|
|
profile.getCompleted().preferredContentSubtitleLanguage
|
|
).displayLanguage
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun showThemeDialog() {
|
|
val items = arrayOf(
|
|
resources.getString(R.string.theme_light),
|
|
resources.getString(R.string.theme_dark)
|
|
)
|
|
|
|
MaterialAlertDialogBuilder(requireContext())
|
|
.setTitle(R.string.settings_content_language)
|
|
.setSingleChoiceItems(items, Preferences.theme.ordinal){ _, which ->
|
|
when(which) {
|
|
0 -> Preferences.saveTheme(requireContext(), Theme.LIGHT)
|
|
1 -> Preferences.saveTheme(requireContext(), Theme.DARK)
|
|
else -> Preferences.saveTheme(requireContext(), Theme.DARK)
|
|
}
|
|
|
|
(activity as MainActivity).restart()
|
|
}
|
|
.show()
|
|
}
|
|
|
|
} |