Commit Graph

9 Commits

Author SHA1 Message Date
e0537e3455 Keep the README's download in step with the build, and prove it
A README that advertises last version is worse than one that says nothing:
someone follows the link, installs an old build, and has no way to know.

tools/update_release_docs.py rewrites the download heading, the size and the
checksum in README.md and the checksum list in releases/README.md from whatever
app/build.gradle.kts declares and whatever is actually archived. It takes no
arguments on purpose — the documentation can only describe the release the build
produced.

ReleaseDocsTest is what makes forgetting to run it a failed build rather than a
quiet wrong answer: the offered version must match versionName, the APK must be
archived, and every checksum in releases/README.md must match the file beside it.

The declared test inputs are not decoration. Without them Gradle sees only Kotlin
sources, calls the task up to date and never re-runs it — I checked, and a README
rolled back to 0.3.0 passed green. With README.md and releases/README.md declared,
the same edit fails on the right assertion and passes again when restored.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-07 23:32:10 +02:00
3407f010c9 Release 0.4.0
Twenty commits since v0.3.0, and the tag still pointed at the old one: nothing
could be published while main declared a version that was already taken.

0.4.0 rather than 0.3.1 — this is not a patch. Tablets and unfolded foldables
read in columns now, the dictionary and the reading settings moved beside the
poem instead of over it, couplets sit in cards and share a line where there is
room, pages fill in where they load, and the design system that describes all of
it lives in design/.

Changelog 6 in all three languages, as F-Droid reads them from fastlane/.

The release APK is not archived in releases/ yet: the signing key is not on this
machine, and every release so far shares one key so that each upgrades the last
in place. Signing and archiving wait for it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-07 18:47:06 +02:00
Anas Rashid
c9269713d1 Pin poets to the home screen
Three views, chosen by the chips: the poets you pinned, Ganjoor's own order,
and alphabetical. Press and hold a poet anywhere to pin or unpin — tapping
still opens them, and a pin marker sits beside the name.

Pinned is the default. With nothing pinned it is Ganjoor's order untouched, so
a fresh install never opens to an empty screen; the hint about holding a poet
shows only while the shelf is empty, because once there is something on it the
shelf explains itself.

Pins keep the order they were made in rather than being sorted. A shelf someone
arranges themselves should stay where they put it, and a new pin appearing in
the middle of the row is disorienting.

Cards or a list, switched from the app bar and remembered. The same storage as
bookmarks: a list of a few urls needs no schema.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-04 20:26:26 +02:00
Anas Rashid
d7568d1f49 Credit Material Symbols, and state the assistant's terms
Two gaps in the licence file, both from work done after it was written.

The share, lookup and assistant glyphs are Material Symbols path data copied
into our own vector files. The Libraries table credits the Material icons
library, which is not the same thing as copying its paths, so the drawables now
have their own entry and appear in the app's About page.

The assistant was not mentioned at all. It ships no vendor SDK, no key and no
default endpoint, so nothing non-free is distributed — but a reader may point
it at a service whose terms are their own, and what a model writes back belongs
to neither Ganjoor nor this app. Written down for F-Droid's sake as much as the
reader's.

No new dependencies came with any of it: the assistant reuses the HTTP client
and JSON parser already here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-04 20:19:00 +02:00
Anas Rashid
ec05989f7d Release 0.2.1
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-04 19:51:20 +02:00
Anas Rashid
d92445f21e Release 0.2.0
Pre-1.0 while the app is still being shaped: 0.1.0 was the build after the
dictionary work, this is the one with share and the optional assistant.

The APK is named for its version, because a file called app-release.apk tells
whoever receives it nothing. Changelogs in all three languages, one per
versionCode, which is the layout F-Droid reads.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-04 19:21:53 +02:00
Anas Rashid
abcffbc43b Add offline reading, bookmarks, three UI languages and downloads
Reading
- Naskh is now the default face, and both Arabic-script fonts are registered
  at four weights so the text can be thickened for a lit screen.
- Category listings show each poem's opening line, fetched best-effort from
  api.ganjoor.net since the data set doesn't carry excerpts.
- Tap a couplet to save that passage or copy it; a saved passage keeps a
  tappable link back to its poem. Poem text is selectable for plain copying.

Languages
- Persian, Urdu and English, Persian by default whatever the phone's locale,
  applied in attachBaseContext and switchable from the top bar or the sheet.
- English chrome uses Libron (OFL); poems stay naskh or nastaliq throughout.
- Each language gets its own values-* folder: with Farsi only in values/,
  Android was resolving it to the Urdu strings, since a same-script locale
  outranks the default.

Offline
- Downloaded poets mirror the data set's layout under filesDir, so offline
  mode is one lookup rather than a parallel path. Downloads run one poet at
  a time, skip what's on disk, and resume by restarting.
- Downloads screen lists every poet with their portrait and tick boxes for
  picking several, plus storage used, delete, and download-everything behind
  a size warning.
- Offline mode refuses the network and says what's missing rather than
  blaming the connection.

Also: poet sort (Ganjoor's order or alphabetical, via a Persian collator),
RTL nav transitions, an original shamsa launcher icon with a monochrome layer
for themed icons, and preferences written with commit so they survive the
process being killed.

F-Droid: dependenciesInfo off, optional signing so the build works with no
keystore, fastlane metadata in three languages, cleartext traffic disabled.

Verified on an API 36 emulator: downloaded a poet, pulled the emulator's
network, read them offline, and confirmed an undownloaded poet reports being
missing rather than erroring.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-03 23:20:42 +02:00
Anas Rashid
d9915eac6c Build the Ganjoor reader on the static ganjoor-data set
Poets grid, category browsing and a poem reader backed by
github.com/anas-rashid/ganjoor-data over jsDelivr — no backend, addressed by
Ganjoor URLs rather than numeric ids, with a 64 MB OkHttp disk cache so
anything already read stays readable offline.

Reading: couplets stack with the first hemistich at the start of the line and
the second at the end; prose sections fill the column. Bundled Noto Naskh
Arabic and Noto Nastaliq Urdu, switchable while reading, with the extra
leading nastaliq needs. Five themes (system, light, dark, sepia, sepia night)
and a text size slider, all persisted. Whole app lays out right-to-left.

Verified on an API 36 emulator through poets -> category -> poem in both
sepia schemes and both fonts.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-03 22:46:09 +02:00
Anas Rashid
46ba109207 Initial Android Studio Compose scaffold 2026-10-03 22:16:22 +02:00