Recently Written · git

scan-subread

PDF reader that follows an audiobook with the SubRead suite

git clone https://github.com/equwal/scan-subread

Log | Files | Refs


commit 7a308b9de1fa1d652096a3e48310d345eca76c88
equwal <13551856+equwal@users.noreply.github.com>
2026-09-27 00:23:35 -0700

Prepare release 0.1.1 for F-Droid and Google Play

Remove the google-services plugin of the Capacitor template. The app does not use it, and the F-Droid scanner flags it.

Do not put the dependency info block in the APK. F-Droid rejects an APK that has it.

Add the store texts, the store icon, the feature graphic, the privacy policy and the F-Droid recipe. The recipe builds the web app with Node 22 and compares the result with the signed release APK.

 .prettierignore                                    |   2 +
 PRIVACY.md                                         |  39 +++++++++++++++++++
 android/app/build.gradle                           |  18 ++++-----
 android/build.gradle                               |   1 -
 fastlane/metadata/android/en-US/changelogs/2.txt   |   7 ++++
 .../metadata/android/en-US/full_description.txt    |  25 ++++++++++++
 .../android/en-US/images/featureGraphic.png        | Bin 0 -> 27148 bytes
 fastlane/metadata/android/en-US/images/icon.png    | Bin 0 -> 5459 bytes
 .../metadata/android/en-US/short_description.txt   |   1 +
 fastlane/metadata/android/en-US/title.txt          |   1 +
 fdroid/com.equwal.scansubread.yml                  |  42 +++++++++++++++++++++
 package-lock.json                                  |   4 +-
 package.json                                       |   2 +-
 13 files changed, 127 insertions(+), 15 deletions(-)
