mirror of
https://github.com/Suwayomi/Suwayomi-Server.git
synced 2026-07-14 00:04:34 -05:00
Compare commits
21 Commits
6493eaaa02
...
a403b1c564
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a403b1c564 | ||
|
|
98833fa738 | ||
|
|
f571b52740 | ||
|
|
744c5189c4 | ||
|
|
96859f90f0 | ||
|
|
76ee471933 | ||
|
|
6fdc247ace | ||
|
|
d0d28a692a | ||
|
|
7051a5d525 | ||
|
|
0e4de02b52 | ||
|
|
1b9db6cb01 | ||
|
|
af45cce641 | ||
|
|
903a3d53b3 | ||
|
|
13a5b3a831 | ||
|
|
da3a1dce9e | ||
|
|
c68a108298 | ||
|
|
911c0ce2e3 | ||
|
|
2a1f1faae5 | ||
|
|
07dceeb07c | ||
|
|
ba2257a164 | ||
|
|
669cb44864 |
@@ -11,4 +11,8 @@ ktlint_standard_if-else-wrapping=disabled
|
|||||||
ktlint_standard_no-consecutive-comments=disabled
|
ktlint_standard_no-consecutive-comments=disabled
|
||||||
|
|
||||||
[**/generated/**]
|
[**/generated/**]
|
||||||
ktlint=disabled
|
ktlint=disabled
|
||||||
|
|
||||||
|
[*.json]
|
||||||
|
indent_size=2
|
||||||
|
indent_style = space
|
||||||
9
.github/workflows/wiki.yml
vendored
9
.github/workflows/wiki.yml
vendored
@@ -24,6 +24,8 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
repository: ${{github.repository}}
|
repository: ${{github.repository}}
|
||||||
path: ${{github.repository}}
|
path: ${{github.repository}}
|
||||||
|
fetch-depth: 0 # fetch history & tags to determine stable version
|
||||||
|
fetch-tags: true
|
||||||
|
|
||||||
- name: Checkout Wiki
|
- name: Checkout Wiki
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v6
|
||||||
@@ -36,6 +38,13 @@ jobs:
|
|||||||
set -e
|
set -e
|
||||||
cd $GITHUB_WORKSPACE/${{github.repository}}.wiki
|
cd $GITHUB_WORKSPACE/${{github.repository}}.wiki
|
||||||
cp -r $GITHUB_WORKSPACE/${{github.repository}}/docs/* .
|
cp -r $GITHUB_WORKSPACE/${{github.repository}}/docs/* .
|
||||||
|
|
||||||
|
stable="$(git -C $GITHUB_WORKSPACE/${{github.repository}} describe --abbrev=0 --tags)"
|
||||||
|
if ! git -C $GITHUB_WORKSPACE/${{github.repository}} log --exit-code --pretty= "$stable.." -- docs/Configuring-Suwayomi‐Server.md; then
|
||||||
|
echo "Changes to config detected, embedding link to stable"
|
||||||
|
sed -i '1s/^/> [!WARNING]\n> This document describes the settings available in the preview version. Please head to ['$stable'](https:\/\/github.com\/Suwayomi\/Suwayomi-Server\/blob\/'$stable'\/docs\/Configuring-Suwayomi%E2%80%90Server.md) for the current stable version\n\n/' Configuring-Suwayomi‐Server.md
|
||||||
|
fi
|
||||||
|
|
||||||
git config --local user.email "action@github.com"
|
git config --local user.email "action@github.com"
|
||||||
git config --local user.name "GitHub Action"
|
git config --local user.name "GitHub Action"
|
||||||
git add .
|
git add .
|
||||||
|
|||||||
@@ -775,15 +775,23 @@ class KcefWebViewProvider(
|
|||||||
|
|
||||||
override fun getContentWidth(): Int = throw RuntimeException("Stub!")
|
override fun getContentWidth(): Int = throw RuntimeException("Stub!")
|
||||||
|
|
||||||
override fun pauseTimers(): Unit = throw RuntimeException("Stub!")
|
override fun pauseTimers() {
|
||||||
|
Log.v(TAG, "pauseTimers: doing nothing")
|
||||||
|
}
|
||||||
|
|
||||||
override fun resumeTimers(): Unit = throw RuntimeException("Stub!")
|
override fun resumeTimers() {
|
||||||
|
Log.v(TAG, "resumeTimers: doing nothing")
|
||||||
|
}
|
||||||
|
|
||||||
override fun onPause(): Unit = throw RuntimeException("Stub!")
|
override fun onPause() {
|
||||||
|
Log.v(TAG, "onPause: doing nothing")
|
||||||
|
}
|
||||||
|
|
||||||
override fun onResume(): Unit = throw RuntimeException("Stub!")
|
override fun onResume() {
|
||||||
|
Log.v(TAG, "onResume: doing nothing")
|
||||||
|
}
|
||||||
|
|
||||||
override fun isPaused(): Boolean = throw RuntimeException("Stub!")
|
override fun isPaused(): Boolean = false
|
||||||
|
|
||||||
override fun freeMemory(): Unit = throw RuntimeException("Stub!")
|
override fun freeMemory(): Unit = throw RuntimeException("Stub!")
|
||||||
|
|
||||||
|
|||||||
@@ -25,9 +25,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|||||||
- (**Extension**) Do not indicate an update is available when the extension is not installed
|
- (**Extension**) Do not indicate an update is available when the extension is not installed
|
||||||
- (**Chapter**) Fix losing chapter data on failed chapter list update
|
- (**Chapter**) Fix losing chapter data on failed chapter list update
|
||||||
- (**Chapter**) Fix database error when fetching chapter updates
|
- (**Chapter**) Fix database error when fetching chapter updates
|
||||||
- (**Manga/API**) Fix "mangas" graphql query with active sorting and using a postgresql database (QUERY "mangas")
|
- (**Manga/API**) Fix "mangas" graphql query with active sorting and using a PostgreSQL database (QUERY "mangas")
|
||||||
- (**API**) Fix GraphQL `Filter` `notAll` and `notAny` being inversed
|
- (**API**) Fix GraphQL `Filter` `notAll` and `notAny` being inversed
|
||||||
- (**API**) Fix GraphQL `Filter` causing an UnsupportedOperationException when passing an empty list as a `Any` filter value
|
- (**API**) Fix GraphQL `Filter` causing an UnsupportedOperationException when passing an empty list as a `Any` filter value
|
||||||
|
- (**Build**) Fix CURL failing silently in builds
|
||||||
|
|
||||||
## [v2.2.2100] + [WebUI: v20260508.01] - 2026-05-08
|
## [v2.2.2100] + [WebUI: v20260508.01] - 2026-05-08
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
- [Features](#features)
|
- [Features](#features)
|
||||||
- [Suwayomi client projects](#suwayomi-client-projects)
|
- [Suwayomi client projects](#suwayomi-client-projects)
|
||||||
- [Integrated clients](#integrated-clients)
|
- [Integrated clients](#integrated-clients)
|
||||||
- [Other clients](#other-clients-potentially-inactive-or-abondend)
|
- [Other clients](#other-clients-potentially-inactive-or-abandoned)
|
||||||
- [Downloading and Running the app](#downloading-and-running-the-app)
|
- [Downloading and Running the app](#downloading-and-running-the-app)
|
||||||
- [Using Operating System Specific Bundles](#using-operating-system-specific-bundles)
|
- [Using Operating System Specific Bundles](#using-operating-system-specific-bundles)
|
||||||
- [Windows](#windows)
|
- [Windows](#windows)
|
||||||
@@ -82,6 +82,7 @@ These clients are built-in options, and the server can keep them automatically u
|
|||||||
- [Tachidesk-JUI](https://github.com/Suwayomi/Tachidesk-JUI): Desktop app (windows, linux, mac); can manage its own suwayomi server instance
|
- [Tachidesk-JUI](https://github.com/Suwayomi/Tachidesk-JUI): Desktop app (windows, linux, mac); can manage its own suwayomi server instance
|
||||||
- [Tachidesk-Sorayomi](https://github.com/Suwayomi/Tachidesk-Sorayomi): Web app; Desktop app (windows, linux, mac); Android app; requires access to a running server
|
- [Tachidesk-Sorayomi](https://github.com/Suwayomi/Tachidesk-Sorayomi): Web app; Desktop app (windows, linux, mac); Android app; requires access to a running server
|
||||||
- [Tachidesk-qtui](https://github.com/Suwayomi/Tachidesk-qtui): Android app; iOS app Desktop app (linux); requires access to a running server
|
- [Tachidesk-qtui](https://github.com/Suwayomi/Tachidesk-qtui): Android app; iOS app Desktop app (linux); requires access to a running server
|
||||||
|
- [Suwayomi Client for KOReader](https://github.com/LK4D4/suwayomi.koplugin): KOReader plugin; works anywhere KOReader can run (Android, Kindle, Kobo, etc.); requires access to a running server
|
||||||
|
|
||||||
# Downloading and Running the app
|
# Downloading and Running the app
|
||||||
## Using Operating System Specific Bundles
|
## Using Operating System Specific Bundles
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ val getTachideskVersion = { "v2.2.${getCommitCount()}" }
|
|||||||
|
|
||||||
val webUIRevisionTag = "r3136"
|
val webUIRevisionTag = "r3136"
|
||||||
|
|
||||||
val webviewJbrRelease = "jbr-release-25.0.3b475.60"
|
val webviewJbrRelease = "jbr-release-25.0.3b496.62"
|
||||||
|
|
||||||
private val getCommitCount = {
|
private val getCommitCount = {
|
||||||
runCatching {
|
runCatching {
|
||||||
|
|||||||
@@ -52,6 +52,29 @@ Solutions:
|
|||||||
- If the WebView still does not work after a restart, your installation is incomplete. On Linux, refer to [the README](https://github.com/Suwayomi/Suwayomi-Server#webview-support-gnulinux).
|
- If the WebView still does not work after a restart, your installation is incomplete. On Linux, refer to [the README](https://github.com/Suwayomi/Suwayomi-Server#webview-support-gnulinux).
|
||||||
|
|
||||||
|
|
||||||
|
## Flaresolverr required
|
||||||
|
|
||||||
|
- `java.io.IOException: Cloudflare bypass currently disabled`
|
||||||
|
|
||||||
|
The source you are using has enabled CloudFlare's bot protection.
|
||||||
|
If you open the source's website in your browser, you should see the "Confirm I'm human" page.
|
||||||
|
|
||||||
|
Solution:
|
||||||
|
- Download and set up [Flaresolverr](https://github.com/FlareSolverr/FlareSolverr) or [Byparr](https://github.com/ThePhaseless/Byparr). Make sure to run Flaresolverr/Byparr every time you use this source.
|
||||||
|
|
||||||
|
|
||||||
|
## Flaresolverr not running
|
||||||
|
|
||||||
|
- `java.io.IOException: Failed to connect to localhost/[0:0:0:0:0:0:0:1]:8191`
|
||||||
|
|
||||||
|
You have configured Flaresolverr by enabling the `server.flareSolverrEnabled` setting, but Flaresolverr is not installed and/or running.
|
||||||
|
|
||||||
|
Solutions:
|
||||||
|
- Install Flaresolverr if you haven't already (see previous section). Then ensure it is running (Windows: do not close the console window!).
|
||||||
|
- If it is running, ensure the configured url in `server.flareSolverrUrl` is correct. There is usually no need to change this.
|
||||||
|
- If it is running and the url is correct, check your firewall settings, your system may be blocking access to Flaresolverr.
|
||||||
|
|
||||||
|
|
||||||
## General Troubleshooting
|
## General Troubleshooting
|
||||||
This guide will try to fix Suwayomi by reseting it to a clean installation state.
|
This guide will try to fix Suwayomi by reseting it to a clean installation state.
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ jvmTarget = "21"
|
|||||||
okhttp = "5.3.2" # Major version is locked by Tachiyomi extensions
|
okhttp = "5.3.2" # Major version is locked by Tachiyomi extensions
|
||||||
javalin = "7.2.2"
|
javalin = "7.2.2"
|
||||||
jte = "3.2.4"
|
jte = "3.2.4"
|
||||||
jackson = "3.1.3" # jackson version locked by javalin, ref: `io.javalin.core.util.OptionalDependency`
|
jackson = "3.1.4" # jackson version locked by javalin, ref: `io.javalin.core.util.OptionalDependency`
|
||||||
exposed = "1.2.0"
|
exposed = "1.2.0"
|
||||||
dex2jar = "2.4.36"
|
dex2jar = "2.4.36"
|
||||||
polyglot = "25.0.3"
|
polyglot = "25.0.3"
|
||||||
@@ -17,7 +17,7 @@ xmlserialization = "0.91.3"
|
|||||||
ktlint = "1.8.0"
|
ktlint = "1.8.0"
|
||||||
koin = "4.2.1"
|
koin = "4.2.1"
|
||||||
moko = "0.26.4"
|
moko = "0.26.4"
|
||||||
jcef = "144.0.15-g72717cf-chromium-144.0.7559.172-api-1.21-262-b34"
|
jcef = "144.0.15-g72717cf-chromium-144.0.7559.172-api-1.21-262-b37"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
# Kotlin
|
# Kotlin
|
||||||
@@ -39,8 +39,8 @@ serialization-xml = { module = "io.github.pdvrieze.xmlutil:serialization-jvm", v
|
|||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
slf4japi = "org.slf4j:slf4j-api:2.0.18"
|
slf4japi = "org.slf4j:slf4j-api:2.0.18"
|
||||||
logback = "ch.qos.logback:logback-classic:1.5.32"
|
logback = "ch.qos.logback:logback-classic:1.5.33"
|
||||||
kotlinlogging = "io.github.oshai:kotlin-logging-jvm:8.0.02"
|
kotlinlogging = "io.github.oshai:kotlin-logging-jvm:8.0.4"
|
||||||
|
|
||||||
# OkHttp
|
# OkHttp
|
||||||
okhttp-core = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
|
okhttp-core = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
|
||||||
@@ -55,7 +55,7 @@ javalin-openapi = { module = "io.javalin:javalin-openapi", version.ref = "javali
|
|||||||
javalin-rendering = { module = "io.javalin:javalin-rendering-jte", version.ref = "javalin" }
|
javalin-rendering = { module = "io.javalin:javalin-rendering-jte", version.ref = "javalin" }
|
||||||
jackson-databind = { module = "tools.jackson.core:jackson-databind", version.ref = "jackson" }
|
jackson-databind = { module = "tools.jackson.core:jackson-databind", version.ref = "jackson" }
|
||||||
jackson-kotlin = { module = "tools.jackson.module:jackson-module-kotlin", version.ref = "jackson" }
|
jackson-kotlin = { module = "tools.jackson.module:jackson-module-kotlin", version.ref = "jackson" }
|
||||||
jackson-annotations = "com.fasterxml.jackson.core:jackson-annotations:2.21"
|
jackson-annotations = "com.fasterxml.jackson.core:jackson-annotations:2.22"
|
||||||
jte = { module = "gg.jte:jte", version.ref = "jte" }
|
jte = { module = "gg.jte:jte", version.ref = "jte" }
|
||||||
kte = { module = "gg.jte:jte-kotlin", version.ref = "jte" }
|
kte = { module = "gg.jte:jte-kotlin", version.ref = "jte" }
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ twelvemonkeys-imageio-webp = { module = "com.twelvemonkeys.imageio:imageio-webp"
|
|||||||
imageio-webp = "com.github.usefulness:webp-imageio:0.10.2"
|
imageio-webp = "com.github.usefulness:webp-imageio:0.10.2"
|
||||||
|
|
||||||
# Testing
|
# Testing
|
||||||
mockk = "io.mockk:mockk:1.14.9"
|
mockk = "io.mockk:mockk:1.14.11"
|
||||||
|
|
||||||
# cron scheduler
|
# cron scheduler
|
||||||
cron4j = "it.sauronsoftware.cron4j:cron4j:2.2.5"
|
cron4j = "it.sauronsoftware.cron4j:cron4j:2.2.5"
|
||||||
@@ -186,7 +186,7 @@ buildconfig = { id = "com.github.gmazzo.buildconfig", version = "6.0.9"}
|
|||||||
download = { id = "de.undercouch.download", version = "5.7.0"}
|
download = { id = "de.undercouch.download", version = "5.7.0"}
|
||||||
|
|
||||||
# ShadowJar
|
# ShadowJar
|
||||||
shadowjar = { id = "com.gradleup.shadow", version = "8.3.10"}
|
shadowjar = { id = "com.gradleup.shadow", version = "8.3.11"}
|
||||||
|
|
||||||
# Moko
|
# Moko
|
||||||
moko = { id = "dev.icerock.mobile.multiplatform-resources", version.ref = "moko" }
|
moko = { id = "dev.icerock.mobile.multiplatform-resources", version.ref = "moko" }
|
||||||
|
|||||||
@@ -16,14 +16,43 @@
|
|||||||
"depNameTemplate": "zulu",
|
"depNameTemplate": "zulu",
|
||||||
"datasourceTemplate": "custom.zulu",
|
"datasourceTemplate": "custom.zulu",
|
||||||
"versioningTemplate": "regex:^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+).*$"
|
"versioningTemplate": "regex:^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+).*$"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"customType": "regex",
|
||||||
|
"managerFilePatterns": [
|
||||||
|
"/buildSrc/src/main/kotlin/Constants.kt/"
|
||||||
|
],
|
||||||
|
"matchStrings": [
|
||||||
|
"val\\s+webviewJbrRelease\\s*=\\s*\"(?<currentValue>[^\"]+)\""
|
||||||
|
],
|
||||||
|
"depNameTemplate": "JetBrainsRuntime",
|
||||||
|
"packageNameTemplate": "JetBrains/JetBrainsRuntime",
|
||||||
|
"datasourceTemplate": "github-releases",
|
||||||
|
"versioningTemplate": "regex:^jbr-release-(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)b(?<build>\\d+)\\.(?<revision>\\d+)$"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"customDatasources": {
|
"customDatasources": {
|
||||||
"zulu": {
|
"zulu": {
|
||||||
"defaultRegistryUrlTemplate": "https://api.azul.com/metadata/v1/zulu/packages?availability_types=ca&release_status=both&java_package_type=jre&crac_supported=false&javafx_bundled=false&support_term=lts&arch=x86&os=linux&archive_type=zip&page_size=1000&include_fields=java_package_features,release_status,support_term,os,arch,hw_bitness,abi,java_package_type,javafx_bundled,sha256_hash,cpu_gen,size,archive_type,certifications,lib_c_type,crac_supported&page=1&azul_com=true",
|
"defaultRegistryUrlTemplate": "https://api.azul.com/metadata/v1/zulu/packages?availability_types=ca&release_status=both&java_package_type=jre&crac_supported=false&javafx_bundled=false&support_term=lts&arch=x86&os=linux&archive_type=zip&page_size=1000&include_fields=java_package_features,release_status,support_term,os,arch,hw_bitness,abi,java_package_type,javafx_bundled,sha256_hash,cpu_gen,size,archive_type,certifications,lib_c_type,crac_supported&page=1&azul_com=true",
|
||||||
"transformTemplates": [
|
"transformTemplates": [
|
||||||
"{\"releases\": $$.$join([$join($map(distro_version[[0..2]], $string), \".\"), \"_\", $join($map(java_version, $string), \".\")])}"
|
"{ \"releases\": $map($, function($v) { { \"version\": $join([$string($v.distro_version[0]), \".\", $string($v.distro_version[1]), \".\", $string($v.distro_version[2]), \"_\", $string($v.java_version[0]), \".\", $string($v.java_version[1]), \".\", $string($v.java_version[2])]) } }) }"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"packageRules": [
|
||||||
|
{
|
||||||
|
"matchPackageNames": [
|
||||||
|
"org.jetbrains.intellij.deps.jcef:jcef",
|
||||||
|
"JetBrains/JetBrainsRuntime"
|
||||||
|
],
|
||||||
|
"groupName": "JCEF + JetBrains Runtime",
|
||||||
|
"groupSlug": "jcef-jbr"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"matchPackageNames": [
|
||||||
|
"com.github.Suwayomi:android-jar"
|
||||||
|
],
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ main() {
|
|||||||
gcc -fPIC -shared scripts/resources/catch_abort.c -lpthread -o scripts/resources/catch_abort.so
|
gcc -fPIC -shared scripts/resources/catch_abort.c -lpthread -o scripts/resources/catch_abort.so
|
||||||
fi
|
fi
|
||||||
|
|
||||||
JRE_ZULU="25.30.17_25.0.1"
|
JRE_ZULU="25.34.17_25.0.3"
|
||||||
JRE_RELEASE="jre${JRE_ZULU#*_}" # e.g. jre25.0.1
|
JRE_RELEASE="jre${JRE_ZULU#*_}" # e.g. jre25.0.1
|
||||||
ZULU_RELEASE="zulu${JRE_ZULU%_*}" # e.g. zulu25.30.17
|
ZULU_RELEASE="zulu${JRE_ZULU%_*}" # e.g. zulu25.30.17
|
||||||
|
|
||||||
@@ -149,15 +149,15 @@ move_release_to_output_dir() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
download_launcher() {
|
download_launcher() {
|
||||||
LAUNCHER_URL=$(curl -s "https://api.github.com/repos/Suwayomi/Suwayomi-Launcher/releases/latest" | grep "browser_download_url" | grep ".jar" | head -n 1 | cut -d '"' -f 4)
|
LAUNCHER_URL=$(curl -sf "https://api.github.com/repos/Suwayomi/Suwayomi-Launcher/releases/latest" | grep "browser_download_url" | grep ".jar" | head -n 1 | cut -d '"' -f 4)
|
||||||
curl -L "$LAUNCHER_URL" -o "Suwayomi-Launcher.jar"
|
curl -fL "$LAUNCHER_URL" -o "Suwayomi-Launcher.jar"
|
||||||
mv "Suwayomi-Launcher.jar" "$RELEASE_NAME/Suwayomi-Launcher.jar"
|
mv "Suwayomi-Launcher.jar" "$RELEASE_NAME/Suwayomi-Launcher.jar"
|
||||||
}
|
}
|
||||||
|
|
||||||
download_jogamp() {
|
download_jogamp() {
|
||||||
local platform="$1"
|
local platform="$1"
|
||||||
if [ ! -f jogamp-all-platforms.7z ]; then
|
if [ ! -f jogamp-all-platforms.7z ]; then
|
||||||
curl "https://jogamp.org/deployment/jogamp-current/archive/jogamp-all-platforms.7z" -o jogamp-all-platforms.7z
|
curl -f "https://jogamp.org/deployment/jogamp-current/archive/jogamp-all-platforms.7z" -o jogamp-all-platforms.7z
|
||||||
fi
|
fi
|
||||||
|
|
||||||
7z x jogamp-all-platforms.7z "jogamp-all-platforms/lib/$platform/"
|
7z x jogamp-all-platforms.7z "jogamp-all-platforms/lib/$platform/"
|
||||||
@@ -168,7 +168,7 @@ download_jogamp() {
|
|||||||
|
|
||||||
download_electron() {
|
download_electron() {
|
||||||
if [ ! -f "$ELECTRON" ]; then
|
if [ ! -f "$ELECTRON" ]; then
|
||||||
curl -L "$ELECTRON_URL" -o "$ELECTRON"
|
curl -fL "$ELECTRON_URL" -o "$ELECTRON"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
unzip "$ELECTRON" -d "$RELEASE_NAME/electron/"
|
unzip "$ELECTRON" -d "$RELEASE_NAME/electron/"
|
||||||
@@ -181,7 +181,7 @@ setup_jre() {
|
|||||||
mv "jre" "$RELEASE_NAME/jre"
|
mv "jre" "$RELEASE_NAME/jre"
|
||||||
else
|
else
|
||||||
if [ ! -f "$JRE" ]; then
|
if [ ! -f "$JRE" ]; then
|
||||||
curl -L "$JRE_URL" -o "$JRE"
|
curl -fL "$JRE_URL" -o "$JRE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local ext="${JRE##*.}"
|
local ext="${JRE##*.}"
|
||||||
@@ -273,7 +273,7 @@ make_appimage() {
|
|||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install libfuse2
|
sudo apt install libfuse2
|
||||||
fi
|
fi
|
||||||
curl -L $APPIMAGE_URL -o $APPIMAGE_TOOLNAME
|
curl -fL $APPIMAGE_URL -o $APPIMAGE_TOOLNAME
|
||||||
chmod +x $APPIMAGE_TOOLNAME
|
chmod +x $APPIMAGE_TOOLNAME
|
||||||
ARCH=x86_64 ./$APPIMAGE_TOOLNAME "$RELEASE_NAME" "$RELEASE"
|
ARCH=x86_64 ./$APPIMAGE_TOOLNAME "$RELEASE_NAME" "$RELEASE"
|
||||||
}
|
}
|
||||||
@@ -300,7 +300,7 @@ make_windows_bundle() {
|
|||||||
#local rcedit_url="https://github.com/electron/rcedit/releases/download/v0.1.1/$rcedit"
|
#local rcedit_url="https://github.com/electron/rcedit/releases/download/v0.1.1/$rcedit"
|
||||||
## change electron's icon
|
## change electron's icon
|
||||||
#if [ ! -f "$rcedit" ]; then
|
#if [ ! -f "$rcedit" ]; then
|
||||||
#curl -L "$rcedit_url" -o "$rcedit"
|
#curl -fL "$rcedit_url" -o "$rcedit"
|
||||||
#fi
|
#fi
|
||||||
|
|
||||||
#local icon="server/src/main/resources/icon/faviconlogo.ico"
|
#local icon="server/src/main/resources/icon/faviconlogo.ico"
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import kotlinx.coroutines.flow.Flow
|
|||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.flow.conflate
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.drop
|
import kotlinx.coroutines.flow.drop
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
@@ -73,6 +74,21 @@ val serverConfig: ServerConfig by lazy { GlobalConfigManager.module() }
|
|||||||
|
|
||||||
private val application: Application by injectLazy()
|
private val application: Application by injectLazy()
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
fun <T> subscribeTo(
|
||||||
|
flow: Flow<T>,
|
||||||
|
ignoreInitialValue: Boolean = true,
|
||||||
|
onChange: suspend (value: T) -> Unit,
|
||||||
|
) {
|
||||||
|
val actualFlow =
|
||||||
|
if (ignoreInitialValue) {
|
||||||
|
flow.drop(1)
|
||||||
|
} else {
|
||||||
|
flow
|
||||||
|
}
|
||||||
|
actualFlow.distinctUntilChanged().conflate().onEach { onChange(it) }.launchIn(mutableConfigValueScope)
|
||||||
|
}
|
||||||
|
|
||||||
// Settings are ordered by "protoNumber".
|
// Settings are ordered by "protoNumber".
|
||||||
class ServerConfig(
|
class ServerConfig(
|
||||||
getConfig: () -> Config,
|
getConfig: () -> Config,
|
||||||
@@ -1067,18 +1083,7 @@ class ServerConfig(
|
|||||||
flow: Flow<T>,
|
flow: Flow<T>,
|
||||||
onChange: suspend (value: T) -> Unit,
|
onChange: suspend (value: T) -> Unit,
|
||||||
ignoreInitialValue: Boolean = true,
|
ignoreInitialValue: Boolean = true,
|
||||||
) {
|
) = subscribeTo(flow, ignoreInitialValue, onChange)
|
||||||
val actualFlow =
|
|
||||||
if (ignoreInitialValue) {
|
|
||||||
flow.drop(1)
|
|
||||||
} else {
|
|
||||||
flow
|
|
||||||
}
|
|
||||||
|
|
||||||
val sharedFlow = MutableSharedFlow<T>(extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
|
|
||||||
actualFlow.distinctUntilChanged().mapLatest { sharedFlow.emit(it) }.launchIn(mutableConfigValueScope)
|
|
||||||
sharedFlow.onEach { onChange(it) }.launchIn(mutableConfigValueScope)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T> subscribeTo(
|
fun <T> subscribeTo(
|
||||||
flow: Flow<T>,
|
flow: Flow<T>,
|
||||||
|
|||||||
26
server/src/test/kotlin/suwayomi/tachidesk/FlowTest.kt
Normal file
26
server/src/test/kotlin/suwayomi/tachidesk/FlowTest.kt
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package suwayomi.tachidesk
|
||||||
|
|
||||||
|
import graphql.Assert.assertTrue
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import suwayomi.tachidesk.server.subscribeTo
|
||||||
|
import java.util.concurrent.CountDownLatch
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
import kotlin.test.Test
|
||||||
|
|
||||||
|
class FlowTest {
|
||||||
|
@Test
|
||||||
|
fun subscribe() =
|
||||||
|
runTest {
|
||||||
|
(1..1000).forEach { _ ->
|
||||||
|
val testFlow = MutableStateFlow(value = 3)
|
||||||
|
testFlow.first()
|
||||||
|
val latch = CountDownLatch(1)
|
||||||
|
subscribeTo(testFlow, ignoreInitialValue = false) { _ ->
|
||||||
|
latch.countDown()
|
||||||
|
}
|
||||||
|
assertTrue(latch.await(5, TimeUnit.SECONDS))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user