Skip to content

Commit 71de1f2

Browse files
add open help options in paperback android
1 parent 8821b83 commit 71de1f2

5 files changed

Lines changed: 122 additions & 16 deletions

File tree

android/app/src/main/kotlin/dev/paperback/mobile/ui/MainScreen.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,9 @@ fun MainScreen(
320320
} else {
321321
importSettingsLauncher.launch(arrayOf("*/*"))
322322
}
323+
},
324+
onHelpOpen = {
325+
viewModel.openHelpDocument()
323326
}
324327
)
325328
},

android/app/src/main/kotlin/dev/paperback/mobile/ui/MainScreenTopBar.kt

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ fun MainScreenTopBar(
4444
onSleepTimerOpen: () -> Unit,
4545
onElementsOpen: () -> Unit,
4646
onExportSettings: () -> Unit,
47-
onImportSettings: () -> Unit
47+
onImportSettings: () -> Unit,
48+
onHelpOpen: () -> Unit
4849
) {
4950
var moreOptionsExpanded by remember { mutableStateOf(false) }
5051
Column(
@@ -211,6 +212,12 @@ fun MainScreenTopBar(
211212
true
212213
}
213214
)
215+
add(
216+
CustomAccessibilityAction(t("Help")) {
217+
onHelpOpen()
218+
true
219+
}
220+
)
214221
}
215222
}
216223
) {
@@ -301,17 +308,58 @@ fun MainScreenTopBar(
301308
onSettingsOpen()
302309
}
303310
)
311+
DropdownMenuItem(
312+
text = { Text(t("Help")) },
313+
onClick = {
314+
moreOptionsExpanded = false
315+
onHelpOpen()
316+
}
317+
)
304318
}
305319
}
306320
} else {
321+
var emptyMenuExpanded by remember { mutableStateOf(false) }
307322
Box {
308323
IconButton(
309-
onClick = { onSettingsOpen() },
324+
onClick = { emptyMenuExpanded = true },
310325
modifier = Modifier.semantics {
311-
traversalIndex = -1f
326+
traversalIndex = 2f
327+
this.onClick(label = "show all options in a menu") {
328+
emptyMenuExpanded = true
329+
true
330+
}
331+
customActions = listOf(
332+
CustomAccessibilityAction(t("Settings")) {
333+
onSettingsOpen()
334+
true
335+
},
336+
CustomAccessibilityAction(t("Help")) {
337+
onHelpOpen()
338+
true
339+
}
340+
)
312341
}
313342
) {
314-
Icon(Icons.Filled.Settings, contentDescription = "Settings")
343+
Icon(Icons.Filled.MoreVert, contentDescription = t("More Options"))
344+
}
345+
DropdownMenu(
346+
expanded = emptyMenuExpanded,
347+
onDismissRequest = { emptyMenuExpanded = false }
348+
) {
349+
DropdownMenuItem(
350+
text = { Text(t("Settings")) },
351+
onClick = {
352+
emptyMenuExpanded = false
353+
onSettingsOpen()
354+
}
355+
)
356+
DropdownMenuItem(
357+
text = { Text(t("Help")) },
358+
onClick = {
359+
emptyMenuExpanded = false
360+
onHelpOpen()
361+
}
362+
)
315363
}
316364
}
317365
}

android/app/src/main/kotlin/dev/paperback/mobile/ui/MainScreenViewModel.kt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -973,4 +973,29 @@ class MainScreenViewModel(
973973
fun setShowPermissionRationale(show: Boolean) {
974974
_showPermissionRationale.value = show
975975
}
976+
977+
fun openHelpDocument() {
978+
val lang = java.util.Locale.getDefault().language
979+
val assetName = when (lang) {
980+
"bs", "cs", "fi", "nl", "pl", "sr" -> "readmes/readme-$lang.html"
981+
else -> "readmes/readme.html"
982+
}
983+
viewModelScope.launch(Dispatchers.IO) {
984+
try {
985+
val tempFile = File(context.cacheDir, "readme-$lang.html")
986+
context.assets.open(assetName).use { input ->
987+
FileOutputStream(tempFile).use { output ->
988+
input.copyTo(output)
989+
}
990+
}
991+
withContext(Dispatchers.Main) {
992+
openDocument(Uri.fromFile(tempFile))
993+
}
994+
} catch (e: Exception) {
995+
withContext(Dispatchers.Main) {
996+
android.widget.Toast.makeText(context, dev.paperback.mobile.t("Failed to load document."), android.widget.Toast.LENGTH_LONG).show()
997+
}
998+
}
999+
}
1000+
}
9761001
}

