Navigate the poem tree instead of the visit history
Breadcrumbs: a poem's path (poet » book » section) is now built from its own fullTitle and fullUrl and every ancestor is tappable, so the trail is the same whether the poem was opened by browsing, from the saved list, from a breadcrumb, or by reading on from the previous poem. Back: browsing is a tree, so Back climbs it — poem to section to book to poet to home — rather than retracing however you arrived. Each screen derives its own parent from its URL and navigation keeps the stack flat, which is what stops Back from walking forward again into the page you just left. System Back and the top-bar arrow do the same thing. The exception is a poem opened from the saved list: that was reached from a list, not a shelf, so Back returns to the list, and reading on through the divan keeps that origin. Plus a Home button on every screen below the poet list. Verified on an API 36 emulator: drilled Hafez > ghazals > ghazal 3 and walked back up to the poet list, and opened a saved Khayyam rubai and confirmed Back returns to the saved list rather than the poet's section. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
abcffbc43b
commit
1accb5ee78
11 files changed
+222
-27
No files matched your search
@@ -1,6 +1,9 @@
|
||||
package com.ganjoor.android
|
||||
|
||||
import com.ganjoor.android.data.Crumb
|
||||
import com.ganjoor.android.data.Verse
|
||||
import com.ganjoor.android.data.breadcrumbs
|
||||
import com.ganjoor.android.data.parentUrl
|
||||
import com.ganjoor.android.data.couplets
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
@@ -66,3 +69,59 @@ class CoupletsTest {
|
||||
assertEquals(listOf(2, 1, 1), grouped.map { it.size })
|
||||
}
|
||||
}
|
||||
|
||||
class BreadcrumbsTest {
|
||||
@Test
|
||||
fun `every ancestor is linked and the poem itself is not`() {
|
||||
val crumbs = breadcrumbs("حافظ » غزلیات » غزل شمارهٔ ۱", "/hafez/ghazal/sh1")
|
||||
|
||||
assertEquals(listOf("حافظ", "غزلیات", "غزل شمارهٔ ۱"), crumbs.map { it.label })
|
||||
assertEquals(listOf("/hafez", "/hafez/ghazal", null), crumbs.map { it.url })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `deeply nested books keep the whole trail`() {
|
||||
val crumbs = breadcrumbs(
|
||||
"مولانا » مثنوی معنوی » دفتر اول » بخش ۱",
|
||||
"/moulavi/masnavi/daftar1/sh1",
|
||||
)
|
||||
|
||||
assertEquals(4, crumbs.size)
|
||||
assertEquals("/moulavi/masnavi/daftar1", crumbs[2].url)
|
||||
assertEquals(null, crumbs.last().url)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `a title and url that disagree produce nothing, so the caller falls back`() {
|
||||
assertEquals(emptyList<Crumb>(), breadcrumbs("حافظ » غزل ۱", "/hafez/ghazal/sh1"))
|
||||
assertEquals(emptyList<Crumb>(), breadcrumbs("", "/hafez/ghazal/sh1"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `a poem directly under a poet still links the poet`() {
|
||||
val crumbs = breadcrumbs("حافظ » ساقینامه", "/hafez/saghinameh")
|
||||
|
||||
assertEquals(listOf("/hafez", null), crumbs.map { it.url })
|
||||
}
|
||||
}
|
||||
|
||||
class ParentUrlTest {
|
||||
@Test
|
||||
fun `each level climbs to the one above it`() {
|
||||
assertEquals("/hafez/ghazal", parentUrl("/hafez/ghazal/sh1"))
|
||||
assertEquals("/hafez", parentUrl("/hafez/ghazal"))
|
||||
assertEquals("/moulavi/masnavi", parentUrl("/moulavi/masnavi/daftar1"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `a poet root has no parent, so the caller sends you home`() {
|
||||
assertEquals(null, parentUrl("/hafez"))
|
||||
assertEquals(null, parentUrl("hafez"))
|
||||
assertEquals(null, parentUrl(""))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `trailing slashes don't invent a level`() {
|
||||
assertEquals("/hafez", parentUrl("/hafez/ghazal/"))
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user