diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a86a778..f45e6a1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -126,7 +126,7 @@ jobs: "os": "ubuntu-latest", "release": "android", "rust_target": "aarch64-linux-android,armv7-linux-androideabi,i686-linux-android,x86_64-linux-android", - "manual": false + "manual": true }, { "os": "ubuntu-22.04", @@ -279,7 +279,17 @@ jobs: cd app/ rm -rf src-tauri/gen/android pnpm tauri android init - pnpm tauri icon ../../data/icons/myreader-book.png + # gen/android is gitignored (never committed), so `tauri android + # init` always regenerates a vanilla app/build.gradle.kts that + # doesn't know about tauri-plugin-native-bridge's foss/googleplay + # `store` product flavor (see plugins/tauri-plugin-native-bridge/ + # android/build.gradle.kts). Without a strategy Gradle can't pick + # between the two variants and fails with a "cannot choose between + # fossReleaseRuntimeElements and googleplayReleaseRuntimeElements" + # dependency resolution error. Re-inject the same fix documented + # in README.md's local Android setup steps on every fresh init. + sed -i '/defaultConfig {/a\ missingDimensionStrategy("store", "foss", "googleplay")' src-tauri/gen/android/app/build.gradle.kts + pnpm tauri icon ../data/icons/myreader-book.png git checkout . pushd src-tauri/gen/android @@ -288,15 +298,39 @@ jobs: base64 -d <<< "${{ secrets.ANDROID_KEY_BASE64 }}" > $RUNNER_TEMP/keystore.jks echo "storeFile=$RUNNER_TEMP/keystore.jks" >> keystore.properties + # `tauri android init` regenerates app/build.gradle.kts from a + # vanilla template with no signingConfigs block at all, so + # keystore.properties above was written but never read: every + # release build was silently *unsigned* + # (app-universal-release-unsigned.apk), which then fails to + # install with INSTALL_PARSE_FAILED_NO_CERTIFICATES even though + # the ANDROID_KEY_* secrets were set correctly. Wire the release + # build type to a signingConfig sourced from keystore.properties + # on every fresh init. + # NOTE: use the bare `Properties()` (already imported at the top of + # build.gradle.kts) rather than `java.util.Properties()` here — AGP's + # `android {}` extension exposes its own `java { ... }` toolchain DSL + # accessor that shadows the top-level `java` package inside this + # scope, so the fully-qualified form fails with + # "Unresolved reference: util". + perl -0777 -pi -e 's/android \{\r?\n/android {\n signingConfigs {\n create("release") {\n val keystorePropertiesFile = rootProject.file("keystore.properties")\n if (keystorePropertiesFile.exists()) {\n val keystoreProperties = Properties()\n keystoreProperties.load(keystorePropertiesFile.inputStream())\n keyAlias = keystoreProperties.getProperty("keyAlias")\n keyPassword = keystoreProperties.getProperty("password")\n storeFile = file(keystoreProperties.getProperty("storeFile"))\n storePassword = keystoreProperties.getProperty("password")\n }\n }\n }\n/' app/build.gradle.kts + sed -i '/getByName("release") {/a\ signingConfig = signingConfigs.getByName("release")' app/build.gradle.kts + popd version=${{ needs.get-release.outputs.release_version }} apk_path=src-tauri/gen/android/app/build/outputs/apk/universal/release universial_apk=MyReader_${version}_universal.apk arm64_apk=MyReader_${version}_arm64.apk + # Now that signingConfig is wired above, release builds produce + # app-universal-release.apk (signed). Still pick the newest + # matching file rather than hardcoding the name, as a safety net + # in case signing silently falls through (e.g. a missing secret + # leaves keystorePropertiesFile.exists() false) and gradle falls + # back to the -unsigned.apk name. pnpm tauri android build - cp ${apk_path}/app-universal-release.apk $universial_apk + cp "$(ls -t ${apk_path}/app-universal-release*.apk | head -n1)" $universial_apk pnpm tauri android build -t aarch64 - cp ${apk_path}/app-universal-release.apk $arm64_apk + cp "$(ls -t ${apk_path}/app-universal-release*.apk | head -n1)" $arm64_apk echo "Uploading $universial_apk to GitHub release" gh release upload ${{ needs.get-release.outputs.release_tag }} $universial_apk --clobber diff --git a/Cargo.lock b/Cargo.lock index 63db812..5bd7f33 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -216,7 +216,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -227,7 +227,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -698,7 +698,7 @@ version = "3.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "519bd3116aeeb42d5372c29d982d16d0170d3d4a5ed85fc7dd91642ffff3c67c" dependencies = [ - "darling 0.23.0", + "darling 0.20.11", "ident_case", "prettyplease", "proc-macro2", @@ -1705,7 +1705,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -1737,7 +1737,7 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab8ecd87370524b461f8557c119c405552c396ed91fc0a8eec68679eab26f94a" dependencies = [ - "libloading 0.8.9", + "libloading 0.7.4", ] [[package]] @@ -1994,7 +1994,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -2471,8 +2471,8 @@ dependencies = [ "libc", "log", "rustversion", - "windows-link 0.2.1", - "windows-result 0.4.1", + "windows-link 0.1.3", + "windows-result 0.3.4", ] [[package]] @@ -2611,7 +2611,7 @@ dependencies = [ "gobject-sys 0.21.5", "libc", "system-deps 7.0.8", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -3066,7 +3066,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.62.2", + "windows-core 0.57.0", ] [[package]] @@ -4237,7 +4237,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -4796,7 +4796,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.45.0", ] [[package]] @@ -5399,7 +5399,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" dependencies = [ "anyhow", - "itertools 0.14.0", + "itertools 0.12.1", "proc-macro2", "quote", "syn 2.0.117", @@ -6077,7 +6077,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -6090,7 +6090,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -6147,7 +6147,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -6762,7 +6762,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -8071,7 +8071,7 @@ dependencies = [ "getrandom 0.4.2", "once_cell", "rustix 1.1.4", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -8820,7 +8820,7 @@ checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e" dependencies = [ "memoffset", "tempfile", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -9393,7 +9393,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -9506,19 +9506,6 @@ dependencies = [ "windows-strings 0.4.2", ] -[[package]] -name = "windows-core" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" -dependencies = [ - "windows-implement 0.60.2", - "windows-interface 0.59.3", - "windows-link 0.2.1", - "windows-result 0.4.1", - "windows-strings 0.5.1", -] - [[package]] name = "windows-future" version = "0.2.1" diff --git a/README.md b/README.md index 3e90d13..1a88dc4 100644 --- a/README.md +++ b/README.md @@ -76,15 +76,28 @@ pnpm preview Android: ```bash -# 初始化 Android 环境(运行一次) +# 初始化 Android 环境(运行一次),需要提前安装Android开发环境,Windows上需要打开发者模式 rm app/src-tauri/gen/android pnpm tauri android init -pnpm tauri icon ../../data/icons/myreader-book.png -git checkout app/src-tauri/gen/android +# app/src-tauri/gen/android 整个目录被 .gitignore 排除,不会被 git 追踪, +# 所以每次 init 都会重新生成一份不带下面这行补丁的 build.gradle.kts。 +# tauri-plugin-native-bridge 声明了 foss/googleplay 两个 store 维度的 flavor, +# 缺这一行 Gradle 会因为无法在两者间选择而构建失败,每次 init 后都要重新执行: +sed -i '/defaultConfig {/a\ missingDimensionStrategy("store", "foss", "googleplay")' app/src-tauri/gen/android/app/build.gradle.kts +pnpm tauri icon ../data/icons/myreader-book.png pnpm tauri android dev # 或在真机上开发 -pnpm tauri android dev --host +pnpm tauri android dev --host +``` + +```bash +# 构建APK +cd app +# 打包全架构包(universal) +pnpm tauri android build +# 只打包aarch64的包 +pnpm tauri android build -t aarch64 ``` iOS: diff --git a/app/next.config.mjs b/app/next.config.mjs index d609e8f..974eee1 100644 --- a/app/next.config.mjs +++ b/app/next.config.mjs @@ -47,7 +47,13 @@ const nextConfig = { assetPrefix: '', reactStrictMode: true, serverExternalPackages: ['isows'], - allowedDevOrigins: ['192.168.2.120'], + // Static entry is a stale LAN IP from a prior network; keep it as a + // harmless fallback and additionally allow whatever IP tauri-cli picked + // for `--host ` this run (forwarded via TAURI_DEV_HOST, see layout.tsx). + allowedDevOrigins: [ + '192.168.2.120', + ...(process.env['TAURI_DEV_HOST'] ? [process.env['TAURI_DEV_HOST']] : []), + ], webpack: (config) => { config.resolve.alias = { ...config.resolve.alias, diff --git a/app/package.json b/app/package.json index 501d937..6345d05 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "@poxenstudio/myreader", - "version": "0.1.0", + "version": "0.2.0", "private": true, "type": "module", "scripts": { diff --git a/app/release-notes.json b/app/release-notes.json index d86c6c0..8a38084 100644 --- a/app/release-notes.json +++ b/app/release-notes.json @@ -1,5 +1,9 @@ { "releases": { + "0.2.0": { + "date": "2026-07-14", + "notes": ["Android版本发布", "支持MyBooks开启私人图书馆模式的登录"] + }, "0.1.0": { "date": "2026-06-28", "notes": ["Initial release"] diff --git a/app/src-tauri/Cargo.toml b/app/src-tauri/Cargo.toml index 9cd6eed..2f6ed9e 100644 --- a/app/src-tauri/Cargo.toml +++ b/app/src-tauri/Cargo.toml @@ -60,7 +60,6 @@ tauri-plugin-webview-upgrade = { path = "./plugins/tauri-plugin-webview-upgrade" tauri-plugin-websocket = "2" tauri-plugin-sharekit = "0.3" tauri-plugin-device-info = "1.0.1" -tauri-plugin-turso = { path = "./plugins/tauri-plugin-turso" } tauri-plugin-webdriver = { version = "0.2", optional = true } [target."cfg(target_os = \"macos\")".dependencies] @@ -80,5 +79,8 @@ tauri-plugin-single-instance = "2" tauri-plugin-updater = "2" tauri-plugin-window-state = "2" +[target.'cfg(not(target_os = "android"))'.dependencies] +tauri-plugin-turso = { path = "./plugins/tauri-plugin-turso" } + [target.'cfg(target_os = "android")'.dependencies] libc = "0.2" diff --git a/app/src-tauri/capabilities/default.json b/app/src-tauri/capabilities/default.json index 8f0bad0..14b5f7e 100644 --- a/app/src-tauri/capabilities/default.json +++ b/app/src-tauri/capabilities/default.json @@ -197,7 +197,6 @@ "deep-link:default", "sharekit:default", "device-info:default", - "turso:default", "native-tts:default", "native-bridge:default" ] diff --git a/app/src-tauri/capabilities/desktop.json b/app/src-tauri/capabilities/desktop.json index 6b56381..21e3532 100644 --- a/app/src-tauri/capabilities/desktop.json +++ b/app/src-tauri/capabilities/desktop.json @@ -3,5 +3,5 @@ "identifier": "desktop-capability", "windows": ["main", "updater", "reader-*"], "platforms": ["linux", "macOS", "windows"], - "permissions": ["updater:default", "cli:default"] + "permissions": ["updater:default", "cli:default", "turso:default"] } diff --git a/app/src-tauri/icons/128x128.png b/app/src-tauri/icons/128x128.png index 0f49772..597dbc3 100644 Binary files a/app/src-tauri/icons/128x128.png and b/app/src-tauri/icons/128x128.png differ diff --git a/app/src-tauri/icons/128x128@2x.png b/app/src-tauri/icons/128x128@2x.png index aec70e6..42fd11a 100644 Binary files a/app/src-tauri/icons/128x128@2x.png and b/app/src-tauri/icons/128x128@2x.png differ diff --git a/app/src-tauri/icons/32x32.png b/app/src-tauri/icons/32x32.png index 2b649e7..7d36551 100644 Binary files a/app/src-tauri/icons/32x32.png and b/app/src-tauri/icons/32x32.png differ diff --git a/app/src-tauri/icons/64x64.png b/app/src-tauri/icons/64x64.png index 7caaf0c..a4a42b4 100644 Binary files a/app/src-tauri/icons/64x64.png and b/app/src-tauri/icons/64x64.png differ diff --git a/app/src-tauri/icons/Square107x107Logo.png b/app/src-tauri/icons/Square107x107Logo.png index 48647c7..c9d0eda 100644 Binary files a/app/src-tauri/icons/Square107x107Logo.png and b/app/src-tauri/icons/Square107x107Logo.png differ diff --git a/app/src-tauri/icons/Square142x142Logo.png b/app/src-tauri/icons/Square142x142Logo.png index 1016683..899c2e6 100644 Binary files a/app/src-tauri/icons/Square142x142Logo.png and b/app/src-tauri/icons/Square142x142Logo.png differ diff --git a/app/src-tauri/icons/Square150x150Logo.png b/app/src-tauri/icons/Square150x150Logo.png index 2de48a9..c6e6aff 100644 Binary files a/app/src-tauri/icons/Square150x150Logo.png and b/app/src-tauri/icons/Square150x150Logo.png differ diff --git a/app/src-tauri/icons/Square284x284Logo.png b/app/src-tauri/icons/Square284x284Logo.png index d853f5e..719b568 100644 Binary files a/app/src-tauri/icons/Square284x284Logo.png and b/app/src-tauri/icons/Square284x284Logo.png differ diff --git a/app/src-tauri/icons/Square30x30Logo.png b/app/src-tauri/icons/Square30x30Logo.png index e3e1e26..0a0782c 100644 Binary files a/app/src-tauri/icons/Square30x30Logo.png and b/app/src-tauri/icons/Square30x30Logo.png differ diff --git a/app/src-tauri/icons/Square310x310Logo.png b/app/src-tauri/icons/Square310x310Logo.png index 521b755..91e90af 100644 Binary files a/app/src-tauri/icons/Square310x310Logo.png and b/app/src-tauri/icons/Square310x310Logo.png differ diff --git a/app/src-tauri/icons/Square44x44Logo.png b/app/src-tauri/icons/Square44x44Logo.png index d00123c..35e8213 100644 Binary files a/app/src-tauri/icons/Square44x44Logo.png and b/app/src-tauri/icons/Square44x44Logo.png differ diff --git a/app/src-tauri/icons/Square71x71Logo.png b/app/src-tauri/icons/Square71x71Logo.png index cb7c2f3..7c62e00 100644 Binary files a/app/src-tauri/icons/Square71x71Logo.png and b/app/src-tauri/icons/Square71x71Logo.png differ diff --git a/app/src-tauri/icons/Square89x89Logo.png b/app/src-tauri/icons/Square89x89Logo.png index ba96884..fac4da8 100644 Binary files a/app/src-tauri/icons/Square89x89Logo.png and b/app/src-tauri/icons/Square89x89Logo.png differ diff --git a/app/src-tauri/icons/StoreLogo.png b/app/src-tauri/icons/StoreLogo.png index 2827df2..cdd113f 100644 Binary files a/app/src-tauri/icons/StoreLogo.png and b/app/src-tauri/icons/StoreLogo.png differ diff --git a/app/src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml b/app/src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml index 46433ea..2ffbf24 100644 --- a/app/src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml +++ b/app/src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml @@ -1,5 +1,5 @@ + - - - - + + + \ No newline at end of file diff --git a/app/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png b/app/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png index 62c4aec..4b08097 100644 Binary files a/app/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png and b/app/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png differ diff --git a/app/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png b/app/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png index c4b35f3..47ed981 100644 Binary files a/app/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png and b/app/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/app/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png b/app/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png index cbf1258..0e1805f 100644 Binary files a/app/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png and b/app/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png differ diff --git a/app/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png b/app/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png index 012186b..99dc4fa 100644 Binary files a/app/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png and b/app/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png differ diff --git a/app/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png b/app/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png index fb9d3aa..f662a0a 100644 Binary files a/app/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png and b/app/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/app/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png b/app/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png index 1b59af8..b7181a4 100644 Binary files a/app/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png and b/app/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png differ diff --git a/app/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png b/app/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png index 3962496..d091a6a 100644 Binary files a/app/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png and b/app/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png b/app/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png index 1a1cc89..3f9e0a5 100644 Binary files a/app/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png and b/app/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/app/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png b/app/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png index c45e015..a7aac80 100644 Binary files a/app/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png and b/app/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/app/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png b/app/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png index 3864314..b2dc00a 100644 Binary files a/app/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png and b/app/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png b/app/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png index 57d30b4..4d759ef 100644 Binary files a/app/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png and b/app/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/app/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png b/app/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png index 9338b9a..ec018c3 100644 Binary files a/app/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png and b/app/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/app/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png b/app/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png index ebae229..81e8838 100644 Binary files a/app/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png and b/app/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png b/app/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png index 4507d2f..6c1844e 100644 Binary files a/app/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png and b/app/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/app/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png b/app/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png index 34a33ed..959d508 100644 Binary files a/app/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png and b/app/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/app/src-tauri/icons/icon.icns b/app/src-tauri/icons/icon.icns index 6c2b009..db72dc1 100644 Binary files a/app/src-tauri/icons/icon.icns and b/app/src-tauri/icons/icon.icns differ diff --git a/app/src-tauri/icons/icon.ico b/app/src-tauri/icons/icon.ico index 29187bf..d321d22 100644 Binary files a/app/src-tauri/icons/icon.ico and b/app/src-tauri/icons/icon.ico differ diff --git a/app/src-tauri/icons/icon.png b/app/src-tauri/icons/icon.png index fa7240c..0723ce4 100644 Binary files a/app/src-tauri/icons/icon.png and b/app/src-tauri/icons/icon.png differ diff --git a/app/src-tauri/icons/ios/AppIcon-20x20@1x.png b/app/src-tauri/icons/ios/AppIcon-20x20@1x.png index 836b293..03e6a56 100644 Binary files a/app/src-tauri/icons/ios/AppIcon-20x20@1x.png and b/app/src-tauri/icons/ios/AppIcon-20x20@1x.png differ diff --git a/app/src-tauri/icons/ios/AppIcon-20x20@2x-1.png b/app/src-tauri/icons/ios/AppIcon-20x20@2x-1.png index 53c60da..c86a065 100644 Binary files a/app/src-tauri/icons/ios/AppIcon-20x20@2x-1.png and b/app/src-tauri/icons/ios/AppIcon-20x20@2x-1.png differ diff --git a/app/src-tauri/icons/ios/AppIcon-20x20@2x.png b/app/src-tauri/icons/ios/AppIcon-20x20@2x.png index 53c60da..c86a065 100644 Binary files a/app/src-tauri/icons/ios/AppIcon-20x20@2x.png and b/app/src-tauri/icons/ios/AppIcon-20x20@2x.png differ diff --git a/app/src-tauri/icons/ios/AppIcon-20x20@3x.png b/app/src-tauri/icons/ios/AppIcon-20x20@3x.png index 4ff8051..c9264f2 100644 Binary files a/app/src-tauri/icons/ios/AppIcon-20x20@3x.png and b/app/src-tauri/icons/ios/AppIcon-20x20@3x.png differ diff --git a/app/src-tauri/icons/ios/AppIcon-29x29@1x.png b/app/src-tauri/icons/ios/AppIcon-29x29@1x.png index db231aa..15f521a 100644 Binary files a/app/src-tauri/icons/ios/AppIcon-29x29@1x.png and b/app/src-tauri/icons/ios/AppIcon-29x29@1x.png differ diff --git a/app/src-tauri/icons/ios/AppIcon-29x29@2x-1.png b/app/src-tauri/icons/ios/AppIcon-29x29@2x-1.png index 6416e70..32fc6d9 100644 Binary files a/app/src-tauri/icons/ios/AppIcon-29x29@2x-1.png and b/app/src-tauri/icons/ios/AppIcon-29x29@2x-1.png differ diff --git a/app/src-tauri/icons/ios/AppIcon-29x29@2x.png b/app/src-tauri/icons/ios/AppIcon-29x29@2x.png index 6416e70..32fc6d9 100644 Binary files a/app/src-tauri/icons/ios/AppIcon-29x29@2x.png and b/app/src-tauri/icons/ios/AppIcon-29x29@2x.png differ diff --git a/app/src-tauri/icons/ios/AppIcon-29x29@3x.png b/app/src-tauri/icons/ios/AppIcon-29x29@3x.png index 50a4436..b9f1c83 100644 Binary files a/app/src-tauri/icons/ios/AppIcon-29x29@3x.png and b/app/src-tauri/icons/ios/AppIcon-29x29@3x.png differ diff --git a/app/src-tauri/icons/ios/AppIcon-40x40@1x.png b/app/src-tauri/icons/ios/AppIcon-40x40@1x.png index 53c60da..c86a065 100644 Binary files a/app/src-tauri/icons/ios/AppIcon-40x40@1x.png and b/app/src-tauri/icons/ios/AppIcon-40x40@1x.png differ diff --git a/app/src-tauri/icons/ios/AppIcon-40x40@2x-1.png b/app/src-tauri/icons/ios/AppIcon-40x40@2x-1.png index 2c026eb..b827bc6 100644 Binary files a/app/src-tauri/icons/ios/AppIcon-40x40@2x-1.png and b/app/src-tauri/icons/ios/AppIcon-40x40@2x-1.png differ diff --git a/app/src-tauri/icons/ios/AppIcon-40x40@2x.png b/app/src-tauri/icons/ios/AppIcon-40x40@2x.png index 2c026eb..b827bc6 100644 Binary files a/app/src-tauri/icons/ios/AppIcon-40x40@2x.png and b/app/src-tauri/icons/ios/AppIcon-40x40@2x.png differ diff --git a/app/src-tauri/icons/ios/AppIcon-40x40@3x.png b/app/src-tauri/icons/ios/AppIcon-40x40@3x.png index b2d6fb9..b6c614a 100644 Binary files a/app/src-tauri/icons/ios/AppIcon-40x40@3x.png and b/app/src-tauri/icons/ios/AppIcon-40x40@3x.png differ diff --git a/app/src-tauri/icons/ios/AppIcon-512@2x.png b/app/src-tauri/icons/ios/AppIcon-512@2x.png index d5da239..705e80e 100644 Binary files a/app/src-tauri/icons/ios/AppIcon-512@2x.png and b/app/src-tauri/icons/ios/AppIcon-512@2x.png differ diff --git a/app/src-tauri/icons/ios/AppIcon-60x60@2x.png b/app/src-tauri/icons/ios/AppIcon-60x60@2x.png index b2d6fb9..b6c614a 100644 Binary files a/app/src-tauri/icons/ios/AppIcon-60x60@2x.png and b/app/src-tauri/icons/ios/AppIcon-60x60@2x.png differ diff --git a/app/src-tauri/icons/ios/AppIcon-60x60@3x.png b/app/src-tauri/icons/ios/AppIcon-60x60@3x.png index 3d168f2..0a16342 100644 Binary files a/app/src-tauri/icons/ios/AppIcon-60x60@3x.png and b/app/src-tauri/icons/ios/AppIcon-60x60@3x.png differ diff --git a/app/src-tauri/icons/ios/AppIcon-76x76@1x.png b/app/src-tauri/icons/ios/AppIcon-76x76@1x.png index 45eabc8..ce6bcae 100644 Binary files a/app/src-tauri/icons/ios/AppIcon-76x76@1x.png and b/app/src-tauri/icons/ios/AppIcon-76x76@1x.png differ diff --git a/app/src-tauri/icons/ios/AppIcon-76x76@2x.png b/app/src-tauri/icons/ios/AppIcon-76x76@2x.png index c7c1db6..77ea4ba 100644 Binary files a/app/src-tauri/icons/ios/AppIcon-76x76@2x.png and b/app/src-tauri/icons/ios/AppIcon-76x76@2x.png differ diff --git a/app/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png b/app/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png index dd8e32c..e25fc71 100644 Binary files a/app/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png and b/app/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png differ diff --git a/app/src-tauri/src/lib.rs b/app/src-tauri/src/lib.rs index 3851efd..9749311 100644 --- a/app/src-tauri/src/lib.rs +++ b/app/src-tauri/src/lib.rs @@ -308,9 +308,12 @@ pub fn run() { .plugin(tauri_plugin_os::init()) .plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_sharekit::init()) - .plugin(tauri_plugin_device_info::init()) - .plugin(tauri_plugin_turso::init()) - .plugin(tauri_plugin_native_bridge::init()) + .plugin(tauri_plugin_device_info::init()); + + #[cfg(not(target_os = "android"))] + let builder = builder.plugin(tauri_plugin_turso::init()); + + let builder = builder.plugin(tauri_plugin_native_bridge::init()) .plugin(tauri_plugin_native_tts::init()) .plugin(tauri_plugin_webview_upgrade::init()); diff --git a/app/src-tauri/tauri.conf.json b/app/src-tauri/tauri.conf.json index 5ea3cc1..2b3ac77 100644 --- a/app/src-tauri/tauri.conf.json +++ b/app/src-tauri/tauri.conf.json @@ -71,7 +71,7 @@ "minSdkVersion": 26 }, "iOS": { - "developmentTeam": "J5W48D69VR", + "developmentTeam": "MHNRDP49V2", "infoPlist": "./Info-ios.plist", "minimumSystemVersion": "15.0" }, diff --git a/app/src/app/library/components/LibraryHeader.tsx b/app/src/app/library/components/LibraryHeader.tsx index 887aeb2..9f70197 100644 --- a/app/src/app/library/components/LibraryHeader.tsx +++ b/app/src/app/library/components/LibraryHeader.tsx @@ -87,9 +87,11 @@ const LibraryHeader: React.FC = ({ ); const [userInfo, setUserInfo] = useState(null); const [showUserSettings, setShowUserSettings] = useState(false); + const [showMobileSearch, setShowMobileSearch] = useState(false); const headerRef = useRef(null); - const { isTrafficLightVisible } = useTrafficLight(headerRef); + const topBarRef = useRef(null); + const { isTrafficLightVisible } = useTrafficLight(topBarRef); const iconSize18 = useResponsiveSize(18); const { safeAreaInsets: insets } = useThemeStore(); @@ -201,7 +203,7 @@ const LibraryHeader: React.FC = ({
= ({ : '0px', }} > -
+
-
- - {_(currentCategoryLabel)} - - - } - > - - - - - - - - - 1 - ? _('Search in {{count}} Book(s)...', { - count: currentBooksCount, - }) - : _('Search Books...') - } - onChange={handleSearchChange} - spellCheck='false' - className={clsx( - 'search-input input h-9 w-full rounded-full pr-[30%] ps-36 sm:h-7', - 'bg-base-300/45 border-0', - 'font-sans text-sm font-light', - 'placeholder:text-base-content/50 truncate', - 'focus:outline-none focus:ring-0', - )} - /> -
-
- {searchQuery && ( - - )} - - {!isCloudLibrary && ( - } - > - +
+ + {_(currentCategoryLabel)} + + + } + > + + + + + + + + + 1 + ? _('Search in {{count}} Book(s)...', { + count: currentBooksCount, + }) + : _('Search Books...') + } + onChange={handleSearchChange} + spellCheck='false' + className={clsx( + 'search-input input h-9 w-full rounded-full pr-[30%] ps-36 sm:h-7', + 'bg-base-300/45 border-0', + 'font-sans text-sm font-light', + 'placeholder:text-base-content/50 truncate', + 'focus:outline-none focus:ring-0', + )} /> - - )} - {isMobile || isCloudLibrary ? null : ( -
+
+ {searchQuery && ( + )} - - )} -
+ + {!isCloudLibrary && ( + } + > + + + )} + {isMobile || isCloudLibrary ? null : ( + + )} +
+ + )}
{isSelectMode ? (
= ({
) : (
+ {isMobile && ( + + )} {connectionStatus === 'unreachable' && (
)}
+ {isMobile && showMobileSearch && ( +
+
+ + {_(currentCategoryLabel)} + + + } + > + + + + + + 1 + ? _('Search in {{count}} Book(s)...', { + count: currentBooksCount, + }) + : _('Search Books...') + } + onChange={handleSearchChange} + spellCheck='false' + autoFocus + className={clsx( + 'search-input input h-9 w-full rounded-full pr-[30%] ps-28', + 'bg-base-300/45 border-0', + 'font-sans text-sm font-light', + 'placeholder:text-base-content/50 truncate', + 'focus:outline-none focus:ring-0', + )} + /> +
+
+ {searchQuery && ( + + )} + + {!isCloudLibrary && ( + } + > + + + )} +
+
+ )} setShowUserSettings(false)} />
); diff --git a/app/src/app/reader/hooks/useNativeSync.ts b/app/src/app/reader/hooks/useNativeSync.ts index 8813a9a..01da85f 100644 --- a/app/src/app/reader/hooks/useNativeSync.ts +++ b/app/src/app/reader/hooks/useNativeSync.ts @@ -87,6 +87,17 @@ export const useNativeSync = (bookKey: string) => { })), }); dirtyRef.current = false; + + const latest = getConfig(bookKey); + if (latest) { + const synced: BookConfig = { + ...latest, + lastSyncedAtConfig: now, + lastSyncedAtNotes: now, + }; + setConfig(bookKey, synced); + await saveConfig(envConfig, bookKey, synced, settings); + } } catch (e) { if (e instanceof SyncApiError) { eventDispatcher.dispatch('toast', { @@ -97,7 +108,7 @@ export const useNativeSync = (bookKey: string) => { console.warn('Native sync push failed', e); } } - }, [isReady, bookKey, getConfig, getBookData, _]); + }, [isReady, bookKey, getConfig, getBookData, setConfig, saveConfig, envConfig, settings, _]); const pullNow = useCallback(async (): Promise => { if (!isReady) return false; @@ -108,10 +119,10 @@ export const useNativeSync = (bookKey: string) => { try { const result = await pullSync(0, { book: book.hash }); lastPulledAtRef.current = Date.now(); + const now = Date.now(); const remoteConfig = result.configs?.[0]; const remoteNotes = result.notes ?? []; - if (!remoteConfig && remoteNotes.length === 0) return false; const localUpdatedAt = config.updatedAt ?? 0; const remoteUpdatedAt = remoteConfig?.updatedAt ?? remoteConfig?.updated_at ?? 0; @@ -124,7 +135,8 @@ export const useNativeSync = (bookKey: string) => { xpointer: remoteConfig.xpointer ?? config.xpointer, updatedAt: remoteUpdatedAt, } - : config; + : { ...config }; + mergedConfig.lastSyncedAtConfig = now; const byId = new Map(); for (const n of config.booknotes ?? []) byId.set(n.id, n); @@ -135,6 +147,7 @@ export const useNativeSync = (bookKey: string) => { if (remoteTs >= localTs) byId.set(remote.id, { ...local, ...remote } as BookNote); } mergedConfig.booknotes = Array.from(byId.values()); + mergedConfig.lastSyncedAtNotes = now; setConfig(bookKey, mergedConfig); const latest = getConfig(bookKey); diff --git a/app/src/components/user/LoginDialog.tsx b/app/src/components/user/LoginDialog.tsx index 7ce75af..cae9630 100644 --- a/app/src/components/user/LoginDialog.tsx +++ b/app/src/components/user/LoginDialog.tsx @@ -50,6 +50,7 @@ interface MyBooksUserInfoResponse { avatar?: string; is_admin?: boolean; is_login?: boolean; + is_guest?: boolean; }; sys?: { allow?: { diff --git a/app/src/services/mybooksService.ts b/app/src/services/mybooksService.ts index 482cf7a..9b9f899 100644 --- a/app/src/services/mybooksService.ts +++ b/app/src/services/mybooksService.ts @@ -62,6 +62,7 @@ export interface MyBooksUserInfo { avatar: string; is_admin: boolean; is_login: boolean; + is_guest: boolean; } export interface MyBooksUserDetailInfo extends MyBooksUserInfo { @@ -229,7 +230,7 @@ export async function checkMyBooksConnectivity(): Promise<{ }> { try { const response = await fetchMyBooks('/user/info'); - return { online: true, needsLogin: !response.user?.is_login }; + return { online: true, needsLogin: !response.user?.is_login && !response.user?.is_guest }; } catch (error) { // The server responded but reported a logical error (e.g. session // expired) — we did reach it, so this isn't "offline". @@ -452,13 +453,13 @@ export async function getUserInfo(): Promise { updateSysInfo(response.sys); const user = response.user; if (typeof window !== 'undefined') { - if (user?.is_login) { + if (user?.is_login || user?.is_guest) { localStorage.setItem(MYBOOKS_USER_INFO_CACHE_KEY, JSON.stringify(user)); } else { localStorage.removeItem(MYBOOKS_USER_INFO_CACHE_KEY); } } - if (!user?.is_login) return null; + if (!user?.is_login && !user?.is_guest) return null; return user; } catch (error) { // The server responded and told us the real current state (e.g. an @@ -566,7 +567,7 @@ export interface MyBooksUserDetailResult { export async function getUserDetailInfo(): Promise { const response = await fetchMyBooks('/user/info', { detail: 1 }); updateSysInfo(response.sys); - if (!response.user?.is_login) return null; + if (!response.user?.is_login && !response.user?.is_guest) return null; return { user: response.user as MyBooksUserDetailInfo, sys: response.sys ?? null }; } diff --git a/data/icons/myreader-book-480x480.png b/data/icons/myreader-book-480x480.png index e69a6a8..5bb2228 100644 Binary files a/data/icons/myreader-book-480x480.png and b/data/icons/myreader-book-480x480.png differ diff --git a/data/icons/myreader-book-640x640.png b/data/icons/myreader-book-640x640.png index f22a2f1..4c7d83f 100644 Binary files a/data/icons/myreader-book-640x640.png and b/data/icons/myreader-book-640x640.png differ diff --git a/data/icons/myreader-book.png b/data/icons/myreader-book.png index fa7240c..801d28c 100644 Binary files a/data/icons/myreader-book.png and b/data/icons/myreader-book.png differ