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
|
|
@ -189,7 +189,7 @@
|
|||
window.VIEWPORT_PADDING_BOTTOM = bottom || 0;
|
||||
};
|
||||
|
||||
window.applyReaderTheme = function (isDark, bgHex, textHex, textureBase64) {
|
||||
window.applyReaderTheme = function (isDark, bgHex, textHex, textureBase64, textureAlpha) {
|
||||
var styleId = "readerThemeStyle";
|
||||
var themeStyleElement = document.getElementById(styleId);
|
||||
|
||||
|
|
@ -207,8 +207,14 @@
|
|||
var effectiveBg = bgHex || (isDark ? '#121212' : '#FFFFFF');
|
||||
var effectiveText = textHex || (isDark ? '#E0E0E0' : '#000000');
|
||||
|
||||
var effectiveTextureAlpha = Math.max(0, Math.min(1, textureAlpha == null ? 0.55 : textureAlpha));
|
||||
var bgMatch = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(effectiveBg);
|
||||
var bgRgb = bgMatch
|
||||
? `${parseInt(bgMatch[1], 16)}, ${parseInt(bgMatch[2], 16)}, ${parseInt(bgMatch[3], 16)}`
|
||||
: (isDark ? '18, 18, 18' : '255, 255, 255');
|
||||
|
||||
var textureCss = textureBase64
|
||||
? `background-image: url('${textureBase64}'); background-repeat: repeat; background-blend-mode: multiply;`
|
||||
? `background-image: linear-gradient(rgba(${bgRgb},${1 - effectiveTextureAlpha}), rgba(${bgRgb},${1 - effectiveTextureAlpha})), url('${textureBase64}'); background-repeat: repeat, repeat; background-blend-mode: normal, normal;`
|
||||
: 'background-image: none;';
|
||||
|
||||
var css = `
|
||||
|
|
@ -517,7 +523,65 @@
|
|||
}
|
||||
}, true);
|
||||
|
||||
window.updateReaderStyles = function (fontSizeEm, lineHeight, fontFamily, textAlign, paragraphGap, imageSize, horizontalMargin) {
|
||||
function getReaderImageElements() {
|
||||
return Array.prototype.slice.call(document.querySelectorAll("img, svg, video, canvas, image"));
|
||||
}
|
||||
|
||||
function rememberReaderImageAnchors() {
|
||||
getReaderImageElements().forEach(function (image) {
|
||||
if (image.getAttribute("data-reader-image-anchor")) return;
|
||||
|
||||
var parent = image.parentElement || document.body;
|
||||
var imageRect = image.getBoundingClientRect();
|
||||
var parentRect = parent.getBoundingClientRect();
|
||||
var parentWidth = parentRect.width || document.documentElement.clientWidth || window.innerWidth || 0;
|
||||
|
||||
if (!parentWidth || imageRect.width <= 0) {
|
||||
image.setAttribute("data-reader-image-anchor", "center");
|
||||
return;
|
||||
}
|
||||
|
||||
var imageCenter = imageRect.left + imageRect.width / 2;
|
||||
var parentCenter = parentRect.left + parentWidth / 2;
|
||||
var tolerance = Math.max(4, parentWidth * 0.08);
|
||||
var anchor = "center";
|
||||
|
||||
if (Math.abs(imageCenter - parentCenter) <= tolerance || imageRect.width >= parentWidth - 2) {
|
||||
anchor = "center";
|
||||
} else if (imageCenter > parentCenter) {
|
||||
anchor = "right";
|
||||
} else {
|
||||
anchor = "left";
|
||||
}
|
||||
|
||||
image.setAttribute("data-reader-image-anchor", anchor);
|
||||
});
|
||||
}
|
||||
|
||||
function applyReaderImageAnchors() {
|
||||
getReaderImageElements().forEach(function (image) {
|
||||
var anchor = image.getAttribute("data-reader-image-anchor") || "center";
|
||||
|
||||
image.style.setProperty("display", "block", "important");
|
||||
image.style.setProperty("height", "auto", "important");
|
||||
image.style.setProperty("object-fit", "contain", "important");
|
||||
|
||||
if (anchor === "right") {
|
||||
image.style.setProperty("float", "none", "important");
|
||||
image.style.setProperty("margin-left", "auto", "important");
|
||||
image.style.setProperty("margin-right", "0", "important");
|
||||
} else if (anchor === "left") {
|
||||
image.style.setProperty("margin-left", "0", "important");
|
||||
image.style.setProperty("margin-right", "auto", "important");
|
||||
} else {
|
||||
image.style.setProperty("float", "none", "important");
|
||||
image.style.setProperty("margin-left", "auto", "important");
|
||||
image.style.setProperty("margin-right", "auto", "important");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
window.updateReaderStyles = function (fontSizeEm, lineHeight, fontFamily, textAlign, paragraphGap, imageSize, horizontalMargin, verticalMargin) {
|
||||
var logTag = "ReaderFontDiagnosis";
|
||||
console.log(
|
||||
logTag +
|
||||
|
|
@ -534,7 +598,9 @@
|
|||
", ImageSize: " +
|
||||
imageSize +
|
||||
", HorizontalMargin: " +
|
||||
horizontalMargin
|
||||
horizontalMargin +
|
||||
", VerticalMargin: " +
|
||||
verticalMargin
|
||||
);
|
||||
|
||||
var dynamicStyleId = "dynamicReaderStyles";
|
||||
|
|
@ -551,12 +617,16 @@
|
|||
var newGap = parseFloat(paragraphGap);
|
||||
var newImageSize = parseFloat(imageSize);
|
||||
var newHorizontalMargin = parseFloat(horizontalMargin);
|
||||
var newVerticalMargin = parseFloat(verticalMargin);
|
||||
|
||||
if (isNaN(newFontSize) || newFontSize < 0.5 || newFontSize > 5.0) newFontSize = 1.0;
|
||||
if (isNaN(newLineHeight) || newLineHeight < 1.0 || newLineHeight > 3.0) newLineHeight = 1.0;
|
||||
if (isNaN(newGap) || newGap < 0.0 || newGap > 3.0) newGap = 1.0;
|
||||
if (isNaN(newImageSize) || newImageSize < 0.5 || newImageSize > 2.0) newImageSize = 1.0;
|
||||
if (isNaN(newHorizontalMargin) || newHorizontalMargin < 0.0 || newHorizontalMargin > 3.0) newHorizontalMargin = 1.0;
|
||||
if (isNaN(newVerticalMargin) || newVerticalMargin < 0.0 || newVerticalMargin > 3.0) newVerticalMargin = 1.0;
|
||||
|
||||
rememberReaderImageAnchors();
|
||||
|
||||
var fontCss = "";
|
||||
if (fontFamily && fontFamily !== "Original" && fontFamily !== "") {
|
||||
|
|
@ -609,11 +679,14 @@
|
|||
}
|
||||
|
||||
var horizontalPaddingPx = Math.max(0, 16 * newHorizontalMargin);
|
||||
var verticalPaddingPx = Math.max(0, 16 * newVerticalMargin);
|
||||
var horizontalMarginCss = `
|
||||
body {
|
||||
box-sizing: border-box !important;
|
||||
padding-left: ${horizontalPaddingPx}px !important;
|
||||
padding-right: ${horizontalPaddingPx}px !important;
|
||||
padding-top: ${verticalPaddingPx}px !important;
|
||||
padding-bottom: ${verticalPaddingPx}px !important;
|
||||
}
|
||||
`;
|
||||
|
||||
|
|
@ -629,10 +702,22 @@
|
|||
width: min(100%, calc(100% * var(--reader-image-size))) !important;
|
||||
max-width: 100% !important;
|
||||
height: auto !important;
|
||||
display: block !important;
|
||||
float: none !important;
|
||||
margin-left: auto !important;
|
||||
margin-right: auto !important;
|
||||
object-fit: contain !important;
|
||||
}
|
||||
body p:has(> img:only-child),
|
||||
body div:has(> img:only-child),
|
||||
body figure {
|
||||
text-align: center !important;
|
||||
}
|
||||
`;
|
||||
|
||||
dynamicStyleElement.innerHTML = [sizeCss, lineHeightCss, fontCss, alignCss, gapCss, imageCss, horizontalMarginCss].join("\n");
|
||||
applyReaderImageAnchors();
|
||||
setTimeout(applyReaderImageAnchors, 80);
|
||||
|
||||
setTimeout(
|
||||
function () {
|
||||
|
|
@ -2170,6 +2255,7 @@
|
|||
if (window.checkImagesForDiagnosis) {
|
||||
setTimeout(window.checkImagesForDiagnosis, 100);
|
||||
}
|
||||
setTimeout(applyReaderImageAnchors, 80);
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue