Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
1516b8f
app: add verse long press gesture hook
nehemiaharchives Jul 8, 2026
3d61dff
app: add Bible text selection model
nehemiaharchives Jul 8, 2026
797bb78
app: highlight selected single Bible verses
nehemiaharchives Jul 8, 2026
f641f9b
app: highlight selected side-by-side verses
nehemiaharchives Jul 8, 2026
49f91f2
app: highlight selected bilingual under verses
nehemiaharchives Jul 8, 2026
52acb4e
app: show icon-only copy popup on verse long press
nehemiaharchives Jul 8, 2026
bfbe46b
app: expose Bible text selection type for public widgets
nehemiaharchives Jul 8, 2026
4d983f3
app: make copy icon tintable in compose resources
nehemiaharchives Jul 8, 2026
1bf7fa7
app: make select all icon tintable in compose resources
nehemiaharchives Jul 8, 2026
207399d
app: align icon resource style
nehemiaharchives Jul 8, 2026
85fbb06
app: align select all icon resource style
nehemiaharchives Jul 8, 2026
3f0b0cd
app: tint selection popup icons with primary color
nehemiaharchives Jul 8, 2026
61ef6bd
smaller select/copy icon
nehemiaharchives Jul 8, 2026
531a5b1
app: position selection popup from text bounds
nehemiaharchives Jul 8, 2026
47b8e60
app: trim bilingual side verse popup bounds
nehemiaharchives Jul 8, 2026
9eb0f34
app: trim bilingual under verse popup bounds
nehemiaharchives Jul 8, 2026
ed03ee1
app: derive selection popup position from static size constants
nehemiaharchives Jul 8, 2026
aa6c2ef
compact but easy to tap select/copy icon
nehemiaharchives Jul 8, 2026
7271252
copied text should not include translation code
nehemiaharchives Jul 8, 2026
8cd47a0
app: let platform text selection handle long press
nehemiaharchives Jul 8, 2026
9656d8d
app: enable platform text selection in single reader
nehemiaharchives Jul 8, 2026
2816891
app: enable platform text selection in side reader
nehemiaharchives Jul 8, 2026
33875f2
app: enable platform text selection in under reader
nehemiaharchives Jul 8, 2026
91d2d09
app: use platform text selection handles
nehemiaharchives Jul 8, 2026
652b1e0
app: fix nullable long press callback type
nehemiaharchives Jul 8, 2026
2c77dea
app: remove custom selection popup code
nehemiaharchives Jul 8, 2026
fc01d86
app: remove custom selection state from single reader
nehemiaharchives Jul 8, 2026
5fe75e9
app: remove custom selection state from side reader
nehemiaharchives Jul 8, 2026
d70d87e
app: remove custom selection state from under reader
nehemiaharchives Jul 8, 2026
b6149e8
app: remove unused selection drawable
nehemiaharchives Jul 8, 2026
a3291af
remove unused drawable
nehemiaharchives Jul 8, 2026
68fbe73
remove custom selection model
nehemiaharchives Jul 8, 2026
513f2a7
app: remove custom long press hook
nehemiaharchives Jul 8, 2026
4718b6e
app: fix verse padding helper type
nehemiaharchives Jul 8, 2026
f065f43
app: remove single reader long press parameter
nehemiaharchives Jul 8, 2026
4899c90
app: remove side reader long press parameter
nehemiaharchives Jul 8, 2026
9e66716
app: remove under reader long press parameter
nehemiaharchives Jul 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

10 changes: 0 additions & 10 deletions app/shared/src/commonMain/composeResources/drawable/select_all.xml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.offset
Expand All @@ -36,8 +36,8 @@ import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.input.pointer.PointerEventPass
import androidx.compose.ui.input.pointer.PointerEventType
import androidx.compose.ui.input.pointer.isCtrlPressed
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextOverflow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ internal fun Modifier.verseTapGestures(
onVerseTap: (Int) -> Unit,
onVerseDoubleTap: (Int) -> Unit
): Modifier {
return pointerInput(verse) {
return pointerInput(verse, onVerseTap, onVerseDoubleTap) {
detectTapGestures(
onTap = { onVerseTap(verse) },
onDoubleTap = { onVerseDoubleTap(verse) }
Expand Down Expand Up @@ -160,4 +160,4 @@ fun getVersePairs(bible: Bible, bibleState: BibleState): List<Pair<String, Strin
val newPair = addEmptyEntryToMakeSameSize(mainVerses.toList(), subVerses.toList())
newPair.first.zip(newPair.second)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.positionInParent
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
Expand Down Expand Up @@ -43,6 +45,7 @@ fun BilingualSideBible(
val readingMode = bibleState.readingMode
require(readingMode == ReadingMode.BILINGUAL_SIDE) { "ReadingMode should be ${ReadingMode.BILINGUAL_SIDE} but trying to put $readingMode" }
requireNotNull(bibleState.subTranslation) { "ReadingMode should be ${ReadingMode.BILINGUAL_SIDE} so subTranslation is needed but null" }
val verseSpacingPx = with(LocalDensity.current) { bibleState.spaceBetweenVerses.dp.roundToPx() }

ScrollableColumn(
bibleState = bibleState,
Expand All @@ -52,53 +55,60 @@ fun BilingualSideBible(
bottomContentPadding = bottomContentPadding,
onTitleTap = onTitleTap
) {
versePairs.forEachIndexed { verse, pair ->
val background = animatedVerseBackgroundColor(bibleState, verse, highlightedVerse).value
val textColor = animatedVerseTextColor(verse, highlightedVerse).value
SelectionContainer {
Column {
versePairs.forEachIndexed { verse, pair ->
val animatedBackground = animatedVerseBackgroundColor(bibleState, verse, highlightedVerse).value
val animatedTextColor = animatedVerseTextColor(verse, highlightedVerse).value
val verseNumber = verse + 1

Column(
modifier = Modifier
.fillMaxWidth()
.verseTapGestures(
verse = verse + 1,
onVerseTap = onVerseTap,
onVerseDoubleTap = onVerseDoubleTap
)
.onGloballyPositioned { coordinates ->
onVersePositioned(
verse + 1,
VerseLayoutInfo(
topPx = coordinates.positionInParent().y.toInt(),
heightPx = coordinates.size.height
Column(
modifier = Modifier
.fillMaxWidth()
.verseTapGestures(
verse = verseNumber,
onVerseTap = onVerseTap,
onVerseDoubleTap = onVerseDoubleTap
)
)
.onGloballyPositioned { coordinates ->
onVersePositioned(
verseNumber,
VerseLayoutInfo(
topPx = coordinates.positionInParent().y.toInt(),
heightPx = (coordinates.size.height - verseSpacingPx).coerceAtLeast(0)
)
)
}
) {
Row(
modifier = Modifier.fillMaxWidth()
) {
Text(
text = "$verseNumber ${pair.first}",
style = TextStyle(
fontSize = bibleState.fontSize.sp,
fontFamily = if (bibleState.isFontFamilySerif) bibleState.mainTranslation.language.serifFontFamily() else bibleState.mainTranslation.language.sansFontFamily(),
color = animatedTextColor
),
modifier = Modifier
.weight(1f)
.background(animatedBackground)
)
Text(
text = "$verseNumber ${pair.second}",
style = TextStyle(
fontSize = bibleState.fontSize.sp,
fontFamily = if (bibleState.isFontFamilySerif) bibleState.subTranslation.language.serifFontFamily() else bibleState.subTranslation.language.sansFontFamily(),
color = animatedTextColor
),
modifier = Modifier
.weight(1f)
.background(animatedBackground)
)
}
Spacer(modifier = Modifier.height(bibleState.spaceBetweenVerses.dp))
}
) {
Row(
modifier = Modifier
.fillMaxWidth()
.background(background)
) {
Text(
text = "${verse + 1} ${pair.first}",
style = TextStyle(
fontSize = bibleState.fontSize.sp,
fontFamily = if (bibleState.isFontFamilySerif) bibleState.mainTranslation.language.serifFontFamily() else bibleState.mainTranslation.language.sansFontFamily(),
color = textColor
),
modifier = Modifier.weight(1f)
)
Text(
text = "${verse + 1} ${pair.second}",
style = TextStyle(
fontSize = bibleState.fontSize.sp,
fontFamily = if (bibleState.isFontFamilySerif) bibleState.subTranslation.language.serifFontFamily() else bibleState.subTranslation.language.sansFontFamily(),
color = textColor
),
modifier = Modifier.weight(1f)
)
}
Spacer(modifier = Modifier.height(bibleState.spaceBetweenVerses.dp))
}
}
}
Expand All @@ -121,4 +131,4 @@ fun BilingualSideBiblePreview() {
scrollState = scrollState
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.positionInParent
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
Expand Down Expand Up @@ -42,6 +44,7 @@ fun BilingualUnderBible(
val readingMode = bibleState.readingMode
require(readingMode == ReadingMode.BILINGUAL_UNDER) { "Expected ${ReadingMode.BILINGUAL_UNDER}, got $readingMode" }
requireNotNull(bibleState.subTranslation) { "subTranslation is required for ${ReadingMode.BILINGUAL_UNDER}" }
val verseSpacingPx = with(LocalDensity.current) { bibleState.spaceBetweenVerses.dp.roundToPx() }

ScrollableColumn(
bibleState = bibleState,
Expand All @@ -51,62 +54,67 @@ fun BilingualUnderBible(
bottomContentPadding = bottomContentPadding,
onTitleTap = onTitleTap
) {
versePairs.forEachIndexed { verse, pair ->
val mainBackground = animatedBilingualUnderTranslationBackgroundColor(
bibleState = bibleState,
verseIndex = verse,
highlightedVerse = highlightedVerse,
isSubTranslation = false
).value
val subBackground = animatedBilingualUnderTranslationBackgroundColor(
bibleState = bibleState,
verseIndex = verse,
highlightedVerse = highlightedVerse,
isSubTranslation = true
).value
val textColor = animatedVerseTextColor(verse, highlightedVerse).value
SelectionContainer {
Column {
versePairs.forEachIndexed { verse, pair ->
val animatedMainBackground = animatedBilingualUnderTranslationBackgroundColor(
bibleState = bibleState,
verseIndex = verse,
highlightedVerse = highlightedVerse,
isSubTranslation = false
).value
val animatedSubBackground = animatedBilingualUnderTranslationBackgroundColor(
bibleState = bibleState,
verseIndex = verse,
highlightedVerse = highlightedVerse,
isSubTranslation = true
).value
val animatedTextColor = animatedVerseTextColor(verse, highlightedVerse).value
val verseNumber = verse + 1

Column(
modifier = Modifier
.fillMaxWidth()
.verseTapGestures(
verse = verse + 1,
onVerseTap = onVerseTap,
onVerseDoubleTap = onVerseDoubleTap
)
.onGloballyPositioned { coordinates ->
onVersePositioned(
verse + 1,
VerseLayoutInfo(
topPx = coordinates.positionInParent().y.toInt(),
heightPx = coordinates.size.height
Column(
modifier = Modifier
.fillMaxWidth()
.verseTapGestures(
verse = verseNumber,
onVerseTap = onVerseTap,
onVerseDoubleTap = onVerseDoubleTap
)
.onGloballyPositioned { coordinates ->
onVersePositioned(
verseNumber,
VerseLayoutInfo(
topPx = coordinates.positionInParent().y.toInt(),
heightPx = (coordinates.size.height - verseSpacingPx).coerceAtLeast(0)
)
)
}
) {
Text(
text = "$verseNumber ${pair.first}",
style = TextStyle(
fontSize = bibleState.fontSize.sp,
fontFamily = if (bibleState.isFontFamilySerif) bibleState.mainTranslation.language.serifFontFamily() else bibleState.mainTranslation.language.sansFontFamily(),
color = animatedTextColor
),
modifier = Modifier
.fillMaxWidth()
.background(animatedMainBackground)
)
Text(
text = "$verseNumber ${pair.second}",
style = TextStyle(
fontSize = bibleState.fontSize.sp,
fontFamily = if (bibleState.isFontFamilySerif) bibleState.subTranslation.language.serifFontFamily() else bibleState.subTranslation.language.sansFontFamily(),
color = animatedTextColor
),
modifier = Modifier
.fillMaxWidth()
.background(animatedSubBackground)
)
Spacer(modifier = Modifier.height(bibleState.spaceBetweenVerses.dp))
}
) {
Text(
text = "${verse + 1} ${pair.first}",
style = TextStyle(
fontSize = bibleState.fontSize.sp,
fontFamily = if (bibleState.isFontFamilySerif) bibleState.mainTranslation.language.serifFontFamily() else bibleState.mainTranslation.language.sansFontFamily(),
color = textColor
),
modifier = Modifier
.fillMaxWidth()
.background(mainBackground)
)
Text(
text = "${verse + 1} ${pair.second}",
style = TextStyle(
fontSize = bibleState.fontSize.sp,
fontFamily = if (bibleState.isFontFamilySerif) bibleState.subTranslation.language.serifFontFamily() else bibleState.subTranslation.language.sansFontFamily(),
color = textColor
),
modifier = Modifier
.fillMaxWidth()
.background(subBackground)
)
Spacer(modifier = Modifier.height(bibleState.spaceBetweenVerses.dp))
}
}
}
}
Expand All @@ -129,4 +137,4 @@ fun BilingualUnderBiblePreview() {
scrollState = scrollState
)
}
}
}
Loading
Loading