feat: Presenter Vor/Zurück-Spulen mit Folien-Sync
- prevSlide() in usePresenterMode: springt zur vorherigen Folie, stoppt aktuelle Audio, startet Präsentation der vorherigen Folie - SkipBack Button in PresenterOverlay neben SkipForward - Beide Buttons springen zur korrekten Folie UND starten die Audio Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -251,6 +251,7 @@ export default function PitchDeck({ lang, onToggleLanguage }: PitchDeckProps) {
|
|||||||
onResume={presenter.resume}
|
onResume={presenter.resume}
|
||||||
onStop={presenter.stop}
|
onStop={presenter.stop}
|
||||||
onSkip={presenter.skipSlide}
|
onSkip={presenter.skipSlide}
|
||||||
|
onPrev={presenter.prevSlide}
|
||||||
isSpeaking={presenter.isSpeaking}
|
isSpeaking={presenter.isSpeaking}
|
||||||
ttsAvailable={presenter.ttsAvailable}
|
ttsAvailable={presenter.ttsAvailable}
|
||||||
ttsEnabled={presenter.ttsEnabled}
|
ttsEnabled={presenter.ttsEnabled}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { motion, AnimatePresence } from 'framer-motion'
|
import { motion, AnimatePresence } from 'framer-motion'
|
||||||
import { Play, Pause, Square, SkipForward, Volume2, VolumeX } from 'lucide-react'
|
import { Play, Pause, Square, SkipForward, SkipBack, Volume2, VolumeX } from 'lucide-react'
|
||||||
import { Language } from '@/lib/types'
|
import { Language } from '@/lib/types'
|
||||||
import { PresenterState } from '@/lib/presenter/types'
|
import { PresenterState } from '@/lib/presenter/types'
|
||||||
import { SLIDE_ORDER } from '@/lib/hooks/useSlideNavigation'
|
import { SLIDE_ORDER } from '@/lib/hooks/useSlideNavigation'
|
||||||
@@ -18,6 +18,7 @@ interface PresenterOverlayProps {
|
|||||||
onResume: () => void
|
onResume: () => void
|
||||||
onStop: () => void
|
onStop: () => void
|
||||||
onSkip: () => void
|
onSkip: () => void
|
||||||
|
onPrev?: () => void
|
||||||
isSpeaking?: boolean
|
isSpeaking?: boolean
|
||||||
ttsAvailable?: boolean
|
ttsAvailable?: boolean
|
||||||
ttsEnabled?: boolean
|
ttsEnabled?: boolean
|
||||||
@@ -35,6 +36,7 @@ export default function PresenterOverlay({
|
|||||||
onResume,
|
onResume,
|
||||||
onStop,
|
onStop,
|
||||||
onSkip,
|
onSkip,
|
||||||
|
onPrev,
|
||||||
isSpeaking,
|
isSpeaking,
|
||||||
ttsAvailable,
|
ttsAvailable,
|
||||||
ttsEnabled = true,
|
ttsEnabled = true,
|
||||||
@@ -108,6 +110,15 @@ export default function PresenterOverlay({
|
|||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={onPrev}
|
||||||
|
className="w-7 h-7 rounded-full bg-white/10 flex items-center justify-center
|
||||||
|
hover:bg-white/20 transition-colors"
|
||||||
|
title={lang === 'de' ? 'Vorherige Folie' : 'Previous slide'}
|
||||||
|
>
|
||||||
|
<SkipBack className="w-3.5 h-3.5 text-white/60" />
|
||||||
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={onSkip}
|
onClick={onSkip}
|
||||||
className="w-7 h-7 rounded-full bg-white/10 flex items-center justify-center
|
className="w-7 h-7 rounded-full bg-white/10 flex items-center justify-center
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ interface UsePresenterModeReturn {
|
|||||||
pause: () => void
|
pause: () => void
|
||||||
resume: () => void
|
resume: () => void
|
||||||
skipSlide: () => void
|
skipSlide: () => void
|
||||||
|
prevSlide: () => void
|
||||||
toggle: () => void
|
toggle: () => void
|
||||||
displayText: string
|
displayText: string
|
||||||
progress: number
|
progress: number
|
||||||
@@ -386,6 +387,20 @@ export function usePresenterMode({
|
|||||||
}
|
}
|
||||||
}, [cancelAll, totalSlides, goToSlide])
|
}, [cancelAll, totalSlides, goToSlide])
|
||||||
|
|
||||||
|
const prevSlide = useCallback(() => {
|
||||||
|
cancelAll()
|
||||||
|
const prevIdx = slideIndexRef.current - 1
|
||||||
|
if (prevIdx >= 0) {
|
||||||
|
goToSlide(prevIdx)
|
||||||
|
slideIndexRef.current = prevIdx
|
||||||
|
if (stateRef.current === 'presenting' || stateRef.current === 'paused') {
|
||||||
|
setState('presenting')
|
||||||
|
stateRef.current = 'presenting'
|
||||||
|
playSlideRef.current(prevIdx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [cancelAll, goToSlide])
|
||||||
|
|
||||||
const toggle = useCallback(() => {
|
const toggle = useCallback(() => {
|
||||||
unlockAudio()
|
unlockAudio()
|
||||||
if (stateRef.current === 'idle') {
|
if (stateRef.current === 'idle') {
|
||||||
@@ -422,6 +437,7 @@ export function usePresenterMode({
|
|||||||
pause,
|
pause,
|
||||||
resume,
|
resume,
|
||||||
skipSlide,
|
skipSlide,
|
||||||
|
prevSlide,
|
||||||
toggle,
|
toggle,
|
||||||
displayText,
|
displayText,
|
||||||
progress,
|
progress,
|
||||||
|
|||||||
Reference in New Issue
Block a user