Twitch-VOD-Manager/src/renderer-locale-de.ts
xRangerDE e098708398 feat: stats-bar pause-on-hidden + bulk-mark downloaded + title tooltip
Three Phase-13 wins.

1. Stats bar polling pauses while document.hidden. Previously
   setInterval(updateStatsBar, 5000) ran forever, including while
   the user had a different tab focused or the window minimised.
   Now wraps start/stopStatsBarPolling and listens to
   visibilitychange. When the page becomes visible the interval
   restarts; while hidden it sleeps. Saves an IPC round-trip every
   5s when nobody's looking.

2. Bulk mark / unmark "as downloaded" on the VOD bulk-bar. Companion
   to the per-card right-click context menu's mark/unmark items —
   when the user has 5 VODs selected they now get one click to
   toggle the green check on all of them instead of right-clicking
   each. Uses the existing markVodDownloaded IPC, refreshes the
   local config copy + re-renders the grid so badges update live.

3. VOD card title tooltip. The card title is text-overflow:ellipsis
   so longer titles get cut off. Adding title="${full title}"
   surfaces the full text on hover via the native browser tooltip
   — no custom UI needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 20:20:42 +02:00

336 lines
16 KiB
TypeScript

const UI_TEXT_DE = {
appName: 'Twitch VOD Manager',
static: {
navVods: 'Twitch VODs',
navClips: 'Twitch Clips',
navCutter: 'Video schneiden',
navMerge: 'Videos zusammenfugen',
navSettings: 'Einstellungen',
queueTitle: 'Warteschlange',
retryFailed: 'Wiederholen',
retryFailedHint: 'Nur fehlgeschlagene Downloads erneut starten',
healthUnknown: 'System: Unbekannt',
healthGood: 'System: Stabil',
healthWarn: 'System: Warnung',
healthBad: 'System: Problem',
clearQueue: 'Leeren',
refresh: 'Aktualisieren',
streamerPlaceholder: 'Streamer hinzufugen...',
clipsHeading: 'Twitch Clip-Download',
clipsInfoTitle: 'Info',
clipsInfoText: 'Unterstutzte Formate:\n- https://clips.twitch.tv/ClipName\n- https://www.twitch.tv/streamer/clip/ClipName\n\nClips werden im Download-Ordner unter "Clips/StreamerName/" gespeichert.',
cutterSelectTitle: 'Video auswahlen',
cutterBrowse: 'Durchsuchen',
mergeTitle: 'Videos zusammenfugen',
mergeDesc: 'Wahle mehrere Videos aus, um sie zu einem Video zusammenzufugen. Die Reihenfolge kann geandert werden.',
mergeAdd: '+ Videos hinzufugen',
designTitle: 'Design',
themeLabel: 'Theme',
themeLight: 'Hell',
languageLabel: 'Sprache',
languageDe: 'Deutsch',
languageEn: 'Englisch',
apiTitle: 'Twitch API',
clientIdLabel: 'Client ID',
clientSecretLabel: 'Client Secret',
saveSettings: 'Speichern & Verbinden',
downloadSettingsTitle: 'Download-Einstellungen',
storageLabel: 'Speicherort',
openFolder: 'Offnen',
modeLabel: 'Download-Modus',
modeFull: 'Ganzes VOD',
modeParts: 'In Teile splitten',
partMinutesLabel: 'Teil-Lange (Minuten)',
parallelDownloadsLabel: 'Parallele Downloads',
parallelDownloads1: '1 (Standard)',
parallelDownloads2: '2 (Parallel)',
performanceModeLabel: 'Performance-Profil',
performanceModeStability: 'Max Stabilitat',
performanceModeBalanced: 'Ausgewogen',
performanceModeSpeed: 'Max Geschwindigkeit',
smartSchedulerLabel: 'Smart Queue Scheduler aktivieren',
smartSchedulerHint: 'Bevorzugt kuerzere VODs und aeltere Queue-Eintraege zuerst, damit der Durchsatz gleichmaessig bleibt. Deaktivieren = strikte Einfuegereihenfolge.',
streamerInvalid: 'Twitch-Username ungueltig (4-25 Zeichen, Buchstaben/Zahlen/Unterstrich).',
apiHelpIntro: 'Du brauchst eine Client-ID und ein Client-Secret von Twitch.',
apiHelpLinkText: 'dev.twitch.tv/console/apps',
openDebugLogFile: 'Log-Datei oeffnen',
backupCardTitle: 'Sicherung & Wartung',
backupCardIntro: 'Konfiguration sichern, auf einem anderen Geraet wiederherstellen oder die Liste der bereits heruntergeladenen VODs zuruecksetzen.',
exportConfig: 'Konfiguration exportieren',
importConfig: 'Konfiguration importieren',
resetDownloadedIds: 'Downloaded-VODs zuruecksetzen',
configExported: 'Konfiguration exportiert.',
configExportFailed: 'Export der Konfiguration fehlgeschlagen.',
configImported: 'Konfiguration importiert. Einige Aenderungen erfordern evtl. einen Neustart.',
configImportFailed: 'Import der Konfiguration fehlgeschlagen.',
resetDownloadedConfirm: 'Liste der heruntergeladenen VODs zuruecksetzen? Karten verlieren das gruene Haekchen, es werden aber keine Dateien geloescht.',
resetDownloadedDone: '{count} Eintraege aus der Downloaded-Liste entfernt.',
duplicatePreventionLabel: 'Duplikate in Queue verhindern',
persistQueueLabel: 'Queue zwischen App-Starts speichern',
autoResumeQueueLabel: 'Queue beim Start automatisch fortsetzen',
autoResumeQueueHint: 'Wenn aktiv und die gespeicherte Queue noch ausstehende Eintraege hat, starten Downloads ~5 Sekunden nach dem Fensteroeffnen. Deaktivieren = Start-Klick noetig.',
notifyEachCompletionLabel: 'Benachrichtigung bei jedem fertigen Download',
notifyEachCompletionHint: 'Standardmaessig aus — bei langen Queues wuerde das System-Notifications-Panel sonst zugespammt. Die Queue-End-Zusammenfassung erscheint trotzdem.',
streamlinkDisableAdsLabel: 'Twitch-Ads beim Download ueberspringen',
streamlinkDisableAdsHint: 'Gibt --twitch-disable-ads an streamlink weiter, damit Mid-Roll-Ads nicht ins VOD eingebettet werden. Empfohlen aktiv lassen.',
streamlinkQualityLabel: 'Stream-Qualitaet',
streamlinkQualityHint: 'Streamlink versucht erst diese Qualitaet; falls das VOD sie nicht anbietet, faellt es auf "best" zurueck.',
streamlinkQualityBest: 'Best (Standard)',
streamlinkQualitySource: 'Source (Original)',
streamlinkQualityAudio: 'Nur Audio',
downloadPathNotWritable: 'Download-Ordner ist nicht beschreibbar. Waehle einen anderen Ordner oder pruefe die Schreibrechte.',
streamerSectionTitle: 'Streamer',
streamerListFilterPlaceholder: 'Filtern...',
streamerBulkRemoveTitle: 'Alle entfernen (oder gefilterte)',
streamerBulkRemoveAll: 'Alle {count} Streamer aus der Liste entfernen?',
streamerBulkRemoveFiltered: 'Die {count} passenden Streamer aus der Liste entfernen?',
cutterDropHint: 'Video-Datei hierher ziehen zum Laden.',
metadataCacheMinutesLabel: 'Metadata-Cache (Minuten)',
filenameTemplatesTitle: 'Dateinamen-Templates',
vodTemplateLabel: 'VOD-Template',
partsTemplateLabel: 'VOD-Teile-Template',
defaultClipTemplateLabel: 'Clip-Template',
filenameTemplateHint: 'Platzhalter: {title} {id} {channel} {date} {part} {part_padded} {trim_start} {trim_end} {trim_length} {date_custom="yyyy-MM-dd"}',
vodTemplatePlaceholder: '{title}.mp4',
partsTemplatePlaceholder: '{date}_Part{part_padded}.mp4',
defaultClipTemplatePlaceholder: '{date}_{part}.mp4',
templateLintOk: 'Template-Check: OK',
templateLintWarn: 'Unbekannte Platzhalter',
templateGuideButton: 'Template Guide',
templateGuideTitle: 'Dateinamen-Template Guide',
templateGuideIntro: 'Nutze Platzhalter fur Dateinamen und teste dein Muster mit einer Live-Vorschau.',
templateGuideTemplateLabel: 'Template',
templateGuideOutputLabel: 'Live-Vorschau',
templateGuideVarsTitle: 'Verfugbare Platzhalter',
templateGuideVarCol: 'Platzhalter',
templateGuideDescCol: 'Beschreibung',
templateGuideExampleCol: 'Beispiel',
templateGuideUseVod: 'VOD-Template nutzen',
templateGuideUseParts: 'Teile-Template nutzen',
templateGuideUseClip: 'Clip-Template nutzen',
templateGuideClose: 'Schliessen',
templateGuideContextVod: 'Kontext: Beispiel fur kompletten VOD-Download',
templateGuideContextParts: 'Kontext: Beispiel fur VOD-Teil',
templateGuideContextClip: 'Kontext: Beispiel fur Clip-Zuschnitt',
templateGuideContextClipLive: 'Kontext: Aktuelle Auswahl im Clip-Dialog',
runtimeMetricsTitle: 'Runtime Metrics',
runtimeMetricsRefresh: 'Aktualisieren',
runtimeMetricsExport: 'Export JSON',
runtimeMetricsAutoRefresh: 'Auto-Refresh',
runtimeMetricsLoading: 'Metriken werden geladen...',
runtimeMetricsError: 'Runtime-Metriken konnten nicht geladen werden.',
runtimeMetricsExportDone: 'Runtime-Metriken wurden exportiert.',
runtimeMetricsExportCancelled: 'Export der Runtime-Metriken abgebrochen.',
runtimeMetricsExportFailed: 'Export der Runtime-Metriken fehlgeschlagen.',
runtimeMetricQueue: 'Queue',
runtimeMetricMode: 'Modus',
runtimeMetricRetries: 'Retries',
runtimeMetricIntegrity: 'Integritatsfehler',
runtimeMetricCache: 'Cache',
runtimeMetricBandwidth: 'Bandbreite',
runtimeMetricDownloads: 'Downloads',
runtimeMetricActive: 'Aktiver Job',
runtimeMetricLastError: 'Letzte Fehlerklasse',
runtimeMetricUpdated: 'Aktualisiert',
updateTitle: 'Updates',
checkUpdates: 'Nach Updates suchen',
preflightTitle: 'System-Check',
preflightRun: 'Check ausfuhren',
preflightFix: 'Auto-Fix Tools',
preflightEmpty: 'Noch kein Check ausgefuhrt.',
preflightChecking: 'Prufe...',
preflightFixing: 'Fixe...',
preflightReady: 'Alles bereit.',
preflightInternet: 'Internet',
preflightStreamlink: 'Streamlink',
preflightFfmpeg: 'FFmpeg',
preflightFfprobe: 'FFprobe',
preflightPath: 'Download-Pfad',
debugLogTitle: 'Live Debug-Log',
refreshLog: 'Aktualisieren',
autoRefresh: 'Auto-Refresh',
notConnected: 'Nicht verbunden'
},
status: {
noLogin: 'Ohne Login (Public Modus)',
connecting: 'Verbinde...',
connected: 'Verbunden',
connectFailedPublic: 'Verbindung fehlgeschlagen - Public Modus aktiv'
},
tabs: {
vods: 'VODs',
clips: 'Clips',
cutter: 'Video schneiden',
merge: 'Videos zusammenfugen',
settings: 'Einstellungen'
},
queue: {
empty: 'Keine Downloads in der Warteschlange',
start: 'Start',
stop: 'Pausieren',
resume: 'Fortsetzen',
statusDone: 'Abgeschlossen',
statusFailed: 'Fehlgeschlagen',
statusRunning: 'Laeuft',
statusPaused: 'Pausiert',
statusWaiting: 'Wartet',
progressError: 'Fehler',
progressReady: 'Bereit',
progressLoading: 'Lade...',
readyToDownload: 'Bereit zum Download',
started: 'Download gestartet',
done: 'Fertig',
failed: 'Download fehlgeschlagen',
speed: 'Geschwindigkeit',
eta: 'Restzeit',
part: 'Teil',
emptyAlert: 'Die Warteschlange ist leer. Fuge zuerst ein VOD oder einen Clip hinzu.',
duplicateSkipped: 'Dieser Eintrag ist bereits aktiv in der Warteschlange.',
openFile: 'Datei oeffnen',
showInFolder: 'Im Ordner zeigen',
openFileFailed: 'Datei konnte nicht geoeffnet werden (evtl. verschoben oder geloescht).',
outputFilesLabel: '{count} Ausgabedateien',
retryItem: 'Diesen Eintrag erneut versuchen',
statusBarSummary: '{downloading} aktiv, {pending} wartet',
ctxMoveTop: 'Nach oben verschieben',
ctxMoveBottom: 'Nach unten verschieben',
ctxCopyUrl: 'URL kopieren',
ctxOpenOnTwitch: 'Auf Twitch oeffnen',
ctxRemove: 'Aus Queue entfernen',
ctxCopiedUrl: 'URL in Zwischenablage kopiert.'
},
vods: {
noneTitle: 'Keine VODs',
noneText: 'Wahle einen Streamer aus der Liste.',
loading: 'Lade VODs...',
notFound: 'Streamer nicht gefunden',
noResultsTitle: 'Keine VODs gefunden',
noResultsText: 'Dieser Streamer hat keine VODs.',
untitled: 'Unbenanntes VOD',
views: 'Aufrufe',
addQueue: '+ Warteschlange',
trimButton: 'VOD zuschneiden',
filterPlaceholder: 'Nach Titel filtern... (Strg+F)',
filterClearTitle: 'Filter loeschen (Esc)',
filterNoMatchTitle: 'Keine Treffer',
filterNoMatchText: 'Keine VODs entsprechen dem aktuellen Filter.',
filterMatchCount: '{shown} von {total} VODs',
sortLabel: 'Sortierung:',
sortDateDesc: 'Neueste zuerst',
sortDateAsc: 'Aelteste zuerst',
sortViewsDesc: 'Meiste Aufrufe',
sortDurationDesc: 'Laengste zuerst',
sortDurationAsc: 'Kuerzeste zuerst',
bulkSelectedCount: '{count} ausgewaehlt',
bulkAddToQueue: '+ Warteschlange',
bulkAdding: 'Fuege hinzu...',
bulkClear: 'Loeschen',
bulkAddedToQueue: '{count} VODs zur Warteschlange hinzugefuegt.',
bulkAddSkipped: 'Keine VODs hinzugefuegt (bereits in Queue oder ungueltig).',
bulkMarkDownloaded: 'Als heruntergeladen markieren',
bulkUnmark: 'Markierung entfernen',
bulkMarkedDownloaded: '{count} VODs als heruntergeladen markiert.',
bulkUnmarkedDownloaded: 'Markierung von {count} VODs entfernt.',
alreadyDownloaded: 'Bereits heruntergeladen',
hideDownloaded: 'Bereits geladene ausblenden',
hideDownloadedTitle: 'VODs ausblenden, die als bereits heruntergeladen markiert sind',
openOnTwitch: 'Auf Twitch oeffnen',
ctxOpenOnTwitch: 'Auf Twitch oeffnen',
ctxCopyUrl: 'VOD-URL kopieren',
ctxCopiedUrl: 'URL in Zwischenablage kopiert.',
ctxMarkDownloaded: 'Als heruntergeladen markieren',
ctxUnmarkDownloaded: 'Markierung entfernen'
},
clips: {
dialogTitle: 'VOD zuschneiden',
dialogStart: 'Start:',
dialogStartTime: 'Startzeit (HH:MM:SS):',
dialogEnd: 'Ende:',
dialogEndTime: 'Endzeit (HH:MM:SS):',
dialogDuration: 'Dauer: ',
dialogPartLabel: 'Start Part-Nummer (optional, fur Fortsetzung):',
dialogPartHint: 'Leer lassen = Teil 1',
dialogFormatLabel: 'Dateinamen-Format:',
dialogConfirm: 'Zur Queue hinzufuegen',
invalidDuration: 'Ungultig!',
endBeforeStart: 'Endzeit muss grosser als Startzeit sein!',
outOfRange: 'Zeit ausserhalb des VOD-Bereichs!',
enterUrl: 'Bitte URL eingeben',
loadingButton: 'Lade...',
loadingStatus: 'Download laeuft...',
downloadButton: 'Clip herunterladen',
success: 'Download erfolgreich!',
errorPrefix: 'Fehler: ',
unknownError: 'Unbekannter Fehler',
formatSimple: '(Standard)',
formatTimestamp: '(mit Zeitstempel)',
formatParts: '(Parts-Format)',
formatTemplate: '(benutzerdefiniert)',
templateEmpty: 'Das Template darf im benutzerdefinierten Modus nicht leer sein.',
templatePlaceholder: '{date}_{part}.mp4',
templateHelp: 'Platzhalter: {title} {id} {channel} {date} {part} {part_padded} {trim_start} {trim_end} {trim_length} {date_custom="yyyy-MM-dd"}'
},
cutter: {
videoInfoFailed: 'Konnte Video-Informationen nicht lesen. FFprobe installiert?',
previewLoading: 'Lade Vorschau...',
previewUnavailable: 'Vorschau nicht verfugbar',
cutting: 'Schneidet...',
cut: 'Schneiden',
cutSuccess: 'Video erfolgreich geschnitten!',
cutFailed: 'Fehler beim Schneiden des Videos.',
infoDuration: 'Dauer',
infoResolution: 'Aufloesung',
infoFps: 'FPS',
infoSelection: 'Auswahl',
startLabel: 'Start:',
endLabel: 'Ende:'
},
merge: {
empty: 'Keine Videos ausgewahlt',
merging: 'Zusammenfugen...',
merge: 'Zusammenfugen',
success: 'Videos erfolgreich zusammengefugt!',
failed: 'Fehler beim Zusammenfugen der Videos.'
},
mergeGroup: {
btn: 'Zusammenfugen & Splitten',
phaseDownloading: 'VOD wird heruntergeladen',
phaseMerging: 'Zusammenfugen...',
phaseSplitting: 'Part wird erstellt',
phaseCleanup: 'Aufraumen...',
needMinTwo: 'Mindestens 2 VODs auswahlen',
titleTwo: 'Merge: {title1} + {title2}',
titleMany: 'Merge: {title1} + {count} weitere',
metaLabel: '{count} VODs',
},
updates: {
bannerDefault: 'Neue Version verfugbar!',
latest: 'Du hast die neueste Version!',
checking: 'Suche nach Updates...',
checkInProgress: 'Update-Prufung lauft bereits.',
readyToInstall: 'Update ist bereit zur Installation.',
checkFailed: 'Update-Prufung fehlgeschlagen.',
downloading: 'Wird heruntergeladen...',
downloadInProgress: 'Update-Download lauft bereits.',
downloadFailed: 'Update-Download fehlgeschlagen.',
available: 'verfugbar!',
downloadNow: 'Jetzt herunterladen',
downloadLabel: 'Download',
ready: 'bereit zur Installation!',
installNow: 'Jetzt installieren & neu starten',
modalAvailableTitle: 'Update verfugbar',
modalAvailableMessage: 'Version {version} ist verfugbar. Jetzt herunterladen?',
modalReadyTitle: 'Update bereit',
modalReadyMessage: 'Version {version} wurde heruntergeladen. Jetzt installieren und neu starten?',
modalDismiss: 'Nein',
modalDownloadConfirm: 'Ja, herunterladen',
modalInstallConfirm: 'Ja, installieren',
modalSkipVersion: 'Diese Version ueberspringen',
changelogLabel: 'Changelog',
showChangelog: 'Changelog anzeigen',
hideChangelog: 'Changelog ausblenden',
noChangelog: 'Kein Changelog verfugbar.',
releasedLabel: 'Release'
}
} as const;