crates/paperback-core/src/parser/mobi.rs

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ impl Parser for MobiParser {
267267
if content.len() > MAX_MOBI_TEXT_BYTES {
268268
content.truncate(MAX_MOBI_TEXT_BYTES);
269269
}
270-
let mut text = if text_encoding == 65001 {
270+
let text = if text_encoding == 65001 {
271271
String::from_utf8_lossy(&content).into_owned()
272272
} else {
273273
WINDOWS_1252.decode(&content).0.into_owned()
@@ -522,8 +522,7 @@ fn build_fragment_offsets(
522522
pos = p;
523523
}
524524
if (control & 4) != 0 {
525-
let (fid, p) = decode_vwi(data_rec, pos);
526-
pos = p;
525+
let (fid, _) = decode_vwi(data_rec, pos);
527526
frag_offsets.insert(fid, insert_offset);
528527
}
529528
}
@@ -903,15 +902,6 @@ impl HuffmanDecoder {
903902
}
904903
}
905904
}
906-
while let Some(mut parent) = stack.pop() {
907-
let finished_out = current.out;
908-
if let Some(idx) = current.target_dict_index {
909-
self.dictionary[idx] = Some((finished_out.clone(), true));
910-
}
911-
parent.out.extend_from_slice(&finished_out);
912-
current = parent;
913-
}
914-
Ok(current.out)
915905
}
916906
}
917907

crates/xtask/src/android.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,46 @@ pub fn android() -> Result<(), Box<dyn Error>> {
8888
}
8989
}
9090

91+
let readmes_assets_dir = assets_dir.join("readmes");
92+
let _ = fs::create_dir_all(&readmes_assets_dir);
93+
let doc_dir = crate::project_root().join("doc");
94+
let pandoc_config = doc_dir.join("pandoc.yaml");
95+
if doc_dir.is_dir() {
96+
let default_readme = doc_dir.join("readme.md");
97+
if default_readme.exists() {
98+
let status = Command::new("pandoc")
99+
.arg(format!("--defaults={}", pandoc_config.display()))
100+
.arg(&default_readme)
101+
.arg("-o")
102+
.arg(readmes_assets_dir.join("readme.html"))
103+
.status();
104+
match status {
105+
Ok(s) if s.success() => {}
106+
_ => println!("Warning: Failed to generate default English documentation"),
107+
}
108+
}
109+
if let Ok(entries) = fs::read_dir(&doc_dir) {
110+
for entry in entries.flatten() {
111+
let path = entry.path();
112+
if let Some(name) = path.file_name().and_then(|n| n.to_str()) {
113+
if name.starts_with("readme-") && name.ends_with(".md") {
114+
let out_name = name.replace(".md", ".html");
115+
let status = Command::new("pandoc")
116+
.arg(format!("--defaults={}", pandoc_config.display()))
117+
.arg(&path)
118+
.arg("-o")
119+
.arg(readmes_assets_dir.join(out_name))
120+
.status();
121+
match status {
122+
Ok(s) if s.success() => {}
123+
_ => println!("Warning: Failed to generate documentation for language: {}", name),
124+
}
125+
}
126+
}
127+
}
128+
}
129+
}
130+
91131
if !gradle_tasks.is_empty() {
92132
println!("Running gradlew with tasks: {:?}", gradle_tasks);
93133
let android_dir = crate::project_root().join("android");

0 commit comments

Comments
 (0)