diff --git a/README-translation.md b/README-translation.md new file mode 100644 index 00000000..4745aafb --- /dev/null +++ b/README-translation.md @@ -0,0 +1,141 @@ +# SMS translation fork of Fossify Messages + +A small fork of [Fossify Messages](https://github.com/FossifyOrg/Messages) that +auto-translates received SMS / MMS on-the-fly, on-device, with no cloud and +no API keys. + +## Why this might be interesting + +If you live somewhere where you get important SMS in a language you don't +read fluently (bank alerts, delivery notifications, OTPs, government +messages…), this lets you keep using a clean FOSS messaging app and still +understand them. + +The translation itself is sub-second per message, runs entirely on-device +(Mozilla Bergamot / Marian NMT models), and preserves numbers and URLs +verbatim — so OTP codes, account numbers, tracking links, etc. don't get +mangled. + +- **Auto-translate**: each received bubble swaps to its translation as it + scrolls into view; conversation-list snippets do the same. +- **Per-language opt-in**: you choose which source languages get auto- + translated (e.g. Korean → English) and which are left alone (e.g. + Swedish, German, anything else you already read). +- **Tap to flip**: a small icon next to each translated bubble toggles it + back to the original. +- **Manual translate**: long-press a bubble → ⋮ → **Translate** to force a + one-off translation even for languages not on your auto-translate list. +- **Copy / Share / Select** capture what you see on screen — if the bubble + is showing English, your clipboard gets English. + +## Screenshots + +| Conversation list | Thread (translated) | Thread (original toggled back) | +|---|---|---| +| ![Conversation list with translated snippets](docs/conversation-list.jpg) | ![Korean SMS auto-translated to English, numbers and URLs preserved](docs/thread-translated.jpg) | ![Same thread flipped back to the Korean originals](docs/thread-original.jpg) | +| Snippets are translated as you scroll, opted-in source languages only. | Auto-translate fires on view; the small icon below each bubble is the toggle. Numbers (145cm, 40kg, 112) and URLs (vo.la/1Pa9m) survive verbatim. | Tap the icon to flip a bubble back to its original. Tap again to flip back. | + +| Translation settings | Manual translate (CAB ⋮) | +|---|---| +| ![Translation settings screen — master toggle, target language, source allowlist](docs/settings.jpg) | ![Long-press menu on a bubble showing the Translate item](docs/cab-translate.jpg) | +| Pick which source languages auto-translate and your target. Off by default. | Long-press → ⋮ → Translate to force a one-off translation for non-allowlisted languages. | + +## Status — please read + +This is an **experiment**, not a maintained project. + +- No commitment to keep it up to date with upstream Fossify or with Android. +- No commitment to fix bugs or ship security updates. +- No releases on F-Droid or Play. Built and signed locally by the author. +- I'd like to propose the core feature upstream to Fossify Messages + eventually; if they accept it, this fork's reason to exist mostly goes + away. If they don't, I'll probably keep using my own build, but you + should not depend on it. + +If you want a clean, maintained build of Fossify Messages, install the +official one from F-Droid. This fork is for tinkerers and for people who +specifically want the translation behavior described above. + +## Dependencies + +1. **`dev.davidv.translator`** — the [offline-translator](https://github.com/DavidVentura/offline-translator) + app on F-Droid. This is the engine. Install it, open it, download the + language pack(s) for the languages you want to translate (e.g. Korean, + the source side, plus the target language pack if it asks). It runs + Mozilla's Bergamot translation models on-device. + + Without this app installed, the translation feature silently does + nothing — the messaging app still works as a plain SMS client. + +2. **ML Kit Language Identification** — bundled inside this APK + (`com.google.mlkit:language-id`, Apache-2.0). Used only for detecting + what language an incoming SMS is in, so we can decide whether to + translate it. About 4 MB of model data baked in. This is transitional: + if davidv accepts a small AIDL addition upstream + ([offline-translator issue](https://github.com/DavidVentura/offline-translator)) + we'll drop ML Kit and use his detection directly. + +3. **Android 8.0+** (same as upstream Fossify). + +## How to use + +1. Install **offline-translator** from F-Droid. Open it and download the + language packs for the source language(s) you want translated (e.g. + Korean) and confirm your target language pack is installed (usually + English). +2. Install this fork's APK (build it yourself — see below). +3. Open this app → top-right ⋮ → **Settings** → **Translation**: + - Turn on **Translate received messages**. + - Pick your **Translate into** target (defaults to your device language). + - Check the **Auto-translate from** languages you want auto-translated. +4. Open any conversation. Bubbles in opted-in languages translate as you + scroll. Tap the small translate icon below a bubble to flip between + original and translation. + +## How it differs from upstream Fossify Messages + +The fork-only changes (not for upstream): + +- **Different package ID** (`net.jeena.smstranslate`) so it installs + alongside any official Fossify Messages. +- **No "make me default SMS app" prompt** on first launch. You can still + make it the default via Android Settings → Default apps → SMS app if you + want — this just doesn't pester you about it. +- **Sideload warning suppressed**. Fossify's built-in + "this APK looks corrupted, go get the official one" dialog is silenced + because of course this APK isn't the official one — it's a fork. + +The translation feature itself lives in a separate `:translate` Gradle +module and is structured so it can be cherry-picked onto upstream cleanly +as a possible PR. + +## Building from source + +You need JDK 17 and the Android SDK. + +```bash +export JAVA_HOME=/path/to/jdk17 +export ANDROID_HOME=/path/to/android-sdk +git clone +cd sms-translate +./gradlew :app:assembleFossDebug +# APK at app/build/outputs/apk/foss/debug/messages-*-foss-debug.apk +adb install -r app/build/outputs/apk/foss/debug/messages-*-foss-debug.apk +``` + +If you want a release build, set up a `keystore.properties` per upstream +Fossify's instructions and `./gradlew :app:assembleFossRelease`. + +## License + +Same as upstream Fossify Messages: **GPL-3.0**. The AIDL stubs from +offline-translator are also GPL-3.0. ML Kit is Apache-2.0. + +## Credits + +- [Fossify Messages](https://github.com/FossifyOrg/Messages) — the + excellent FOSS messaging app this is a fork of. +- [David Ventura](https://github.com/DavidVentura) — author of + [offline-translator](https://github.com/DavidVentura/offline-translator), + which does all the actual translation. +- [Mozilla Bergamot](https://browser.mt/) — the underlying NMT models. diff --git a/docs/cab-translate.jpg b/docs/cab-translate.jpg new file mode 100644 index 00000000..3ebbb07d Binary files /dev/null and b/docs/cab-translate.jpg differ diff --git a/docs/conversation-list.jpg b/docs/conversation-list.jpg new file mode 100644 index 00000000..5dc73339 Binary files /dev/null and b/docs/conversation-list.jpg differ diff --git a/docs/settings.jpg b/docs/settings.jpg new file mode 100644 index 00000000..3235574d Binary files /dev/null and b/docs/settings.jpg differ diff --git a/docs/thread-original.jpg b/docs/thread-original.jpg new file mode 100644 index 00000000..9f5c83c7 Binary files /dev/null and b/docs/thread-original.jpg differ diff --git a/docs/thread-translated.jpg b/docs/thread-translated.jpg new file mode 100644 index 00000000..0e1c1689 Binary files /dev/null and b/docs/thread-translated.jpg differ