~repos /only-bible-app

#kotlin#android#ios

GIT_CONFIG_PARAMETERS="'http.version=HTTP/1.1'" git clone https://git.pyrossh.dev/only-bible-app.git
Discussions: https://groups.google.com/g/rust-embed-devs

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



lib/store/actions_state.dart



import "dart:developer";
import "package:async_redux/async_redux.dart";
import "package:flutter_soloud/flutter_soloud.dart";
import "package:flutter/material.dart";
import "package:only_bible_app/dialog.dart";
import "package:only_bible_app/gen/bible.gen.dart";
import "package:only_bible_app/store/app_state.dart";
import "package:only_bible_app/utils.dart";
class ToggleEngTitlesAction extends ReduxAction<AppState> {
@override
AppState reduce() => state.copy(engTitles: !state.engTitles);
}
class UpdateFontWeightAction extends ReduxAction<AppState> {
final int value;
UpdateFontWeightAction(this.value);
@override
AppState reduce() => state.copy(fontWeight: value);
}
class ToggleDarkModeAction extends ReduxAction<AppState> {
@override
AppState reduce() => state.copy(darkMode: !state.darkMode);
}
class UpdateFontSizeAction extends ReduxAction<AppState> {
final double value;
UpdateFontSizeAction(this.value);
@override
AppState reduce() => state.copy(fontSize: value);
}
class UpdateChapterAction extends ReduxAction<AppState> {
final int book;
final int chapter;
UpdateChapterAction(this.book, this.chapter);
@override
AppState reduce() => state.copy(savedBook: book, savedChapter: chapter);
}
class TogglePlayAction extends ReduxAction<AppState> {
final BuildContext buildContext;
final Bible bible;
TogglePlayAction(this.buildContext, this.bible);
@override
Future<AppState?> reduce() async {
if (SoLoud.instance.getActiveVoiceCount() > 0) {
await SoLoud.instance.disposeAllSources();
return null;
}
final versesToPlay = List<Verse>.from(state.selectedVerses);
final audioVoice = bible.voiceName!;
final audioError = "Audio playback error";
for (final v in versesToPlay) {
final pathname = "${bible.name!}_${v.book}_${v.chapter}_${v.index}";
try {
final data = await convertText(audioVoice, v.text ?? "");
final stream = SoLoud.instance.setBufferStream(
bufferingType: BufferingType.preserved,
format: BufferType.auto,
);
SoLoud.instance.addAudioDataStream(stream, data);
SoLoud.instance.setDataIsEnded(stream);
final handle = await SoLoud.instance.play(stream);
// Wait for playback to complete
await stream.soundEvents.firstWhere(
(e) => e.event == SoundEventType.handleIsNoMoreValid && e.handle == handle,
);
await SoLoud.instance.disposeSource(stream);
} catch (err) {
// If sources were disposed (user stopped playback), don't treat as error
if (SoLoud.instance.getActiveVoiceCount() == 0) {
return null;
}
log(
"Could not play audio",
name: "play",
error: (err.toString(), pathname),
);
recordError((err.toString(), pathname).toString(), null);
if (buildContext.mounted) {
showError(buildContext, audioError);
}
return null;
} finally {}
}
return null;
}
}
class SelectVerseAction extends ReduxAction<AppState> {
final Verse verse;
SelectVerseAction(this.verse);
@override
AppState reduce() {
final isSelected = state.selectedVerses.any(
(el) => el.book == verse.book && el.chapter == verse.chapter && el.index == verse.index,
);
final newVerses = isSelected
? state.selectedVerses.where((it) => it.index != verse.index).toList()
: [...state.selectedVerses, verse];
return state.copy(
selectedVerses: newVerses,
);
}
}
class ClearSelectedVersesAction extends ReduxAction<AppState> {
@override
AppState reduce() => state.copy(selectedVerses: []);
}
class SetHighlightAction extends ReduxAction<AppState> {
final List<Verse> verses;
final int colorIndex;
SetHighlightAction(this.verses, this.colorIndex);
@override
AppState reduce() {
final updated = Map<String, int>.from(state.highlights);
for (final v in verses) {
updated["${v.book}:${v.chapter}:${v.index}"] = colorIndex;
}
return state.copy(highlights: updated, selectedVerses: []);
}
}
class RemoveHighlightAction extends ReduxAction<AppState> {
final List<Verse> verses;
RemoveHighlightAction(this.verses);
@override
AppState reduce() {
final updated = Map<String, int>.from(state.highlights);
for (final v in verses) {
updated.remove("${v.book}:${v.chapter}:${v.index}");
}
return state.copy(highlights: updated, selectedVerses: []);
}
}