Offline dictionary (#45)

* Added support for external dictionary apps and a dictionary settings sheet.

* Refactored external dictionary integration and improved package visibility

 - Updated `AndroidManifest.xml` with `<queries>` for common dictionary apps and intent actions (`PROCESS_TEXT`, `SEARCH`, `SEND`) to support Android 11+ package visibility.
 - Refactored `ExternalDictionaryHelper` to streamline dictionary discovery using `Intent.ACTION_PROCESS_TEXT` and `colordict.intent.action.SEARCH`.
 - Added a package blocklist in `ExternalDictionaryHelper` to filter out system services (e.g., Samsung Pass, GMS) from dictionary lists.
  - Simplified `launchDictionary` logic to prioritize `PROCESS_TEXT` intents.
 - Fixed a bug in `PdfViewerScreen` to only show the dictionary upsell dialog when `useOnlineDictionary` is enabled.

* Refactored dictionary settings into a dialog and updated dictionary selection logic.

- Renamed `DictionarySettingsSheet` to `DictionarySettingsDialog` and converted it from a bottom sheet to a formal dialog.
- Redesigned the dictionary settings UI with a clearer distinction between AI and external app modes.
- Added a "Search" option to the external dictionary list that triggers a web search.
- Updated `ExternalDictionaryHelper` to include a package blocklist and support for generic web search intents.
- Simplified `PdfHelper` by removing Pro user checks for the "Dictionary" action.
- Updated icons for dictionary settings across the EPUB and PDF readers.
This commit is contained in:
Aryan 2026-03-08 15:19:52 +05:30 committed by GitHub
parent dff236fa7f
commit 76780bff31
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 759 additions and 171 deletions

View file

@ -1467,15 +1467,9 @@ internal fun PaginatedReaderContent(
if (isForDictionary) {
if (!text.isNullOrBlank()) {
if (isProUser || countWords(text) <= 1) {
if (text.length <= 2000) {
onWordSelectedForAiDefinition(text)
}
} else {
onShowDictionaryUpsellDialog()
}
onWordSelectedForAiDefinition(text)
}
} else if (isForHighlight) {
} else if (isForHighlight) {
// Do not copy to real clipboard
} else {
realClipboard.setClipEntry(clipEntry)
@ -3022,28 +3016,26 @@ private fun PaginatedTextSelectionMenu(
}
// 5. Dictionary Option
if (!isOss) {
HorizontalDivider()
Row(
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = onDictionary)
.padding(horizontal = 16.dp, vertical = 12.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
Icon(
painter = painterResource(id = R.drawable.dictionary),
contentDescription = null,
tint = MaterialTheme.colorScheme.onSurface,
modifier = Modifier.size(20.dp)
)
Text(
"Dictionary",
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurface
)
}
HorizontalDivider()
Row(
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = onDictionary)
.padding(horizontal = 16.dp, vertical = 12.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
Icon(
painter = painterResource(id = R.drawable.dictionary),
contentDescription = null,
tint = MaterialTheme.colorScheme.onSurface,
modifier = Modifier.size(20.dp)
)
Text(
"Dictionary",
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurface
)
}
}
}