Improve sources settings

pull/128/head
Koitharu 4 years ago
parent 9bd47e0410
commit 8a365250d9
No known key found for this signature in database
GPG Key ID: 8E861F8CE6E7CE27

@ -66,7 +66,7 @@ android {
} }
dependencies { dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
implementation 'com.github.nv95:kotatsu-parsers:master-SNAPSHOT' implementation 'com.github.nv95:kotatsu-parsers:6ab5743f66'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0'

@ -11,7 +11,7 @@ import okhttp3.OkHttpClient
import org.koitharu.kotatsu.core.network.AndroidCookieJar import org.koitharu.kotatsu.core.network.AndroidCookieJar
import org.koitharu.kotatsu.core.prefs.SourceSettings import org.koitharu.kotatsu.core.prefs.SourceSettings
import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceConfig import org.koitharu.kotatsu.parsers.config.MangaSourceConfig
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.utils.ext.toList import org.koitharu.kotatsu.utils.ext.toList
import java.util.* import java.util.*

@ -4,6 +4,7 @@ import org.koitharu.kotatsu.core.prefs.SourceSettings
import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaParser import org.koitharu.kotatsu.parsers.MangaParser
import org.koitharu.kotatsu.parsers.MangaParserAuthProvider import org.koitharu.kotatsu.parsers.MangaParserAuthProvider
import org.koitharu.kotatsu.parsers.config.ConfigKey
import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.newParser import org.koitharu.kotatsu.parsers.newParser
@ -17,6 +18,12 @@ class RemoteMangaRepository(
override val sortOrders: Set<SortOrder> override val sortOrders: Set<SortOrder>
get() = parser.sortOrders get() = parser.sortOrders
var defaultSortOrder: SortOrder?
get() = getConfig().defaultSortOrder ?: sortOrders.firstOrNull()
set(value) {
getConfig().defaultSortOrder = value
}
override suspend fun getList( override suspend fun getList(
offset: Int, offset: Int,
query: String?, query: String?,
@ -36,7 +43,9 @@ class RemoteMangaRepository(
fun getAuthProvider(): MangaParserAuthProvider? = parser as? MangaParserAuthProvider fun getAuthProvider(): MangaParserAuthProvider? = parser as? MangaParserAuthProvider
fun onCreatePreferences(map: MutableMap<String, Any>) { fun getConfigKeys(): List<ConfigKey<*>> = ArrayList<ConfigKey<*>>().also {
map[SourceSettings.KEY_DOMAIN] = parser.defaultDomain parser.onCreateConfig(it)
} }
private fun getConfig() = parser.config as SourceSettings
} }

@ -16,6 +16,8 @@ import kotlinx.coroutines.channels.trySendBlocking
import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.callbackFlow
import org.koitharu.kotatsu.core.model.ZoomMode import org.koitharu.kotatsu.core.model.ZoomMode
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.utils.ext.getEnumValue
import org.koitharu.kotatsu.utils.ext.putEnumValue
import org.koitharu.kotatsu.utils.ext.toUriOrNull import org.koitharu.kotatsu.utils.ext.toUriOrNull
import java.io.File import java.io.File
import java.text.DateFormat import java.text.DateFormat
@ -27,12 +29,12 @@ class AppSettings(context: Context) {
private val prefs = PreferenceManager.getDefaultSharedPreferences(context) private val prefs = PreferenceManager.getDefaultSharedPreferences(context)
var listMode: ListMode var listMode: ListMode
get() = prefs.getString(KEY_LIST_MODE, null)?.findEnumValue(ListMode.values()) ?: ListMode.DETAILED_LIST get() = prefs.getEnumValue(KEY_LIST_MODE, ListMode.DETAILED_LIST)
set(value) = prefs.edit { putString(KEY_LIST_MODE, value.name) } set(value) = prefs.edit { putEnumValue(KEY_LIST_MODE, value) }
var defaultSection: AppSection var defaultSection: AppSection
get() = prefs.getString(KEY_APP_SECTION, null)?.findEnumValue(AppSection.values()) ?: AppSection.HISTORY get() = prefs.getEnumValue(KEY_APP_SECTION, AppSection.HISTORY)
set(value) = prefs.edit { putString(KEY_APP_SECTION, value.name) } set(value) = prefs.edit { putEnumValue(KEY_APP_SECTION, value) }
val theme: Int val theme: Int
get() = prefs.getString(KEY_THEME, null)?.toIntOrNull() ?: AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM get() = prefs.getString(KEY_THEME, null)?.toIntOrNull() ?: AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
@ -96,7 +98,7 @@ class AppSettings(context: Context) {
set(value) = prefs.edit { putBoolean(KEY_REVERSE_CHAPTERS, value) } set(value) = prefs.edit { putBoolean(KEY_REVERSE_CHAPTERS, value) }
val zoomMode: ZoomMode val zoomMode: ZoomMode
get() = prefs.getString(KEY_ZOOM_MODE, null)?.findEnumValue(ZoomMode.values()) ?: ZoomMode.FIT_CENTER get() = prefs.getEnumValue(KEY_ZOOM_MODE, ZoomMode.FIT_CENTER)
val trackSources: Set<String> val trackSources: Set<String>
get() = prefs.getStringSet(KEY_TRACK_SOURCES, null) ?: arraySetOf(TRACK_FAVOURITES, TRACK_HISTORY) get() = prefs.getStringSet(KEY_TRACK_SOURCES, null) ?: arraySetOf(TRACK_FAVOURITES, TRACK_HISTORY)
@ -195,10 +197,6 @@ class AppSettings(context: Context) {
} }
} }
private fun <E : Enum<E>> String.findEnumValue(values: Array<E>): E? {
return values.find { it.name == this }
}
companion object { companion object {
const val PAGE_SWITCH_TAPS = "taps" const val PAGE_SWITCH_TAPS = "taps"

@ -1,23 +1,28 @@
package org.koitharu.kotatsu.core.prefs package org.koitharu.kotatsu.core.prefs
import android.content.Context import android.content.Context
import org.koitharu.kotatsu.parsers.MangaSourceConfig import androidx.core.content.edit
import org.koitharu.kotatsu.parsers.config.ConfigKey
import org.koitharu.kotatsu.parsers.config.MangaSourceConfig
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.model.SortOrder
import org.koitharu.kotatsu.utils.ext.getEnumValue
import org.koitharu.kotatsu.utils.ext.putEnumValue
private const val KEY_SORT_ORDER = "sort_order"
class SourceSettings(context: Context, source: MangaSource) : MangaSourceConfig { class SourceSettings(context: Context, source: MangaSource) : MangaSourceConfig {
private val prefs = context.getSharedPreferences(source.name, Context.MODE_PRIVATE) private val prefs = context.getSharedPreferences(source.name, Context.MODE_PRIVATE)
override fun getDomain(defaultValue: String) = prefs.getString(KEY_DOMAIN, defaultValue) var defaultSortOrder: SortOrder?
?.takeUnless(String::isBlank) get() = prefs.getEnumValue(KEY_SORT_ORDER, SortOrder::class.java)
?: defaultValue set(value) = prefs.edit { putEnumValue(KEY_SORT_ORDER, value) }
override fun isSslEnabled(defaultValue: Boolean) = prefs.getBoolean(KEY_USE_SSL, defaultValue)
companion object {
const val KEY_DOMAIN = "domain" @Suppress("UNCHECKED_CAST")
const val KEY_USE_SSL = "ssl" override fun <T> get(key: ConfigKey<T>): T {
const val KEY_AUTH = "auth" return when (key) {
is ConfigKey.Domain -> prefs.getString(key.key, key.defaultValue) ?: key.defaultValue
} as T
} }
} }

@ -101,11 +101,11 @@ class DetailsFragment : BaseFragment<FragmentDetailsBinding>(), View.OnClickList
chapters.size, chapters.size,
) )
} }
if (manga.rating == Manga.NO_RATING) { if (manga.hasRating) {
infoLayout.ratingContainer.isVisible = false
} else {
infoLayout.textViewRating.text = String.format("%.1f", manga.rating * 5) infoLayout.textViewRating.text = String.format("%.1f", manga.rating * 5)
infoLayout.ratingContainer.isVisible = true infoLayout.ratingContainer.isVisible = true
} else {
infoLayout.ratingContainer.isVisible = false
} }
if (manga.source == MangaSource.LOCAL) { if (manga.source == MangaSource.LOCAL) {
infoLayout.textViewSource.isVisible = false infoLayout.textViewSource.isVisible = false

@ -20,7 +20,7 @@ class FilterCoordinator(
private val coroutineScope: CoroutineScope, private val coroutineScope: CoroutineScope,
) : OnFilterChangedListener { ) : OnFilterChangedListener {
private val currentState = MutableStateFlow(FilterState(repository.sortOrders.firstOrNull(), emptySet())) private val currentState = MutableStateFlow(FilterState(repository.defaultSortOrder, emptySet()))
private var searchQuery = MutableStateFlow("") private var searchQuery = MutableStateFlow("")
private val localTagsDeferred = coroutineScope.async(Dispatchers.Default, CoroutineStart.LAZY) { private val localTagsDeferred = coroutineScope.async(Dispatchers.Default, CoroutineStart.LAZY) {
dataRepository.findTags(repository.source) dataRepository.findTags(repository.source)
@ -38,6 +38,7 @@ class FilterCoordinator(
currentState.update { oldValue -> currentState.update { oldValue ->
FilterState(item.order, oldValue.tags) FilterState(item.order, oldValue.tags)
} }
repository.defaultSortOrder = item.order
} }
override fun onTagItemClick(item: FilterItem.Tag) { override fun onTagItemClick(item: FilterItem.Tag) {

@ -22,7 +22,7 @@ fun Manga.toListDetailedModel(counter: Int) = MangaListDetailedModel(
id = id, id = id,
title = title, title = title,
subtitle = altTitle, subtitle = altTitle,
rating = if (rating == Manga.NO_RATING) null else String.format("%.1f", rating * 5), rating = if (hasRating) String.format("%.1f", rating * 5) else null,
tags = tags.joinToString(", ") { it.title }, tags = tags.joinToString(", ") { it.title },
coverUrl = coverUrl, coverUrl = coverUrl,
manga = this, manga = this,

@ -3,10 +3,7 @@ package org.koitharu.kotatsu.local.data
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONObject import org.json.JSONObject
import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.BuildConfig
import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.model.MangaChapter
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.model.MangaTag
import org.koitharu.kotatsu.parsers.util.json.getBooleanOrDefault import org.koitharu.kotatsu.parsers.util.json.getBooleanOrDefault
import org.koitharu.kotatsu.parsers.util.json.getLongOrDefault import org.koitharu.kotatsu.parsers.util.json.getLongOrDefault
import org.koitharu.kotatsu.parsers.util.json.getStringOrNull import org.koitharu.kotatsu.parsers.util.json.getStringOrNull
@ -28,6 +25,7 @@ class MangaIndex(source: String?) {
json.put("description", manga.description) json.put("description", manga.description)
json.put("rating", manga.rating) json.put("rating", manga.rating)
json.put("nsfw", manga.isNsfw) json.put("nsfw", manga.isNsfw)
json.put("state", manga.state?.name)
json.put("source", manga.source.name) json.put("source", manga.source.name)
json.put("cover_large", manga.largeCoverUrl) json.put("cover_large", manga.largeCoverUrl)
json.put("tags", JSONArray().also { a -> json.put("tags", JSONArray().also { a ->
@ -59,6 +57,9 @@ class MangaIndex(source: String?) {
rating = json.getDouble("rating").toFloat(), rating = json.getDouble("rating").toFloat(),
isNsfw = json.getBooleanOrDefault("nsfw", false), isNsfw = json.getBooleanOrDefault("nsfw", false),
coverUrl = json.getString("cover"), coverUrl = json.getString("cover"),
state = json.getStringOrNull("state")?.let { stateString ->
MangaState.values().find { it.name == stateString }
},
description = json.getStringOrNull("description"), description = json.getStringOrNull("description"),
tags = json.getJSONArray("tags").mapJSONToSet { x -> tags = json.getJSONArray("tags").mapJSONToSet { x ->
MangaTag( MangaTag(

@ -19,7 +19,9 @@ import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.util.longHashCode import org.koitharu.kotatsu.parsers.util.longHashCode
import org.koitharu.kotatsu.parsers.util.toCamelCase import org.koitharu.kotatsu.parsers.util.toCamelCase
import org.koitharu.kotatsu.utils.AlphanumComparator import org.koitharu.kotatsu.utils.AlphanumComparator
import org.koitharu.kotatsu.utils.ext.* import org.koitharu.kotatsu.utils.ext.deleteAwait
import org.koitharu.kotatsu.utils.ext.readText
import org.koitharu.kotatsu.utils.ext.resolveName
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import java.util.* import java.util.*
@ -95,7 +97,7 @@ class LocalMangaRepository(private val storageManager: LocalStorageManager) : Ma
val index = entry?.let(zip::readText)?.let(::MangaIndex) val index = entry?.let(zip::readText)?.let(::MangaIndex)
val info = index?.getMangaInfo() val info = index?.getMangaInfo()
if (index != null && info != null) { if (index != null && info != null) {
return info.copy( return info.copy2(
source = MangaSource.LOCAL, source = MangaSource.LOCAL,
url = fileUri, url = fileUri,
coverUrl = zipUri( coverUrl = zipUri(
@ -104,8 +106,7 @@ class LocalMangaRepository(private val storageManager: LocalStorageManager) : Ma
?: findFirstEntry(zip.entries(), isImage = true)?.name.orEmpty() ?: findFirstEntry(zip.entries(), isImage = true)?.name.orEmpty()
), ),
chapters = info.chapters?.map { c -> chapters = info.chapters?.map { c ->
c.copy(url = fileUri, c.copy(url = fileUri, source = MangaSource.LOCAL)
source = MangaSource.LOCAL)
} }
) )
} }
@ -136,7 +137,15 @@ class LocalMangaRepository(private val storageManager: LocalStorageManager) : Ma
scanlator = null, scanlator = null,
branch = null, branch = null,
) )
} },
altTitle = null,
rating = -1f,
isNsfw = false,
tags = setOf(),
state = null,
author = null,
largeCoverUrl = null,
description = null,
) )
} }
@ -164,7 +173,7 @@ class LocalMangaRepository(private val storageManager: LocalStorageManager) : Ma
val info = index.getMangaInfo() ?: continue val info = index.getMangaInfo() ?: continue
if (info.id == remoteManga.id) { if (info.id == remoteManga.id) {
val fileUri = file.toUri().toString() val fileUri = file.toUri().toString()
return@runInterruptible info.copy( return@runInterruptible info.copy2(
source = MangaSource.LOCAL, source = MangaSource.LOCAL,
url = fileUri, url = fileUri,
chapters = info.chapters?.map { c -> c.copy(url = fileUri) } chapters = info.chapters?.map { c -> c.copy(url = fileUri) }
@ -175,8 +184,7 @@ class LocalMangaRepository(private val storageManager: LocalStorageManager) : Ma
} }
} }
private fun zipUri(file: File, entryName: String) = private fun zipUri(file: File, entryName: String) = Uri.fromParts("cbz", file.path, entryName).toString()
Uri.fromParts("cbz", file.path, entryName).toString()
private fun findFirstEntry(entries: Enumeration<out ZipEntry>, isImage: Boolean): ZipEntry? { private fun findFirstEntry(entries: Enumeration<out ZipEntry>, isImage: Boolean): ZipEntry? {
val list = entries.toList() val list = entries.toList()
@ -233,4 +241,41 @@ class LocalMangaRepository(private val storageManager: LocalStorageManager) : Ma
private suspend fun getAllFiles() = storageManager.getReadableDirs().flatMap { dir -> private suspend fun getAllFiles() = storageManager.getReadableDirs().flatMap { dir ->
dir.listFiles(filenameFilter)?.toList().orEmpty() dir.listFiles(filenameFilter)?.toList().orEmpty()
} }
private fun Manga.copy2(
url: String = this.url,
coverUrl: String = this.coverUrl,
chapters: List<MangaChapter>? = this.chapters,
source: MangaSource = this.source,
) = Manga(
id = id,
title = title,
altTitle = altTitle,
url = url,
publicUrl = publicUrl,
rating = rating,
isNsfw = isNsfw,
coverUrl = coverUrl,
tags = tags,
state = state,
author = author,
largeCoverUrl = largeCoverUrl,
description = description,
chapters = chapters,
source = source,
)
private fun MangaChapter.copy(
url: String = this.url,
source: MangaSource = this.source,
) = MangaChapter(
id = id,
name = name,
number = number,
url = url,
scanlator = scanlator,
uploadDate = uploadDate,
branch = branch,
source = source,
)
} }

@ -293,6 +293,24 @@ class ReaderViewModel(
} }
} }
private fun Manga.copy(chapters: List<MangaChapter>?) = Manga(
id = id,
title = title,
altTitle = altTitle,
url = url,
publicUrl = publicUrl,
rating = rating,
isNsfw = isNsfw,
coverUrl = coverUrl,
tags = tags,
state = state,
author = author,
largeCoverUrl = largeCoverUrl,
description = description,
chapters = chapters,
source = source,
)
private companion object : KoinComponent { private companion object : KoinComponent {
const val BOUNDS_PAGE_OFFSET = 2 const val BOUNDS_PAGE_OFFSET = 2

@ -0,0 +1,48 @@
package org.koitharu.kotatsu.settings
import android.view.inputmethod.EditorInfo
import androidx.preference.*
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
import org.koitharu.kotatsu.parsers.config.ConfigKey
import org.koitharu.kotatsu.settings.utils.EditTextBindListener
import org.koitharu.kotatsu.settings.utils.EditTextDefaultSummaryProvider
import org.koitharu.kotatsu.utils.ext.setDefaultValueCompat
private const val KEY_DOMAIN = "domain"
fun PreferenceFragmentCompat.addPreferencesFromRepository(repository: RemoteMangaRepository) {
val configKeys = repository.getConfigKeys()
val screen = preferenceScreen
for (key in configKeys) {
val preference: Preference = when (key) {
is ConfigKey.Domain -> {
val presetValues = key.presetValues
if (presetValues.isNullOrEmpty()) {
EditTextPreference(requireContext()).apply {
summaryProvider = EditTextDefaultSummaryProvider(key.defaultValue)
setOnBindEditTextListener(
EditTextBindListener(
inputType = EditorInfo.TYPE_CLASS_TEXT or EditorInfo.TYPE_TEXT_VARIATION_URI,
hint = key.defaultValue,
)
)
}
} else {
DropDownPreference(requireContext()).apply {
entries = presetValues
entryValues = entries
summaryProvider = ListPreference.SimpleSummaryProvider.getInstance()
setDefaultValueCompat(key.defaultValue)
}
}.apply {
setTitle(R.string.domain)
setDialogTitle(R.string.domain)
}
}
}
preference.isIconSpaceReserved = false
preference.key = key.key
screen.addPreference(preference)
}
}

@ -1,13 +1,9 @@
package org.koitharu.kotatsu.settings package org.koitharu.kotatsu.settings
import android.os.Bundle import android.os.Bundle
import android.util.ArrayMap
import android.view.View import android.view.View
import android.view.inputmethod.EditorInfo
import androidx.preference.EditTextPreference
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import androidx.preference.TwoStatePreference
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -15,12 +11,9 @@ import org.koitharu.kotatsu.BuildConfig
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.parser.MangaRepository import org.koitharu.kotatsu.core.parser.MangaRepository
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
import org.koitharu.kotatsu.core.prefs.SourceSettings
import org.koitharu.kotatsu.parsers.exception.AuthRequiredException import org.koitharu.kotatsu.parsers.exception.AuthRequiredException
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.settings.sources.auth.SourceAuthActivity import org.koitharu.kotatsu.settings.sources.auth.SourceAuthActivity
import org.koitharu.kotatsu.settings.utils.EditTextBindListener
import org.koitharu.kotatsu.settings.utils.EditTextDefaultSummaryProvider
import org.koitharu.kotatsu.utils.ext.serializableArgument import org.koitharu.kotatsu.utils.ext.serializableArgument
import org.koitharu.kotatsu.utils.ext.viewLifecycleScope import org.koitharu.kotatsu.utils.ext.viewLifecycleScope
import org.koitharu.kotatsu.utils.ext.withArgs import org.koitharu.kotatsu.utils.ext.withArgs
@ -40,18 +33,9 @@ class SourceSettingsFragment : PreferenceFragmentCompat() {
val repo = MangaRepository(source) as? RemoteMangaRepository ?: return val repo = MangaRepository(source) as? RemoteMangaRepository ?: return
repository = repo repository = repo
addPreferencesFromResource(R.xml.pref_source) addPreferencesFromResource(R.xml.pref_source)
val screen = preferenceScreen addPreferencesFromRepository(repo)
val prefsMap = ArrayMap<String, Any>(screen.preferenceCount)
repo.onCreatePreferences(prefsMap) findPreference<Preference>(KEY_AUTH)?.run {
for (i in 0 until screen.preferenceCount) {
val pref = screen.getPreference(i)
val defValue = prefsMap[pref.key]
pref.isVisible = defValue != null
if (defValue != null) {
initPreferenceWithDefaultValue(pref, defValue)
}
}
findPreference<Preference>(SourceSettings.KEY_AUTH)?.run {
val authProvider = repo.getAuthProvider() val authProvider = repo.getAuthProvider()
isVisible = authProvider != null isVisible = authProvider != null
isEnabled = authProvider?.isAuthorized == false isEnabled = authProvider?.isAuthorized == false
@ -60,7 +44,7 @@ class SourceSettingsFragment : PreferenceFragmentCompat() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
findPreference<Preference>(SourceSettings.KEY_AUTH)?.run { findPreference<Preference>(KEY_AUTH)?.run {
if (isVisible) { if (isVisible) {
loadUsername(this) loadUsername(this)
} }
@ -69,40 +53,14 @@ class SourceSettingsFragment : PreferenceFragmentCompat() {
override fun onPreferenceTreeClick(preference: Preference): Boolean { override fun onPreferenceTreeClick(preference: Preference): Boolean {
return when (preference.key) { return when (preference.key) {
SourceSettings.KEY_AUTH -> { KEY_AUTH -> {
startActivity( startActivity(SourceAuthActivity.newIntent(preference.context, source))
SourceAuthActivity.newIntent(
context ?: return false,
source,
)
)
true true
} }
else -> super.onPreferenceTreeClick(preference) else -> super.onPreferenceTreeClick(preference)
} }
} }
private fun initPreferenceWithDefaultValue(preference: Preference, defaultValue: Any) {
when (preference) {
is EditTextPreference -> {
preference.summaryProvider = EditTextDefaultSummaryProvider(defaultValue.toString())
when (preference.key) {
SourceSettings.KEY_DOMAIN -> preference.setOnBindEditTextListener(
EditTextBindListener(
EditorInfo.TYPE_CLASS_TEXT or EditorInfo.TYPE_TEXT_VARIATION_URI,
defaultValue.toString()
)
)
}
}
is TwoStatePreference -> {
if (defaultValue is Boolean) {
preference.isChecked = defaultValue
}
}
}
}
private fun loadUsername(preference: Preference) = viewLifecycleScope.launch { private fun loadUsername(preference: Preference) = viewLifecycleScope.launch {
runCatching { runCatching {
withContext(Dispatchers.Default) { withContext(Dispatchers.Default) {
@ -120,6 +78,8 @@ class SourceSettingsFragment : PreferenceFragmentCompat() {
companion object { companion object {
private const val KEY_AUTH = "auth"
private const val EXTRA_SOURCE = "source" private const val EXTRA_SOURCE = "source"
fun newInstance(source: MangaSource) = SourceSettingsFragment().withArgs(1) { fun newInstance(source: MangaSource) = SourceSettingsFragment().withArgs(1) {

@ -1,9 +1,25 @@
package org.koitharu.kotatsu.utils.ext package org.koitharu.kotatsu.utils.ext
import android.content.SharedPreferences
import androidx.preference.ListPreference import androidx.preference.ListPreference
fun ListPreference.setDefaultValueCompat(defaultValue: String) { fun ListPreference.setDefaultValueCompat(defaultValue: String) {
if (value == null) { if (value == null) {
value = defaultValue value = defaultValue
} }
}
fun <E: Enum<E>> SharedPreferences.getEnumValue(key: String, enumClass: Class<E>): E? {
val stringValue = getString(key, null) ?: return null
return enumClass.enumConstants?.find {
it.name == stringValue
}
}
fun <E: Enum<E>> SharedPreferences.getEnumValue(key: String, defaultValue: E): E {
return getEnumValue(key, defaultValue.javaClass) ?: defaultValue
}
fun <E: Enum<E>> SharedPreferences.Editor.putEnumValue(key: String, value: E?) {
putString(key, value?.name)
} }

@ -3,21 +3,11 @@
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<EditTextPreference
android:key="domain"
android:title="@string/domain"
app:iconSpaceReserved="false" />
<SwitchPreferenceCompat
android:defaultValue="true"
android:key="ssl"
android:title="@string/use_ssl"
app:iconSpaceReserved="false" />
<Preference <Preference
android:key="auth" android:key="auth"
android:persistent="false" android:persistent="false"
android:title="@string/sign_in" android:title="@string/sign_in"
android:order="100"
app:allowDividerAbove="true" app:allowDividerAbove="true"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />

Loading…
Cancel
Save