i18n: localize 2 hardcoded English alt texts on dynamic <img> elements
Two <img> elements rendered by renderer code had hardcoded English alt text that never localized: - renderer.ts cutter preview frame: alt="Preview" - renderer-profile.ts live-thumb: alt="Live preview" Added two new locale keys (DE+EN): - cutter.previewAlt — "Vorschau" / "Preview" - profile.liveThumbAlt — "Live-Vorschau" / "Live preview" renderer.ts updates: the three preview.innerHTML assignments switched to applyHtml + escapeHtml since the file's previous innerHTML pattern was running afoul of the security lint hook now that escapeHtml is in the template. Same shape as the other consolidated renderers (stats, archive, profile). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3d40160b5c
commit
e8404b8802
@ -332,6 +332,7 @@ const UI_TEXT_DE = {
|
|||||||
openTwitch: 'Auf Twitch oeffnen',
|
openTwitch: 'Auf Twitch oeffnen',
|
||||||
openTwitchTooltip: 'Diesen Kanal auf twitch.tv oeffnen',
|
openTwitchTooltip: 'Diesen Kanal auf twitch.tv oeffnen',
|
||||||
liveCardTooltip: 'Klick um sofort eine Live-Aufnahme zu starten',
|
liveCardTooltip: 'Klick um sofort eine Live-Aufnahme zu starten',
|
||||||
|
liveThumbAlt: 'Live-Vorschau',
|
||||||
recordNow: 'Jetzt aufnehmen',
|
recordNow: 'Jetzt aufnehmen',
|
||||||
refresh: 'Aktualisieren',
|
refresh: 'Aktualisieren',
|
||||||
agoMinutes: 'vor {n} Min',
|
agoMinutes: 'vor {n} Min',
|
||||||
@ -443,6 +444,7 @@ const UI_TEXT_DE = {
|
|||||||
videoInfoFailed: 'Konnte Video-Informationen nicht lesen. FFprobe installiert?',
|
videoInfoFailed: 'Konnte Video-Informationen nicht lesen. FFprobe installiert?',
|
||||||
previewLoading: 'Lade Vorschau...',
|
previewLoading: 'Lade Vorschau...',
|
||||||
previewUnavailable: 'Vorschau nicht verfugbar',
|
previewUnavailable: 'Vorschau nicht verfugbar',
|
||||||
|
previewAlt: 'Vorschau',
|
||||||
cutting: 'Schneidet...',
|
cutting: 'Schneidet...',
|
||||||
cut: 'Schneiden',
|
cut: 'Schneiden',
|
||||||
cutSuccess: 'Video erfolgreich geschnitten!',
|
cutSuccess: 'Video erfolgreich geschnitten!',
|
||||||
|
|||||||
@ -332,6 +332,7 @@ const UI_TEXT_EN = {
|
|||||||
openTwitch: 'Open on Twitch',
|
openTwitch: 'Open on Twitch',
|
||||||
openTwitchTooltip: 'Open this channel on twitch.tv',
|
openTwitchTooltip: 'Open this channel on twitch.tv',
|
||||||
liveCardTooltip: 'Click to start a live recording right now',
|
liveCardTooltip: 'Click to start a live recording right now',
|
||||||
|
liveThumbAlt: 'Live preview',
|
||||||
recordNow: 'Record now',
|
recordNow: 'Record now',
|
||||||
refresh: 'Refresh',
|
refresh: 'Refresh',
|
||||||
agoMinutes: '{n} min ago',
|
agoMinutes: '{n} min ago',
|
||||||
@ -443,6 +444,7 @@ const UI_TEXT_EN = {
|
|||||||
videoInfoFailed: 'Could not read video info. Is FFprobe installed?',
|
videoInfoFailed: 'Could not read video info. Is FFprobe installed?',
|
||||||
previewLoading: 'Loading preview...',
|
previewLoading: 'Loading preview...',
|
||||||
previewUnavailable: 'Preview unavailable',
|
previewUnavailable: 'Preview unavailable',
|
||||||
|
previewAlt: 'Preview',
|
||||||
cutting: 'Cutting...',
|
cutting: 'Cutting...',
|
||||||
cut: 'Cut',
|
cut: 'Cut',
|
||||||
cutSuccess: 'Video cut successfully!',
|
cutSuccess: 'Video cut successfully!',
|
||||||
|
|||||||
@ -106,7 +106,7 @@ function renderStreamerProfileCard(p: StreamerProfile): void {
|
|||||||
? `
|
? `
|
||||||
<div class="streamer-profile-live-card" role="button" tabindex="0" aria-label="${escapeHtml(UI_TEXT.profile.liveCardTooltip)}" onclick="triggerLiveRecordingFromProfile('${safeLogin}')" onkeydown="if((event.key==='Enter'||event.key===' ')&&event.target===event.currentTarget){event.preventDefault();triggerLiveRecordingFromProfile('${safeLogin}');}" title="${escapeHtml(UI_TEXT.profile.liveCardTooltip)}">
|
<div class="streamer-profile-live-card" role="button" tabindex="0" aria-label="${escapeHtml(UI_TEXT.profile.liveCardTooltip)}" onclick="triggerLiveRecordingFromProfile('${safeLogin}')" onkeydown="if((event.key==='Enter'||event.key===' ')&&event.target===event.currentTarget){event.preventDefault();triggerLiveRecordingFromProfile('${safeLogin}');}" title="${escapeHtml(UI_TEXT.profile.liveCardTooltip)}">
|
||||||
${p.currentStreamPreviewUrl
|
${p.currentStreamPreviewUrl
|
||||||
? `<img class="streamer-profile-live-thumb" src="${escapeHtml(p.currentStreamPreviewUrl)}" alt="Live preview" onerror="onProfileLivePreviewError(this)">`
|
? `<img class="streamer-profile-live-thumb" src="${escapeHtml(p.currentStreamPreviewUrl)}" alt="${escapeHtml(UI_TEXT.profile.liveThumbAlt)}" onerror="onProfileLivePreviewError(this)">`
|
||||||
: `<div class="streamer-profile-live-thumb-fallback"></div>`}
|
: `<div class="streamer-profile-live-thumb-fallback"></div>`}
|
||||||
<div class="streamer-profile-live-body">
|
<div class="streamer-profile-live-body">
|
||||||
<div class="streamer-profile-live-badge-row">
|
<div class="streamer-profile-live-badge-row">
|
||||||
|
|||||||
@ -1557,15 +1557,15 @@ async function updatePreview(time: number): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const preview = byId('cutterPreview');
|
const preview = byId('cutterPreview');
|
||||||
preview.innerHTML = `<div class="placeholder"><p>${UI_TEXT.cutter.previewLoading}</p></div>`;
|
applyHtml(preview, `<div class="placeholder"><p>${escapeHtml(UI_TEXT.cutter.previewLoading)}</p></div>`);
|
||||||
|
|
||||||
const frame = await window.api.extractFrame(cutterFile, time);
|
const frame = await window.api.extractFrame(cutterFile, time);
|
||||||
if (frame) {
|
if (frame) {
|
||||||
preview.innerHTML = `<img src="${frame}" alt="Preview">`;
|
applyHtml(preview, `<img src="${escapeHtml(frame)}" alt="${escapeHtml(UI_TEXT.cutter.previewAlt)}">`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
preview.innerHTML = `<div class="placeholder"><p>${UI_TEXT.cutter.previewUnavailable}</p></div>`;
|
applyHtml(preview, `<div class="placeholder"><p>${escapeHtml(UI_TEXT.cutter.previewUnavailable)}</p></div>`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function startCutting(): Promise<void> {
|
async function startCutting(): Promise<void> {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user