Reader: Schriftgewicht einstellbar (SW v47)
Neuer Regler im Einstellungs-Panel, 200-800: bei Source Serif 4 (variabel) in 25er-Schritten, bei Systemschriften in 100ern. null behält das Gewicht aus dem Stylesheet. --reader-weight erlaubt alten WebViews ohne variable Schriften, einen statischen Schnitt zu wählen. "Kein Fett" erbt jetzt das eingestellte Gewicht statt fest normal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
09055b9874
commit
7ee44622ee
3 changed files with 52 additions and 4 deletions
|
|
@ -2130,7 +2130,7 @@ body.reader-immersive.reader-show-bottom .reader-overlay { bottom: var(--bar-h)
|
||||||
.footnote-popover-close { position:absolute; top:4px; right:6px; background:none; border:none; color:inherit; opacity:0.5; cursor:pointer; font-size:14px; padding:2px 4px; line-height:1; }
|
.footnote-popover-close { position:absolute; top:4px; right:6px; background:none; border:none; color:inherit; opacity:0.5; cursor:pointer; font-size:14px; padding:2px 4px; line-height:1; }
|
||||||
|
|
||||||
/* Highlight marks */
|
/* Highlight marks */
|
||||||
.reader-no-bold * { font-weight: normal !important; }
|
.reader-no-bold * { font-weight: inherit !important; }
|
||||||
.reader-content img { max-width: 100%; height: auto; display: block; }
|
.reader-content img { max-width: 100%; height: auto; display: block; }
|
||||||
/* color:inherit overrides the browser's UA-default `mark { color: black }` —
|
/* color:inherit overrides the browser's UA-default `mark { color: black }` —
|
||||||
without it, highlighted text abruptly flips to black regardless of the
|
without it, highlighted text abruptly flips to black regardless of the
|
||||||
|
|
|
||||||
|
|
@ -3254,7 +3254,7 @@ async function _syncPendingAnnotations() {
|
||||||
|
|
||||||
// Reader settings
|
// Reader settings
|
||||||
let readerSettings = { fontSize: 16, lineHeight: 1.8, maxWidth: 65, theme: 'dark',
|
let readerSettings = { fontSize: 16, lineHeight: 1.8, maxWidth: 65, theme: 'dark',
|
||||||
fontFamily: 'serif', noBold: false,
|
fontFamily: 'serif', noBold: false, fontWeight: null,
|
||||||
pdfZoom: 100, pdfInverted: false, pdfPaginated: false, pdfSpread: false };
|
pdfZoom: 100, pdfInverted: false, pdfPaginated: false, pdfSpread: false };
|
||||||
let readerSettingsPanelOpen = false;
|
let readerSettingsPanelOpen = false;
|
||||||
let currentPdfDoc = null;
|
let currentPdfDoc = null;
|
||||||
|
|
@ -5026,7 +5026,7 @@ function jumpToTocEntry(href) {
|
||||||
function loadReaderSettings(bookId) {
|
function loadReaderSettings(bookId) {
|
||||||
// Reset to defaults, then apply per-book overrides
|
// Reset to defaults, then apply per-book overrides
|
||||||
Object.assign(readerSettings, { fontSize: 16, lineHeight: 1.8, maxWidth: 65, theme: 'dark',
|
Object.assign(readerSettings, { fontSize: 16, lineHeight: 1.8, maxWidth: 65, theme: 'dark',
|
||||||
fontFamily: 'serif', noBold: false,
|
fontFamily: 'serif', noBold: false, fontWeight: null,
|
||||||
pdfZoom: 100, pdfInverted: false, pdfPaginated: false, pdfSpread: false });
|
pdfZoom: 100, pdfInverted: false, pdfPaginated: false, pdfSpread: false });
|
||||||
try {
|
try {
|
||||||
const saved = JSON.parse(localStorage.getItem(`diora_reader_settings_${bookId}`) || '{}');
|
const saved = JSON.parse(localStorage.getItem(`diora_reader_settings_${bookId}`) || '{}');
|
||||||
|
|
@ -5060,6 +5060,16 @@ function applyReaderSettings(isPdf) {
|
||||||
};
|
};
|
||||||
contentEl.style.fontFamily = fontMap[readerSettings.fontFamily] || fontMap.serif;
|
contentEl.style.fontFamily = fontMap[readerSettings.fontFamily] || fontMap.serif;
|
||||||
contentEl.classList.toggle('reader-no-bold', !!readerSettings.noBold);
|
contentEl.classList.toggle('reader-no-bold', !!readerSettings.noBold);
|
||||||
|
// Weight: null keeps the stylesheet's. --reader-weight lets old WebViews
|
||||||
|
// without variable-font support (which drop weights like 425) pick a
|
||||||
|
// static cut instead.
|
||||||
|
contentEl.style.fontWeight = '';
|
||||||
|
if (readerSettings.fontWeight) {
|
||||||
|
contentEl.style.fontWeight = String(readerSettings.fontWeight);
|
||||||
|
contentEl.style.setProperty('--reader-weight', String(readerSettings.fontWeight));
|
||||||
|
} else {
|
||||||
|
contentEl.style.removeProperty('--reader-weight');
|
||||||
|
}
|
||||||
if (_currentPositionAnchor && currentBookId) {
|
if (_currentPositionAnchor && currentBookId) {
|
||||||
_suppressScrollJumpDetect();
|
_suppressScrollJumpDetect();
|
||||||
requestAnimationFrame(() => restoreFromAnchor($('reader-content'), _currentPositionAnchor));
|
requestAnimationFrame(() => restoreFromAnchor($('reader-content'), _currentPositionAnchor));
|
||||||
|
|
@ -5083,6 +5093,19 @@ function applyReaderSettings(isPdf) {
|
||||||
if (isPdf && markerModeActive) toggleMarkerMode();
|
if (isPdf && markerModeActive) toggleMarkerMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Font weight slider: the variable Source Serif 4 takes any weight, the
|
||||||
|
// system fonts only their fixed cuts (multiples of 100).
|
||||||
|
function _readerWeightStep() {
|
||||||
|
return readerSettings.fontFamily === 'serif' ? 25 : 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _readerWeight() {
|
||||||
|
const step = _readerWeightStep();
|
||||||
|
const w = readerSettings.fontWeight
|
||||||
|
|| parseInt(getComputedStyle($('reader-content')).fontWeight, 10) || 400;
|
||||||
|
return Math.round(w / step) * step;
|
||||||
|
}
|
||||||
|
|
||||||
function toggleSettingsPanel() {
|
function toggleSettingsPanel() {
|
||||||
const overlay = $('reader-overlay');
|
const overlay = $('reader-overlay');
|
||||||
const contentEl = $('reader-content');
|
const contentEl = $('reader-content');
|
||||||
|
|
@ -5108,6 +5131,7 @@ function toggleSettingsPanel() {
|
||||||
<label>Line <button class="btn btn-sm" id="rs-line-minus">−</button> <input type="range" id="rs-line" min="12" max="30" step="1" value="${Math.round(readerSettings.lineHeight * 10)}"> <button class="btn btn-sm" id="rs-line-plus">+</button> <span id="rs-line-val">${readerSettings.lineHeight}</span></label>
|
<label>Line <button class="btn btn-sm" id="rs-line-minus">−</button> <input type="range" id="rs-line" min="12" max="30" step="1" value="${Math.round(readerSettings.lineHeight * 10)}"> <button class="btn btn-sm" id="rs-line-plus">+</button> <span id="rs-line-val">${readerSettings.lineHeight}</span></label>
|
||||||
<label>Width <button class="btn btn-sm" id="rs-width-minus">−</button> <input type="range" id="rs-width" min="40" max="90" step="5" value="${readerSettings.maxWidth}"> <button class="btn btn-sm" id="rs-width-plus">+</button> <span id="rs-width-val">${readerSettings.maxWidth}ch</span></label>
|
<label>Width <button class="btn btn-sm" id="rs-width-minus">−</button> <input type="range" id="rs-width" min="40" max="90" step="5" value="${readerSettings.maxWidth}"> <button class="btn btn-sm" id="rs-width-plus">+</button> <span id="rs-width-val">${readerSettings.maxWidth}ch</span></label>
|
||||||
<button class="btn btn-sm" id="rs-width-full">Full</button>
|
<button class="btn btn-sm" id="rs-width-full">Full</button>
|
||||||
|
<label>Weight <button class="btn btn-sm" id="rs-weight-minus">−</button> <input type="range" id="rs-weight" min="200" max="800" step="${_readerWeightStep()}" value="${_readerWeight()}"> <button class="btn btn-sm" id="rs-weight-plus">+</button> <span id="rs-weight-val">${_readerWeight()}</span></label>
|
||||||
<button class="btn btn-sm ${readerSettings.fontFamily === 'serif' ? 'active' : ''}" data-rs-font="serif">Serif</button>
|
<button class="btn btn-sm ${readerSettings.fontFamily === 'serif' ? 'active' : ''}" data-rs-font="serif">Serif</button>
|
||||||
<button class="btn btn-sm ${readerSettings.fontFamily === 'sans' ? 'active' : ''}" data-rs-font="sans">Sans</button>
|
<button class="btn btn-sm ${readerSettings.fontFamily === 'sans' ? 'active' : ''}" data-rs-font="sans">Sans</button>
|
||||||
<button class="btn btn-sm ${readerSettings.fontFamily === 'humanist' ? 'active' : ''}" data-rs-font="humanist">Verdana</button>
|
<button class="btn btn-sm ${readerSettings.fontFamily === 'humanist' ? 'active' : ''}" data-rs-font="humanist">Verdana</button>
|
||||||
|
|
@ -5187,12 +5211,36 @@ function toggleSettingsPanel() {
|
||||||
saveReaderSettings();
|
saveReaderSettings();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const weightRange = panel.querySelector('#rs-weight');
|
||||||
|
const weightVal = panel.querySelector('#rs-weight-val');
|
||||||
|
weightRange.addEventListener('input', () => {
|
||||||
|
readerSettings.fontWeight = parseInt(weightRange.value, 10);
|
||||||
|
weightVal.textContent = readerSettings.fontWeight;
|
||||||
|
applyReaderSettings(false);
|
||||||
|
saveReaderSettings();
|
||||||
|
});
|
||||||
|
panel.querySelector('#rs-weight-minus').addEventListener('click', () => {
|
||||||
|
weightRange.value = Math.max(+weightRange.min, parseInt(weightRange.value, 10) - +weightRange.step);
|
||||||
|
weightRange.dispatchEvent(new Event('input'));
|
||||||
|
});
|
||||||
|
panel.querySelector('#rs-weight-plus').addEventListener('click', () => {
|
||||||
|
weightRange.value = Math.min(+weightRange.max, parseInt(weightRange.value, 10) + +weightRange.step);
|
||||||
|
weightRange.dispatchEvent(new Event('input'));
|
||||||
|
});
|
||||||
|
|
||||||
panel.querySelectorAll('[data-rs-font]').forEach(btn => {
|
panel.querySelectorAll('[data-rs-font]').forEach(btn => {
|
||||||
btn.addEventListener('click', () => {
|
btn.addEventListener('click', () => {
|
||||||
readerSettings.fontFamily = btn.dataset.rsFont;
|
readerSettings.fontFamily = btn.dataset.rsFont;
|
||||||
panel.querySelectorAll('[data-rs-font]').forEach(b => b.classList.toggle('active', b === btn));
|
panel.querySelectorAll('[data-rs-font]').forEach(b => b.classList.toggle('active', b === btn));
|
||||||
|
// The system fonts only have cuts at multiples of 100.
|
||||||
|
weightRange.step = _readerWeightStep();
|
||||||
|
if (readerSettings.fontWeight) {
|
||||||
|
readerSettings.fontWeight = Math.round(readerSettings.fontWeight / weightRange.step) * weightRange.step;
|
||||||
|
}
|
||||||
applyReaderSettings(false);
|
applyReaderSettings(false);
|
||||||
saveReaderSettings();
|
saveReaderSettings();
|
||||||
|
weightRange.value = _readerWeight();
|
||||||
|
weightVal.textContent = _readerWeight();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
* diora service worker — caches the app shell for offline use.
|
* diora service worker — caches the app shell for offline use.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const CACHE = 'diora-v46';
|
const CACHE = 'diora-v47';
|
||||||
const PODCAST_CACHE = 'diora-podcast-v1';
|
const PODCAST_CACHE = 'diora-podcast-v1';
|
||||||
const SHELL = [
|
const SHELL = [
|
||||||
'/static/css/app.css',
|
'/static/css/app.css',
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue