~repos /only-bible-app

#kotlin#android#ios

git clone https://pyrossh.dev/repos/only-bible-app.git

The only bible app you will ever need. No ads. No in-app purchases. No distractions.


677f16b3 Peter John

1 year ago
fix various issues
app/src/main/java/dev/pyrossh/onlyBible/AppHost.kt CHANGED
@@ -20,14 +20,14 @@ import androidx.navigation.toRoute
20
20
  import dev.pyrossh.onlyBible.domain.Verse
21
21
 
22
22
  @Composable
23
- fun AppHost(model: AppViewModel = viewModel()) {
23
+ fun AppHost(model: AppViewModel) {
24
24
  val navController = rememberNavController()
25
25
  val navigateToChapter = { props: ChapterScreenProps ->
26
26
  model.resetScrollState()
27
27
  navController.navigate(props)
28
28
  }
29
29
  val onSwipeLeft = {
30
- val pair = Verse.getForwardPair(model.bookIndex, model.chapterIndex)
30
+ val pair = model.getForwardPair()
31
31
  navigateToChapter(
32
32
  ChapterScreenProps(
33
33
  bookIndex = pair.first,
@@ -36,19 +36,20 @@ fun AppHost(model: AppViewModel = viewModel()) {
36
36
  )
37
37
  }
38
38
  val onSwipeRight = {
39
- val pair = Verse.getBackwardPair(model.bookIndex, model.chapterIndex)
39
+ val pair = model.getBackwardPair()
40
40
  if (navController.previousBackStackEntry != null) {
41
41
  val previousBook =
42
- navController.previousBackStackEntry?.arguments?.getInt("book")
42
+ navController.previousBackStackEntry?.arguments?.getInt("bookIndex")
43
43
  ?: 0
44
44
  val previousChapter =
45
- navController.previousBackStackEntry?.arguments?.getInt("chapter")
45
+ navController.previousBackStackEntry?.arguments?.getInt("chapterIndex")
46
46
  ?: 0
47
- // println("currentBackStackEntry ${previousBook} ${previousChapter} || ${pair.first} ${pair.second}")
47
+ // println("currentBackStackEntry ${previousBook} ${previousChapter} || ${pair.first} ${pair.second}")
48
48
  if (previousBook == pair.first && previousChapter == pair.second) {
49
49
  println("Popped")
50
50
  navController.popBackStack()
51
51
  } else {
52
+ println("navigated with stack")
52
53
  navController.navigate(
53
54
  ChapterScreenProps(
54
55
  bookIndex = pair.first,
@@ -58,7 +59,7 @@ fun AppHost(model: AppViewModel = viewModel()) {
58
59
  )
59
60
  }
60
61
  } else {
61
- println("navigated navigate")
62
+ println("navigated without stack")
62
63
  navController.navigate(
63
64
  ChapterScreenProps(
64
65
  bookIndex = pair.first,
app/src/main/java/dev/pyrossh/onlyBible/AppViewModel.kt CHANGED
@@ -9,44 +9,32 @@ import android.os.Build
9
9
  import android.os.LocaleList
10
10
  import androidx.appcompat.app.AppCompatDelegate
11
11
  import androidx.compose.foundation.lazy.LazyListState
12
- import androidx.compose.runtime.MutableState
13
12
  import androidx.compose.runtime.getValue
14
13
  import androidx.compose.runtime.mutableIntStateOf
15
14
  import androidx.compose.runtime.mutableStateOf
16
15
  import androidx.compose.runtime.setValue
17
16
  import androidx.core.os.LocaleListCompat
18
- import androidx.datastore.preferences.core.Preferences
19
- import androidx.datastore.preferences.core.booleanPreferencesKey
20
- import androidx.datastore.preferences.core.edit
21
- import androidx.datastore.preferences.core.intPreferencesKey
22
- import androidx.datastore.preferences.core.stringPreferencesKey
23
- import androidx.datastore.preferences.preferencesDataStore
24
17
  import androidx.lifecycle.AndroidViewModel
25
18
  import androidx.lifecycle.viewModelScope
26
19
  import com.microsoft.cognitiveservices.speech.SpeechConfig
27
20
  import com.microsoft.cognitiveservices.speech.SpeechSynthesisEventArgs
28
21
  import com.microsoft.cognitiveservices.speech.SpeechSynthesizer
22
+ import dev.pyrossh.onlyBible.domain.BOOKS_COUNT
29
23
  import dev.pyrossh.onlyBible.domain.Verse
30
- import kotlinx.coroutines.CoroutineScope
24
+ import dev.pyrossh.onlyBible.domain.Verse.Companion.chapterSizes
31
25
  import kotlinx.coroutines.Dispatchers
32
26
  import kotlinx.coroutines.FlowPreview
33
27
  import kotlinx.coroutines.flow.MutableStateFlow
34
28
  import kotlinx.coroutines.flow.SharingStarted
35
29
  import kotlinx.coroutines.flow.asStateFlow
36
- import kotlinx.coroutines.flow.collectLatest
37
30
  import kotlinx.coroutines.flow.combine
38
31
  import kotlinx.coroutines.flow.debounce
39
- import kotlinx.coroutines.flow.distinctUntilChanged
40
- import kotlinx.coroutines.flow.map
41
32
  import kotlinx.coroutines.flow.stateIn
42
33
  import kotlinx.coroutines.launch
43
- import kotlinx.coroutines.withContext
44
34
  import org.json.JSONObject
45
35
  import java.io.IOException
46
36
  import java.util.Locale
47
37
 
48
- internal val Context.dataStore by preferencesDataStore(name = "onlyBible")
49
-
50
38
  class AppViewModel(application: Application) : AndroidViewModel(application) {
51
39
  private val context
52
40
  get() = getApplication<Application>()
@@ -78,51 +66,16 @@ class AppViewModel(application: Application) : AndroidViewModel(application) {
78
66
  var showBottomSheet by mutableStateOf(false)
79
67
  var highlightedVerses = MutableStateFlow(JSONObject())
80
68
 
81
- var bookIndex by preferenceMutableState(
69
+ var bookIndex by mutableIntStateOf(0)
82
- coroutineScope = viewModelScope,
83
- context = context,
84
- keyName = "bookIndex",
85
- initialValue = 0,
86
- defaultValue = 0,
87
- getPreferencesKey = ::intPreferencesKey,
88
- )
89
- var chapterIndex by preferenceMutableState(
70
+ var chapterIndex by mutableIntStateOf(0)
71
+ var fontType by mutableStateOf(FontType.Sans)
90
- coroutineScope = viewModelScope,
72
+ var fontSizeDelta by mutableIntStateOf(0)
91
- context = context,
73
+ var fontBoldEnabled by mutableStateOf(false)
92
- keyName = "chapterIndex",
74
+ var uiMode by mutableIntStateOf(0)
93
- initialValue = 0,
94
- defaultValue = 0,
95
- getPreferencesKey = ::intPreferencesKey,
96
- )
97
75
  var scrollState = LazyListState(
98
76
  0,
99
77
  0
100
78
  )
101
- var uiMode by mutableIntStateOf(0)
102
- var fontType by preferenceMutableState(
103
- coroutineScope = viewModelScope,
104
- context = context,
105
- keyName = "fontType",
106
- initialValue = FontType.Sans.name,
107
- defaultValue = FontType.Sans.name,
108
- getPreferencesKey = ::stringPreferencesKey,
109
- )
110
- var fontSizeDelta by preferenceMutableState(
111
- coroutineScope = viewModelScope,
112
- context = context,
113
- keyName = "fontSizeDelta",
114
- initialValue = 0,
115
- defaultValue = 0,
116
- getPreferencesKey = ::intPreferencesKey,
117
- )
118
- var fontBoldEnabled by preferenceMutableState(
119
- coroutineScope = viewModelScope,
120
- context = context,
121
- keyName = "fontBoldEnabled",
122
- initialValue = false,
123
- defaultValue = false,
124
- getPreferencesKey = ::booleanPreferencesKey,
125
- )
126
79
 
127
80
  private val _isSearching = MutableStateFlow(false)
128
81
  val isSearching = _isSearching.asStateFlow()
@@ -175,18 +128,69 @@ class AppViewModel(application: Application) : AndroidViewModel(application) {
175
128
  showBottomSheet = false
176
129
  }
177
130
 
178
- fun loadData(p: Preferences) {
131
+ fun loadData() {
132
+ viewModelScope.launch(Dispatchers.IO) {
179
- uiMode = context.applicationContext.resources.configuration.uiMode
133
+ uiMode = context.applicationContext.resources.configuration.uiMode
180
- bookIndex = prefs.getInt("bookIndex", 0)
134
+ bookIndex = prefs.getInt("bookIndex", 0)
181
- chapterIndex = prefs.getInt("chapterIndex", 0)
135
+ chapterIndex = prefs.getInt("chapterIndex", 0)
136
+ fontType =
137
+ FontType.valueOf(
182
- fontType = prefs.getString("fontType", FontType.Sans.name) ?: FontType.Sans.name
138
+ prefs.getString("fontType", FontType.Sans.name) ?: FontType.Sans.name
139
+ )
183
- fontSizeDelta = prefs.getInt("fontSizeDelta", 0)
140
+ fontSizeDelta = prefs.getInt("fontSizeDelta", 0)
184
- fontBoldEnabled = prefs.getBoolean("fontBoldEnabled", false)
141
+ fontBoldEnabled = prefs.getBoolean("fontBoldEnabled", false)
185
- highlightedVerses.value = JSONObject(prefs.getString("highlightedVerses", "{}") ?: "{}")
142
+ highlightedVerses.value = JSONObject(prefs.getString("highlightedVerses", "{}") ?: "{}")
186
- scrollState = LazyListState(
143
+ scrollState = LazyListState(
187
- p[intPreferencesKey("scrollIndex")] ?: 0,
144
+ prefs.getInt("scrollIndex", 0),
188
- p[intPreferencesKey("scrollOffset")] ?: 0
145
+ prefs.getInt("scrollOffset", 0)
189
- )
146
+ )
147
+ loadBible()
148
+ }
149
+ }
150
+
151
+ fun loadBible() {
152
+ viewModelScope.launch(Dispatchers.Main) {
153
+ isLoading = true
154
+ isOnError = false
155
+ }
156
+ try {
157
+ val buffer =
158
+ context.assets.open(
159
+ "bibles/${
160
+ context.getCurrentLocale().getDisplayLanguage(Locale.ENGLISH)
161
+ }.txt"
162
+ )
163
+ .bufferedReader()
164
+ val localVerses = buffer.readLines().filter { it.isNotEmpty() }.map {
165
+ val arr = it.split("|")
166
+ val bookName = arr[0]
167
+ val book = arr[1].toInt()
168
+ val chapter = arr[2].toInt()
169
+ val verseNo = arr[3].toInt()
170
+ val heading = arr[4]
171
+ val verseText = arr.subList(5, arr.size).joinToString("|")
172
+ Verse(
173
+ bookIndex = book,
174
+ bookName = bookName,
175
+ chapterIndex = chapter,
176
+ verseIndex = verseNo,
177
+ heading = heading,
178
+ text = verseText,
179
+ )
180
+ }
181
+ viewModelScope.launch(Dispatchers.Main) {
182
+ verses.value = localVerses
183
+ bookNames.value = localVerses.distinctBy { it.bookName }.map { it.bookName }
184
+ isLoading = false
185
+ isOnError = false
186
+ }
187
+ } catch (e: IOException) {
188
+ e.printStackTrace()
189
+ viewModelScope.launch(Dispatchers.Main) {
190
+ isLoading = false
191
+ isOnError = true
192
+ }
193
+ }
190
194
  }
191
195
 
192
196
  fun saveData() {
@@ -194,79 +198,61 @@ class AppViewModel(application: Application) : AndroidViewModel(application) {
194
198
  with(prefs.edit()) {
195
199
  putInt("bookIndex", bookIndex)
196
200
  putInt("chapterIndex", chapterIndex)
197
- putString("fontType", fontType)
201
+ putString("fontType", fontType.name)
198
202
  putInt("fontSizeDelta", fontSizeDelta)
199
203
  putBoolean("fontBoldEnabled", fontBoldEnabled)
200
204
  putString("highlightedVerses", highlightedVerses.value.toString())
205
+ putInt("scrollIndex", scrollState.firstVisibleItemIndex)
206
+ putInt("scrollOffset", scrollState.firstVisibleItemScrollOffset)
201
207
  apply()
202
208
  commit()
203
209
  }
204
210
  }
205
211
  }
206
212
 
213
+ fun getForwardPair(): Pair<Int, Int> {
214
+ val sizes = chapterSizes[bookIndex];
207
- fun resetScrollState() {
215
+ if (sizes > chapterIndex + 1) {
216
+ return Pair(bookIndex, chapterIndex + 1)
217
+ }
218
+ if (bookIndex + 1 < BOOKS_COUNT) {
208
- scrollState = LazyListState(0, 0)
219
+ return Pair(bookIndex + 1, 0)
220
+ }
221
+ return Pair(0, 0)
209
222
  }
210
223
 
211
- fun loadBible(loc: Locale, context: Context) {
224
+ fun getBackwardPair(): Pair<Int, Int> {
212
- viewModelScope.launch(Dispatchers.IO) {
213
- launch(Dispatchers.Main) {
214
- isLoading = true
215
- isOnError = false
216
- }
217
- try {
218
- val buffer =
219
- context.assets.open("bibles/${loc.getDisplayLanguage(Locale.ENGLISH)}.txt")
220
- .bufferedReader()
221
- val localVerses = buffer.readLines().filter { it.isNotEmpty() }.map {
222
- val arr = it.split("|")
223
- val bookName = arr[0]
224
- val book = arr[1].toInt()
225
- val chapter = arr[2].toInt()
226
- val verseNo = arr[3].toInt()
227
- val heading = arr[4]
228
- val verseText = arr.subList(5, arr.size).joinToString("|")
229
- Verse(
230
- bookIndex = book,
231
- bookName = bookName,
232
- chapterIndex = chapter,
225
+ if (chapterIndex - 1 >= 0) {
233
- verseIndex = verseNo,
226
+ return Pair(bookIndex, chapterIndex - 1)
234
- heading = heading,
235
- text = verseText,
236
- )
237
- }
238
- launch(Dispatchers.Main) {
239
- isLoading = false
240
- isOnError = false
241
- verses.value = localVerses
242
- bookNames.value = localVerses.distinctBy { it.bookName }.map { it.bookName }
243
- }
244
- } catch (e: IOException) {
245
- e.printStackTrace()
246
- launch(Dispatchers.Main) {
247
- isLoading = false
248
- isOnError = true
249
- }
250
- }
251
227
  }
228
+ if (bookIndex - 1 >= 0) {
229
+ return Pair(bookIndex - 1, chapterSizes[bookIndex - 1] - 1)
230
+ }
231
+ return Pair(BOOKS_COUNT - 1, chapterSizes[BOOKS_COUNT - 1] - 1)
232
+ }
233
+
234
+ fun resetScrollState() {
235
+ scrollState = LazyListState(0, 0)
252
236
  }
253
237
 
254
238
  fun getHighlightForVerse(v: Verse): Int? {
255
- val k = "${v.bookIndex}:${v.chapterIndex}:${v.verseIndex}"
256
- if (highlightedVerses.value.has(k))
239
+ if (highlightedVerses.value.has(v.key()))
257
- return highlightedVerses.value.getInt(k)
240
+ return highlightedVerses.value.getInt(v.key())
258
241
  return null
259
242
  }
260
243
 
261
244
  fun addHighlightedVerses(verses: List<Verse>, colorIndex: Int) {
262
245
  verses.forEach { v ->
263
- highlightedVerses.value.put("${v.bookIndex}:${v.chapterIndex}:${v.verseIndex}", colorIndex)
246
+ highlightedVerses.value.put(
247
+ v.key(),
248
+ colorIndex
249
+ )
264
250
  }
265
251
  }
266
252
 
267
253
  fun removeHighlightedVerses(verses: List<Verse>) {
268
254
  verses.forEach { v ->
269
- highlightedVerses.value.remove("${v.bookIndex}:${v.chapterIndex}:${v.verseIndex}")
255
+ highlightedVerses.value.remove(v.key())
270
256
  }
271
257
  }
272
258
  }
@@ -301,50 +287,4 @@ fun setLocale(context: Context, loc: Locale) {
301
287
  LocaleListCompat.forLanguageTags(loc.language)
302
288
  )
303
289
  }
304
- }
305
-
306
- private inline fun <reified T, reified NNT : T> preferenceMutableState(
307
- coroutineScope: CoroutineScope,
308
- context: Context,
309
- keyName: String,
310
- initialValue: T,
311
- defaultValue: T,
312
- getPreferencesKey: (keyName: String) -> Preferences.Key<NNT>,
313
- ): MutableState<T> {
314
- val snapshotMutableState: MutableState<T> = mutableStateOf(initialValue)
315
- val key: Preferences.Key<NNT> = getPreferencesKey(keyName)
316
- coroutineScope.launch {
317
- context.dataStore.data
318
- .map { if (it[key] == null) defaultValue else it[key] }
319
- .distinctUntilChanged()
320
- .collectLatest {
321
- withContext(Dispatchers.Main) {
322
- snapshotMutableState.value = it as T
323
- }
324
- }
325
- }
326
- return object : MutableState<T> {
327
- override var value: T
328
- get() = snapshotMutableState.value
329
- set(value) {
330
- val rollbackValue = snapshotMutableState.value
331
- snapshotMutableState.value = value
332
- coroutineScope.launch {
333
- try {
334
- context.dataStore.edit {
335
- if (value != null) {
336
- it[key] = value as NNT
337
- } else {
338
- it.remove(key)
339
- }
340
- }
341
- } catch (e: Exception) {
342
- snapshotMutableState.value = rollbackValue
343
- }
344
- }
345
- }
346
-
347
- override fun component1() = value
348
- override fun component2(): (T) -> Unit = { value = it }
349
- }
350
290
  }
app/src/main/java/dev/pyrossh/onlyBible/ChapterScreen.kt CHANGED
@@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.PaddingValues
8
8
  import androidx.compose.foundation.layout.Row
9
9
  import androidx.compose.foundation.layout.fillMaxSize
10
10
  import androidx.compose.foundation.layout.fillMaxWidth
11
+ import androidx.compose.foundation.layout.height
11
12
  import androidx.compose.foundation.layout.padding
12
13
  import androidx.compose.foundation.lazy.LazyColumn
13
14
  import androidx.compose.foundation.lazy.LazyListState
@@ -194,7 +195,6 @@ fun ChapterScreen(
194
195
  val searchText by model.searchText.collectAsState()
195
196
  val isSearching by model.isSearching.collectAsState()
196
197
  val versesList by model.versesList.collectAsState()
197
- val fontType = FontType.valueOf(model.fontType)
198
198
  val fontSizeDelta = model.fontSizeDelta
199
199
  val headingColor = MaterialTheme.colorScheme.onSurface // MaterialTheme.colorScheme.primary,
200
200
  val chapterVerses =
@@ -224,7 +224,7 @@ fun ChapterScreen(
224
224
  vertical = 12.dp,
225
225
  ),
226
226
  style = TextStyle(
227
- fontFamily = fontType.family(),
227
+ fontFamily = model.fontType.family(),
228
228
  fontSize = (16 + fontSizeDelta).sp,
229
229
  fontWeight = FontWeight.W700,
230
230
  color = headingColor,
@@ -245,8 +245,8 @@ fun ChapterScreen(
245
245
  }
246
246
  }
247
247
  TopAppBar(
248
- // modifier = Modifier
248
+ modifier = Modifier
249
- // .height(72.dp),
249
+ .height(72.dp),
250
250
  title = {
251
251
 
252
252
  Row(
@@ -340,7 +340,7 @@ fun ChapterScreen(
340
340
  top = if (v.verseIndex != 0) 12.dp else 0.dp, bottom = 12.dp
341
341
  ),
342
342
  style = TextStyle(
343
- fontFamily = fontType.family(),
343
+ fontFamily = model.fontType.family(),
344
344
  fontSize = (16 + fontSizeDelta).sp,
345
345
  fontWeight = FontWeight.W700,
346
346
  color = headingColor,
app/src/main/java/dev/pyrossh/onlyBible/MainActivity.kt CHANGED
@@ -11,10 +11,7 @@ import androidx.activity.enableEdgeToEdge
11
11
  import androidx.activity.viewModels
12
12
  import androidx.core.animation.doOnEnd
13
13
  import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
14
- import androidx.datastore.preferences.core.edit
15
- import androidx.datastore.preferences.core.intPreferencesKey
16
14
  import androidx.lifecycle.lifecycleScope
17
- import kotlinx.coroutines.flow.first
18
15
  import kotlinx.coroutines.launch
19
16
  import java.util.Locale
20
17
 
@@ -31,9 +28,7 @@ class MainActivity : ComponentActivity() {
31
28
  super.onCreate(savedInstanceState)
32
29
  enableEdgeToEdge()
33
30
  lifecycleScope.launch {
34
- val data = applicationContext.dataStore.data.first()
35
- model.loadData(data)
31
+ model.loadData()
36
- model.loadBible(applicationContext.getCurrentLocale(), applicationContext)
37
32
  }
38
33
  splashScreen.setKeepOnScreenCondition { model.isLoading }
39
34
  splashScreen.setOnExitAnimationListener { viewProvider ->
@@ -59,7 +54,7 @@ class MainActivity : ComponentActivity() {
59
54
  }
60
55
  setContent {
61
56
  AppTheme {
62
- AppHost()
57
+ AppHost(model = model)
63
58
  if (model.showBottomSheet) {
64
59
  TextSettingsBottomSheet(model = model)
65
60
  }
@@ -71,12 +66,6 @@ class MainActivity : ComponentActivity() {
71
66
  super.onSaveInstanceState(outState)
72
67
  lifecycleScope.launch {
73
68
  model.saveData()
74
- applicationContext.dataStore.edit {
75
- println("saveData ${model.scrollState.firstVisibleItemIndex}")
76
- it[intPreferencesKey("scrollIndex")] = model.scrollState.firstVisibleItemIndex
77
- it[intPreferencesKey("scrollOffset")] =
78
- model.scrollState.firstVisibleItemScrollOffset
79
- }
80
69
  }
81
70
  }
82
71
  }
app/src/main/java/dev/pyrossh/onlyBible/TextSettingsBottomSheet.kt CHANGED
@@ -51,7 +51,6 @@ fun TextSettingsBottomSheet(model: AppViewModel) {
51
51
  val uiMode = model.uiMode and Configuration.UI_MODE_NIGHT_MASK
52
52
  val scope = rememberCoroutineScope()
53
53
  val sheetState = rememberModalBottomSheetState()
54
- val fontType = FontType.valueOf(model.fontType)
55
54
  return ModalBottomSheet(
56
55
  tonalElevation = 2.dp,
57
56
  sheetState = sheetState,
@@ -192,7 +191,7 @@ fun TextSettingsBottomSheet(model: AppViewModel) {
192
191
  FontType.entries.map {
193
192
  Surface(
194
193
  shape = RoundedCornerShape(8.dp),
195
- border = if (fontType == it) BorderStroke(
194
+ border = if (model.fontType == it) BorderStroke(
196
195
  2.dp, MaterialTheme.colorScheme.primary
197
196
  ) else null,
198
197
  modifier = Modifier
@@ -201,7 +200,7 @@ fun TextSettingsBottomSheet(model: AppViewModel) {
201
200
  .padding(end = 16.dp)
202
201
  .weight(1f),
203
202
  onClick = {
204
- model.fontType = it.name
203
+ model.fontType = it
205
204
  }) {
206
205
  Column(
207
206
  modifier = Modifier.background(
@@ -216,7 +215,7 @@ fun TextSettingsBottomSheet(model: AppViewModel) {
216
215
  fontFamily = it.family(),
217
216
  fontSize = 18.sp,
218
217
  fontWeight = FontWeight.W600,
219
- color = if (fontType == it)
218
+ color = if (model.fontType == it)
220
219
  MaterialTheme.colorScheme.primary
221
220
  else
222
221
  MaterialTheme.colorScheme.onSurface,
app/src/main/java/dev/pyrossh/onlyBible/composables/VerseView.kt CHANGED
@@ -13,6 +13,7 @@ import androidx.compose.foundation.layout.Arrangement
13
13
  import androidx.compose.foundation.layout.Row
14
14
  import androidx.compose.foundation.layout.fillMaxSize
15
15
  import androidx.compose.foundation.layout.height
16
+ import androidx.compose.foundation.layout.padding
16
17
  import androidx.compose.foundation.layout.size
17
18
  import androidx.compose.foundation.layout.width
18
19
  import androidx.compose.foundation.shape.RoundedCornerShape
@@ -28,7 +29,6 @@ import androidx.compose.material3.MaterialTheme
28
29
  import androidx.compose.material3.Surface
29
30
  import androidx.compose.material3.Text
30
31
  import androidx.compose.runtime.Composable
31
- import androidx.compose.runtime.collectAsState
32
32
  import androidx.compose.runtime.getValue
33
33
  import androidx.compose.runtime.mutableIntStateOf
34
34
  import androidx.compose.runtime.remember
@@ -52,7 +52,6 @@ import androidx.compose.ui.unit.dp
52
52
  import androidx.compose.ui.unit.sp
53
53
  import androidx.compose.ui.window.Popup
54
54
  import dev.pyrossh.onlyBible.AppViewModel
55
- import dev.pyrossh.onlyBible.FontType
56
55
  import dev.pyrossh.onlyBible.R
57
56
  import dev.pyrossh.onlyBible.darkHighlights
58
57
  import dev.pyrossh.onlyBible.domain.Verse
@@ -75,7 +74,6 @@ fun VerseView(
75
74
  val scope = rememberCoroutineScope()
76
75
  val context = LocalContext.current
77
76
  val isLight = isLightTheme(model.uiMode, isSystemInDarkTheme())
78
- val fontType = FontType.valueOf(model.fontType)
79
77
  val fontSizeDelta = model.fontSizeDelta
80
78
  val boldWeight = if (model.fontBoldEnabled) FontWeight.W700 else FontWeight.W400
81
79
  val buttonInteractionSource = remember { MutableInteractionSource() }
@@ -107,7 +105,7 @@ fun VerseView(
107
105
  currentHighlightColors[highlightedColorIndex]
108
106
  else
109
107
  Color.Unspecified,
110
- fontFamily = fontType.family(),
108
+ fontFamily = model.fontType.family(),
111
109
  color = if (isLight)
112
110
  Color(0xFF000104)
113
111
  else
@@ -194,7 +192,8 @@ fun VerseView(
194
192
  ) {
195
193
  Row(
196
194
  modifier = Modifier
197
- .fillMaxSize(),
195
+ .fillMaxSize()
196
+ .padding(horizontal = 4.dp),
198
197
  horizontalArrangement = Arrangement.SpaceAround,
199
198
  verticalAlignment = Alignment.CenterVertically,
200
199
  ) {
app/src/main/java/dev/pyrossh/onlyBible/domain/Verse.kt CHANGED
@@ -1,8 +1,6 @@
1
1
  package dev.pyrossh.onlyBible.domain
2
2
 
3
3
  import android.os.Parcelable
4
- import androidx.appsearch.annotation.Document
5
- import androidx.appsearch.app.AppSearchSchema
6
4
  import kotlinx.parcelize.Parcelize
7
5
  import kotlinx.serialization.Serializable
8
6
 
@@ -88,6 +86,8 @@ data class Verse(
88
86
  val text: String,
89
87
  ) : Parcelable {
90
88
 
89
+ fun key() = "${bookIndex}:${chapterIndex}:${verseIndex}"
90
+
91
91
  fun toSSML(voice: String): String {
92
92
  return """
93
93
  <speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">
@@ -167,26 +167,5 @@ data class Verse(
167
167
  1,
168
168
  22
169
169
  )
170
-
171
- fun getForwardPair(book: Int, chapter: Int): Pair<Int, Int> {
172
- val sizes = chapterSizes[book];
173
- if (sizes > chapter + 1) {
174
- return Pair(book, chapter + 1)
175
- }
176
- if (book + 1 < BOOKS_COUNT) {
177
- return Pair(book + 1, 0)
178
- }
179
- return Pair(0, 0)
180
- }
181
-
182
- fun getBackwardPair(book: Int, chapter: Int): Pair<Int, Int> {
183
- if (chapter - 1 >= 0) {
184
- return Pair(book, chapter - 1)
185
- }
186
- if (book - 1 >= 0) {
187
- return Pair(book - 1, chapterSizes[book - 1] - 1)
188
- }
189
- return Pair(BOOKS_COUNT - 1, chapterSizes[BOOKS_COUNT - 1] - 1)
190
- }
191
170
  }
192
171
  }