diff --git a/.prettierignore b/.prettierignore
index 4818b89..a2a21bd 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -2,3 +2,5 @@ dist/
 package-lock.json
 fixtures/*.srt
 android/
+# F-Droid tools format this recipe (fdroid rewritemeta).
+fdroid/
diff --git a/PRIVACY.md b/PRIVACY.md
new file mode 100644
index 0000000..85b1279
--- /dev/null
+++ b/PRIVACY.md
@@ -0,0 +1,39 @@
+# Privacy policy of Scan SubRead
+
+Scan SubRead has no account, no ads, no analytics and no tracking. The
+developer gets no data from the app.
+
+## Data on the device
+
+The app keeps these items in its own storage on the device:
+
+- a copy of the last book that you opened,
+- the text of the pages that it read,
+- the page, the subtitles and the settings of each book.
+
+Uninstalling the app deletes them. "Clear all pages" in the menu deletes
+the pages.
+
+## Data that goes to other apps on the device
+
+- The text that you tap goes to the dictionary app that you choose.
+- A word and its sentence go to SubRead Anki when you make a card.
+- The text of the book goes to SubRead when you make subtitles.
+- The app asks SubRead Overlay for the position of the audiobook player.
+
+These apps are on your device. Scan SubRead sends nothing to a server
+for them.
+
+## Network
+
+The first OCR run of a language downloads the language data of Tesseract
+from `cdn.jsdelivr.net`. The request sends no data about you or your
+books. The CDN sees the IP address of the device, as each web server
+does. The privacy policy of jsDelivr applies to it:
+https://www.jsdelivr.com/terms/privacy-policy-jsdelivr-net
+
+The app makes no other network request.
+
+## Contact
+
+Open an issue at https://github.com/equwal/scan-subread/issues.
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 781694c..6bb1ad6 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -13,8 +13,8 @@ android {
         minSdkVersion rootProject.ext.minSdkVersion
         targetSdkVersion rootProject.ext.targetSdkVersion
         // versionCode must increase with each release.
-        versionCode 1
-        versionName "0.1.0"
+        versionCode 2
+        versionName "0.1.1"
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
         aaptOptions {
              // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
@@ -32,6 +32,11 @@ android {
             }
         }
     }
+    // The dependency info block is encrypted for Google only. F-Droid rejects
+    // an APK that has it.
+    dependenciesInfo {
+        includeInApk = false
+    }
     buildTypes {
         release {
             minifyEnabled false
@@ -60,12 +65,3 @@ dependencies {
 }
 
 apply from: 'capacitor.build.gradle'
-
-try {
-    def servicesJSON = file('google-services.json')
-    if (servicesJSON.text) {
-        apply plugin: 'com.google.gms.google-services'
-    }
-} catch(Exception e) {
-    logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work")
-}
diff --git a/android/build.gradle b/android/build.gradle
index f8f0e43..4f622dc 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -8,7 +8,6 @@ buildscript {
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:8.13.0'
-        classpath 'com.google.gms:google-services:4.4.4'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
diff --git a/fastlane/metadata/android/en-US/changelogs/2.txt b/fastlane/metadata/android/en-US/changelogs/2.txt
new file mode 100644
index 0000000..89b868b
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/2.txt
@@ -0,0 +1,7 @@
+* A new icon.
+* A book that you open wins over the restore of the last book.
+* Subtitles stay with the book that loads.
+* A SubRead result for a closed book is offered when that book opens.
+* The menu tells when SubRead waits for pages that could not be read, with Retry.
+* OCR start has a time limit and its own error message.
+* Each status message is readable on a phone.
diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt
new file mode 100644
index 0000000..e7237eb
--- /dev/null
+++ b/fastlane/metadata/android/en-US/full_description.txt
@@ -0,0 +1,25 @@
+Scan SubRead is a PDF reader that follows the audiobook. It works with scans and with text PDFs. It is made for people who read and listen in a language that they learn.
+
+Load a PDF and the subtitle file (.srt) of its audiobook. The app reads the text of each page, aligns each subtitle line to it, and follows the player: it marks the line that the narrator reads and turns the page.
+
+<b>What it does</b>
+<ul>
+<li>Scans: OCR reads each page in the app, also Japanese, horizontal and vertical. Text PDFs: the app reads the text layer.</li>
+<li>Tap a word: the text from that word to the end of the line goes to the dictionary of your choice. The player pauses while the dictionary is open.</li>
+<li>Press a word for half a second: SubRead Anki makes a card with its sentence.</li>
+<li>"Make subtitles with SubRead": pick the audiobook, and SubRead makes the .srt from the audio and the text of the book.</li>
+<li>The app keeps the last book, its page and its subtitles, and opens them at the next start.</li>
+<li>After a page turn by hand, the page stops following. The Follow button brings it back.</li>
+</ul>
+
+<b>The SubRead suite</b>
+<ul>
+<li>SubRead Overlay reads the position of the audiobook player and gives it to this app.</li>
+<li>SubRead Dictionary, or another app in the text selection menu, looks up the words.</li>
+<li>SubRead makes the subtitle file.</li>
+<li>SubRead Anki makes the cards.</li>
+</ul>
+The start card shows which of these apps are installed.
+
+<b>Network</b>
+The first OCR run of a language downloads the language data of Tesseract from cdn.jsdelivr.net. The app keeps it after that. Nothing else leaves the device.
diff --git a/fastlane/metadata/android/en-US/images/featureGraphic.png b/fastlane/metadata/android/en-US/images/featureGraphic.png
new file mode 100644
index 0000000..dd3a6b3
Binary files /dev/null and b/fastlane/metadata/android/en-US/images/featureGraphic.png differ
diff --git a/fastlane/metadata/android/en-US/images/icon.png b/fastlane/metadata/android/en-US/images/icon.png
new file mode 100644
index 0000000..9330619
Binary files /dev/null and b/fastlane/metadata/android/en-US/images/icon.png differ
diff --git a/fastlane/metadata/android/en-US/short_description.txt b/fastlane/metadata/android/en-US/short_description.txt
new file mode 100644
index 0000000..fad9b2e
--- /dev/null
+++ b/fastlane/metadata/android/en-US/short_description.txt
@@ -0,0 +1 @@
+PDF reader that follows the audiobook: marks the line and turns the page
diff --git a/fastlane/metadata/android/en-US/title.txt b/fastlane/metadata/android/en-US/title.txt
new file mode 100644
index 0000000..afd29b5
--- /dev/null
+++ b/fastlane/metadata/android/en-US/title.txt
@@ -0,0 +1 @@
+Scan SubRead
diff --git a/fdroid/com.equwal.scansubread.yml b/fdroid/com.equwal.scansubread.yml
new file mode 100644
index 0000000..a501a0d
--- /dev/null
+++ b/fdroid/com.equwal.scansubread.yml
@@ -0,0 +1,42 @@
+Categories:
+  - Audiobook
+  - Reading
+  - Science & Education
+License: AGPL-3.0-only
+AuthorName: equwal
+SourceCode: https://github.com/equwal/scan-subread
+IssueTracker: https://github.com/equwal/scan-subread/issues
+Changelog: https://github.com/equwal/scan-subread/releases
+Donate: https://ko-fi.com/truex
+
+AutoName: Scan SubRead
+
+RepoType: git
+Repo: https://github.com/equwal/scan-subread.git
+Binaries:
+  https://github.com/equwal/scan-subread/releases/download/v%v/Scan-SubRead-%v.apk
+
+Builds:
+  - versionName: 0.1.1
+    versionCode: 2
+    commit: v0.1.1
+    subdir: android/app
+    sudo:
+      - curl -Lo node.tar.xz https://nodejs.org/dist/v22.23.3/node-v22.23.3-linux-x64.tar.xz
+      - echo "df450af89261115ef9f9e3830c3eeb2cc9213b63c720b1af623cb5dcbe2e02de  node.tar.xz"
+        | sha256sum -c -
+      - tar xJf node.tar.xz --strip-components=1 -C /usr/local
+      - rm node.tar.xz
+    init: cd ../.. && npm ci --no-audit --no-fund
+    gradle:
+      - yes
+    prebuild: cd ../.. && npm run build && npx cap sync android
+    scandelete:
+      - node_modules
+
+AllowedAPKSigningKeys: e46f72ef28c79489cad0f1eee60cbf7fd3f29b5bff1bb1d82bab1e30427ff44f
+
+AutoUpdateMode: Version
+UpdateCheckMode: Tags
+CurrentVersion: 0.1.1
+CurrentVersionCode: 2
diff --git a/package-lock.json b/package-lock.json
index d5c53cf..225bb7e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "scan-subread",
-  "version": "0.1.0",
+  "version": "0.1.1",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "scan-subread",
-      "version": "0.1.0",
+      "version": "0.1.1",
       "dependencies": {
         "@capacitor/android": "^8.5.2",
         "@capacitor/app": "^8.1.1",
diff --git a/package.json b/package.json
index c14651a..4a9f2db 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
 {
   "name": "scan-subread",
   "private": true,
-  "version": "0.1.0",
+  "version": "0.1.1",
   "type": "module",
   "scripts": {
     "dev": "vite",