i18n+polish: localize queue detail labels + style the retry button

Three queue-item detail labels were hardcoded German in the
renderer's HTML template: "Streamer:" / "Dauer:" / "Datum:". The
queue-details panel that expands when a user clicks a queue items
title would render these labels in German regardless of the
selected locale — same i18n gap as the empty states fixed in
4.6.37.

Added queue.detailStreamer / detailDuration / detailDate to both
locale tables ("Streamer:" / "Duration:" / "Date:" in EN,
"Streamer:" / "Dauer:" / "Datum:" in DE) and wrapped the labels
in a .queue-detail-label span so the colour distinction between
label and value (secondary vs primary text colour) is consistent.

The error-state retry button was a span with five inline-style
props and a unicode ↻ as its glyph — visually drab and not really
a button semantically (screen reader read it as text). Promoted
to a real <button class="queue-retry-btn"> with a proper hover
state (purple-tinted background + accent border + white text +
active-press scale-down). Subtler than .btn-pill but obviously
clickable.

Cursor:pointer on .queue-item .title moved from inline style on
the HTML template to the CSS rule — same effect, one less
attribute per queue item.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
xRangerDE 2026-05-11 03:13:42 +02:00
parent edf3836b26
commit fedf3a9945
4 changed files with 42 additions and 6 deletions

View File

@ -264,6 +264,9 @@ const UI_TEXT_DE = {
}, },
queue: { queue: {
empty: 'Keine Downloads in der Warteschlange', empty: 'Keine Downloads in der Warteschlange',
detailStreamer: 'Streamer:',
detailDuration: 'Dauer:',
detailDate: 'Datum:',
start: 'Start', start: 'Start',
stop: 'Pausieren', stop: 'Pausieren',
resume: 'Fortsetzen', resume: 'Fortsetzen',

View File

@ -264,6 +264,9 @@ const UI_TEXT_EN = {
}, },
queue: { queue: {
empty: 'No downloads in queue', empty: 'No downloads in queue',
detailStreamer: 'Streamer:',
detailDuration: 'Duration:',
detailDate: 'Date:',
start: 'Start', start: 'Start',
stop: 'Pause', stop: 'Pause',
resume: 'Resume', resume: 'Resume',

View File

@ -555,7 +555,7 @@ function renderQueue(): void {
<div class="status ${item.status}"></div> <div class="status ${item.status}"></div>
<div class="queue-main"> <div class="queue-main">
<div class="queue-title-row"> <div class="queue-title-row">
<div class="title" title="${safeTitle}" onclick="toggleQueueDetails('${item.id}')" style="cursor:pointer">${liveBadge}${healthBadge}${mergeIcon}${isClip}${safeTitle}</div> <div class="title" title="${safeTitle}" onclick="toggleQueueDetails('${item.id}')">${liveBadge}${healthBadge}${mergeIcon}${isClip}${safeTitle}</div>
<div class="queue-status-label">${safeStatusLabel}</div> <div class="queue-status-label">${safeStatusLabel}</div>
</div> </div>
<div class="queue-meta">${safeMeta}${mergeMetaExtra}</div> <div class="queue-meta">${safeMeta}${mergeMetaExtra}</div>
@ -564,14 +564,14 @@ function renderQueue(): void {
</div> </div>
<div class="queue-progress-text">${safeProgressText}</div> <div class="queue-progress-text">${safeProgressText}</div>
<div class="queue-details" id="details-${item.id}" style="display:${expandedQueueIds.has(item.id) ? 'block' : 'none'}"> <div class="queue-details" id="details-${item.id}" style="display:${expandedQueueIds.has(item.id) ? 'block' : 'none'}">
<div>URL: ${escapeHtml(item.url)}</div> <div><span class="queue-detail-label">URL:</span> ${escapeHtml(item.url)}</div>
<div>Streamer: ${escapeHtml(item.streamer)}</div> <div><span class="queue-detail-label">${escapeHtml(UI_TEXT.queue.detailStreamer)}</span> ${escapeHtml(item.streamer)}</div>
<div>Dauer: ${escapeHtml(item.duration_str)}</div> <div><span class="queue-detail-label">${escapeHtml(UI_TEXT.queue.detailDuration)}</span> ${escapeHtml(item.duration_str)}</div>
<div>Datum: ${escapeHtml(new Date(item.date).toLocaleString())}</div> <div><span class="queue-detail-label">${escapeHtml(UI_TEXT.queue.detailDate)}</span> ${escapeHtml(new Date(item.date).toLocaleString())}</div>
${renderQueueItemFileActions(item)} ${renderQueueItemFileActions(item)}
</div> </div>
</div> </div>
${item.status === 'error' ? `<span class="queue-retry-btn" title="${escapeHtml(UI_TEXT.queue.retryItem)}" onclick="retryQueueItem('${item.id}')" style="cursor:pointer; color: var(--text-secondary); font-size:14px; padding: 0 6px;">&#x21bb;</span>` : ''} ${item.status === 'error' ? `<button class="queue-retry-btn" title="${escapeHtml(UI_TEXT.queue.retryItem)}" onclick="retryQueueItem('${item.id}')">&#x21bb;</button>` : ''}
<span class="remove" onclick="removeFromQueue('${item.id}')">x</span> <span class="remove" onclick="removeFromQueue('${item.id}')">x</span>
</div> </div>
`; `;

View File

@ -859,6 +859,36 @@ select option {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
cursor: pointer;
}
.queue-detail-label {
color: var(--text-secondary);
font-weight: 500;
margin-right: 4px;
}
.queue-retry-btn {
background: transparent;
border: 1px solid var(--border-soft);
border-radius: 6px;
color: var(--text-secondary);
cursor: pointer;
padding: 4px 8px;
font-size: 14px;
line-height: 1;
align-self: center;
transition: background 0.15s, color 0.15s, border-color 0.15s, transform 0.12s;
}
.queue-retry-btn:hover {
background: rgba(145, 70, 255, 0.18);
border-color: rgba(145, 70, 255, 0.55);
color: #fff;
}
.queue-retry-btn:active {
transform: scale(0.92);
} }
.queue-main { .queue-main {