Release v1.26.10
Some checks are pending
Test and SonarQube / quality (push) Waiting to run

This commit is contained in:
mARTin-B78 2026-09-10 12:50:33 +02:00
parent e6211f1333
commit 29dc913ed1
6 changed files with 112 additions and 22 deletions

View File

@ -9,6 +9,13 @@ Follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) · versioned wi
---
## [1.26.10] — 2026-09-10
### Fixed
- **Instant Dropzone Upload & Active Progress Card.** Dropping a PDF (or picking a file) now automatically initiates upload and ingestion immediately. The dropzone transforms into an active progress card with a spinning loader, animated progress bar, status note (`Uploading "filename.pdf" (X MB)`), and disabled input controls so users get un-missable, immediate feedback.
---
## [1.26.9] — 2026-09-10
### Fixed
@ -3905,7 +3912,8 @@ Initial feature-complete release.
---
[Unreleased]: https://github.com/mARTin-B78/tts-voice-creator-clone-and-design-2/compare/v1.26.9...HEAD
[Unreleased]: https://github.com/mARTin-B78/tts-voice-creator-clone-and-design-2/compare/v1.26.10...HEAD
[1.26.10]: https://github.com/mARTin-B78/tts-voice-creator-clone-and-design-2/compare/v1.26.9...v1.26.10
[1.26.9]: https://github.com/mARTin-B78/tts-voice-creator-clone-and-design-2/compare/v1.26.8...v1.26.9
[1.26.1]: https://github.com/mARTin-B78/tts-voice-creator-clone-and-design-2/compare/v1.26.0...v1.26.1
[1.26.0]: https://github.com/mARTin-B78/tts-voice-creator-clone-and-design-2/compare/v1.25.3...v1.26.0

View File

@ -1 +1 @@
1.26.9
1.26.10

View File

@ -352,6 +352,47 @@
.reader-extract-info p { margin: 2px 0 0; color: var(--subtext); font-size: 12.5px; }
.reader-dropzone.dragover { border-color: var(--accent); background: rgba(37,99,235,.06); color: var(--accent); }
.reader-dropzone.dragover .reader-dropzone-icon { opacity: 1; }
.reader-dropzone.is-selected {
border-style: solid;
border-color: var(--accent);
background: rgba(37, 99, 235, 0.04);
}
.reader-dropzone.is-selected .reader-dropzone-icon {
opacity: 1;
color: var(--accent);
}
.reader-dropzone.is-uploading {
border-style: solid;
border-color: var(--accent);
background: rgba(37, 99, 235, 0.08);
box-shadow: 0 0 16px rgba(37, 99, 235, 0.2);
padding: 26px 16px;
}
.reader-dropzone.is-uploading .reader-dropzone-icon {
opacity: 1;
color: var(--accent);
}
.mag-dropzone-progress {
width: 100%;
max-width: 420px;
height: 6px;
background: rgba(37, 99, 235, 0.2);
border-radius: 999px;
overflow: hidden;
margin-top: 8px;
}
.mag-dropzone-progress-bar {
height: 100%;
width: 40%;
background: var(--accent);
border-radius: 999px;
animation: magIndeterminateProgress 1.4s infinite ease-in-out;
}
@keyframes magIndeterminateProgress {
0% { transform: translateX(-100%); width: 30%; }
50% { transform: translateX(100%); width: 50%; }
100% { transform: translateX(300%); width: 30%; }
}
#s-reader .reader-file-pick {
margin-top: 4px;
cursor: pointer;

View File

@ -10,7 +10,7 @@
<meta name="format-detection" content="telephone=no">
<meta name="color-scheme" content="light dark">
<meta name="theme-color" content="#2563EB">
<meta name="app-version" content="1.26.9">
<meta name="app-version" content="1.26.10">
<link rel="manifest" href="/manifest.webmanifest">
<link rel="icon" href="/static/icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/static/icon.svg">
@ -27,12 +27,12 @@
<!-- ── Core styles (local — no CDN dependency for first paint) ────────── -->
<link rel="stylesheet" href="/static/vendor/mdi/materialdesignicons.min.css">
<link rel="stylesheet" href="/static/style.css?v=1.26.9">
<link rel="stylesheet" href="/static/css/resource-diagnostics.css?v=1.26.9">
<link rel="stylesheet" href="/static/css/background-jobs.css?v=1.26.9">
<link rel="stylesheet" href="/static/css/voice-design.css?v=1.26.9">
<link rel="stylesheet" href="/static/css/rehearser.css?v=1.26.9">
<link rel="stylesheet" href="/static/css/audiobook.css?v=1.26.9">
<link rel="stylesheet" href="/static/style.css?v=1.26.10">
<link rel="stylesheet" href="/static/css/resource-diagnostics.css?v=1.26.10">
<link rel="stylesheet" href="/static/css/background-jobs.css?v=1.26.10">
<link rel="stylesheet" href="/static/css/voice-design.css?v=1.26.10">
<link rel="stylesheet" href="/static/css/rehearser.css?v=1.26.10">
<link rel="stylesheet" href="/static/css/audiobook.css?v=1.26.10">
<!-- ── Flag icons — non-blocking (loaded async, icons appear after JS) ── -->
@ -403,7 +403,7 @@ window.toggleNavTree = function(treeId, chevronId) {
</script>
<!-- loader.js: fetches sections → loads JS modules → removes skeleton -->
<script src="/static/loader.js?v=1.26.9"></script>
<script src="/static/loader.js?v=1.26.10"></script>
</body>
</html>

View File

@ -189,11 +189,13 @@ function magShowDroppedFile(file) {
const titleEl = $('mag-dropzone-title');
const iconEl = $('mag-dropzone-icon');
const titleInput = $('mag-new-title');
const dropzone = $('mag-dropzone');
if (file) {
const sizeMb = (file.size / (1024 * 1024)).toFixed(1);
if (dropzone) dropzone.classList.add('is-selected');
if (noteEl) noteEl.textContent = `Selected: ${file.name} (${sizeMb} MB)`;
if (titleEl) titleEl.textContent = 'PDF file selected';
if (titleEl) titleEl.textContent = 'PDF file selected — uploading...';
if (iconEl) iconEl.className = 'mdi mdi-file-check-outline reader-dropzone-icon';
// Auto-fill title from filename if title input is empty
@ -201,6 +203,7 @@ function magShowDroppedFile(file) {
titleInput.value = magFormatFilenameAsTitle(file.name);
}
} else {
if (dropzone) dropzone.classList.remove('is-selected', 'is-uploading');
if (noteEl) noteEl.textContent = MAG_DROPZONE_DEFAULT_NOTE;
if (titleEl) titleEl.textContent = 'Drop a PDF or click to browse';
if (iconEl) iconEl.className = 'mdi mdi-cloud-upload-outline reader-dropzone-icon';
@ -257,8 +260,15 @@ function setupMagDropzone() {
dt.items.add(file);
input.files = dt.files;
magShowDroppedFile(file);
magCreate();
});
input.addEventListener('change', () => {
const file = input.files?.[0];
if (file) {
magShowDroppedFile(file);
magCreate();
}
});
input.addEventListener('change', () => magShowDroppedFile(input.files?.[0]));
}
async function magCreate() {
@ -276,29 +286,57 @@ async function magCreate() {
const dropzone = $('mag-dropzone');
const titleInp = $('mag-new-title');
const issueInp = $('mag-new-issue');
const progress = $('mag-dropzone-progress');
const pickBtn = $('mag-dropzone-pick-btn');
const titleEl = $('mag-dropzone-title');
const noteEl = $('mag-dropzone-note');
const iconEl = $('mag-dropzone-icon');
const origBtnText = addBtn ? addBtn.innerHTML : '';
const setUploadingState = (uploading) => {
if (addBtn) {
addBtn.disabled = uploading;
addBtn.innerHTML = uploading
? '<span class="mdi mdi-loading mdi-spin"></span> Uploading PDF...'
: origBtnText;
const sizeMb = file ? (file.size / (1024 * 1024)).toFixed(1) : 0;
if (uploading) {
if (dropzone) {
dropzone.classList.add('is-uploading');
dropzone.style.pointerEvents = 'none';
}
if (progress) progress.hidden = false;
if (pickBtn) pickBtn.hidden = true;
if (iconEl) iconEl.className = 'mdi mdi-loading mdi-spin reader-dropzone-icon';
if (titleEl) titleEl.textContent = 'Uploading & Ingesting PDF...';
if (noteEl) noteEl.textContent = `Processing "${file.name}" (${sizeMb} MB). Transferring source file and extracting layout...`;
if (addBtn) {
addBtn.disabled = true;
addBtn.innerHTML = '<span class="mdi mdi-loading mdi-spin"></span> Uploading PDF...';
}
if (titleInp) titleInp.disabled = true;
if (issueInp) issueInp.disabled = true;
} else {
if (dropzone) {
dropzone.classList.remove('is-uploading');
dropzone.style.pointerEvents = 'auto';
}
if (progress) progress.hidden = true;
if (pickBtn) pickBtn.hidden = false;
if (addBtn) {
addBtn.disabled = false;
addBtn.innerHTML = origBtnText;
}
if (titleInp) titleInp.disabled = false;
if (issueInp) issueInp.disabled = false;
}
if (titleInp) titleInp.disabled = uploading;
if (issueInp) issueInp.disabled = uploading;
if (dropzone) dropzone.style.pointerEvents = uploading ? 'none' : 'auto';
};
try {
setUploadingState(true);
say(`Uploading ${file.name} (${(file.size / (1024 * 1024)).toFixed(1)} MB)...`, 'ok');
const { id } = await api('/api/magazine/docs', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title, issue }),
});
await api('/api/reader/docs/' + id + '/source?ext=pdf', { method: 'PUT', body: file });
say('Magazine added — starting ingestion', 'ok');
say('Magazine uploaded — starting ingestion', 'ok');
if ($('mag-new-title')) $('mag-new-title').value = '';
if ($('mag-new-issue')) $('mag-new-issue').value = '';

View File

@ -22,7 +22,10 @@
<span class="mdi mdi-cloud-upload-outline reader-dropzone-icon" id="mag-dropzone-icon"></span>
<strong id="mag-dropzone-title">Drop a PDF or click to browse</strong>
<span class="note" id="mag-dropzone-note">Scanned issues work too &mdash; pages without selectable text are read with OCR.</span>
<label class="btn-secondary btn-sm reader-file-pick" title="Choose a PDF file" onclick="event.stopPropagation()">
<div class="mag-dropzone-progress" id="mag-dropzone-progress" hidden>
<div class="mag-dropzone-progress-bar"></div>
</div>
<label class="btn-secondary btn-sm reader-file-pick" id="mag-dropzone-pick-btn" title="Choose a PDF file" onclick="event.stopPropagation()">
<span class="mdi mdi-file-upload-outline"></span> Choose file
<input type="file" id="mag-new-file" accept="application/pdf" style="display:none">
</label>