Compare commits

..
Author SHA1 Message Date
anasandClaude Opus 5 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
7 changed files with 57 additions and 61 deletions

No files matched your search

+3 -3
View File
@@ -16,7 +16,7 @@ val keystoreProperties = Properties().apply {
// A delivered file should say what it is without being opened.
base {
archivesName = "ganjoor-0.3.0"
archivesName = "ganjoor-0.4.0"
}
android {
@@ -32,8 +32,8 @@ android {
// Pre-1.0 while the app is still being shaped. versionCode only ever climbs: F-Droid
// refuses an update that does not, and one changelog file per code lives in
// fastlane/metadata/android/*/changelogs/.
versionCode = 5
versionName = "0.3.0"
versionCode = 6
versionName = "0.4.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
@@ -111,7 +111,7 @@ fun PoemScreen(
// foldable held open in portrait the page is already down to ~450dp, and a panel beside it
// left the verse a couple of characters a line. Where it does not fit, the sheet is the
// better answer: it covers the foot of the poem but leaves the lines whole.
val roomForPanel = dictionaryFitsBeside(maxWidth, wide)
val roomForPanel = wide && maxWidth - DictionaryPanelWidth >= MinPageMeasure
Load(
key = fullUrl,
@@ -39,7 +39,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.ganjoor.android.R
import com.ganjoor.android.data.Definition
@@ -65,21 +64,6 @@ val DictionaryPanelWidth = 216.dp
*/
val MinPageMeasure = 400.dp
/**
* Whether the dictionary earns a column of its own beside a page [pageWidth] wide.
*
* Not a question about the window but about the page: by the time a poem is open the columns have
* already taken their room, and on a book-style foldable held open in portrait what is left is
* about 450dp. A panel beside that leaves the verse a couple of characters a line, so below
* [MinPageMeasure] the bottom sheet is used instead — it covers the foot of the poem but leaves
* every line whole.
*
* A pure function so the rule can be tested: the gesture that reaches it cannot be driven
* reliably, but the arithmetic behind it can.
*/
internal fun dictionaryFitsBeside(pageWidth: Dp, wide: Boolean): Boolean =
wide && pageWidth - DictionaryPanelWidth >= MinPageMeasure
/** English prose inside an otherwise right-to-left sheet. */
@Composable
private fun LeftToRight(content: @Composable () -> Unit) {
@@ -1,41 +0,0 @@
package com.ganjoor.android
import androidx.compose.ui.unit.dp
import com.ganjoor.android.ui.dictionaryFitsBeside
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
/**
* The rule that decides whether the dictionary opens beside the poem or as a sheet over it.
*
* Driving the gesture that reaches it — a tap landing on the glyphs of one Persian word — is not
* something adb does reliably, so the arithmetic is tested directly instead.
*/
class DictionaryPanelFitTest {
@Test
fun `a tablet has room beside the poem`() {
// 1280dp window, less the poets rail and two list columns, leaves the page about 900dp.
assertTrue(dictionaryFitsBeside(900.dp, wide = true))
}
@Test
fun `a foldable open in portrait does not`() {
// 700dp window, less the rail and the newest column, leaves about 450dp — and 450 less
// the 216dp panel is 234dp, which is a cramped phone column, not a measure for a verse.
assertFalse(dictionaryFitsBeside(450.dp, wide = true))
}
@Test
fun `a phone never gets the panel, however the page is measured`() {
assertFalse(dictionaryFitsBeside(420.dp, wide = false))
assertFalse(dictionaryFitsBeside(2000.dp, wide = false))
}
@Test
fun `the boundary is the panel plus the minimum measure`() {
assertTrue(dictionaryFitsBeside(616.dp, wide = true)) // 400 + 216, exactly
assertFalse(dictionaryFitsBeside(615.dp, wide = true))
}
}
@@ -0,0 +1,19 @@
Tablets and unfolded foldables now read in columns: the poets on the right, then
a column for each level of the open book, and the poem in whatever room is left.
Each column scrolls on its own and narrows as you read, so the poem keeps the
middle. A button in the top bar folds them away.
Where there is room, a couplet's two hemistichs sit on one line, as Ganjoor sets
them on a desktop. Each couplet now sits in a soft card.
The dictionary and the reading settings open beside the poem rather than over
it, so nothing you are reading is covered.
Pages fill in where they load instead of blanking the screen, and Home and the
reading settings stay reachable while they do.
Tapping a word no longer carries the comma or question mark after it into the
lookup.
A reading keeps playing when you scroll down the poem, and a seek bar moves it
back and forth.
@@ -0,0 +1,17 @@
تبلت‌ها و گوشی‌های تاشوی باز حالا ستونی خوانده می‌شوند: شاعران در سمت راست، سپس
یک ستون برای هر لایهٔ کتاب باز، و شعر در هر فضایی که می‌ماند. هر ستون جداگانه
پیمایش می‌شود و با خواندن باریک‌تر می‌شود تا شعر میانه را نگه دارد. دکمه‌ای در
نوار بالا آن‌ها را جمع می‌کند.
هر جا جا باشد، دو مصرع یک بیت در یک سطر می‌نشینند، همان‌گونه که گنجور روی رایانه
می‌چیند. هر بیت اکنون در کارتی ملایم می‌نشیند.
لغت‌نامه و تنظیمات خواندن کنار شعر باز می‌شوند، نه رویش، تا چیزی از آنچه
می‌خوانید پوشیده نشود.
صفحه‌ها همان‌جا که بار می‌شوند پر می‌شوند و صفحه سفید نمی‌ماند؛ خانه و تنظیمات
خواندن در همان حال هم در دسترس‌اند.
ضربه بر یک واژه دیگر ویرگول یا علامت پرسش پس از آن را به جست‌وجو نمی‌برد.
خوانش با پیمایش شعر قطع نمی‌شود، و نواری تازه آن را پس و پیش می‌برد.
@@ -0,0 +1,17 @@
ٹیبلٹ اور کھلے فولڈ ایبل اب ستونوں میں پڑھے جاتے ہیں: شعرا دائیں طرف، پھر کھلی
کتاب کی ہر سطح کے لیے ایک ستون، اور باقی جگہ میں کلام۔ ہر ستون الگ سکرول ہوتا ہے
اور پڑھتے وقت تنگ ہو جاتا ہے تاکہ کلام درمیان میں رہے۔ اوپر کی پٹی کا ایک بٹن
انہیں سمیٹ دیتا ہے۔
جہاں گنجائش ہو، شعر کے دونوں مصرعے ایک ہی سطر میں آتے ہیں، جیسے گنجور کمپیوٹر پر
دکھاتا ہے۔ ہر شعر اب ایک ہلکے کارڈ میں بیٹھتا ہے۔
لغت نامہ اور مطالعے کی ترتیبات کلام کے ساتھ کھلتی ہیں، اُس پر نہیں، تاکہ جو آپ
پڑھ رہے ہیں وہ ڈھکا نہ جائے۔
صفحات وہیں بھرتے ہیں جہاں لوڈ ہوتے ہیں، خالی اسکرین نہیں آتی؛ ہوم اور مطالعے کی
ترتیبات اُس دوران بھی دستیاب رہتی ہیں۔
کسی لفظ پر ٹیپ اب اُس کے بعد والا کوما یا سوالیہ نشان ساتھ نہیں لے جاتی۔
سکرول کرنے پر تلاوت بند نہیں ہوتی، اور ایک نئی سیک بار اُسے آگے پیچھے کرتی ہے۔