feat(ui): segmented High Quality / Fast render-mode toggle for office trio (.docx/.odt/.rtf); progressive disclosure shows toggle only for office files
Test / Tests (Python 3.12) (push) Canceled after 0s

This commit is contained in:
sirdave73
2026-09-04 20:22:10 -04:00
parent 8dcf5e5faa
commit e96661038d
+29 -5
View File
@@ -312,9 +312,16 @@
.status-top { flex-direction: column; align-items: stretch; } .status-top { flex-direction: column; align-items: stretch; }
.book-block { margin: 0 auto; } .book-block { margin: 0 auto; }
} }
@media (prefers-reduced-motion: reduce) { .render-modes { display: inline-flex; gap: 4px; margin: 18px auto 0; padding: 4px; width: fit-content; border-radius: 14px; background: var(--bg-elev); border: 1px solid var(--line); transition: opacity .25s, transform .25s; }
* { transition: none !important; animation: none !important; } .mode-seg { position: relative; }
} .mode-seg input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.seg-track { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 11px 20px; min-width: 150px; border-radius: 11px; cursor: pointer; color: var(--muted); user-select: none; transition: color .25s, background .25s, transform .3s cubic-bezier(.34,1.56,.64,1); }
.seg-main { font-family: var(--sans); font-size: .95rem; font-weight: 600; letter-spacing: -.01em; }
.seg-sub { font-family: var(--mono); font-size: .72rem; opacity: .85; }
.mode-seg input:checked + .seg-track { color: #fff; background: linear-gradient(135deg, var(--accent), var(--accent-2)); box-shadow: 0 6px 18px -6px rgba(99,102,241,.7); transform: scale(1.04); }
.badge-rec { position: absolute; top: 5px; right: 6px; font-family: var(--mono); font-size: .52rem; letter-spacing: .06em; text-transform: uppercase; color: var(--accent-2); background: var(--accent-soft); padding: 2px 6px; border-radius: 999px; }
.mode-seg input:checked + .seg-track .badge-rec { background: rgba(255,255,255,.22); color: #fff; }
.mode-seg input:focus-visible + .seg-track { outline: 2px solid var(--accent-2); outline-offset: 2px; }
</style> </style>
</head> </head>
<body> <body>
@@ -347,8 +354,21 @@
<p class="drop-note">or <span class="browse">browse your files</span> &middot; up to <span id="maxmb">400</span>&nbsp;MB &middot; <code>.epub .docx .odt .md .html .txt .csv .svg .png .pdf</code></p> <p class="drop-note">or <span class="browse">browse your files</span> &middot; up to <span id="maxmb">400</span>&nbsp;MB &middot; <code>.epub .docx .odt .md .html .txt .csv .svg .png .pdf</code></p>
<p id="droperr" class="drop-err" role="alert"></p> <p id="droperr" class="drop-err" role="alert"></p>
<div class="render-modes" role="radiogroup" aria-label="Rendering mode"> <div class="render-modes" role="radiogroup" aria-label="Rendering mode">
<label class="mode-label"><input type="radio" name="render_mode" value="rich" checked> <span class="mode-name">Rich</span> &mdash; best fidelity (LibreOffice)</label> <label class="mode-seg">
<label class="mode-label"><input type="radio" name="render_mode" value="standard"> <span class="mode-name">Standard</span> &mdash; fastest (pandoc)</label> <input type="radio" name="render_mode" value="rich" checked>
<span class="seg-track">
<span class="seg-main">High Quality</span>
<span class="seg-sub">keeps fonts, colors &amp; tables</span>
<span class="badge-rec">Recommended</span>
</span>
</label>
<label class="mode-seg">
<input type="radio" name="render_mode" value="standard">
<span class="seg-track">
<span class="seg-main">Fast</span>
<span class="seg-sub">simpler, quicker</span>
</span>
</label>
</div> </div>
<input type="file" id="file" accept=".epub,.html,.htm,.txt,.log,.md,.markdown,.csv,.tsv,.json,.xml,.svg,.png,.jpg,.jpeg,.webp,.tiff,.bmp,.pdf,.docx,.odt,.rtf,.tex,.latex,.org,.adoc,.rst"> <input type="file" id="file" accept=".epub,.html,.htm,.txt,.log,.md,.markdown,.csv,.tsv,.json,.xml,.svg,.png,.jpg,.jpeg,.webp,.tiff,.bmp,.pdf,.docx,.odt,.rtf,.tex,.latex,.org,.adoc,.rst">
</section> </section>
@@ -458,6 +478,10 @@
function start(f) { function start(f) {
var OKEXT = /\.(epub|html|htm|txt|log|md|markdown|csv|tsv|json|xml|svg|png|jpe?g|webp|tiff|bmp|pdf|docx|odt|rtf|tex|latex|org|adoc|rst)$/i; var OKEXT = /\.(epub|html|htm|txt|log|md|markdown|csv|tsv|json|xml|svg|png|jpe?g|webp|tiff|bmp|pdf|docx|odt|rtf|tex|latex|org|adoc|rst)$/i;
if (!OKEXT.test(f.name)) { flashError('Unsupported file type &mdash; accepted: .epub .html .htm .txt .log .md .markdown .csv .tsv .json .xml .svg .png .jpg .jpeg .webp .tiff .bmp .pdf .docx .odt .rtf .tex .latex .org .adoc .rst'); return; } if (!OKEXT.test(f.name)) { flashError('Unsupported file type &mdash; accepted: .epub .html .htm .txt .log .md .markdown .csv .tsv .json .xml .svg .png .jpg .jpeg .webp .tiff .bmp .pdf .docx .odt .rtf .tex .latex .org .adoc .rst'); return; }
// STEP 3: progressive disclosure — toggle only for the office trio (.docx/.odt/.rtf)
const isOffice = /\.(docx|odt|rtf)$/i.test(f.name);
const toggle = document.querySelector('.render-modes');
if (toggle) toggle.style.display = isOffice ? '' : 'none';
var form = new FormData(); var form = new FormData();
form.append('file', f); form.append('file', f);
var modeEl = document.querySelector('input[name="render_mode"]:checked'); var modeEl = document.querySelector('input[name="render_mode"]:checked');