Add path prefix preference

This commit is contained in:
Syer10
2022-03-12 18:24:00 -05:00
parent 28045b6341
commit a619c35731
8 changed files with 63 additions and 28 deletions

View File

@@ -145,8 +145,9 @@ class AndroidDownloadService : Service() {
} }
runCatching { runCatching {
client.ws( client.ws(
host = serverUrl.substringAfter("://"), host = serverUrl.host,
path = downloadsQuery() port = serverUrl.port,
path = serverUrl.encodedPath + downloadsQuery()
) { ) {
errorConnectionCount = 0 errorConnectionCount = 0
status.value = Status.RUNNING status.value = Status.RUNNING

View File

@@ -55,8 +55,9 @@ abstract class WebsocketService(
} }
runCatching { runCatching {
client.ws( client.ws(
host = serverUrl.substringAfter("://"), host = serverUrl.host,
path = query port = serverUrl.port,
path = serverUrl.encodedPath + query
) { ) {
errorConnectionCount = 0 errorConnectionCount = 0
_status.value = Status.RUNNING _status.value = Status.RUNNING

View File

@@ -10,6 +10,7 @@ import ca.gosyer.core.prefs.Preference
import ca.gosyer.core.prefs.PreferenceStore import ca.gosyer.core.prefs.PreferenceStore
import ca.gosyer.data.server.model.Auth import ca.gosyer.data.server.model.Auth
import ca.gosyer.data.server.model.Proxy import ca.gosyer.data.server.model.Proxy
import io.ktor.http.Url
class ServerPreferences(private val preferenceStore: PreferenceStore) { class ServerPreferences(private val preferenceStore: PreferenceStore) {
@@ -21,8 +22,12 @@ class ServerPreferences(private val preferenceStore: PreferenceStore) {
return preferenceStore.getInt("server_port", 4567) return preferenceStore.getInt("server_port", 4567)
} }
fun serverUrl(): Preference<String> { fun pathPrefix(): Preference<String> {
return ServerUrlPreference("", server(), port()) return preferenceStore.getString("server_path_prefix", "")
}
fun serverUrl(): Preference<Url> {
return ServerUrlPreference("", server(), port(), pathPrefix())
} }
fun proxy(): Preference<Proxy> { fun proxy(): Preference<Proxy> {

View File

@@ -7,6 +7,8 @@
package ca.gosyer.data.server package ca.gosyer.data.server
import ca.gosyer.core.prefs.Preference import ca.gosyer.core.prefs.Preference
import io.ktor.http.URLBuilder
import io.ktor.http.Url
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
@@ -17,42 +19,56 @@ import kotlinx.coroutines.flow.stateIn
class ServerUrlPreference( class ServerUrlPreference(
private val key: String, private val key: String,
private val server: Preference<String>, private val server: Preference<String>,
private val port: Preference<Int> private val port: Preference<Int>,
) : Preference<String> { private val pathPrefix: Preference<String>
) : Preference<Url> {
override fun key(): String { override fun key(): String {
return key return key
} }
override fun get(): String { override fun get(): Url {
return server.get() + ":" + port.get() return URLBuilder(server.get()).apply {
port = this@ServerUrlPreference.port.get()
if (pathPrefix.isSet() && pathPrefix.get().isNotBlank()) {
path(pathPrefix.get())
}
}.build()
} }
override fun set(value: String) { override fun set(value: Url) {
val (server, port) = value.split(':') server.set(value.protocol.name + "://" + value.host)
this.server.set(server) port.set(value.port)
this.port.set(port.toInt()) pathPrefix.set(value.encodedPath)
} }
override fun isSet(): Boolean { override fun isSet(): Boolean {
return server.isSet() || port.isSet() return server.isSet() || port.isSet() || pathPrefix.isSet()
} }
override fun delete() { override fun delete() {
server.delete() server.delete()
port.delete() port.delete()
pathPrefix.delete()
} }
override fun defaultValue(): String { override fun defaultValue(): Url {
return server.defaultValue() + ":" + port.defaultValue() return URLBuilder(server.defaultValue()).apply {
port = this@ServerUrlPreference.port.defaultValue()
}.build()
} }
override fun changes(): Flow<String> { override fun changes(): Flow<Url> {
return combine(server.changes(), port.changes()) { server, port -> return combine(server.changes(), port.changes(), pathPrefix.changes()) { server, port, pathPrefix ->
"$server:$port" URLBuilder(server).apply {
this.port = port
if (pathPrefix.isNotBlank()) {
path(pathPrefix)
}
}.build()
} }
} }
override fun stateIn(scope: CoroutineScope): StateFlow<String> { override fun stateIn(scope: CoroutineScope): StateFlow<Url> {
return changes().stateIn(scope, SharingStarted.Eagerly, get()) return changes().stateIn(scope, SharingStarted.Eagerly, get())
} }
} }

View File

@@ -14,5 +14,5 @@ open class BaseInteractionHandler(
serverPreferences: ServerPreferences serverPreferences: ServerPreferences
) { ) {
private val _serverUrl = serverPreferences.serverUrl() private val _serverUrl = serverPreferences.serverUrl()
val serverUrl get() = _serverUrl.get() val serverUrl get() = _serverUrl.get().toString()
} }

View File

@@ -237,6 +237,8 @@
<string name="host_basic_auth_password">Basic auth password</string> <string name="host_basic_auth_password">Basic auth password</string>
<string name="server_url">Server URL</string> <string name="server_url">Server URL</string>
<string name="server_port">Server PORT</string> <string name="server_port">Server PORT</string>
<string name="server_path_prefix">Server Path Prefix</string>
<string name="server_path_prefix_sub">Path prefix to be used before endpoint paths, leave blank for unused.</string>
<string name="server_preference_warning">Warning</string> <string name="server_preference_warning">Warning</string>
<string name="server_preference_warning_sub">The below settings require a restart to take affect</string> <string name="server_preference_warning_sub">The below settings require a restart to take affect</string>
<string name="no_proxy">No Proxy</string> <string name="no_proxy">No Proxy</string>

View File

@@ -56,21 +56,21 @@ class KamelConfigProvider @Inject constructor(
} }
} }
class MangaCoverMapper(private val serverUrlStateFlow: StateFlow<String>) : Mapper<Manga, Url> { class MangaCoverMapper(private val serverUrlStateFlow: StateFlow<Url>) : Mapper<Manga, Url> {
override fun map(input: Manga): Url { override fun map(input: Manga): Url {
return Url(serverUrlStateFlow.value + input.thumbnailUrl) return Url(serverUrlStateFlow.value.toString() + input.thumbnailUrl)
} }
} }
class ExtensionIconMapper(private val serverUrlStateFlow: StateFlow<String>) : Mapper<Extension, Url> { class ExtensionIconMapper(private val serverUrlStateFlow: StateFlow<Url>) : Mapper<Extension, Url> {
override fun map(input: Extension): Url { override fun map(input: Extension): Url {
return Url(serverUrlStateFlow.value + input.iconUrl) return Url(serverUrlStateFlow.value.toString() + input.iconUrl)
} }
} }
class SourceIconMapper(private val serverUrlStateFlow: StateFlow<String>) : Mapper<Source, Url> { class SourceIconMapper(private val serverUrlStateFlow: StateFlow<Url>) : Mapper<Source, Url> {
override fun map(input: Source): Url { override fun map(input: Source): Url {
return Url(serverUrlStateFlow.value + input.iconUrl) return Url(serverUrlStateFlow.value.toString() + input.iconUrl)
} }
} }
} }

View File

@@ -59,6 +59,7 @@ class SettingsServerScreen : Screen {
authValue = connectionVM.auth.collectAsState().value, authValue = connectionVM.auth.collectAsState().value,
serverUrl = connectionVM.serverUrl, serverUrl = connectionVM.serverUrl,
serverPort = connectionVM.serverPort, serverPort = connectionVM.serverPort,
serverPathPrefix = connectionVM.serverPathPrefix,
proxy = connectionVM.proxy, proxy = connectionVM.proxy,
proxyChoices = connectionVM.getProxyChoices(), proxyChoices = connectionVM.getProxyChoices(),
httpHost = connectionVM.httpHost, httpHost = connectionVM.httpHost,
@@ -83,6 +84,7 @@ class SettingsServerViewModel @Inject constructor(
) : ViewModel(contextWrapper) { ) : ViewModel(contextWrapper) {
val serverUrl = serverPreferences.server().asStateIn(scope) val serverUrl = serverPreferences.server().asStateIn(scope)
val serverPort = serverPreferences.port().asStringStateIn(scope) val serverPort = serverPreferences.port().asStringStateIn(scope)
val serverPathPrefix = serverPreferences.pathPrefix().asStateIn(scope)
val proxy = serverPreferences.proxy().asStateIn(scope) val proxy = serverPreferences.proxy().asStateIn(scope)
@@ -125,6 +127,7 @@ fun SettingsServerScreenContent(
authValue: Auth, authValue: Auth,
serverUrl: PreferenceMutableStateFlow<String>, serverUrl: PreferenceMutableStateFlow<String>,
serverPort: PreferenceMutableStateFlow<String>, serverPort: PreferenceMutableStateFlow<String>,
serverPathPrefix: PreferenceMutableStateFlow<String>,
proxy: PreferenceMutableStateFlow<Proxy>, proxy: PreferenceMutableStateFlow<Proxy>,
proxyChoices: Map<Proxy, String>, proxyChoices: Map<Proxy, String>,
httpHost: PreferenceMutableStateFlow<String>, httpHost: PreferenceMutableStateFlow<String>,
@@ -159,6 +162,13 @@ fun SettingsServerScreenContent(
subtitle = serverPort.collectAsState().value subtitle = serverPort.collectAsState().value
) )
} }
item {
EditTextPreference(
serverPathPrefix,
stringResource(MR.strings.server_path_prefix),
subtitle = stringResource(MR.strings.server_path_prefix_sub)
)
}
item { item {
PreferenceRow( PreferenceRow(