merge missing commit from #163

This commit is contained in:
Aria Moradi
2021-07-31 04:50:43 +04:30
5 changed files with 68 additions and 25 deletions

View File

@@ -13,7 +13,6 @@ import com.russhwolf.settings.ExperimentalSettingsImplementation
import com.russhwolf.settings.JvmPreferencesSettings import com.russhwolf.settings.JvmPreferencesSettings
import com.russhwolf.settings.serialization.decodeValue import com.russhwolf.settings.serialization.decodeValue
import com.russhwolf.settings.serialization.encodeValue import com.russhwolf.settings.serialization.encodeValue
import com.russhwolf.settings.set
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerializationException import kotlinx.serialization.SerializationException
import kotlinx.serialization.builtins.SetSerializer import kotlinx.serialization.builtins.SetSerializer
@@ -145,9 +144,12 @@ class JavaSharedPreferences(key: String) : SharedPreferences {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
when (value) { when (value) {
is Set<*> -> preferences.encodeValue(SetSerializer(String.serializer()), key, value as Set<String>) is Set<*> -> preferences.encodeValue(SetSerializer(String.serializer()), key, value as Set<String>)
else -> { is String -> preferences.putString(key, value)
preferences[key] = value is Int -> preferences.putInt(key, value)
} is Long -> preferences.putLong(key, value)
is Float -> preferences.putFloat(key, value)
is Double -> preferences.putDouble(key, value)
is Boolean -> preferences.putBoolean(key, value)
} }
} }
} }

View File

