* Implement build profiles and feature policy for offline desktop builds * Introduce unified cross-platform Settings Hub * Refactor main settings into a hierarchical page-based navigation model * Refactor library projection to use shared multiplatform logic * Refactor UI state consumption by removing intermediate screen models * Introduce AndroidSharedStateBridge to centralize state mapping and reduction logic * Refactor state management for tabs, selection, and pinning to use shared bridge logic * Refactor file type management and validation into a centralized shared module * Centralize file type resolution and improve handling of unknown types * Centralize book import logic with SharedImportPlanner * Refactor magnifier geometry logic and coordinate mapping * Properly handle orientation changes in scroll-locked PDF reader * Add screen orientation controls to EPUB and PDF readers * Implement right-to-left (RTL) pagination support and refactor reader menus * Separate right-to-left pagination settings for PDF and EPUB * Ensure PDF page data is scoped by document key for multi tab support * Implement theme-aware link styling for the epub reader * Implement jump history for back and forward navigation in the epub reader * Improve locator handling and navigation logic in paginated reader mode * Implement stable pagination navigation and location tracking * Centralize banner message management and auto-dismiss logic in MainViewModel * Implement zoom and pan state preservation for PDF pan lock mode * Enhance reader navigation UI and workspace layout management in desktop app * Refactor reader navigation sidebar and relocate search controls in desktop app * Enhance reader UI with redesigned selection menus and bottom sheet overlays * Implement custom highlight palettes and reader theme customization in desktop app * Implement cross-platform modal layer and refine reader UI styling * Improve highlight accuracy and implement metadata enrichment on book open in desktop app * Implement two-page spread layout for paginated reader on desktop * Implement persistent caching for book loading and pagination in desktop app * Implement persistent caching for book loading and pagination in desktop app * Optimize reader settings updates by separating layout and appearance changes in desktop app * Improve desktop window branding and native Windows styling * Enhance reader selection interactions and UI across EPUB and PDF viewers in desktop app * Refine selection handle positioning and interaction logic * Implement EPUB selection debug logging and improve handle targeting * Optimize desktop book loading performance and UI responsiveness * Implement anchored zoom gestures and rendering optimizations for the Desktop PDF viewer. * Implement smooth zoom preview for the PDF reader in desktop app * Optimize PDF rendering performance and responsiveness in the desktop reader * Implement conditional diagnostic logging and update desktop build configuration * Implemented hierarchical TOC, custom scrollbars, and improved desktop modal handling * Added management options for annotations and highlights in the sidebar in desktop app * Implemented `SharedStableOutlinedTextField` and updated text input fields to use `TextFieldValue` for improved cursor and selection stability. * Refined library filters and enhanced OPDS functionality in desktop app * Improved EPUB pagination measurement and implemented layout diagnostic logging for desktop app * Added PPTX support including document parsing, rendering, and indexing * Improved PPTX rendering and layout accuracy * Implemented text autofit support for PPTX rendering * Enhanced PPTX rendering with support for custom geometry, automatic numbering, table styles, and image opacity * Improved EPUB pagination accuracy and added layout telemetry in desktop app * Improved folder synchronization with metadata-only mode and hashed sidecar management in desktop app * Implemented rich text font scaling and migrated desktop ink tools to custom pointer input handling * Implemented billing account obfuscation * Implemented hierarchical folder navigation and improved library selection functionality in desktop app * Implemented platform-aware directory resolution and multi-platform native library support for desktop * Added full-screen mode for the reader workspace * Added PDF zoom indicator and interactive vertical scrollbar with page tooltips * Refactored speech bubble prefetching to use a limited radius and improved ML detector initialization and lifecycle management * Updated PDF indexing to replace existing page text and removed search result item keys * Implemented "preparing" foreground notification for TTS service * Optimized PDF rendering performance by pre-calculating page-specific annotations * Refactored desktop packaging tasks and improved distribution configuration * Optimized EPUB parser memory usage and added path traversal protection * Refactored WorkManager monitoring logic and added work pruning * Implemented comprehensive resource cleanup and memory management for WebView-based components to prevent memory leaks * Implemented bitmap size limits and scaling to prevent canvas rendering errors * Split long text paragraphs into multiple semantic blocks during HTML parsing * Implemented local ActionMode for text selection to prevent platform crashes * Refactored PPTX text layout, optimized HtmlParser block detection, and improved banner dismissal logic * Added desktop startup splash screen and deferred WebView initialization * Reorganized settings hub and added separate PDF reader defaults * Implemented embedded cover extraction and metadata support for MOBI and FB2 formats * Implemented batching for MetadataExtractionWorker and optimized EPUB metadata extraction performance. * Implemented procedurally generated book covers and replaced static placeholders * Redesigned search UI with a top bar and results overlay in desktop app * Added PDF page gap and overlay visibility options and implemented DesktopBookImporter * Refactored PDF reader UI with tabbed inspector and improved theme background handling in desktop * Implemented PDF viewport persistence for zoom and scroll positions in desktop app * Improved desktop fullscreen implementation and state restoration * Implemented desktop window state persistence * Implemented flavor-based branding and ProGuard configuration for desktop builds * Implemented precise reader positioning and improved highlight rendering logic in desktop app * Added support for user-editable book metadata * Enhanced book metadata support and integrated info/edit dialogs * Implemented embedded EPUB metadata editing * Improved highlight mapping and added custom scrollbar styling for the reader. * Reduced desktop WebView bundle size by excluding unused locales and runtime files * Added neutral pan mode as the default PDF interaction state. * Refactored library empty states and updated primary navigation tabs in desktop app * Implemented native paginated reader and unified content rendering architecture in desktop epub reader * Implemented native EPUB image rendering for desktop and improved block layout spacing with margin collapsing. * Improved pagination overflow detection in desktop * Implemented multi-block text selection with interactive handles and CFI support in desktop epub pagination
451 lines
21 KiB
Kotlin
451 lines
21 KiB
Kotlin
package com.aryan.reader.pdf
|
|
|
|
import android.content.Context
|
|
import androidx.compose.ui.geometry.Offset
|
|
import androidx.compose.ui.graphics.Color
|
|
import androidx.compose.ui.graphics.toArgb
|
|
import androidx.core.content.edit
|
|
import com.aryan.reader.BuildConfig
|
|
import com.aryan.reader.ReaderTheme
|
|
import com.aryan.reader.ReaderTexture
|
|
import com.aryan.reader.epubreader.SystemUiMode
|
|
|
|
internal const val VERTICAL_SCROLL_TAG = "PdfVerticalScroll"
|
|
internal const val SETTINGS_PREFS_NAME = "epub_reader_settings"
|
|
internal const val TTS_MODE_KEY = "tts_mode"
|
|
internal const val DISPLAY_MODE_KEY = "pdf_display_mode"
|
|
internal const val PDF_DARK_MODE_KEY = "pdf_dark_mode"
|
|
internal const val OCR_LANGUAGE_KEY = "ocr_language_key"
|
|
internal const val OCR_LANGUAGE_SELECTED_KEY = "ocr_language_selected_key"
|
|
internal const val DOCK_LOCATION_KEY = "dock_location"
|
|
internal const val DOCK_OFFSET_X_KEY = "dock_offset_x"
|
|
internal const val DOCK_OFFSET_Y_KEY = "dock_offset_y"
|
|
internal const val PDF_AUTO_SCROLL_SPEED_KEY = "pdf_auto_scroll_speed"
|
|
internal const val PDF_AUTO_SCROLL_USE_SLIDER_KEY = "pdf_auto_scroll_use_slider"
|
|
internal const val PDF_AUTO_SCROLL_MIN_SPEED_KEY = "pdf_auto_scroll_min_speed"
|
|
internal const val PDF_AUTO_SCROLL_MAX_SPEED_KEY = "pdf_auto_scroll_max_speed"
|
|
internal const val STYLUS_ONLY_MODE_KEY = "stylus_only_mode"
|
|
|
|
private const val PDF_AUTO_SCROLL_IS_LOCAL_PREFIX = "pdf_as_local_"
|
|
private const val PDF_AUTO_SCROLL_LOCAL_SPEED_PREFIX = "pdf_as_local_speed_"
|
|
private const val PDF_AUTO_SCROLL_LOCAL_MIN_PREFIX = "pdf_as_local_min_"
|
|
private const val PDF_AUTO_SCROLL_LOCAL_MAX_PREFIX = "pdf_as_local_max_"
|
|
private const val PDF_SCROLL_LOCKED_PREFIX = "pdf_sl_local_"
|
|
internal const val PDF_FULL_SCREEN_PREFIX = "pdf_fs_local_"
|
|
private const val PDF_MUSICIAN_MODE_KEY = "pdf_musician_mode_enabled"
|
|
private const val PREF_USE_ONLINE_DICT = "use_online_dictionary"
|
|
private const val PREF_EXTERNAL_DICT_PKG = "external_dictionary_package"
|
|
private const val PREF_EXTERNAL_TRANSLATE_PKG = "external_translate_package"
|
|
private const val PREF_EXTERNAL_SEARCH_PKG = "external_search_package"
|
|
private const val PDF_THEME_KEY = "pdf_reader_theme"
|
|
private const val PDF_KEEP_SCREEN_ON_KEY = "pdf_keep_screen_on_enabled"
|
|
internal const val PDF_HIDDEN_TOOLS_KEY = "pdf_hidden_tools"
|
|
internal const val PDF_TOOL_ORDER_KEY = "pdf_tool_order"
|
|
internal const val PDF_BOTTOM_TOOLS_KEY = "pdf_bottom_tools"
|
|
internal const val PDF_SYSTEM_UI_MODE_KEY = "pdf_system_ui_mode"
|
|
internal const val PDF_VERTICAL_PAGE_GAP_VISIBLE_KEY = "pdf_vertical_page_gap_visible"
|
|
internal const val PDF_PAGE_NUMBER_OVERLAY_VISIBLE_KEY = "pdf_page_number_overlay_visible"
|
|
internal const val PDF_LAYOUT_DEBUG_TAG = "PdfLayoutDebug"
|
|
private const val PDF_HIDDEN_TOOLS_DEFAULTS_VERSION_KEY = "pdf_hidden_tools_defaults_version"
|
|
private const val PDF_HIDDEN_TOOLS_DEFAULTS_VERSION = 2
|
|
|
|
enum class PdfReaderTool(val title: String, val category: String) {
|
|
DICTIONARY("External Apps", "Top Bar"),
|
|
THEME("Theme Settings", "Top Bar"),
|
|
LOCK_PANNING("Lock Panning", "Top Bar"),
|
|
VISUAL_OPTIONS("Visual Options", "Overflow Menu"),
|
|
TAP_TO_TURN("Tap to Turn Pages", "Overflow Menu"),
|
|
FULL_SCREEN("Full Screen", "Top Bar"),
|
|
SLIDER("Navigation Slider", "Bottom Bar"),
|
|
TOC("Sidebar", "Bottom Bar"),
|
|
SEARCH("Search", "Bottom Bar"),
|
|
HIGHLIGHT_ALL("Highlight selectable text", "Bottom Bar"),
|
|
AI_FEATURES("AI Features", "Bottom Bar"),
|
|
EDIT_MODE("Edit Mode", "Bottom Bar"),
|
|
TTS_CONTROLS("TTS Controls", "Bottom Bar"),
|
|
OCR_LANGUAGE("OCR Language", "Overflow Menu"),
|
|
READING_MODE("Reading Mode", "Overflow Menu"),
|
|
KEEP_SCREEN_ON("Keep Screen On", "Overflow Menu"),
|
|
SCREEN_ORIENTATION("Screen Orientation", "Top Bar"),
|
|
AUTO_SCROLL("Auto Scroll", "Overflow Menu"),
|
|
TTS_SETTINGS("TTS Settings", "Overflow Menu"),
|
|
TTS_REPLACEMENTS("TTS Word Replacements", "Overflow Menu"),
|
|
BOOKMARK("Bookmark", "Overflow Menu"),
|
|
PAGE_MANAGEMENT("Page Management", "Overflow Menu"),
|
|
REFLOW("Text View (Reflow)", "Overflow Menu"),
|
|
SHARE("Share", "Overflow Menu"),
|
|
SAVE_COPY("Save Copy", "Overflow Menu"),
|
|
PRINT("Print", "Overflow Menu")
|
|
}
|
|
|
|
val PdfBuiltInThemes = listOf(
|
|
ReaderTheme("no_theme", "No Theme", Color.Unspecified, Color.Unspecified, false),
|
|
ReaderTheme("reverse", "Reverse", Color.Black, Color.White, true),
|
|
ReaderTheme("light", "Light", Color(0xFFFFFFFF), Color(0xFF000000), false),
|
|
ReaderTheme("dark", "Dark", Color(0xFF121212), Color(0xFFE0E0E0), true),
|
|
ReaderTheme("sepia", "Sepia", Color(0xFFFBF0D9), Color(0xFF5F4B32), false),
|
|
ReaderTheme("slate", "Slate", Color(0xFF2E3440), Color(0xFFECEFF4), true),
|
|
ReaderTheme("oled", "OLED", Color(0xFF000000), Color(0xFFB0B0B0), true),
|
|
ReaderTheme("pdf_natural_white_texture", "Natural White", Color(0xFFF7F1E5), Color(0xFF1D1B18), false, textureId = ReaderTexture.NATURAL_WHITE.id),
|
|
ReaderTheme("pdf_retina_texture", "Retina", Color(0xFFF1E4CD), Color(0xFF2A2119), false, textureId = ReaderTexture.RETINA_WOOD.id),
|
|
ReaderTheme("pdf_veneer_texture", "Veneer", Color(0xFFF4E7CF), Color(0xFF2A2119), false, textureId = ReaderTexture.LIGHT_VENEER.id),
|
|
ReaderTheme("pdf_grey_wash_texture", "Grey Wash", Color(0xFF202124), Color(0xFFFFFFFF), true, textureId = ReaderTexture.GREY_WASH.id),
|
|
ReaderTheme("pdf_fabric_texture", "Fabric", Color(0xFF262626), Color(0xFFE8E2D8), true, textureId = ReaderTexture.CLASSY_FABRIC.id),
|
|
ReaderTheme("pdf_retro_texture", "Retro", Color(0xFFF6ECD8), Color(0xFF2F2118), false, textureId = ReaderTexture.RETRO_INTRO.id)
|
|
)
|
|
|
|
internal fun loadPdfHiddenTools(context: Context): Set<String> {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
val savedHiddenTools = prefs.getStringSet(PDF_HIDDEN_TOOLS_KEY, emptySet()).orEmpty()
|
|
val defaultsVersion = prefs.getInt(PDF_HIDDEN_TOOLS_DEFAULTS_VERSION_KEY, 0)
|
|
if (defaultsVersion < PDF_HIDDEN_TOOLS_DEFAULTS_VERSION) {
|
|
val migratedHiddenTools = savedHiddenTools + setOf(
|
|
PdfReaderTool.SCREEN_ORIENTATION.name,
|
|
PdfReaderTool.HIGHLIGHT_ALL.name
|
|
)
|
|
prefs.edit {
|
|
putStringSet(PDF_HIDDEN_TOOLS_KEY, migratedHiddenTools)
|
|
putInt(PDF_HIDDEN_TOOLS_DEFAULTS_VERSION_KEY, PDF_HIDDEN_TOOLS_DEFAULTS_VERSION)
|
|
}
|
|
return migratedHiddenTools
|
|
}
|
|
return savedHiddenTools
|
|
}
|
|
|
|
internal fun savePdfHiddenTools(context: Context, hiddenTools: Set<String>) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit {
|
|
putStringSet(PDF_HIDDEN_TOOLS_KEY, hiddenTools)
|
|
putInt(PDF_HIDDEN_TOOLS_DEFAULTS_VERSION_KEY, PDF_HIDDEN_TOOLS_DEFAULTS_VERSION)
|
|
}
|
|
}
|
|
|
|
internal fun loadPdfToolOrder(context: Context): List<PdfReaderTool> {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
val savedTools = prefs.getString(PDF_TOOL_ORDER_KEY, null)
|
|
?.split(',')
|
|
?.filter { it.isNotBlank() }
|
|
?.mapNotNull { name -> PdfReaderTool.entries.firstOrNull { it.name == name } }
|
|
.orEmpty()
|
|
return (savedTools + PdfReaderTool.entries.filterNot { it in savedTools }).distinct()
|
|
}
|
|
|
|
internal fun savePdfToolOrder(context: Context, toolOrder: List<PdfReaderTool>) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit { putString(PDF_TOOL_ORDER_KEY, toolOrder.joinToString(",") { it.name }) }
|
|
}
|
|
|
|
internal fun loadPdfBottomTools(context: Context): Set<String> {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
val defaultBottomTools = PdfReaderTool.entries.filter { it.category == "Bottom Bar" }.map { it.name }.toSet()
|
|
return prefs.getStringSet(PDF_BOTTOM_TOOLS_KEY, defaultBottomTools) ?: defaultBottomTools
|
|
}
|
|
|
|
internal fun savePdfBottomTools(context: Context, bottomTools: Set<String>) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit { putStringSet(PDF_BOTTOM_TOOLS_KEY, bottomTools) }
|
|
}
|
|
|
|
internal fun loadCustomHighlightColors(context: Context): Map<PdfHighlightColor, Color> {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
return PdfHighlightColor.entries.associateWith {
|
|
val defaultArgb = it.color.toArgb()
|
|
val savedArgb = prefs.getInt("custom_highlight_${it.name}", defaultArgb)
|
|
Color(savedArgb)
|
|
}
|
|
}
|
|
|
|
internal fun saveCustomHighlightColors(context: Context, colors: Map<PdfHighlightColor, Color>) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit {
|
|
colors.forEach { (colorEnum, color) ->
|
|
putInt("custom_highlight_${colorEnum.name}", color.toArgb())
|
|
}
|
|
}
|
|
}
|
|
|
|
internal fun saveKeepScreenOn(context: Context, isEnabled: Boolean) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit { putBoolean(PDF_KEEP_SCREEN_ON_KEY, isEnabled) }
|
|
}
|
|
|
|
internal fun loadKeepScreenOn(context: Context): Boolean {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
return prefs.getBoolean(PDF_KEEP_SCREEN_ON_KEY, false)
|
|
}
|
|
|
|
internal fun savePdfSystemUiMode(context: Context, mode: SystemUiMode) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit { putInt(PDF_SYSTEM_UI_MODE_KEY, mode.id) }
|
|
}
|
|
|
|
internal fun loadPdfSystemUiMode(context: Context): SystemUiMode {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
val id = prefs.getInt(PDF_SYSTEM_UI_MODE_KEY, SystemUiMode.SYNC.id)
|
|
return SystemUiMode.entries.find { it.id == id } ?: SystemUiMode.SYNC
|
|
}
|
|
|
|
internal fun savePdfVerticalPageGapVisible(context: Context, isVisible: Boolean) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit { putBoolean(PDF_VERTICAL_PAGE_GAP_VISIBLE_KEY, isVisible) }
|
|
}
|
|
|
|
internal fun loadPdfVerticalPageGapVisible(context: Context): Boolean {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
return prefs.getBoolean(PDF_VERTICAL_PAGE_GAP_VISIBLE_KEY, true)
|
|
}
|
|
|
|
internal fun savePdfPageNumberOverlayVisible(context: Context, isVisible: Boolean) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit { putBoolean(PDF_PAGE_NUMBER_OVERLAY_VISIBLE_KEY, isVisible) }
|
|
}
|
|
|
|
internal fun loadPdfPageNumberOverlayVisible(context: Context): Boolean {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
return prefs.getBoolean(PDF_PAGE_NUMBER_OVERLAY_VISIBLE_KEY, true)
|
|
}
|
|
|
|
internal fun savePdfThemeId(context: Context, themeId: String) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit { putString(PDF_THEME_KEY, themeId) }
|
|
}
|
|
|
|
internal fun loadPdfThemeId(context: Context): String {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
return prefs.getString(PDF_THEME_KEY, "no_theme") ?: "no_theme"
|
|
}
|
|
|
|
internal fun loadUseOnlineDict(context: Context): Boolean {
|
|
@Suppress("KotlinConstantConditions") if (BuildConfig.FLAVOR == "oss" && BuildConfig.IS_OFFLINE) return false
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
return prefs.getBoolean(PREF_USE_ONLINE_DICT, true)
|
|
}
|
|
|
|
internal fun saveUseOnlineDict(context: Context, useOnline: Boolean) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit { putBoolean(PREF_USE_ONLINE_DICT, useOnline) }
|
|
}
|
|
|
|
internal fun loadExternalDictPackage(context: Context): String? {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
return prefs.getString(PREF_EXTERNAL_DICT_PKG, null)
|
|
}
|
|
|
|
internal fun saveExternalDictPackage(context: Context, packageName: String) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit { putString(PREF_EXTERNAL_DICT_PKG, packageName) }
|
|
}
|
|
|
|
internal fun loadExternalTranslatePackage(context: Context): String? {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
return prefs.getString(PREF_EXTERNAL_TRANSLATE_PKG, null)
|
|
}
|
|
|
|
internal fun saveExternalTranslatePackage(context: Context, packageName: String) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit { putString(PREF_EXTERNAL_TRANSLATE_PKG, packageName) }
|
|
}
|
|
|
|
internal fun loadExternalSearchPackage(context: Context): String? {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
return prefs.getString(PREF_EXTERNAL_SEARCH_PKG, null)
|
|
}
|
|
|
|
internal fun saveExternalSearchPackage(context: Context, packageName: String) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit { putString(PREF_EXTERNAL_SEARCH_PKG, packageName) }
|
|
}
|
|
|
|
internal fun savePdfMusicianMode(context: Context, isEnabled: Boolean) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit { putBoolean(PDF_MUSICIAN_MODE_KEY, isEnabled) }
|
|
}
|
|
|
|
internal fun loadPdfMusicianMode(context: Context): Boolean {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
return prefs.getBoolean(PDF_MUSICIAN_MODE_KEY, false)
|
|
}
|
|
|
|
internal fun savePdfScrollLocked(context: Context, bookId: String, isLocked: Boolean) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit { putBoolean(PDF_SCROLL_LOCKED_PREFIX + bookId, isLocked) }
|
|
}
|
|
|
|
internal fun loadPdfScrollLocked(context: Context, bookId: String): Boolean {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
return prefs.getBoolean(PDF_SCROLL_LOCKED_PREFIX + bookId, false)
|
|
}
|
|
|
|
internal fun savePdfAutoScrollLocalMode(context: Context, bookId: String, isLocal: Boolean) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit { putBoolean(PDF_AUTO_SCROLL_IS_LOCAL_PREFIX + bookId, isLocal) }
|
|
}
|
|
|
|
internal fun loadPdfAutoScrollLocalMode(context: Context, bookId: String): Boolean {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
return prefs.getBoolean(PDF_AUTO_SCROLL_IS_LOCAL_PREFIX + bookId, false)
|
|
}
|
|
|
|
internal fun savePdfAutoScrollLocalSettings(context: Context, bookId: String, speed: Float, min: Float, max: Float) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit {
|
|
putFloat(PDF_AUTO_SCROLL_LOCAL_SPEED_PREFIX + bookId, speed)
|
|
putFloat(PDF_AUTO_SCROLL_LOCAL_MIN_PREFIX + bookId, min)
|
|
putFloat(PDF_AUTO_SCROLL_LOCAL_MAX_PREFIX + bookId, max)
|
|
}
|
|
}
|
|
|
|
internal fun loadPdfAutoScrollLocalSettings(context: Context, bookId: String): Triple<Float, Float, Float>? {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
if (!prefs.contains(PDF_AUTO_SCROLL_LOCAL_SPEED_PREFIX + bookId)) return null
|
|
|
|
val speed = prefs.getFloat(PDF_AUTO_SCROLL_LOCAL_SPEED_PREFIX + bookId, 3.0f)
|
|
val min = prefs.getFloat(PDF_AUTO_SCROLL_LOCAL_MIN_PREFIX + bookId, 0.1f)
|
|
val max = prefs.getFloat(PDF_AUTO_SCROLL_LOCAL_MAX_PREFIX + bookId, 10.0f)
|
|
return Triple(speed, min, max)
|
|
}
|
|
|
|
internal fun savePdfAutoScrollMinSpeed(context: Context, speed: Float) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit { putFloat(PDF_AUTO_SCROLL_MIN_SPEED_KEY, speed) }
|
|
}
|
|
|
|
internal fun saveStylusOnlyMode(context: Context, isEnabled: Boolean) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit { putBoolean(STYLUS_ONLY_MODE_KEY, isEnabled) }
|
|
}
|
|
|
|
internal fun loadStylusOnlyMode(context: Context): Boolean {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
return prefs.getBoolean(STYLUS_ONLY_MODE_KEY, false)
|
|
}
|
|
|
|
internal fun loadPdfAutoScrollMinSpeed(context: Context): Float {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
return prefs.getFloat(PDF_AUTO_SCROLL_MIN_SPEED_KEY, 0.1f)
|
|
}
|
|
|
|
internal fun savePdfAutoScrollMaxSpeed(context: Context, speed: Float) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit { putFloat(PDF_AUTO_SCROLL_MAX_SPEED_KEY, speed) }
|
|
}
|
|
|
|
internal fun loadPdfAutoScrollMaxSpeed(context: Context): Float {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
return prefs.getFloat(PDF_AUTO_SCROLL_MAX_SPEED_KEY, 10.0f)
|
|
}
|
|
|
|
internal fun savePdfAutoScrollUseSlider(context: Context, useSlider: Boolean) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit { putBoolean(PDF_AUTO_SCROLL_USE_SLIDER_KEY, useSlider) }
|
|
}
|
|
|
|
internal fun loadPdfAutoScrollUseSlider(context: Context): Boolean {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
return prefs.getBoolean(PDF_AUTO_SCROLL_USE_SLIDER_KEY, false)
|
|
}
|
|
|
|
internal fun savePdfAutoScrollSpeed(context: Context, speed: Float) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit { putFloat(PDF_AUTO_SCROLL_SPEED_KEY, speed) }
|
|
}
|
|
|
|
internal fun loadPdfAutoScrollSpeed(context: Context): Float {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
return prefs.getFloat(PDF_AUTO_SCROLL_SPEED_KEY, 3.0f)
|
|
}
|
|
|
|
internal fun savePdfLockedState(context: Context, bookId: String, scale: Float, offsetX: Float, offsetY: Float) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit {
|
|
putFloat("pdf_locked_scale_$bookId", scale)
|
|
putFloat("pdf_locked_offset_x_$bookId", offsetX)
|
|
putFloat("pdf_locked_offset_y_$bookId", offsetY)
|
|
}
|
|
}
|
|
|
|
internal fun loadPdfLockedState(context: Context, bookId: String): Triple<Float, Float, Float>? {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
if (!prefs.contains("pdf_locked_scale_$bookId")) return null
|
|
return Triple(
|
|
prefs.getFloat("pdf_locked_scale_$bookId", 1f),
|
|
prefs.getFloat("pdf_locked_offset_x_$bookId", 0f),
|
|
prefs.getFloat("pdf_locked_offset_y_$bookId", 0f)
|
|
)
|
|
}
|
|
|
|
internal fun saveOcrLanguage(context: Context, language: OcrLanguage) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit {
|
|
putString(OCR_LANGUAGE_KEY, language.name)
|
|
putBoolean(OCR_LANGUAGE_SELECTED_KEY, true)
|
|
}
|
|
}
|
|
|
|
internal fun loadOcrLanguage(context: Context): OcrLanguage {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
val name = prefs.getString(OCR_LANGUAGE_KEY, OcrLanguage.LATIN.name)
|
|
return try {
|
|
OcrLanguage.valueOf(name ?: OcrLanguage.LATIN.name)
|
|
} catch (_: Exception) {
|
|
OcrLanguage.LATIN
|
|
}
|
|
}
|
|
|
|
internal fun hasUserSelectedOcrLanguage(context: Context): Boolean {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
return prefs.getBoolean(OCR_LANGUAGE_SELECTED_KEY, false)
|
|
}
|
|
|
|
internal fun saveDockState(context: Context, location: DockLocation, offset: Offset) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit {
|
|
putString(DOCK_LOCATION_KEY, location.name)
|
|
putFloat(DOCK_OFFSET_X_KEY, offset.x)
|
|
putFloat(DOCK_OFFSET_Y_KEY, offset.y)
|
|
}
|
|
}
|
|
|
|
internal fun loadDockState(context: Context): Pair<DockLocation, Offset> {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
val locName = prefs.getString(DOCK_LOCATION_KEY, DockLocation.BOTTOM.name)
|
|
val location = try {
|
|
DockLocation.valueOf(locName ?: DockLocation.BOTTOM.name)
|
|
} catch (_: Exception) {
|
|
DockLocation.BOTTOM
|
|
}
|
|
|
|
val x = prefs.getFloat(DOCK_OFFSET_X_KEY, 0f)
|
|
val y = prefs.getFloat(DOCK_OFFSET_Y_KEY, 0f)
|
|
|
|
return location to Offset(x, y)
|
|
}
|
|
|
|
internal fun saveDisplayMode(context: Context, mode: DisplayMode) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit { putString(DISPLAY_MODE_KEY, mode.name) }
|
|
}
|
|
|
|
internal fun loadDisplayMode(context: Context): DisplayMode {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
val modeName = prefs.getString(DISPLAY_MODE_KEY, DisplayMode.VERTICAL_SCROLL.name)
|
|
return try {
|
|
DisplayMode.valueOf(modeName ?: DisplayMode.VERTICAL_SCROLL.name)
|
|
} catch (_: IllegalArgumentException) {
|
|
DisplayMode.VERTICAL_SCROLL
|
|
}
|
|
}
|
|
|
|
internal data class TtsPageData(
|
|
val pageIndex: Int, val processedText: ProcessedText, val fromOcr: Boolean
|
|
)
|
|
|
|
internal fun savePdfDarkMode(context: Context, isDark: Boolean) {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
prefs.edit { putBoolean(PDF_DARK_MODE_KEY, isDark) }
|
|
}
|
|
|
|
internal fun loadPdfDarkMode(context: Context): Boolean {
|
|
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
|
return prefs.getBoolean(PDF_DARK_MODE_KEY, false)
|
|
}
|