Rewrite filter and preference mutations (#577)
This commit is contained in:
@@ -1,11 +1,18 @@
|
|||||||
package suwayomi.tachidesk.graphql.mutations
|
package suwayomi.tachidesk.graphql.mutations
|
||||||
|
|
||||||
|
import androidx.preference.CheckBoxPreference
|
||||||
|
import androidx.preference.EditTextPreference
|
||||||
|
import androidx.preference.ListPreference
|
||||||
|
import androidx.preference.MultiSelectListPreference
|
||||||
|
import androidx.preference.SwitchPreferenceCompat
|
||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
import suwayomi.tachidesk.graphql.types.FilterChange
|
||||||
import suwayomi.tachidesk.graphql.types.MangaType
|
import suwayomi.tachidesk.graphql.types.MangaType
|
||||||
import suwayomi.tachidesk.graphql.types.PreferenceObject
|
import suwayomi.tachidesk.graphql.types.Preference
|
||||||
|
import suwayomi.tachidesk.graphql.types.preferenceOf
|
||||||
|
import suwayomi.tachidesk.graphql.types.updateFilterList
|
||||||
import suwayomi.tachidesk.manga.impl.MangaList.insertOrGet
|
import suwayomi.tachidesk.manga.impl.MangaList.insertOrGet
|
||||||
import suwayomi.tachidesk.manga.impl.Search
|
|
||||||
import suwayomi.tachidesk.manga.impl.Source
|
import suwayomi.tachidesk.manga.impl.Source
|
||||||
import suwayomi.tachidesk.manga.impl.util.lang.awaitSingle
|
import suwayomi.tachidesk.manga.impl.util.lang.awaitSingle
|
||||||
import suwayomi.tachidesk.manga.impl.util.source.GetCatalogueSource
|
import suwayomi.tachidesk.manga.impl.util.source.GetCatalogueSource
|
||||||
@@ -20,10 +27,6 @@ class SourceMutation {
|
|||||||
POPULAR,
|
POPULAR,
|
||||||
LATEST
|
LATEST
|
||||||
}
|
}
|
||||||
data class FilterChange(
|
|
||||||
val position: Int,
|
|
||||||
val state: String
|
|
||||||
)
|
|
||||||
data class FetchSourceMangaInput(
|
data class FetchSourceMangaInput(
|
||||||
val clientMutationId: String? = null,
|
val clientMutationId: String? = null,
|
||||||
val source: Long,
|
val source: Long,
|
||||||
@@ -50,11 +53,7 @@ class SourceMutation {
|
|||||||
source.fetchSearchManga(
|
source.fetchSearchManga(
|
||||||
page = page,
|
page = page,
|
||||||
query = query.orEmpty(),
|
query = query.orEmpty(),
|
||||||
filters = Search.buildFilterList(
|
filters = updateFilterList(source, filters)
|
||||||
sourceId = sourceId,
|
|
||||||
changes = filters?.map { Search.FilterChange(it.position, it.state) }
|
|
||||||
.orEmpty()
|
|
||||||
)
|
|
||||||
).awaitSingle()
|
).awaitSingle()
|
||||||
}
|
}
|
||||||
FetchSourceMangaType.POPULAR -> {
|
FetchSourceMangaType.POPULAR -> {
|
||||||
@@ -85,7 +84,11 @@ class SourceMutation {
|
|||||||
|
|
||||||
data class SourcePreferenceChange(
|
data class SourcePreferenceChange(
|
||||||
val position: Int,
|
val position: Int,
|
||||||
val state: String
|
val switchState: Boolean? = null,
|
||||||
|
val checkBoxState: Boolean? = null,
|
||||||
|
val editTextState: String? = null,
|
||||||
|
val listState: String? = null,
|
||||||
|
val multiSelectState: List<String>? = null
|
||||||
)
|
)
|
||||||
data class UpdateSourcePreferenceInput(
|
data class UpdateSourcePreferenceInput(
|
||||||
val clientMutationId: String? = null,
|
val clientMutationId: String? = null,
|
||||||
@@ -94,7 +97,7 @@ class SourceMutation {
|
|||||||
)
|
)
|
||||||
data class UpdateSourcePreferencePayload(
|
data class UpdateSourcePreferencePayload(
|
||||||
val clientMutationId: String?,
|
val clientMutationId: String?,
|
||||||
val preferences: List<PreferenceObject>
|
val preferences: List<Preference>
|
||||||
)
|
)
|
||||||
|
|
||||||
fun updateSourcePreference(
|
fun updateSourcePreference(
|
||||||
@@ -102,11 +105,20 @@ class SourceMutation {
|
|||||||
): UpdateSourcePreferencePayload {
|
): UpdateSourcePreferencePayload {
|
||||||
val (clientMutationId, sourceId, change) = input
|
val (clientMutationId, sourceId, change) = input
|
||||||
|
|
||||||
Source.setSourcePreference(sourceId, Source.SourcePreferenceChange(change.position, change.state))
|
Source.setSourcePreference(sourceId, change.position, "") { preference ->
|
||||||
|
when (preference) {
|
||||||
|
is SwitchPreferenceCompat -> change.switchState
|
||||||
|
is CheckBoxPreference -> change.checkBoxState
|
||||||
|
is EditTextPreference -> change.editTextState
|
||||||
|
is ListPreference -> change.listState
|
||||||
|
is MultiSelectListPreference -> change.multiSelectState?.toSet()
|
||||||
|
else -> throw RuntimeException("sealed class cannot have more subtypes!")
|
||||||
|
} ?: throw Exception("Expected change to ${preference::class.simpleName}")
|
||||||
|
}
|
||||||
|
|
||||||
return UpdateSourcePreferencePayload(
|
return UpdateSourcePreferencePayload(
|
||||||
clientMutationId = clientMutationId,
|
clientMutationId = clientMutationId,
|
||||||
preferences = Source.getSourcePreferences(sourceId).map { PreferenceObject(it.type, it.props) }
|
preferences = Source.getSourcePreferencesRaw(sourceId).map { preferenceOf(it) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import com.expediagroup.graphql.generator.SchemaGeneratorConfig
|
|||||||
import com.expediagroup.graphql.generator.TopLevelObject
|
import com.expediagroup.graphql.generator.TopLevelObject
|
||||||
import com.expediagroup.graphql.generator.hooks.FlowSubscriptionSchemaGeneratorHooks
|
import com.expediagroup.graphql.generator.hooks.FlowSubscriptionSchemaGeneratorHooks
|
||||||
import com.expediagroup.graphql.generator.toSchema
|
import com.expediagroup.graphql.generator.toSchema
|
||||||
import graphql.scalars.ExtendedScalars
|
|
||||||
import graphql.schema.GraphQLType
|
import graphql.schema.GraphQLType
|
||||||
import suwayomi.tachidesk.graphql.mutations.CategoryMutation
|
import suwayomi.tachidesk.graphql.mutations.CategoryMutation
|
||||||
import suwayomi.tachidesk.graphql.mutations.ChapterMutation
|
import suwayomi.tachidesk.graphql.mutations.ChapterMutation
|
||||||
@@ -36,7 +35,6 @@ class CustomSchemaGeneratorHooks : FlowSubscriptionSchemaGeneratorHooks() {
|
|||||||
override fun willGenerateGraphQLType(type: KType): GraphQLType? = when (type.classifier as? KClass<*>) {
|
override fun willGenerateGraphQLType(type: KType): GraphQLType? = when (type.classifier as? KClass<*>) {
|
||||||
Long::class -> GraphQLLongAsString // encode to string for JS
|
Long::class -> GraphQLLongAsString // encode to string for JS
|
||||||
Cursor::class -> GraphQLCursor
|
Cursor::class -> GraphQLCursor
|
||||||
Any::class -> ExtendedScalars.Json
|
|
||||||
else -> super.willGenerateGraphQLType(type)
|
else -> super.willGenerateGraphQLType(type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ package suwayomi.tachidesk.graphql.types
|
|||||||
import com.expediagroup.graphql.server.extensions.getValueFromDataLoader
|
import com.expediagroup.graphql.server.extensions.getValueFromDataLoader
|
||||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||||
import eu.kanade.tachiyomi.source.ConfigurableSource
|
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||||
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
import graphql.schema.DataFetchingEnvironment
|
import graphql.schema.DataFetchingEnvironment
|
||||||
import org.jetbrains.exposed.sql.ResultRow
|
import org.jetbrains.exposed.sql.ResultRow
|
||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
@@ -18,14 +19,21 @@ import suwayomi.tachidesk.graphql.server.primitives.Edge
|
|||||||
import suwayomi.tachidesk.graphql.server.primitives.Node
|
import suwayomi.tachidesk.graphql.server.primitives.Node
|
||||||
import suwayomi.tachidesk.graphql.server.primitives.NodeList
|
import suwayomi.tachidesk.graphql.server.primitives.NodeList
|
||||||
import suwayomi.tachidesk.graphql.server.primitives.PageInfo
|
import suwayomi.tachidesk.graphql.server.primitives.PageInfo
|
||||||
import suwayomi.tachidesk.manga.impl.Search
|
import suwayomi.tachidesk.manga.impl.Source.getSourcePreferencesRaw
|
||||||
import suwayomi.tachidesk.manga.impl.Source
|
|
||||||
import suwayomi.tachidesk.manga.impl.extension.Extension
|
import suwayomi.tachidesk.manga.impl.extension.Extension
|
||||||
import suwayomi.tachidesk.manga.impl.util.source.GetCatalogueSource
|
import suwayomi.tachidesk.manga.impl.util.source.GetCatalogueSource
|
||||||
|
import suwayomi.tachidesk.manga.impl.util.source.GetCatalogueSource.getCatalogueSourceOrStub
|
||||||
import suwayomi.tachidesk.manga.model.dataclass.SourceDataClass
|
import suwayomi.tachidesk.manga.model.dataclass.SourceDataClass
|
||||||
import suwayomi.tachidesk.manga.model.table.ExtensionTable
|
import suwayomi.tachidesk.manga.model.table.ExtensionTable
|
||||||
import suwayomi.tachidesk.manga.model.table.SourceTable
|
import suwayomi.tachidesk.manga.model.table.SourceTable
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
|
import androidx.preference.CheckBoxPreference as SourceCheckBoxPreference
|
||||||
|
import androidx.preference.EditTextPreference as SourceEditTextPreference
|
||||||
|
import androidx.preference.ListPreference as SourceListPreference
|
||||||
|
import androidx.preference.MultiSelectListPreference as SourceMultiSelectListPreference
|
||||||
|
import androidx.preference.Preference as SourcePreference
|
||||||
|
import androidx.preference.SwitchPreferenceCompat as SourceSwitchPreference
|
||||||
|
import eu.kanade.tachiyomi.source.model.Filter as SourceFilter
|
||||||
|
|
||||||
class SourceType(
|
class SourceType(
|
||||||
val id: Long,
|
val id: Long,
|
||||||
@@ -67,12 +75,12 @@ class SourceType(
|
|||||||
return dataFetchingEnvironment.getValueFromDataLoader<Long, ExtensionType>("ExtensionForSourceDataLoader", id)
|
return dataFetchingEnvironment.getValueFromDataLoader<Long, ExtensionType>("ExtensionForSourceDataLoader", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun preferences(): List<PreferenceObject> {
|
fun preferences(): List<Preference> {
|
||||||
return Source.getSourcePreferences(id).map { PreferenceObject(it.type, it.props) }
|
return getSourcePreferencesRaw(id).map { preferenceOf(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun filters(): List<FilterObject> {
|
fun filters(): List<Filter> {
|
||||||
return Search.getFilterList(id, false).map { FilterObject(it.type, it.filter) }
|
return getCatalogueSourceOrStub(id).getFilterList().map { filterOf(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,12 +141,255 @@ data class SourceNodeList(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class PreferenceObject(
|
sealed interface Filter
|
||||||
val type: String,
|
|
||||||
val props: Any
|
data class HeaderFilter(val name: String) : Filter
|
||||||
|
|
||||||
|
data class SeparatorFilter(val name: String) : Filter
|
||||||
|
|
||||||
|
data class SelectFilter(val name: String, val values: List<String>, val default: Int) : Filter
|
||||||
|
|
||||||
|
data class TextFilter(val name: String, val default: String) : Filter
|
||||||
|
|
||||||
|
data class CheckBoxFilter(val name: String, val default: Boolean) : Filter
|
||||||
|
|
||||||
|
enum class TriState {
|
||||||
|
IGNORE,
|
||||||
|
INCLUDE,
|
||||||
|
EXCLUDE
|
||||||
|
}
|
||||||
|
|
||||||
|
data class TriStateFilter(val name: String, val default: TriState) : Filter
|
||||||
|
|
||||||
|
data class SortFilter(val name: String, val values: List<String>, val default: SortSelection?) : Filter {
|
||||||
|
data class SortSelection(val index: Int, val ascending: Boolean) {
|
||||||
|
constructor(selection: SourceFilter.Sort.Selection) :
|
||||||
|
this(selection.index, selection.ascending)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class GroupFilter(val name: String, val filters: List<Filter>) : Filter
|
||||||
|
|
||||||
|
fun filterOf(filter: SourceFilter<*>): Filter {
|
||||||
|
return when (filter) {
|
||||||
|
is SourceFilter.Header -> HeaderFilter(filter.name)
|
||||||
|
is SourceFilter.Separator -> SeparatorFilter(filter.name)
|
||||||
|
is SourceFilter.Select<*> -> SelectFilter(filter.name, filter.displayValues, filter.state)
|
||||||
|
is SourceFilter.Text -> TextFilter(filter.name, filter.state)
|
||||||
|
is SourceFilter.CheckBox -> CheckBoxFilter(filter.name, filter.state)
|
||||||
|
is SourceFilter.TriState -> TriStateFilter(
|
||||||
|
filter.name,
|
||||||
|
when (filter.state) {
|
||||||
|
SourceFilter.TriState.STATE_INCLUDE -> TriState.INCLUDE
|
||||||
|
SourceFilter.TriState.STATE_EXCLUDE -> TriState.EXCLUDE
|
||||||
|
else -> TriState.IGNORE
|
||||||
|
}
|
||||||
|
)
|
||||||
|
is SourceFilter.Group<*> -> GroupFilter(
|
||||||
|
filter.name,
|
||||||
|
filter.state.map { filterOf(it as SourceFilter<*>) }
|
||||||
|
)
|
||||||
|
is SourceFilter.Sort -> SortFilter(filter.name, filter.values.asList(), filter.state?.let(SortFilter::SortSelection))
|
||||||
|
else -> throw RuntimeException("sealed class cannot have more subtypes!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*sealed interface FilterChange {
|
||||||
|
val position: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
data class GroupFilterChange(
|
||||||
|
override val position: Int,
|
||||||
|
val filter: FilterChange
|
||||||
|
) : FilterChange
|
||||||
|
|
||||||
|
data class TriStateFilterChange(
|
||||||
|
override val position: Int,
|
||||||
|
val state: TriState
|
||||||
|
) : FilterChange
|
||||||
|
|
||||||
|
data class CheckBoxFilterChange(
|
||||||
|
override val position: Int,
|
||||||
|
val state: Boolean
|
||||||
|
) : FilterChange
|
||||||
|
|
||||||
|
data class SelectFilterChange(
|
||||||
|
override val position: Int,
|
||||||
|
val state: Int
|
||||||
|
) : FilterChange
|
||||||
|
|
||||||
|
data class TextFilterChange(
|
||||||
|
override val position: Int,
|
||||||
|
val state: String
|
||||||
|
) : FilterChange
|
||||||
|
|
||||||
|
data class SortFilterChange(
|
||||||
|
override val position: Int,
|
||||||
|
val state: SortFilter.SortSelection
|
||||||
|
) : FilterChange
|
||||||
|
|
||||||
|
private inline fun <reified T> filterChangeAs(filterChange: FilterChange): T {
|
||||||
|
return filterChange as? T ?: throw Exception("Expected ${T::class.simpleName}, found ${filterChange::class.simpleName}")
|
||||||
|
}*/
|
||||||
|
|
||||||
|
data class FilterChange(
|
||||||
|
val position: Int,
|
||||||
|
val selectState: Int? = null,
|
||||||
|
val textState: String? = null,
|
||||||
|
val checkBoxState: Boolean? = null,
|
||||||
|
val triState: TriState? = null,
|
||||||
|
val sortState: SortFilter.SortSelection? = null,
|
||||||
|
val groupChange: FilterChange? = null
|
||||||
)
|
)
|
||||||
|
|
||||||
data class FilterObject(
|
fun updateFilterList(source: CatalogueSource, changes: List<FilterChange>?): FilterList {
|
||||||
val type: String,
|
val filterList = source.getFilterList()
|
||||||
val filter: Any
|
|
||||||
)
|
changes?.forEach { change ->
|
||||||
|
when (val filter = filterList[1]) {
|
||||||
|
is SourceFilter.Header -> {
|
||||||
|
// NOOP
|
||||||
|
}
|
||||||
|
is SourceFilter.Separator -> {
|
||||||
|
// NOOP
|
||||||
|
}
|
||||||
|
is SourceFilter.Select<*> -> {
|
||||||
|
filter.state = change.selectState ?: throw Exception("Expected select state change at position ${change.position}")
|
||||||
|
}
|
||||||
|
is SourceFilter.Text -> {
|
||||||
|
filter.state = change.textState ?: throw Exception("Expected text state change at position ${change.position}")
|
||||||
|
}
|
||||||
|
is SourceFilter.CheckBox -> {
|
||||||
|
filter.state = change.checkBoxState ?: throw Exception("Expected checkbox state change at position ${change.position}")
|
||||||
|
}
|
||||||
|
is SourceFilter.TriState -> {
|
||||||
|
filter.state = change.triState?.ordinal ?: throw Exception("Expected tri state change at position ${change.position}")
|
||||||
|
}
|
||||||
|
is SourceFilter.Group<*> -> {
|
||||||
|
val groupChange = change.groupChange ?: throw Exception("Expected group change at position ${change.position}")
|
||||||
|
|
||||||
|
when (val groupFilter = filter.state[1]) {
|
||||||
|
is SourceFilter.CheckBox -> {
|
||||||
|
groupFilter.state = groupChange.checkBoxState ?: throw Exception("Expected checkbox state change at position ${change.position}")
|
||||||
|
}
|
||||||
|
is SourceFilter.TriState -> {
|
||||||
|
groupFilter.state = groupChange.triState?.ordinal ?: throw Exception("Expected tri state change at position ${change.position}")
|
||||||
|
}
|
||||||
|
is SourceFilter.Text -> {
|
||||||
|
groupFilter.state = groupChange.textState ?: throw Exception("Expected text state change at position ${change.position}")
|
||||||
|
}
|
||||||
|
is SourceFilter.Select<*> -> {
|
||||||
|
groupFilter.state = groupChange.selectState ?: throw Exception("Expected select state change at position ${change.position}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is SourceFilter.Sort -> {
|
||||||
|
filter.state = change.sortState?.run {
|
||||||
|
SourceFilter.Sort.Selection(index, ascending)
|
||||||
|
} ?: throw Exception("Expected sort state change at position ${change.position}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filterList
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed interface Preference
|
||||||
|
|
||||||
|
data class SwitchPreference(
|
||||||
|
val key: String,
|
||||||
|
val title: String,
|
||||||
|
val summary: String?,
|
||||||
|
val currentValue: Boolean?,
|
||||||
|
val default: Boolean
|
||||||
|
) : Preference
|
||||||
|
|
||||||
|
data class CheckBoxPreference(
|
||||||
|
val key: String,
|
||||||
|
val title: String,
|
||||||
|
val summary: String?,
|
||||||
|
val currentValue: Boolean?,
|
||||||
|
val default: Boolean
|
||||||
|
) : Preference
|
||||||
|
|
||||||
|
data class EditTextPreference(
|
||||||
|
val key: String,
|
||||||
|
val title: String?,
|
||||||
|
val summary: String?,
|
||||||
|
val currentValue: String?,
|
||||||
|
val default: String?,
|
||||||
|
val dialogTitle: String?,
|
||||||
|
val dialogMessage: String?,
|
||||||
|
val text: String?
|
||||||
|
) : Preference
|
||||||
|
|
||||||
|
data class ListPreference(
|
||||||
|
val key: String,
|
||||||
|
val title: String?,
|
||||||
|
val summary: String?,
|
||||||
|
val currentValue: String?,
|
||||||
|
val default: String?,
|
||||||
|
val entries: List<String>,
|
||||||
|
val entryValues: List<String>
|
||||||
|
) : Preference
|
||||||
|
|
||||||
|
data class MultiSelectListPreference(
|
||||||
|
val key: String,
|
||||||
|
val title: String?,
|
||||||
|
val summary: String?,
|
||||||
|
val currentValue: List<String>?,
|
||||||
|
val default: List<String>?,
|
||||||
|
val dialogTitle: String?,
|
||||||
|
val dialogMessage: String?,
|
||||||
|
val entries: List<String>,
|
||||||
|
val entryValues: List<String>
|
||||||
|
) : Preference
|
||||||
|
|
||||||
|
fun preferenceOf(preference: SourcePreference): Preference {
|
||||||
|
return when (preference) {
|
||||||
|
is SourceSwitchPreference -> SwitchPreference(
|
||||||
|
preference.key,
|
||||||
|
preference.title.toString(),
|
||||||
|
preference.summary?.toString(),
|
||||||
|
preference.currentValue as Boolean,
|
||||||
|
preference.defaultValue as Boolean
|
||||||
|
)
|
||||||
|
is SourceCheckBoxPreference -> CheckBoxPreference(
|
||||||
|
preference.key,
|
||||||
|
preference.title.toString(),
|
||||||
|
preference.summary?.toString(),
|
||||||
|
preference.currentValue as Boolean,
|
||||||
|
preference.defaultValue as Boolean
|
||||||
|
)
|
||||||
|
is SourceEditTextPreference -> EditTextPreference(
|
||||||
|
preference.key,
|
||||||
|
preference.title?.toString(),
|
||||||
|
preference.summary?.toString(),
|
||||||
|
(preference.currentValue as CharSequence?)?.toString(),
|
||||||
|
(preference.defaultValue as CharSequence?)?.toString(),
|
||||||
|
preference.dialogTitle?.toString(),
|
||||||
|
preference.dialogMessage?.toString(),
|
||||||
|
preference.text
|
||||||
|
)
|
||||||
|
is SourceListPreference -> ListPreference(
|
||||||
|
preference.key,
|
||||||
|
preference.title?.toString(),
|
||||||
|
preference.summary?.toString(),
|
||||||
|
(preference.currentValue as CharSequence?)?.toString(),
|
||||||
|
(preference.defaultValue as CharSequence?)?.toString(),
|
||||||
|
preference.entries.map { it.toString() },
|
||||||
|
preference.entryValues.map { it.toString() }
|
||||||
|
)
|
||||||
|
is SourceMultiSelectListPreference -> MultiSelectListPreference(
|
||||||
|
preference.key,
|
||||||
|
preference.title?.toString(),
|
||||||
|
preference.summary?.toString(),
|
||||||
|
(preference.currentValue as Collection<*>?)?.map { it.toString() },
|
||||||
|
(preference.defaultValue as Collection<*>?)?.map { it.toString() },
|
||||||
|
preference.dialogTitle?.toString(),
|
||||||
|
preference.dialogMessage?.toString(),
|
||||||
|
preference.entries.map { it.toString() },
|
||||||
|
preference.entryValues.map { it.toString() }
|
||||||
|
)
|
||||||
|
else -> throw RuntimeException("sealed class cannot have more subtypes!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ object SourceController {
|
|||||||
},
|
},
|
||||||
behaviorOf = { ctx, sourceId ->
|
behaviorOf = { ctx, sourceId ->
|
||||||
val preferenceChange = ctx.bodyAsClass(SourcePreferenceChange::class.java)
|
val preferenceChange = ctx.bodyAsClass(SourcePreferenceChange::class.java)
|
||||||
ctx.json(Source.setSourcePreference(sourceId, preferenceChange))
|
ctx.json(Source.setSourcePreference(sourceId, preferenceChange.position, preferenceChange.value))
|
||||||
},
|
},
|
||||||
withResults = {
|
withResults = {
|
||||||
httpCode(HttpCode.OK)
|
httpCode(HttpCode.OK)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ package suwayomi.tachidesk.manga.impl
|
|||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import androidx.preference.Preference
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import eu.kanade.tachiyomi.source.ConfigurableSource
|
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||||
import eu.kanade.tachiyomi.source.getPreferenceKey
|
import eu.kanade.tachiyomi.source.getPreferenceKey
|
||||||
@@ -96,6 +97,12 @@ object Source {
|
|||||||
* Gets a source's PreferenceScreen, puts the result into [preferenceScreenMap]
|
* Gets a source's PreferenceScreen, puts the result into [preferenceScreenMap]
|
||||||
*/
|
*/
|
||||||
fun getSourcePreferences(sourceId: Long): List<PreferenceObject> {
|
fun getSourcePreferences(sourceId: Long): List<PreferenceObject> {
|
||||||
|
return getSourcePreferencesRaw(sourceId).map {
|
||||||
|
PreferenceObject(it::class.java.simpleName, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getSourcePreferencesRaw(sourceId: Long): List<Preference> {
|
||||||
val source = getCatalogueSourceOrStub(sourceId)
|
val source = getCatalogueSourceOrStub(sourceId)
|
||||||
|
|
||||||
if (source is ConfigurableSource) {
|
if (source is ConfigurableSource) {
|
||||||
@@ -109,9 +116,7 @@ object Source {
|
|||||||
|
|
||||||
preferenceScreenMap[sourceId] = screen
|
preferenceScreenMap[sourceId] = screen
|
||||||
|
|
||||||
return screen.preferences.map {
|
return screen.preferences
|
||||||
PreferenceObject(it::class.java.simpleName, it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
@@ -123,18 +128,25 @@ object Source {
|
|||||||
|
|
||||||
private val jsonMapper by DI.global.instance<JsonMapper>()
|
private val jsonMapper by DI.global.instance<JsonMapper>()
|
||||||
|
|
||||||
@Suppress("IMPLICIT_CAST_TO_ANY", "UNCHECKED_CAST")
|
fun setSourcePreference(
|
||||||
fun setSourcePreference(sourceId: Long, change: SourcePreferenceChange) {
|
sourceId: Long,
|
||||||
val screen = preferenceScreenMap[sourceId]!!
|
position: Int,
|
||||||
val pref = screen.preferences[change.position]
|
value: String,
|
||||||
|
getValue: (Preference) -> Any = { pref ->
|
||||||
println(jsonMapper::class.java.name)
|
println(jsonMapper::class.java.name)
|
||||||
val newValue = when (pref.defaultValueType) {
|
@Suppress("UNCHECKED_CAST")
|
||||||
"String" -> change.value
|
when (pref.defaultValueType) {
|
||||||
"Boolean" -> change.value.toBoolean()
|
"String" -> value
|
||||||
"Set<String>" -> jsonMapper.fromJsonString(change.value, List::class.java as Class<List<String>>).toSet()
|
"Boolean" -> value.toBoolean()
|
||||||
else -> throw RuntimeException("Unsupported type conversion")
|
"Set<String>" -> jsonMapper.fromJsonString(value, List::class.java as Class<List<String>>).toSet()
|
||||||
|
else -> throw RuntimeException("Unsupported type conversion")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
) {
|
||||||
|
val screen = preferenceScreenMap[sourceId]!!
|
||||||
|
val pref = screen.preferences[position]
|
||||||
|
|
||||||
|
val newValue = getValue(pref)
|
||||||
|
|
||||||
pref.saveNewValue(newValue)
|
pref.saveNewValue(newValue)
|
||||||
pref.callChangeListener(newValue)
|
pref.callChangeListener(newValue)
|
||||||
|
|||||||
Reference in New Issue
Block a user