Compare commits

..

2 Commits

Author SHA1 Message Date
xRangerDE
7be9453762 release: 4.6.66 update-banner progress bar a11y
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 04:36:43 +02:00
xRangerDE
c393457492 a11y: update-banner progress bar role=progressbar + aria-valuenow
Third progress bar in this a11y pass — the download-progress bar
shown in the update banner during an auto-update download. Same
pattern as 4.6.64 (queue) + 4.6.65 (cut/merge): bare div with
JS-driven width, no semantic role.

Promoted the .update-banner-progress-track to role="progressbar"
with aria-valuemin / max / now + a localized aria-label
(updateProgressAria: "Update download progress" / "Update-Download-
Fortschritt").

Three call sites in renderer-updates.ts that drive bar.style.width
now also stamp aria-valuenow on the gauge:
- onUpdateProgress event handler (per-tick percent)
- setDownloadPendingUi (initial 30% indeterminate placeholder)
- setDownloadReadyUi (100% on finish)

renderer-texts.applyText sets the localized aria-label at boot +
on language switch.

That's all three application-level progress bars now AT-friendly.
The same pattern would extend to any future progress UI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 04:36:42 +02:00
7 changed files with 14 additions and 7 deletions

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "twitch-vod-manager", "name": "twitch-vod-manager",
"version": "4.6.65", "version": "4.6.66",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "twitch-vod-manager", "name": "twitch-vod-manager",
"version": "4.6.65", "version": "4.6.66",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"axios": "^1.6.0", "axios": "^1.6.0",

View File

@ -1,6 +1,6 @@
{ {
"name": "twitch-vod-manager", "name": "twitch-vod-manager",
"version": "4.6.65", "version": "4.6.66",
"description": "Twitch VOD Manager - Download Twitch VODs easily", "description": "Twitch VOD Manager - Download Twitch VODs easily",
"main": "dist/main.js", "main": "dist/main.js",
"author": "xRangerDE", "author": "xRangerDE",

View File

@ -11,7 +11,7 @@
<div class="update-banner" id="updateBanner"> <div class="update-banner" id="updateBanner">
<span id="updateText">Neue Version verfügbar!</span> <span id="updateText">Neue Version verfügbar!</span>
<div id="updateProgress" class="update-banner-progress-wrap" style="display: none;"> <div id="updateProgress" class="update-banner-progress-wrap" style="display: none;">
<div class="update-banner-progress-track"> <div class="update-banner-progress-track" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0" aria-label="Update download" id="updateProgressGauge">
<div id="updateProgressBar" class="update-banner-progress-bar"></div> <div id="updateProgressBar" class="update-banner-progress-bar"></div>
</div> </div>
</div> </div>

View File

@ -359,7 +359,8 @@ const UI_TEXT_DE = {
sidebarEmpty: 'Noch keine Streamer. Fuege oben rechts einen hinzu.', sidebarEmpty: 'Noch keine Streamer. Fuege oben rechts einen hinzu.',
removeAria: 'Entfernen', removeAria: 'Entfernen',
cutProgressAria: 'Schnitt-Fortschritt', cutProgressAria: 'Schnitt-Fortschritt',
mergeProgressAria: 'Merge-Fortschritt' mergeProgressAria: 'Merge-Fortschritt',
updateProgressAria: 'Update-Download-Fortschritt'
}, },
vods: { vods: {
noneTitle: 'Keine VODs', noneTitle: 'Keine VODs',

View File

@ -359,7 +359,8 @@ const UI_TEXT_EN = {
sidebarEmpty: 'No streamers yet. Add one via the input at the top right.', sidebarEmpty: 'No streamers yet. Add one via the input at the top right.',
removeAria: 'Remove', removeAria: 'Remove',
cutProgressAria: 'Cut progress', cutProgressAria: 'Cut progress',
mergeProgressAria: 'Merge progress' mergeProgressAria: 'Merge progress',
updateProgressAria: 'Update download progress'
}, },
vods: { vods: {
noneTitle: 'No VODs', noneTitle: 'No VODs',

View File

@ -255,6 +255,7 @@ function applyLanguageToStaticUI(): void {
setAriaLabelAll('.modal-close-localizable', UI_TEXT.streamers.modalCloseAria); setAriaLabelAll('.modal-close-localizable', UI_TEXT.streamers.modalCloseAria);
document.getElementById('cutProgressGauge')?.setAttribute('aria-label', UI_TEXT.streamers.cutProgressAria); document.getElementById('cutProgressGauge')?.setAttribute('aria-label', UI_TEXT.streamers.cutProgressAria);
document.getElementById('mergeProgressGauge')?.setAttribute('aria-label', UI_TEXT.streamers.mergeProgressAria); document.getElementById('mergeProgressGauge')?.setAttribute('aria-label', UI_TEXT.streamers.mergeProgressAria);
document.getElementById('updateProgressGauge')?.setAttribute('aria-label', UI_TEXT.streamers.updateProgressAria);
setText('backupCardTitle', UI_TEXT.static.backupCardTitle); setText('backupCardTitle', UI_TEXT.static.backupCardTitle);
setText('backupCardIntro', UI_TEXT.static.backupCardIntro); setText('backupCardIntro', UI_TEXT.static.backupCardIntro);
setText('btnExportConfig', UI_TEXT.static.exportConfig); setText('btnExportConfig', UI_TEXT.static.exportConfig);

View File

@ -127,7 +127,9 @@ function setDownloadPendingUi(): void {
const bar = byId('updateProgressBar'); const bar = byId('updateProgressBar');
bar.classList.add('downloading'); bar.classList.add('downloading');
bar.style.width = latestDownloadProgress ? `${latestDownloadProgress.percent}%` : '30%'; const pendingPct = latestDownloadProgress ? latestDownloadProgress.percent : 30;
bar.style.width = `${pendingPct}%`;
byId('updateProgressGauge').setAttribute('aria-valuenow', String(Math.round(pendingPct)));
if (!latestDownloadProgress) { if (!latestDownloadProgress) {
byId('updateText').textContent = `Version ${latestUpdateVersion || '?'} ${UI_TEXT.updates.downloading}`; byId('updateText').textContent = `Version ${latestUpdateVersion || '?'} ${UI_TEXT.updates.downloading}`;
@ -145,6 +147,7 @@ function setDownloadReadyUi(info?: UpdateInfo): void {
const bar = byId('updateProgressBar'); const bar = byId('updateProgressBar');
bar.classList.remove('downloading'); bar.classList.remove('downloading');
bar.style.width = '100%'; bar.style.width = '100%';
byId('updateProgressGauge').setAttribute('aria-valuenow', '100');
byId('updateProgress').style.display = 'block'; byId('updateProgress').style.display = 'block';
byId('updateText').textContent = `Version ${activeInfo.version} ${UI_TEXT.updates.ready}`; byId('updateText').textContent = `Version ${activeInfo.version} ${UI_TEXT.updates.ready}`;
@ -574,6 +577,7 @@ window.api.onUpdateDownloadProgress((progress: UpdateDownloadProgress) => {
const bar = byId('updateProgressBar'); const bar = byId('updateProgressBar');
bar.classList.remove('downloading'); bar.classList.remove('downloading');
bar.style.width = progress.percent + '%'; bar.style.width = progress.percent + '%';
byId('updateProgressGauge').setAttribute('aria-valuenow', String(Math.round(progress.percent)));
showUpdateBanner(); showUpdateBanner();
byId('updateProgress').style.display = 'block'; byId('updateProgress').style.display = 'block';