@@ -28,9 +28,11 @@ import suwayomi.tachidesk.manga.impl.Page.getPageImage
import suwayomi.tachidesk.manga.impl.Search.sourceFilters import suwayomi.tachidesk.manga.impl.Search.sourceFilters
import suwayomi.tachidesk.manga.impl.Search.sourceGlobalSearch import suwayomi.tachidesk.manga.impl.Search.sourceGlobalSearch
import suwayomi.tachidesk.manga.impl.Search.sourceSearch import suwayomi.tachidesk.manga.impl.Search.sourceSearch
import suwayomi.tachidesk.manga.impl.Source.SourcePreferenceChange
import suwayomi.tachidesk.manga.impl.Source.getSource import suwayomi.tachidesk.manga.impl.Source.getSource
import suwayomi.tachidesk.manga.impl.Source.getSourceList import suwayomi.tachidesk.manga.impl.Source.getSourceList
import suwayomi.tachidesk.manga.impl.Source.getSourcePreferences import suwayomi.tachidesk.manga.impl.Source.getSourcePreferences
import suwayomi.tachidesk.manga.impl.Source.setSourcePreference
import suwayomi.tachidesk.manga.impl.backup.BackupFlags import suwayomi.tachidesk.manga.impl.backup.BackupFlags
import suwayomi.tachidesk.manga.impl.backup.legacy.LegacyBackupExport.createLegacyBackup import suwayomi.tachidesk.manga.impl.backup.legacy.LegacyBackupExport.createLegacyBackup
import suwayomi.tachidesk.manga.impl.backup.legacy.LegacyBackupImport.restoreLegacyBackup import suwayomi.tachidesk.manga.impl.backup.legacy.LegacyBackupImport.restoreLegacyBackup
@@ -45,7 +47,7 @@ import suwayomi.tachidesk.server.impl.About
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
object TachideskAPI { object MangaAPI {
fun defineEndpoints(app: Javalin) { fun defineEndpoints(app: Javalin) {
// list all extensions // list all extensions
app.get("/api/v1/extension/list") { ctx -> app.get("/api/v1/extension/list") { ctx ->
@@ -111,11 +113,18 @@ object TachideskAPI {
} }
// fetch preferences of source with id `sourceId` // fetch preferences of source with id `sourceId`
app.get("/api/v1/source/:sourceId/preference-screen") { ctx -> app.get("/api/v1/source/:sourceId/preference") { ctx ->
val sourceId = ctx.pathParam("sourceId").toLong() val sourceId = ctx.pathParam("sourceId").toLong()
ctx.json(getSourcePreferences(sourceId)) ctx.json(getSourcePreferences(sourceId))
} }
// fetch preferences of source with id `sourceId`
app.post("/api/v1/source/:sourceId/preference") { ctx ->
val sourceId = ctx.pathParam("sourceId").toLong()
val preferenceChange = ctx.bodyAsClass(SourcePreferenceChange::class.java)
ctx.json(setSourcePreference(sourceId, preferenceChange))
}
// popular mangas from source with id `sourceId` // popular mangas from source with id `sourceId`
app.get("/api/v1/source/:sourceId/popular/:pageNum") { ctx -> app.get("/api/v1/source/:sourceId/popular/:pageNum") { ctx ->
val sourceId = ctx.pathParam("sourceId").toLong() val sourceId = ctx.pathParam("sourceId").toLong()

View File

@@ -18,6 +18,7 @@ import org.kodein.di.conf.global
import org.kodein.di.instance import org.kodein.di.instance
import suwayomi.tachidesk.manga.impl.extension.Extension.getExtensionIconUrl import suwayomi.tachidesk.manga.impl.extension.Extension.getExtensionIconUrl
import suwayomi.tachidesk.manga.impl.util.GetHttpSource.getHttpSource import suwayomi.tachidesk.manga.impl.util.GetHttpSource.getHttpSource
import suwayomi.tachidesk.manga.impl.util.GetHttpSource.invalidateSourceCache
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
@@ -30,12 +31,12 @@ object Source {
return transaction { return transaction {
SourceTable.selectAll().map { SourceTable.selectAll().map {
SourceDataClass( SourceDataClass(
it[SourceTable.id].value.toString(), it[SourceTable.id].value.toString(),
it[SourceTable.name], it[SourceTable.name],
it[SourceTable.lang], it[SourceTable.lang],
getExtensionIconUrl(ExtensionTable.select { ExtensionTable.id eq it[SourceTable.extension] }.first()[ExtensionTable.apkName]), getExtensionIconUrl(ExtensionTable.select { ExtensionTable.id eq it[SourceTable.extension] }.first()[ExtensionTable.apkName]),
getHttpSource(it[SourceTable.id].value).supportsLatest, getHttpSource(it[SourceTable.id].value).supportsLatest,
getHttpSource(it[SourceTable.id].value) is ConfigurableSource getHttpSource(it[SourceTable.id].value) is ConfigurableSource
) )
} }
} }
@@ -46,12 +47,12 @@ object Source {
val source = SourceTable.select { SourceTable.id eq sourceId }.firstOrNull() val source = SourceTable.select { SourceTable.id eq sourceId }.firstOrNull()
SourceDataClass( SourceDataClass(
sourceId.toString(), sourceId.toString(),
source?.get(SourceTable.name), source?.get(SourceTable.name),
source?.get(SourceTable.lang), source?.get(SourceTable.lang),
source?.let { ExtensionTable.select { ExtensionTable.id eq source[SourceTable.extension] }.first()[ExtensionTable.iconUrl] }, source?.let { ExtensionTable.select { ExtensionTable.id eq source[SourceTable.extension] }.first()[ExtensionTable.iconUrl] },
source?.let { getHttpSource(sourceId).supportsLatest }, source?.let { getHttpSource(sourceId).supportsLatest },
source?.let { getHttpSource(sourceId) is ConfigurableSource }, source?.let { getHttpSource(sourceId) is ConfigurableSource },
) )
} }
} }
@@ -59,22 +60,24 @@ object Source {
private val context by DI.global.instance<CustomContext>() private val context by DI.global.instance<CustomContext>()
data class PreferenceObject( data class PreferenceObject(
val type: String, val type: String,
val props: Any val props: Any
) )
var lastPreferenceScreen: PreferenceScreen? = null var preferenceScreenMap: MutableMap<Long, PreferenceScreen> = mutableMapOf()
/**
* Gets a source's PreferenceScreen, puts the result into [preferenceScreenMap]
*/
fun getSourcePreferences(sourceId: Long): List<PreferenceObject> { fun getSourcePreferences(sourceId: Long): List<PreferenceObject> {
val source = getHttpSource(sourceId) val source = getHttpSource(sourceId)
if (source is ConfigurableSource) { if (source is ConfigurableSource) {
val screen = PreferenceScreen(context) val screen = PreferenceScreen(context)
lastPreferenceScreen = screen
source.setupPreferenceScreen(screen) source.setupPreferenceScreen(screen)
screen.preferences.first().callChangeListener("yo") preferenceScreenMap[sourceId] = screen
return screen.preferences.map { return screen.preferences.map {
PreferenceObject(it::class.java.name, it) PreferenceObject(it::class.java.name, it)
@@ -82,4 +85,29 @@ object Source {
} }
return emptyList() return emptyList()
} }
data class SourcePreferenceChange(
val position: Int,
val type: String,
val value: String
)
fun setSourcePreference(sourceId: Long, change: SourcePreferenceChange ) {
val screen = preferenceScreenMap[sourceId]!!
val newValue = when(change.type) {
"String" -> change.value
"Int" -> change.value.toInt()
"Long" -> change.value.toLong()
"Float" -> change.value.toLong()
"Double" -> change.value.toDouble()
"Boolean" -> change.value.toBoolean()
else -> throw RuntimeException("Unsupported type conversion")
}
screen.preferences[change.position].callChangeListener(newValue)
// must reload the source cache because a preference was changed
invalidateSourceCache(sourceId)
}
} }

View File

@@ -54,4 +54,8 @@ object GetHttpSource {
} }
return sourceCache[sourceId]!! return sourceCache[sourceId]!!
} }
fun invalidateSourceCache(sourceId: Long) {
sourceCache.remove(sourceId)
}
} }

View File

@@ -14,7 +14,7 @@ import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.future.future import kotlinx.coroutines.future.future
import mu.KotlinLogging import mu.KotlinLogging
import suwayomi.tachidesk.anime.AnimeAPI import suwayomi.tachidesk.anime.AnimeAPI
import suwayomi.tachidesk.manga.TachideskAPI import suwayomi.tachidesk.manga.MangaAPI
import suwayomi.tachidesk.server.util.Browser import suwayomi.tachidesk.server.util.Browser
import java.io.IOException import java.io.IOException
import java.util.concurrent.CompletableFuture import java.util.concurrent.CompletableFuture
@@ -75,7 +75,7 @@ object JavalinSetup {
ctx.result(e.message ?: "Internal Server Error") ctx.result(e.message ?: "Internal Server Error")
} }
TachideskAPI.defineEndpoints(app) MangaAPI.defineEndpoints(app)
AnimeAPI.defineEndpoints(app) AnimeAPI.defineEndpoints(app)
} }
} }