Skip to content

Repository files navigation

かな Kana Pairs

Anki and Duolingo had a baby: a spaced-repetition app for learning hiragana and katakana in pairs, plus essential & tech Japanese vocabulary — with Anki's exact SM-2 scheduling under the hood and a playful, dark-mode-first UI on top. No decks, no accounts.

Platforms

Target Where How
Phone / tablet / Google TV app/ one APK; TV gets a leanback launcher entry + D-pad focus
Wear OS watch wear/ standalone watch app (Wear 3+), shares the same engine
Linux desktop (any distro, incl. Hyprland) desktop/ Compose Desktop app image with bundled JRE

Features

  • Anki-faithful SM-2 scheduler — learning steps (1m/10m), Again/Hard/Good/Easy with live interval previews, ease factor, lapses, leech suspension, 4 AM day cutover.
  • Duolingo feel — streak flame, daily XP goal, chunky 3D buttons, session celebrations.
  • GitHub-style activity heatmap and daily reminder notifications.
  • Add your own words — type romaji or kana; an offline IME-style transliterator (っ/ん/long-vowel aware) fills in the other side.
  • Account-free Wi-Fi sync across all devices: cards, your words, scheduling progress, deletions, review history — and therefore streak & XP — converge peer-to-peer (mDNS discovery + manual address entry). Last change wins per card; deletions carry tombstones; logs are unioned.
  • Missing built-in cards are detected and restorable in one tap.

Building

# phone + Google TV APK
./gradlew :app:assembleDebug

# Wear OS APK
./gradlew :wear:assembleDebug

# Linux desktop (self-contained app image)
cd desktop && ../gradlew createDistributable
# → desktop/build/compose/binaries/main/app/kana-pairs/
# install with desktop/install.sh, see desktop/README.md

# tests (scheduler, romaji converter, sync merge)
./gradlew :app:testDebugUnitTest

Toolchain: AGP 9 (built-in Kotlin 2.2), compileSdk 37, Room + KSP, Compose everywhere. gradle.properties sets android.disallowKotlinSourceSets=false for KSP compatibility.

Architecture notes

  • app/src/main/java/.../domain/ is pure Kotlin (scheduler, dates, romaji, seed data, sync engine + TCP protocol) — shared as source by all three targets.
  • The Wear module reuses the phone app's domain/data/sync packages via sourceSets (see wear/build.gradle.kts); the desktop build shares domain/ only and keeps its own SQLite store.
  • Sync is a single TCP round trip of full JSON snapshots, merged deterministically on both sides (domain/SyncModel.kt, unit-tested).

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages