New welcome screen
This commit is contained in:
@@ -1,64 +0,0 @@
|
||||
package org.koitharu.kotatsu.settings.onboard
|
||||
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.ui.AlertDialogFragment
|
||||
import org.koitharu.kotatsu.core.util.ext.observe
|
||||
import org.koitharu.kotatsu.core.util.ext.showAllowStateLoss
|
||||
import org.koitharu.kotatsu.databinding.DialogOnboardBinding
|
||||
import org.koitharu.kotatsu.settings.onboard.adapter.SourceLocaleListener
|
||||
import org.koitharu.kotatsu.settings.onboard.adapter.SourceLocalesAdapter
|
||||
import org.koitharu.kotatsu.settings.onboard.model.SourceLocale
|
||||
|
||||
@AndroidEntryPoint
|
||||
class OnboardDialogFragment :
|
||||
AlertDialogFragment<DialogOnboardBinding>(),
|
||||
DialogInterface.OnClickListener, SourceLocaleListener {
|
||||
|
||||
private val viewModel by viewModels<OnboardViewModel>()
|
||||
|
||||
override fun onCreateViewBinding(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
) = DialogOnboardBinding.inflate(inflater, container, false)
|
||||
|
||||
override fun onBuildDialog(builder: MaterialAlertDialogBuilder): MaterialAlertDialogBuilder {
|
||||
super.onBuildDialog(builder)
|
||||
.setPositiveButton(R.string.done, this)
|
||||
.setCancelable(false)
|
||||
builder.setTitle(R.string.welcome)
|
||||
return builder
|
||||
}
|
||||
|
||||
override fun onViewBindingCreated(binding: DialogOnboardBinding, savedInstanceState: Bundle?) {
|
||||
super.onViewBindingCreated(binding, savedInstanceState)
|
||||
val adapter = SourceLocalesAdapter(this)
|
||||
binding.recyclerView.adapter = adapter
|
||||
binding.textViewTitle.setText(R.string.onboard_text)
|
||||
viewModel.list.observe(viewLifecycleOwner, adapter)
|
||||
}
|
||||
|
||||
override fun onItemCheckedChanged(item: SourceLocale, isChecked: Boolean) {
|
||||
viewModel.setItemChecked(item.key, isChecked)
|
||||
}
|
||||
|
||||
override fun onClick(dialog: DialogInterface, which: Int) {
|
||||
when (which) {
|
||||
DialogInterface.BUTTON_POSITIVE -> dialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val TAG = "OnboardDialog"
|
||||
|
||||
fun show(fm: FragmentManager) = OnboardDialogFragment().showAllowStateLoss(fm, TAG)
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
package org.koitharu.kotatsu.settings.onboard
|
||||
|
||||
import android.content.Context
|
||||
import androidx.core.os.ConfigurationCompat
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import org.koitharu.kotatsu.core.ui.BaseViewModel
|
||||
import org.koitharu.kotatsu.core.util.LocaleComparator
|
||||
import org.koitharu.kotatsu.core.util.ext.sortedWithSafe
|
||||
import org.koitharu.kotatsu.core.util.ext.toList
|
||||
import org.koitharu.kotatsu.explore.data.MangaSourcesRepository
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.util.mapNotNullToSet
|
||||
import org.koitharu.kotatsu.parsers.util.toTitleCase
|
||||
import org.koitharu.kotatsu.settings.onboard.model.SourceLocale
|
||||
import java.util.EnumSet
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class OnboardViewModel @Inject constructor(
|
||||
private val repository: MangaSourcesRepository,
|
||||
@ApplicationContext context: Context,
|
||||
) : BaseViewModel() {
|
||||
|
||||
private val allSources = repository.allMangaSources
|
||||
private val locales = allSources.groupBy { it.locale }
|
||||
private val selectedLocales = HashSet<String?>()
|
||||
val list = MutableStateFlow<List<SourceLocale>?>(null)
|
||||
private var updateJob: Job
|
||||
|
||||
init {
|
||||
updateJob = launchJob(Dispatchers.Default) {
|
||||
if (repository.isSetupRequired()) {
|
||||
selectedLocales += ConfigurationCompat.getLocales(context.resources.configuration).toList()
|
||||
.firstOrNull { lc -> lc.language in locales.keys }?.language
|
||||
selectedLocales += null
|
||||
} else {
|
||||
selectedLocales.addAll(
|
||||
repository.getEnabledSources().mapNotNullToSet { x -> x.locale },
|
||||
)
|
||||
}
|
||||
commit()
|
||||
}
|
||||
}
|
||||
|
||||
fun setItemChecked(key: String?, isChecked: Boolean) {
|
||||
val isModified = if (isChecked) {
|
||||
selectedLocales.add(key)
|
||||
} else {
|
||||
selectedLocales.remove(key)
|
||||
}
|
||||
if (isModified) {
|
||||
val prevJob = updateJob
|
||||
updateJob = launchJob(Dispatchers.Default) {
|
||||
prevJob.join()
|
||||
commit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun commit() {
|
||||
val enabledSources = allSources.filterTo(EnumSet.noneOf(MangaSource::class.java)) { x ->
|
||||
x.locale in selectedLocales
|
||||
}
|
||||
repository.setSourcesEnabledExclusive(enabledSources)
|
||||
list.value = locales.map { (key, srcs) ->
|
||||
val locale = key?.let { Locale(it) }
|
||||
SourceLocale(
|
||||
key = key,
|
||||
title = locale?.getDisplayLanguage(locale)?.toTitleCase(locale),
|
||||
summary = srcs.joinToString { it.title },
|
||||
isChecked = key in selectedLocales,
|
||||
)
|
||||
}.sortedWithSafe(SourceLocaleComparator())
|
||||
}
|
||||
|
||||
private class SourceLocaleComparator : Comparator<SourceLocale> {
|
||||
|
||||
private val delegate = nullsFirst(LocaleComparator())
|
||||
|
||||
override fun compare(a: SourceLocale, b: SourceLocale): Int {
|
||||
val localeA = a.key?.let { Locale(it) }
|
||||
val localeB = b.key?.let { Locale(it) }
|
||||
return delegate.compare(localeA, localeB)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package org.koitharu.kotatsu.settings.onboard.adapter
|
||||
|
||||
import android.widget.CompoundButton
|
||||
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.util.ext.setChecked
|
||||
import org.koitharu.kotatsu.core.util.ext.textAndVisible
|
||||
import org.koitharu.kotatsu.databinding.ItemSourceLocaleBinding
|
||||
import org.koitharu.kotatsu.settings.onboard.model.SourceLocale
|
||||
|
||||
fun sourceLocaleAD(
|
||||
listener: SourceLocaleListener,
|
||||
) = adapterDelegateViewBinding<SourceLocale, SourceLocale, ItemSourceLocaleBinding>(
|
||||
{ inflater, parent -> ItemSourceLocaleBinding.inflate(inflater, parent, false) },
|
||||
) {
|
||||
|
||||
val checkedChangeListener = CompoundButton.OnCheckedChangeListener { _, isChecked ->
|
||||
listener.onItemCheckedChanged(item, isChecked)
|
||||
}
|
||||
binding.switchToggle.setOnCheckedChangeListener(checkedChangeListener)
|
||||
|
||||
bind { payloads ->
|
||||
binding.textViewTitle.text = item.title ?: getString(R.string.different_languages)
|
||||
binding.textViewDescription.textAndVisible = item.summary
|
||||
binding.switchToggle.setOnCheckedChangeListener(null)
|
||||
binding.switchToggle.setChecked(item.isChecked, payloads.isNotEmpty())
|
||||
binding.switchToggle.setOnCheckedChangeListener(checkedChangeListener)
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package org.koitharu.kotatsu.settings.onboard.adapter
|
||||
|
||||
import org.koitharu.kotatsu.settings.onboard.model.SourceLocale
|
||||
|
||||
interface SourceLocaleListener {
|
||||
|
||||
fun onItemCheckedChanged(item: SourceLocale, isChecked: Boolean)
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package org.koitharu.kotatsu.settings.onboard.adapter
|
||||
|
||||
import org.koitharu.kotatsu.core.ui.BaseListAdapter
|
||||
import org.koitharu.kotatsu.settings.onboard.model.SourceLocale
|
||||
|
||||
class SourceLocalesAdapter(
|
||||
listener: SourceLocaleListener,
|
||||
) : BaseListAdapter<SourceLocale>() {
|
||||
|
||||
init {
|
||||
delegatesManager.addDelegate(sourceLocaleAD(listener))
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package org.koitharu.kotatsu.settings.onboard.model
|
||||
|
||||
import org.koitharu.kotatsu.list.ui.ListModelDiffCallback
|
||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||
import java.util.Locale
|
||||
|
||||
data class SourceLocale(
|
||||
val key: String?,
|
||||
val title: String?,
|
||||
val summary: String?,
|
||||
val isChecked: Boolean,
|
||||
) : ListModel, Comparable<SourceLocale> {
|
||||
|
||||
override fun areItemsTheSame(other: ListModel): Boolean {
|
||||
return other is SourceLocale && key == other.key
|
||||
}
|
||||
|
||||
override fun getChangePayload(previousState: ListModel): Any? {
|
||||
return if (previousState is SourceLocale && previousState.isChecked != isChecked) {
|
||||
ListModelDiffCallback.PAYLOAD_CHECKED_CHANGED
|
||||
} else {
|
||||
super.getChangePayload(previousState)
|
||||
}
|
||||
}
|
||||
|
||||
override fun compareTo(other: SourceLocale): Int {
|
||||
return when {
|
||||
this === other -> 0
|
||||
key == Locale.getDefault().language -> -2
|
||||
key == null -> 1
|
||||
other.key == null -> -1
|
||||
else -> compareValues(title, other.title)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user