Merge pull request #5344 from Bnyro/master

feat: show instance regions, uptime and registration status in settings
This commit is contained in:
Bnyro 2023-12-17 17:10:55 +01:00 committed by GitHub
commit 853b884276
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 15 deletions

View File

@ -17,7 +17,7 @@ data class PipedInstance(
@SerialName("s3_enabled") val s3Enabled: Boolean = false, @SerialName("s3_enabled") val s3Enabled: Boolean = false,
@SerialName("image_proxy_url") val imageProxyUrl: String = "", @SerialName("image_proxy_url") val imageProxyUrl: String = "",
@SerialName("registration_disabled") val registrationDisabled: Boolean = false, @SerialName("registration_disabled") val registrationDisabled: Boolean = false,
@SerialName("uptime_24h") val uptimeToday: Float = 0f, @SerialName("uptime_24h") val uptimeToday: Float? = null,
@SerialName("uptime_7d") val uptimeWeek: Float = 0f, @SerialName("uptime_7d") val uptimeWeek: Float? = null,
@SerialName("uptime_30d") val uptimeMonth: Float = 0f @SerialName("uptime_30d") val uptimeMonth: Float? = null
) )

View File

@ -48,7 +48,7 @@ class WelcomeActivity : BaseActivity() {
// ALl the binding values are optional due to two different possible layouts (normal, landscape) // ALl the binding values are optional due to two different possible layouts (normal, landscape)
viewModel.instances.observe(this) { instances -> viewModel.instances.observe(this) { instances ->
binding.instancesRecycler?.layoutManager = LinearLayoutManager(this@WelcomeActivity) binding.instancesRecycler?.layoutManager = LinearLayoutManager(this@WelcomeActivity)
binding.instancesRecycler?.adapter = InstancesAdapter(instances, viewModel) { index -> binding.instancesRecycler?.adapter = InstancesAdapter(instances, viewModel.selectedInstanceIndex.value) { index ->
viewModel.selectedInstanceIndex.value = index viewModel.selectedInstanceIndex.value = index
binding.okay?.alpha = 1f binding.okay?.alpha = 1f
} }

View File

@ -7,15 +7,14 @@ import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.api.obj.PipedInstance import com.github.libretube.api.obj.PipedInstance
import com.github.libretube.databinding.InstanceRowBinding import com.github.libretube.databinding.InstanceRowBinding
import com.github.libretube.ui.models.WelcomeModel
import com.github.libretube.ui.viewholders.InstancesViewHolder import com.github.libretube.ui.viewholders.InstancesViewHolder
class InstancesAdapter( class InstancesAdapter(
private val instances: List<PipedInstance>, private val instances: List<PipedInstance>,
viewModel: WelcomeModel, initialSelectionApiIndex: Int?,
private val onSelectInstance: (index: Int) -> Unit private val onSelectInstance: (index: Int) -> Unit
) : RecyclerView.Adapter<InstancesViewHolder>() { ) : RecyclerView.Adapter<InstancesViewHolder>() {
private var selectedInstanceIndex = viewModel.selectedInstanceIndex.value private var selectedInstanceIndex = initialSelectionApiIndex?.takeIf { it >= 0 }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): InstancesViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): InstancesViewHolder {
val layoutInflater = LayoutInflater.from(parent.context) val layoutInflater = LayoutInflater.from(parent.context)
@ -28,14 +27,19 @@ class InstancesAdapter(
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: InstancesViewHolder, position: Int) { override fun onBindViewHolder(holder: InstancesViewHolder, position: Int) {
val instance = instances[position] val instance = instances[position]
holder.binding.apply { holder.binding.apply {
var instanceText = "${instance.name} ${instance.locations}" var instanceText = "${instance.name} ${instance.locations}"
if (instance.cdn) instanceText += " (\uD83C\uDF10 CDN)" if (instance.cdn) {
instanceText += " (\uD83C\uDF10 CDN)"
}
if (instance.registrationDisabled) { if (instance.registrationDisabled) {
instanceText += instanceText +=
" (${root.context.getString(R.string.registration_disabled)})" " (${root.context.getString(R.string.registration_disabled)})"
} }
instanceText += ", " + root.context.getString(R.string.uptime, instance.uptimeMonth) if (instance.uptimeMonth != null) {
instanceText += ", " + root.context.getString(R.string.uptime, instance.uptimeMonth)
}
radioButton.text = instanceText radioButton.text = instanceText
radioButton.setOnCheckedChangeListener(null) radioButton.setOnCheckedChangeListener(null)

View File

@ -1,26 +1,31 @@
package com.github.libretube.ui.preferences package com.github.libretube.ui.preferences
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater
import android.widget.Toast import android.widget.Toast
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.preference.ListPreference import androidx.preference.ListPreference
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.SwitchPreferenceCompat import androidx.preference.SwitchPreferenceCompat
import androidx.recyclerview.widget.LinearLayoutManager
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.api.InstanceHelper import com.github.libretube.api.InstanceHelper
import com.github.libretube.api.RetrofitInstance import com.github.libretube.api.RetrofitInstance
import com.github.libretube.api.obj.PipedInstance import com.github.libretube.api.obj.PipedInstance
import com.github.libretube.constants.IntentData import com.github.libretube.constants.IntentData
import com.github.libretube.constants.PreferenceKeys import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.databinding.SimpleOptionsRecyclerBinding
import com.github.libretube.db.DatabaseHolder.Database import com.github.libretube.db.DatabaseHolder.Database
import com.github.libretube.extensions.toastFromMainDispatcher import com.github.libretube.extensions.toastFromMainDispatcher
import com.github.libretube.helpers.PreferenceHelper import com.github.libretube.helpers.PreferenceHelper
import com.github.libretube.ui.adapters.InstancesAdapter
import com.github.libretube.ui.base.BasePreferenceFragment import com.github.libretube.ui.base.BasePreferenceFragment
import com.github.libretube.ui.dialogs.CustomInstanceDialog import com.github.libretube.ui.dialogs.CustomInstanceDialog
import com.github.libretube.ui.dialogs.DeleteAccountDialog import com.github.libretube.ui.dialogs.DeleteAccountDialog
import com.github.libretube.ui.dialogs.LoginDialog import com.github.libretube.ui.dialogs.LoginDialog
import com.github.libretube.ui.dialogs.LogoutDialog import com.github.libretube.ui.dialogs.LogoutDialog
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -28,6 +33,7 @@ import kotlinx.coroutines.withContext
class InstanceSettings : BasePreferenceFragment() { class InstanceSettings : BasePreferenceFragment() {
override val titleResourceId: Int = R.string.instance override val titleResourceId: Int = R.string.instance
private val token get() = PreferenceHelper.getToken() private val token get() = PreferenceHelper.getToken()
private var instances = listOf<PipedInstance>()
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.instance_settings, rootKey) setPreferencesFromResource(R.xml.instance_settings, rootKey)
@ -137,14 +143,11 @@ class InstanceSettings : BasePreferenceFragment() {
instancePrefs: List<ListPreference>, instancePrefs: List<ListPreference>,
publicInstances: List<PipedInstance> publicInstances: List<PipedInstance>
) = runCatching { ) = runCatching {
val customInstanceList = withContext(Dispatchers.IO) { val customInstances = withContext(Dispatchers.IO) {
Database.customInstanceDao().getAll() Database.customInstanceDao().getAll()
} }.map { PipedInstance(it.name, it.apiUrl) }
val customInstances = customInstanceList instances = publicInstances
.map { PipedInstance(it.name, it.apiUrl) }
val instances = publicInstances
.plus(customInstances) .plus(customInstances)
.sortedBy { it.name } .sortedBy { it.name }
@ -163,6 +166,35 @@ class InstanceSettings : BasePreferenceFragment() {
} }
} }
override fun onDisplayPreferenceDialog(preference: Preference) {
if (preference.key in arrayOf(PreferenceKeys.FETCH_INSTANCE, PreferenceKeys.AUTH_INSTANCE)) {
showInstanceSelectionDialog(preference as ListPreference)
} else {
super.onDisplayPreferenceDialog(preference)
}
}
private fun showInstanceSelectionDialog(preference: ListPreference) {
var selectedInstance = preference.value
val selectedIndex = instances.indexOfFirst { it.apiUrl == selectedInstance }
val layoutInflater = LayoutInflater.from(context)
val binding = SimpleOptionsRecyclerBinding.inflate(layoutInflater)
binding.optionsRecycler.layoutManager = LinearLayoutManager(context)
binding.optionsRecycler.adapter = InstancesAdapter(instances, selectedIndex) {
selectedInstance = instances[it].apiUrl
}
MaterialAlertDialogBuilder(requireContext())
.setTitle(preference.title)
.setView(binding.root)
.setPositiveButton(R.string.okay) { _, _ ->
preference.value = selectedInstance
}
.setNegativeButton(R.string.cancel, null)
.show()
}
private fun logoutAndUpdateUI() { private fun logoutAndUpdateUI() {
PreferenceHelper.setToken("") PreferenceHelper.setToken("")
Toast.makeText(context, getString(R.string.loggedout), Toast.LENGTH_SHORT).show() Toast.makeText(context, getString(R.string.loggedout), Toast.LENGTH_SHORT).show()