diff --git a/package-lock.json b/package-lock.json index ab9650e..4ee8fae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "twitch-vod-manager", - "version": "5.0.13", + "version": "5.0.14", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "twitch-vod-manager", - "version": "5.0.13", + "version": "5.0.14", "license": "MIT", "dependencies": { "axios": "^1.16.1", diff --git a/package.json b/package.json index 50097b5..7fe8ec2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "twitch-vod-manager", - "version": "5.0.13", + "version": "5.0.14", "description": "Twitch VOD Manager - Download Twitch VODs easily", "main": "dist/main.js", "author": "xRangerDE", diff --git a/scripts/ui-screenshot2.js b/scripts/ui-screenshot2.js new file mode 100644 index 0000000..1a01149 --- /dev/null +++ b/scripts/ui-screenshot2.js @@ -0,0 +1,90 @@ +// UI-Screenshot Teil 2 — Modals, Hover-States, schmales Fenster, Queue mit +// aktivem Download. Ergaenzt ui-screenshot.js fuer die selteneren UI-Pfade. +const { _electron: electron } = require('playwright'); +const fs = require('fs'); +const path = require('path'); + +const OUT_DIR = path.join(process.cwd(), 'tmp_ui_shots'); + +async function run() { + fs.mkdirSync(OUT_DIR, { recursive: true }); + const electronPath = require('electron'); + const app = await electron.launch({ executablePath: electronPath, args: ['.'], cwd: process.cwd() }); + const win = await app.firstWindow(); + await win.setViewportSize({ width: 1280, height: 900 }); + await win.waitForTimeout(2500); + + const shot = async (name) => { + try { await win.screenshot({ path: path.join(OUT_DIR, `${name}.png`), animations: 'disabled', timeout: 8000 }); process.stdout.write(`shot: ${name}\n`); } + catch (e) { process.stdout.write(`shot FAILED: ${name} — ${String(e).split('\n')[0]}\n`); } + }; + + // VODs mit xqc laden fuer Modal-Kontext + await win.evaluate(() => window.showTab('vods')); + await win.evaluate(async () => { await window.selectStreamer('xqc'); }); + await win.waitForTimeout(4000); + + // 1. Clip/Trim-Dialog Modal (Trim VOD auf erster Card) + const trimBtn = win.locator('.vod-card .vod-btn.secondary').first(); + if (await trimBtn.count()) { + await trimBtn.click().catch(() => {}); + await win.waitForTimeout(800); + await shot('07-modal-trim'); + await win.keyboard.press('Escape'); + await win.waitForTimeout(400); + } + + // 2. Command Palette (Ctrl+K) + await win.keyboard.press('Control+K'); + await win.waitForTimeout(500); + await shot('08-command-palette'); + // Tippe etwas zum Filtern + await win.keyboard.type('set'); + await win.waitForTimeout(300); + await shot('08-command-palette-filtered'); + await win.keyboard.press('Escape'); + await win.waitForTimeout(300); + + // 3. Template Guide Modal (Settings -> Template-Guide oeffnen falls Button da) + await win.evaluate(() => window.showTab('settings')); + await win.waitForTimeout(500); + const tgOpened = await win.evaluate(() => { + if (typeof window.openTemplateGuide === 'function') { window.openTemplateGuide(); return true; } + return false; + }); + if (tgOpened) { + await win.waitForTimeout(700); + await shot('09-template-guide'); + await win.keyboard.press('Escape'); + await win.waitForTimeout(400); + } + + // 4. VOD-Card Hover (Storyboard-Preview) + await win.evaluate(() => window.showTab('vods')); + await win.waitForTimeout(800); + const firstCard = win.locator('.vod-card').first(); + if (await firstCard.count()) { + await firstCard.hover(); + await win.waitForTimeout(1200); // debounce + storyboard fetch + await shot('10-vod-hover'); + } + + // 5. Schmales Fenster (responsive) — 760px + await win.setViewportSize({ width: 760, height: 900 }); + await win.waitForTimeout(800); + await shot('11-narrow-vods'); + await win.evaluate(() => window.showTab('settings')); + await win.waitForTimeout(500); + await shot('11-narrow-settings'); + + // 6. Sehr schmal — 520px + await win.setViewportSize({ width: 520, height: 800 }); + await win.evaluate(() => window.showTab('vods')); + await win.waitForTimeout(800); + await shot('12-tiny-vods'); + + await app.close(); + process.stdout.write(`\nDone part 2.\n`); +} + +run().catch((e) => { process.stderr.write(String(e) + '\n'); process.exit(1); }); diff --git a/src/index.html b/src/index.html index 1adeedf..8b5b15c 100644 --- a/src/index.html +++ b/src/index.html @@ -821,10 +821,10 @@ placeholder="Suche Befehl..." autocomplete="off" spellcheck="false" - aria-label="Command Palette Suche" + aria-label="Command Palette" />
Up/Down zum Navigieren, Enter zum Ausfuhren, Esc zum Schliessen
+Up/Down zum Navigieren, Enter zum Ausfuehren, Esc zum Schliessen
diff --git a/src/renderer-command-palette.ts b/src/renderer-command-palette.ts index 63e2dfe..cb5f3e4 100644 --- a/src/renderer-command-palette.ts +++ b/src/renderer-command-palette.ts @@ -28,13 +28,15 @@ interface PaletteCommand { return []; } + // hint 'Open' statt 'Tab' — 'Tab' las sich wie eine Tastatur-Taste + // ('druecke Tab') statt 'oeffnet diesen Tab'. const tabs: Array<{ id: string; labels: string[]; hint: string }> = [ - { id: 'vods', labels: ['VODs', 'videos', 'streams'], hint: 'Tab' }, - { id: 'queue', labels: ['Queue', 'downloads', 'warteschlange'], hint: 'Tab' }, - { id: 'streamers', labels: ['Streamers', 'channels'], hint: 'Tab' }, - { id: 'stats', labels: ['Stats', 'statistiken', 'dashboard'], hint: 'Tab' }, - { id: 'archive', labels: ['Archive', 'archiv'], hint: 'Tab' }, - { id: 'settings', labels: ['Settings', 'einstellungen', 'config'], hint: 'Tab' }, + { id: 'vods', labels: ['VODs', 'videos', 'streams'], hint: 'Open' }, + { id: 'queue', labels: ['Queue', 'downloads', 'warteschlange'], hint: 'Open' }, + { id: 'streamers', labels: ['Streamers', 'channels'], hint: 'Open' }, + { id: 'stats', labels: ['Stats', 'statistiken', 'dashboard'], hint: 'Open' }, + { id: 'archive', labels: ['Archive', 'archiv'], hint: 'Open' }, + { id: 'settings', labels: ['Settings', 'einstellungen', 'config'], hint: 'Open' }, ]; const tabCommands: PaletteCommand[] = tabs.map(t => ({ diff --git a/src/renderer-locale-de.ts b/src/renderer-locale-de.ts index 10814a8..260332b 100644 --- a/src/renderer-locale-de.ts +++ b/src/renderer-locale-de.ts @@ -22,6 +22,8 @@ const UI_TEXT_DE = { cutterSelectTitle: 'Video auswahlen', cutterPreviewPlaceholder: 'Video auswahlen um Vorschau zu sehen', cutterBrowse: 'Durchsuchen', + commandPaletteSearchPlaceholder: 'Befehl suchen...', + commandPaletteHint: 'Up/Down zum Navigieren, Enter zum Ausfuehren, Esc zum Schliessen', mergeTitle: 'Videos zusammenfugen', mergeDesc: 'Wahle mehrere Videos aus, um sie zu einem Video zusammenzufugen. Die Reihenfolge kann geandert werden.', mergeAdd: '+ Videos hinzufugen', diff --git a/src/renderer-locale-en.ts b/src/renderer-locale-en.ts index ec960a7..e0e990f 100644 --- a/src/renderer-locale-en.ts +++ b/src/renderer-locale-en.ts @@ -22,6 +22,8 @@ const UI_TEXT_EN = { cutterSelectTitle: 'Select video', cutterPreviewPlaceholder: 'Select a video to see a preview', cutterBrowse: 'Browse', + commandPaletteSearchPlaceholder: 'Search command...', + commandPaletteHint: 'Up/Down to navigate, Enter to run, Esc to close', mergeTitle: 'Merge videos', mergeDesc: 'Select multiple videos to merge into one file. You can change the order before merging.', mergeAdd: '+ Add videos', diff --git a/src/renderer-texts.ts b/src/renderer-texts.ts index f52130b..5fe5503 100644 --- a/src/renderer-texts.ts +++ b/src/renderer-texts.ts @@ -120,6 +120,8 @@ function applyLanguageToStaticUI(): void { setText('cutterSelectTitle', UI_TEXT.static.cutterSelectTitle); setText('cutterPreviewPlaceholder', UI_TEXT.static.cutterPreviewPlaceholder); setText('cutterBrowseBtn', UI_TEXT.static.cutterBrowse); + setPlaceholder('commandPaletteInput', UI_TEXT.static.commandPaletteSearchPlaceholder); + setText('commandPaletteHint', UI_TEXT.static.commandPaletteHint); setText('cutterInfoDurationLabel', UI_TEXT.cutter.infoDuration); setText('cutterInfoResolutionLabel', UI_TEXT.cutter.infoResolution); setText('cutterInfoFpsLabel', UI_TEXT.cutter.infoFps);