mirror of
https://github.com/Andre-Bzk/twitch4steamdeck.git
synced 2026-11-15 15:43:08 +01:00
refactor: remove duplicate VOD start and chapter panel helpers
handleWatchVodFromChapter was identical to handleWatchVod except for an optional startSeconds argument that the bridge already supports. Merged into a single function with startSeconds?: number. openChapterPanel was a wrapper around showChapterPanel whose two branches both executed the same code. Removed the wrapper; call sites now call showChapterPanel directly. Also removes stale mpv references from CLAUDE.md that were superseded by the hls.js migration commit.
This commit is contained in:
@@ -84,8 +84,6 @@ bash flatpak/build-flatpak.sh
|
|||||||
```
|
```
|
||||||
Das Skript: prüft deps → npm-Build → Python-Deps generieren → Streamlink-Tarballs hashen → `flatpak-builder` → SCP zum Steam Deck.
|
Das Skript: prüft deps → npm-Build → Python-Deps generieren → Streamlink-Tarballs hashen → `flatpak-builder` → SCP zum Steam Deck.
|
||||||
|
|
||||||
> **Hinweis:** Das Flatpak-Manifest (`flatpak/tv.twitch4steamdeck.App.yml`) enthält noch mpv als Dependency — muss bereinigt werden, sobald der hls.js-Ansatz auf dem Steam Deck getestet und bestätigt ist.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Codebase-Struktur
|
## Codebase-Struktur
|
||||||
@@ -154,11 +152,10 @@ scripts/
|
|||||||
test-playback-pipeline.mjs — Standalone-Test: streamlink → HLS-URL → Manifest → Segment (node scripts/test-playback-pipeline.mjs twitch.tv/<kanal>)
|
test-playback-pipeline.mjs — Standalone-Test: streamlink → HLS-URL → Manifest → Segment (node scripts/test-playback-pipeline.mjs twitch.tv/<kanal>)
|
||||||
|
|
||||||
flatpak/
|
flatpak/
|
||||||
tv.twitch4steamdeck.App.yml — Flatpak-Manifest (Streamlink, alle Native-Deps; mpv-Einträge noch zu bereinigen)
|
tv.twitch4steamdeck.App.yml — Flatpak-Manifest (Streamlink, alle Native-Deps)
|
||||||
build-flatpak.sh — 6-Schritt Build-Pipeline (WSL2)
|
build-flatpak.sh — 6-Schritt Build-Pipeline (WSL2)
|
||||||
twitch4steamdeck.sh — Launcher mit zypak-wrapper
|
twitch4steamdeck.sh — Launcher mit zypak-wrapper
|
||||||
tv.twitch4steamdeck.App.desktop
|
tv.twitch4steamdeck.App.desktop
|
||||||
patches/mpv-ffmpeg7-avio-const.patch — (obsolet nach mpv-Entfernung)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -259,7 +256,7 @@ Wenn der User während der Wiedergabe das Kapitel-Panel öffnet (Y-Taste), läuf
|
|||||||
|
|
||||||
| Problem | Status | Details |
|
| Problem | Status | Details |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| hls.js Performance auf Steam Deck | Ungetestet | Chromiums VA-API Hardware-Decode sollte ausreichen. Falls Dropped Frames bei 1080p60 → Qualitäts-Button im Overlay nutzen (720p60 wählen) oder mpv-Fallback evaluieren. |
|
| hls.js Performance auf Steam Deck | Ungetestet | Chromiums VA-API Hardware-Decode sollte ausreichen. Falls Dropped Frames bei 1080p60 → Qualitäts-Button im Overlay nutzen (720p60 wählen). |
|
||||||
| Twitch Live-Stream URL-Expiry | Unkritisch | `streamlink --stream-url` Token in URL kann ablaufen. hls.js handelt Playlist-Refresh automatisch; bei Verbindungsabbruch muss neu gestartet werden. |
|
| Twitch Live-Stream URL-Expiry | Unkritisch | `streamlink --stream-url` Token in URL kann ablaufen. hls.js handelt Playlist-Refresh automatisch; bei Verbindungsabbruch muss neu gestartet werden. |
|
||||||
| Ad-Bypass | Nicht implementiert | `--twitch-disable-ads` von Streamlink deprecated. Post-MVP. |
|
| Ad-Bypass | Nicht implementiert | `--twitch-disable-ads` von Streamlink deprecated. Post-MVP. |
|
||||||
| Flaggen-Emojis auf Windows | Nur Rechtecke | Unicode Regional Indicators brauchen Noto Color Emoji (Linux). Im Dev-Mode ignorieren. |
|
| Flaggen-Emojis auf Windows | Nur Rechtecke | Unicode Regional Indicators brauchen Noto Color Emoji (Linux). Im Dev-Mode ignorieren. |
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ export default function ChannelScreen({ channel, onBack }: Props): JSX.Element {
|
|||||||
setFocusRegion('hero')
|
setFocusRegion('hero')
|
||||||
} else {
|
} else {
|
||||||
if (chapter) {
|
if (chapter) {
|
||||||
void handleWatchVodFromChapter(vod, chapter.positionSeconds)
|
void handleWatchVod(vod, chapter.positionSeconds)
|
||||||
} else {
|
} else {
|
||||||
void handleWatchVod(vod)
|
void handleWatchVod(vod)
|
||||||
setChapterPanelVod(null)
|
setChapterPanelVod(null)
|
||||||
@@ -229,7 +229,7 @@ export default function ChannelScreen({ channel, onBack }: Props): JSX.Element {
|
|||||||
case 'y': {
|
case 'y': {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
const vod = currentVod ?? vods[shelfIndex]
|
const vod = currentVod ?? vods[shelfIndex]
|
||||||
if (vod) openChapterPanel(vod, true)
|
if (vod) showChapterPanel(vod)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case 'x':
|
case 'x':
|
||||||
@@ -273,7 +273,7 @@ export default function ChannelScreen({ channel, onBack }: Props): JSX.Element {
|
|||||||
if (e.key === 'y') {
|
if (e.key === 'y') {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
const vod = vods[shelfIndex]
|
const vod = vods[shelfIndex]
|
||||||
if (vod) openChapterPanel(vod, false)
|
if (vod) showChapterPanel(vod)
|
||||||
} else if (e.key === 'ArrowLeft') {
|
} else if (e.key === 'ArrowLeft') {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
setShelfIndex((i) => Math.max(0, i - 1))
|
setShelfIndex((i) => Math.max(0, i - 1))
|
||||||
@@ -413,54 +413,7 @@ export default function ChannelScreen({ channel, onBack }: Props): JSX.Element {
|
|||||||
.catch(() => setAvailableQualities([]))
|
.catch(() => setAvailableQualities([]))
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleWatchVod = async (vod: VodInfo): Promise<void> => {
|
const handleWatchVod = async (vod: VodInfo, startSeconds?: number): Promise<void> => {
|
||||||
setPlayState('starting')
|
|
||||||
setErrorMsg('')
|
|
||||||
setFocusRegion('hero')
|
|
||||||
setChapterPanelVod(null)
|
|
||||||
setCurrentVod(vod)
|
|
||||||
setPendingChapterVod(null)
|
|
||||||
setVodChaptersLoaded(false)
|
|
||||||
setAvailableQualities(undefined)
|
|
||||||
setCurrentQuality('best')
|
|
||||||
setQualityPanelOpen(false)
|
|
||||||
void loadChapters(vod.id)
|
|
||||||
.then((loaded) => { setChapters(loaded); setVodChaptersLoaded(true) })
|
|
||||||
.catch(() => { setVodChaptersLoaded(true) })
|
|
||||||
try {
|
|
||||||
await window.t4sd.playback.startVod(
|
|
||||||
vod.id,
|
|
||||||
channel.broadcasterLogin,
|
|
||||||
vod.title,
|
|
||||||
vod.durationSeconds
|
|
||||||
)
|
|
||||||
} catch (e) {
|
|
||||||
setPlayState('error')
|
|
||||||
setErrorMsg(String(e))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
window.t4sd.playback.getQualities(`twitch.tv/videos/${vod.id}`)
|
|
||||||
.then((qs) => setAvailableQualities(qs.length > 0 ? qs : []))
|
|
||||||
.catch(() => setAvailableQualities([]))
|
|
||||||
}
|
|
||||||
|
|
||||||
const openChapterPanel = (vod: VodInfo, duringPlayback: boolean): void => {
|
|
||||||
if (duringPlayback) {
|
|
||||||
setChapterPanelVod(vod)
|
|
||||||
setChapters([])
|
|
||||||
setChapterIndex(0)
|
|
||||||
setChaptersLoading(true)
|
|
||||||
setFocusRegion('chapters')
|
|
||||||
void loadChapters(vod.id)
|
|
||||||
.then((loaded) => setChapters(loaded))
|
|
||||||
.catch(() => {})
|
|
||||||
.finally(() => setChaptersLoading(false))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
showChapterPanel(vod)
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleWatchVodFromChapter = async (vod: VodInfo, startSeconds: number): Promise<void> => {
|
|
||||||
setPlayState('starting')
|
setPlayState('starting')
|
||||||
setErrorMsg('')
|
setErrorMsg('')
|
||||||
setFocusRegion('hero')
|
setFocusRegion('hero')
|
||||||
@@ -815,7 +768,7 @@ export default function ChannelScreen({ channel, onBack }: Props): JSX.Element {
|
|||||||
}}
|
}}
|
||||||
onChangeQuality={(q) => void handleQualityChange(q)}
|
onChangeQuality={(q) => void handleQualityChange(q)}
|
||||||
onOpenChapters={!isLivePlayback && currentVod
|
onOpenChapters={!isLivePlayback && currentVod
|
||||||
? () => openChapterPanel(currentVod, true)
|
? () => showChapterPanel(currentVod)
|
||||||
: undefined}
|
: undefined}
|
||||||
onTogglePause={() => {
|
onTogglePause={() => {
|
||||||
if (playState === 'playing') {
|
if (playState === 'playing') {
|
||||||
|
|||||||
Reference in New Issue
Block a user