General improvements (#151)

* Updated folder synchronization logic and redesigned the file type filter dialog.

* Fixed CFI generation and navigation stability in the EPUB reader.

* Improved CFI scrolling and position calculation in the EPUB reader by implementing text node traversal using `TreeWalker`. This ensures accurate positioning and scrolling when a CFI offset spans multiple fragmented text nodes.

* fix fb2 multiline titles, retain footnotes, and prevent stream leaks

- Fix FB2 titles with multiple paragraphs by inserting breaks/spaces
- Prevent resource leaks by properly closing InputStreams in all importers
- Retain "notes" and "comments" sections in FB2 instead of skipping them
- Add support for FB2 poem, stanza, cite, and link tags

* Implement persistence for zoom and pan states when pan lock is enabled in the PDF reader.

* Added `FileTypeBadge` to home and library screens

* Bump version to 1.0.41(42)
This commit is contained in:
Aryan 2026-04-05 10:36:44 +05:30 committed by GitHub
parent 65e0570d0e
commit 26692d2c05
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 747 additions and 664 deletions

View file

@ -1404,13 +1404,25 @@ private fun LibraryListItem(
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
item.progressPercentage?.let {
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "${it.toInt()}% complete",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.primary
)
Spacer(modifier = Modifier.height(8.dp))
Row(verticalAlignment = Alignment.CenterVertically) {
FileTypeBadge(type = item.type, overlay = false)
item.progressPercentage?.let {
Spacer(modifier = Modifier.width(8.dp))
Text(
text = "",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Spacer(modifier = Modifier.width(8.dp))
Text(
text = "${it.toInt()}% complete",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.primary
)
}
}
}
}
@ -1743,6 +1755,7 @@ private fun FolderCard(
}
}
@OptIn(androidx.compose.foundation.layout.ExperimentalLayoutApi::class)
@Composable
private fun EditFolderFiltersDialog(
folder: SyncedFolder,
@ -1753,44 +1766,74 @@ private fun EditFolderFiltersDialog(
AlertDialog(
onDismissRequest = onDismiss,
title = { Text(stringResource(R.string.filter_file_types)) },
text = {
title = {
Column {
Text(
stringResource(R.string.filter_file_types_desc),
style = MaterialTheme.typography.bodyMedium
text = stringResource(R.string.filter_file_types),
style = MaterialTheme.typography.headlineSmall,
fontWeight = FontWeight.Bold
)
Spacer(modifier = Modifier.height(8.dp))
FileType.entries.forEach { type ->
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.clickable {
selectedTypes = if (type in selectedTypes) selectedTypes - type else selectedTypes + type
}
.padding(vertical = 4.dp)
) {
androidx.compose.material3.Checkbox(
checked = type in selectedTypes,
onCheckedChange = { checked ->
selectedTypes = if (checked) selectedTypes + type else selectedTypes - type
}
Text(
text = stringResource(R.string.filter_file_types_desc),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
},
text = {
Column(modifier = Modifier.fillMaxWidth()) {
HorizontalDivider(modifier = Modifier.padding(bottom = 16.dp))
androidx.compose.foundation.layout.FlowRow(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
FileType.entries.forEach { type ->
val isSelected = type in selectedTypes
FilterChip(
selected = isSelected,
onClick = {
selectedTypes = if (isSelected) {
selectedTypes - type
} else {
selectedTypes + type
}
},
label = {
Text(
text = type.name,
style = MaterialTheme.typography.labelLarge
)
},
leadingIcon = if (isSelected) {
{
Icon(
imageVector = Icons.Default.Check,
contentDescription = null,
modifier = Modifier.size(16.dp)
)
}
} else null,
shape = MaterialTheme.shapes.medium
)
Spacer(modifier = Modifier.width(8.dp))
Text(type.name)
}
}
}
},
confirmButton = {
TextButton(
androidx.compose.material3.Button(
onClick = { onConfirm(selectedTypes) },
enabled = selectedTypes.isNotEmpty()
) { Text(stringResource(R.string.action_save)) }
enabled = selectedTypes.isNotEmpty(),
shape = MaterialTheme.shapes.medium
) {
Text(stringResource(R.string.action_save))
}
},
dismissButton = {
TextButton(onClick = onDismiss) { Text(stringResource(R.string.action_cancel)) }
TextButton(onClick = onDismiss) {
Text(stringResource(R.string.action_cancel))
}
}
)
}