v1.0.47 (#279)
* Add performance and stylus debugging logs * Refactor and decouple UI models from `MainViewModel` * Refactor library state management and projection logic * Implement desktop shell using Compose Multiplatform * Implement desktop shell using Compose Multiplatform * Implement desktop shell using Compose Multiplatform * Introduce ReaderEngine and enhance EPUB reader features in windows app * Move core paginated reader logic to a Kotlin Multiplatform `shared` module and introduce experimental desktop support. * Implement PDF rendering and text extraction for desktop using Pdfium * Add `NonReaderScreens.kt` and UI dependencies * Refactor and centralize library state management and models to improve cross-platform consistency * Implement JSON persistence for desktop library and enhance library management features including shelf CRUD, tagging, and metadata editing * Implement PDF annotation system and enhanced zoom controls for the desktop viewer * Implement WebView-based EPUB rendering for desktop using CEF and embedded resources * Optimize UI state projection, navigation state handling, and main screen pager performance * Implement Bring Your Own Key (BYOK) support for AI features in OSS version * Support Gemini-based Cloud TTS with BYOK support for OSS builds * Refactor table cell image sizing in `PaginatedReader` and improve `MobiParser` native library loading and error handling. * crash fixes * Enhance navigation stability with lifecycle-aware safety checks and update `navigation-compose` to 2.9.6 * Implement dynamic bottom padding for the page info bar to account for device rounded corners * Implement bidirectional jump history navigation and replace the jump-back pill with a dedicated `PdfJumpHistoryBar` * Optimize PDF tiling performance and refine pan-and-fling gesture handling * Implement customizable toolbars with drag-and-drop reordering and placement for PDF and EPUB readers * Updated UI for customize toolbar * Refine drag-and-drop reordering and section assignment for PDF and EPUB reader controls * restructure PDF viewer UI component hierarchy to fix verifier crash * Implement separate text dimming factors for light and dark themes * Synchronize Pdfium access and improve resource lifecycle safety across Kotlin and native layers * Enhance image alignment in paginated and EPUB readers through anchor detection and style-based positioning * Centralize file type resolution logic and implement HTML sanitization during import * Introduce vertical margin customization and configurable progress bar positioning * texture support in epub reader * Enhance TTS session management, progress tracking, and diagnostic logging * Optimize library state projection and folder synchronization performance by refactoring collection lookups and refining metadata extraction logic. * Refine TTS page mapping for PDF and overhaul TTS control UI * Implement natural session completion logic in `TtsPlaybackManager` for cloud tts * Replace Snackbar with `CustomTopBanner` for notifications in `PdfViewerScreen` * Refine TTS playback continuity across PDF pages and improve state management for session transitions * Implement global texture transparency and enhance textured theme support across PDF and EPUB readers. * Update reader themes and improve texture rendering in page animations, EPUB UI, and immersive mode * Add Support Project screen * Optimize library performance via projection caching, batch database updates, and scoped folder synchronization. * Enhance folder synchronization with fallback query mechanisms and refactor annotation sidecar importing logic * Bump version to 1.0.47 (51)
This commit is contained in:
parent
f42de6b462
commit
d7a9cae9e1
126 changed files with 15287 additions and 3154 deletions
|
|
@ -120,6 +120,7 @@ private const val TAP_TO_NAVIGATE_ENABLED_KEY = "tap_to_navigate_enabled"
|
|||
private const val VOLUME_SCROLL_ENABLED_KEY = "volume_scroll_enabled"
|
||||
private const val SYSTEM_UI_MODE_KEY = "reader_system_ui_mode"
|
||||
private const val PAGE_INFO_MODE_KEY = "reader_page_info_mode"
|
||||
private const val PAGE_INFO_POSITION_KEY = "reader_page_info_position"
|
||||
private const val PULL_TO_TURN_ENABLED_KEY = "reader_pull_to_turn_enabled"
|
||||
|
||||
const val DEFAULT_FONT_SIZE_VAL = 1.0f
|
||||
|
|
@ -127,6 +128,7 @@ const val DEFAULT_LINE_HEIGHT_VAL = 1.0f
|
|||
const val DEFAULT_PARAGRAPH_GAP_VAL = 1.0f
|
||||
const val DEFAULT_IMAGE_SIZE_VAL = 1.0f
|
||||
const val DEFAULT_HORIZONTAL_MARGIN_VAL = 1.0f
|
||||
const val DEFAULT_VERTICAL_MARGIN_VAL = 1.0f
|
||||
private const val TTS_SPEECH_RATE_KEY = "tts_speech_rate"
|
||||
private const val TTS_PITCH_KEY = "tts_pitch"
|
||||
|
||||
|
|
@ -177,12 +179,18 @@ enum class PageInfoMode(val id: Int, val title: String) {
|
|||
HIDDEN(2, "Always Hide")
|
||||
}
|
||||
|
||||
enum class PageInfoPosition(val id: Int, val title: String) {
|
||||
BOTTOM(0, "Bottom"),
|
||||
TOP(1, "Top")
|
||||
}
|
||||
|
||||
data class FormatSettings(
|
||||
val fontSize: Float,
|
||||
val lineHeight: Float,
|
||||
val paragraphGap: Float,
|
||||
val imageSize: Float,
|
||||
val horizontalMargin: Float,
|
||||
val verticalMargin: Float,
|
||||
val font: ReaderFont,
|
||||
val customPath: String?,
|
||||
val textAlign: ReaderTextAlign
|
||||
|
|
@ -194,9 +202,11 @@ private const val LOCAL_LINE_HEIGHT_PREFIX = "local_line_height_"
|
|||
private const val LOCAL_PARAGRAPH_GAP_PREFIX = "local_paragraph_gap_"
|
||||
private const val LOCAL_IMAGE_SIZE_PREFIX = "local_image_size_"
|
||||
private const val LOCAL_HORIZONTAL_MARGIN_PREFIX = "local_horizontal_margin_"
|
||||
private const val LOCAL_VERTICAL_MARGIN_PREFIX = "local_vertical_margin_"
|
||||
private const val LOCAL_FONT_FAMILY_PREFIX = "local_font_family_"
|
||||
private const val LOCAL_TEXT_ALIGN_PREFIX = "local_text_align_"
|
||||
private const val HORIZONTAL_MARGIN_KEY = "reader_horizontal_margin"
|
||||
private const val VERTICAL_MARGIN_KEY = "reader_vertical_margin"
|
||||
|
||||
fun loadFormatIsLocal(context: Context, bookId: String): Boolean {
|
||||
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
||||
|
|
@ -216,6 +226,7 @@ fun saveLocalReaderSettings(
|
|||
paragraphGap: Float,
|
||||
imageSize: Float,
|
||||
horizontalMargin: Float,
|
||||
verticalMargin: Float,
|
||||
fontFamily: ReaderFont,
|
||||
customFontPath: String?,
|
||||
textAlign: ReaderTextAlign
|
||||
|
|
@ -227,6 +238,7 @@ fun saveLocalReaderSettings(
|
|||
putFloat(LOCAL_PARAGRAPH_GAP_PREFIX + bookId, paragraphGap)
|
||||
putFloat(LOCAL_IMAGE_SIZE_PREFIX + bookId, imageSize)
|
||||
putFloat(LOCAL_HORIZONTAL_MARGIN_PREFIX + bookId, horizontalMargin)
|
||||
putFloat(LOCAL_VERTICAL_MARGIN_PREFIX + bookId, verticalMargin)
|
||||
if (customFontPath != null) {
|
||||
putString(LOCAL_FONT_FAMILY_PREFIX + bookId, "custom|$customFontPath")
|
||||
} else {
|
||||
|
|
@ -258,6 +270,17 @@ fun loadPageInfoMode(context: Context): PageInfoMode {
|
|||
return PageInfoMode.entries.find { it.id == id } ?: PageInfoMode.DEFAULT
|
||||
}
|
||||
|
||||
fun savePageInfoPosition(context: Context, position: PageInfoPosition) {
|
||||
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
||||
prefs.edit { putInt(PAGE_INFO_POSITION_KEY, position.id) }
|
||||
}
|
||||
|
||||
fun loadPageInfoPosition(context: Context): PageInfoPosition {
|
||||
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
||||
val id = prefs.getInt(PAGE_INFO_POSITION_KEY, PageInfoPosition.BOTTOM.id)
|
||||
return PageInfoPosition.entries.find { it.id == id } ?: PageInfoPosition.BOTTOM
|
||||
}
|
||||
|
||||
fun savePullToTurn(context: Context, enabled: Boolean) {
|
||||
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
||||
prefs.edit { putBoolean(PULL_TO_TURN_ENABLED_KEY, enabled) }
|
||||
|
|
@ -288,6 +311,11 @@ fun loadHorizontalMargin(context: Context): Float {
|
|||
return if (loadRemoveEdgePadding(context)) 0f else DEFAULT_HORIZONTAL_MARGIN_VAL
|
||||
}
|
||||
|
||||
fun loadVerticalMargin(context: Context): Float {
|
||||
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
||||
return prefs.getFloat(VERTICAL_MARGIN_KEY, DEFAULT_VERTICAL_MARGIN_VAL)
|
||||
}
|
||||
|
||||
fun loadFormatSettings(context: Context, bookId: String, isLocal: Boolean): FormatSettings {
|
||||
val prefs = context.getSharedPreferences(SETTINGS_PREFS_NAME, Context.MODE_PRIVATE)
|
||||
|
||||
|
|
@ -321,6 +349,12 @@ fun loadFormatSettings(context: Context, bookId: String, isLocal: Boolean): Form
|
|||
loadHorizontalMargin(context)
|
||||
}
|
||||
|
||||
val verticalMargin = if (isLocal && prefs.contains(LOCAL_VERTICAL_MARGIN_PREFIX + bookId)) {
|
||||
prefs.getFloat(LOCAL_VERTICAL_MARGIN_PREFIX + bookId, DEFAULT_VERTICAL_MARGIN_VAL)
|
||||
} else {
|
||||
loadVerticalMargin(context)
|
||||
}
|
||||
|
||||
val savedFontVal = if (isLocal && prefs.contains(LOCAL_FONT_FAMILY_PREFIX + bookId)) {
|
||||
prefs.getString(LOCAL_FONT_FAMILY_PREFIX + bookId, ReaderFont.ORIGINAL.id) ?: ReaderFont.ORIGINAL.id
|
||||
} else {
|
||||
|
|
@ -346,6 +380,7 @@ fun loadFormatSettings(context: Context, bookId: String, isLocal: Boolean): Form
|
|||
paragraphGap = paragraphGap,
|
||||
imageSize = imageSize,
|
||||
horizontalMargin = horizontalMargin,
|
||||
verticalMargin = verticalMargin,
|
||||
font = font,
|
||||
customPath = customPath,
|
||||
textAlign = textAlign
|
||||
|
|
@ -390,6 +425,7 @@ fun saveReaderSettings(
|
|||
paragraphGap: Float,
|
||||
imageSize: Float,
|
||||
horizontalMargin: Float,
|
||||
verticalMargin: Float,
|
||||
fontFamily: ReaderFont,
|
||||
customFontPath: String?,
|
||||
textAlign: ReaderTextAlign
|
||||
|
|
@ -401,6 +437,7 @@ fun saveReaderSettings(
|
|||
putFloat(PARAGRAPH_GAP_KEY, paragraphGap)
|
||||
putFloat(IMAGE_SIZE_KEY, imageSize)
|
||||
putFloat(HORIZONTAL_MARGIN_KEY, horizontalMargin)
|
||||
putFloat(VERTICAL_MARGIN_KEY, verticalMargin)
|
||||
if (customFontPath != null) {
|
||||
putString(FONT_FAMILY_KEY, "custom|$customFontPath")
|
||||
} else {
|
||||
|
|
@ -454,6 +491,8 @@ fun ReaderTextFormatPanel(
|
|||
onImageSizeChange: (Float) -> Unit,
|
||||
currentHorizontalMargin: Float,
|
||||
onHorizontalMarginChange: (Float) -> Unit,
|
||||
currentVerticalMargin: Float,
|
||||
onVerticalMarginChange: (Float) -> Unit,
|
||||
currentFont: ReaderFont,
|
||||
currentCustomFontName: String?,
|
||||
onFontOptionClick: () -> Unit,
|
||||
|
|
@ -699,6 +738,20 @@ fun ReaderTextFormatPanel(
|
|||
}
|
||||
}
|
||||
)
|
||||
|
||||
FormatSlider(
|
||||
label = stringResource(R.string.label_vertical_margin),
|
||||
value = currentVerticalMargin,
|
||||
onValueChange = onVerticalMarginChange,
|
||||
valueRange = 0.0f..3.0f,
|
||||
formatValue = {
|
||||
when {
|
||||
it <= 0.01f -> noneLabel
|
||||
it in 0.99f..1.01f -> originalLabel
|
||||
else -> "%.1fx".format(it)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -830,6 +883,8 @@ fun VisualOptionsSheet(
|
|||
onSystemUiModeChange: (SystemUiMode) -> Unit,
|
||||
pageInfoMode: PageInfoMode,
|
||||
onPageInfoModeChange: (PageInfoMode) -> Unit,
|
||||
pageInfoPosition: PageInfoPosition,
|
||||
onPageInfoPositionChange: (PageInfoPosition) -> Unit,
|
||||
pullToTurnEnabled: Boolean,
|
||||
onPullToTurnChange: (Boolean) -> Unit,
|
||||
pullToTurnMultiplier: Float,
|
||||
|
|
@ -884,6 +939,16 @@ fun VisualOptionsSheet(
|
|||
getLabel = { it.title }
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Text(stringResource(R.string.visual_options_progress_bar_position), style = MaterialTheme.typography.titleSmall)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
OptionSegmentedControl(
|
||||
options = PageInfoPosition.entries,
|
||||
selectedOption = pageInfoPosition,
|
||||
onOptionSelected = onPageInfoPositionChange,
|
||||
getLabel = { it.title }
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
// Pull to change chapter
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue