ソースを参照

Update visualization toggle logic

Use native inputs instead of React for state management.
pull/1/head
コミット
7fb2ff8c39
4個のファイルの変更78行の追加70行の削除
  1. +72
    -60
      packages/web-kitchensink-reactnext/src/categories/blob/react/components/AudioFilePreview/index.tsx
  2. +2
    -1
      packages/web-kitchensink-reactnext/src/categories/blob/react/components/VideoFilePreview/index.tsx
  3. +3
    -8
      packages/web-kitchensink-reactnext/src/categories/blob/react/hooks/interactive/media.ts
  4. +1
    -1
      packages/web-kitchensink-reactnext/src/pages/_document.tsx

+ 72
- 60
packages/web-kitchensink-reactnext/src/categories/blob/react/components/AudioFilePreview/index.tsx ファイルの表示

@@ -57,8 +57,7 @@ export const AudioFilePreview = React.forwardRef<AudioFilePreviewDerivedComponen
startSeek, startSeek,
endSeek, endSeek,
setSeek, setSeek,
visualizationMode,
handleVisualizationModeChange,
visualizationId,
} = useMediaControls<HTMLAudioElement>({ } = useMediaControls<HTMLAudioElement>({
controllerRef: forwardedRef, controllerRef: forwardedRef,
visualizationMode: 'waveform', visualizationMode: 'waveform',
@@ -115,91 +114,103 @@ export const AudioFilePreview = React.forwardRef<AudioFilePreviewDerivedComponen
</audio> </audio>
{enhanced && ( {enhanced && (
<> <>
<WaveformCanvas
className={clsx(
'absolute w-full sm:h-full top-0 left-0 block object-center object-contain flex-auto aspect-video sm:aspect-auto bg-primary/10 cursor-text',
visualizationMode !== 'waveform' && 'opacity-0',
)}
ref={mediaControllerRef}
data-testid="preview"
barWidth={1}
barGap={1}
progressColor={`rgb(${theme['color-primary']})`}
waveColor={`rgb(${theme['color-primary'].split(' ').map((c) => Math.floor(Number(c) / 2)).join(' ')})`}
interact
// waveColor={`rgb(${theme.primary})`}
// barHeight={4}
// minPxPerSec={20000}
// hideScrollbar
// autoCenter
// autoScroll
/>
<SpectrogramCanvas
className={clsx(
'absolute w-full sm:h-full top-0 left-0 block object-center object-contain flex-auto aspect-video sm:aspect-auto bg-primary/10 pointer-events-none',
visualizationMode !== 'spectrum' && 'opacity-0',
)}
ref={mediaControllerRef}
data-testid="preview"
barWidth={1}
barGap={1}
waveColor={`rgb(${theme['color-primary']})`}
cursorWidth={2}
minPxPerSec={20000}
hideScrollbar
autoCenter
autoScroll
/>
<div className="flex gap-4 absolute top-0 right-0 z-[5] px-4">
<label
className={clsx(
'h-12 flex items-center justify-center leading-none gap-4 select-none',
)}
>
<div className="flex justify-end w-full h-full gap-4 absolute top-0 right-0 z-[5] px-4">
<div className="contents">
<input <input
type="radio" type="radio"
name="visualizationMode" name="visualizationMode"
value="waveform" value="waveform"
className="sr-only peer/waveform" className="sr-only peer/waveform"
onChange={handleVisualizationModeChange}
defaultChecked defaultChecked
id={`${visualizationId}-waveform`}
/> />
<span
<label
htmlFor={`${visualizationId}-waveform`}
className={clsx( className={clsx(
'flex items-center uppercase font-bold h-full w-full whitespace-nowrap overflow-hidden text-ellipsis font-semi-expanded text-primary cursor-pointer',
'relative z-[5]',
'h-12 flex items-center justify-center leading-none gap-4 select-none',
'text-primary cursor-pointer',
'peer-focus/waveform:text-secondary', 'peer-focus/waveform:text-secondary',
'peer-active/waveform:text-tertiary', 'peer-active/waveform:text-tertiary',
'peer-checked/waveform:text-tertiary', 'peer-checked/waveform:text-tertiary',
'peer-disabled/waveform:text-primary peer-disabled/waveform:cursor-not-allowed peer-disabled/waveform:opacity-50', 'peer-disabled/waveform:text-primary peer-disabled/waveform:cursor-not-allowed peer-disabled/waveform:opacity-50',
)} )}
> >
Waveform
</span>
</label>
<label
className={clsx(
'h-12 flex items-center justify-center leading-none gap-4 select-none',
)}
<span
className={clsx(
'flex items-center uppercase font-bold h-full w-full whitespace-nowrap overflow-hidden text-ellipsis',
)}
>
Waveform
</span>
</label>
<WaveformCanvas
className={clsx(
'absolute w-full sm:h-full top-0 left-0 block object-center object-contain flex-auto aspect-video sm:aspect-auto bg-primary/10 cursor-text opacity-0',
'peer-checked/waveform:opacity-100',
)}
ref={mediaControllerRef}
data-testid="preview"
barWidth={1}
barGap={1}
progressColor={`rgb(${theme['color-primary']})`}
waveColor={`rgb(${theme['color-primary'].split(' ').map((c) => Math.floor(Number(c) / 2)).join(' ')})`}
interact
// waveColor={`rgb(${theme.primary})`}
// barHeight={4}
// minPxPerSec={20000}
// hideScrollbar
// autoCenter
// autoScroll
/>
</div>
<div
className="contents"
> >
<input <input
type="radio" type="radio"
name="visualizationMode" name="visualizationMode"
value="spectrum" value="spectrum"
className="sr-only peer/waveform" className="sr-only peer/waveform"
onChange={handleVisualizationModeChange}
id={`${visualizationId}-spectrum`}
/> />
<span
<label
htmlFor={`${visualizationId}-spectrum`}
className={clsx( className={clsx(
'flex items-center uppercase font-bold h-full w-full whitespace-nowrap overflow-hidden text-ellipsis font-semi-expanded text-primary cursor-pointer',
'relative z-[5]',
'h-12 flex items-center justify-center leading-none gap-4 select-none',
'text-primary cursor-pointer',
'peer-focus/waveform:text-secondary', 'peer-focus/waveform:text-secondary',
'peer-active/waveform:text-tertiary', 'peer-active/waveform:text-tertiary',
'peer-checked/waveform:text-tertiary', 'peer-checked/waveform:text-tertiary',
'peer-disabled/waveform:text-primary peer-disabled/waveform:cursor-not-allowed peer-disabled/waveform:opacity-50', 'peer-disabled/waveform:text-primary peer-disabled/waveform:cursor-not-allowed peer-disabled/waveform:opacity-50',
)} )}
> >
Spectrum
</span>
</label>
<span
className={clsx(
'flex items-center uppercase font-bold h-full w-full whitespace-nowrap overflow-hidden text-ellipsis',
)}
>
Spectrum
</span>
</label>
<SpectrogramCanvas
className={clsx(
'absolute w-full sm:h-full top-0 left-0 block object-center object-contain flex-auto aspect-video sm:aspect-auto bg-primary/10 pointer-events-none opacity-0',
'peer-checked/waveform:opacity-100',
)}
ref={mediaControllerRef}
data-testid="preview"
barWidth={1}
barGap={1}
waveColor={`rgb(${theme['color-primary']})`}
cursorWidth={2}
minPxPerSec={20000}
hideScrollbar
autoCenter
autoScroll
/>
</div>
</div> </div>
</> </>
)} )}
@@ -286,7 +297,7 @@ export const AudioFilePreview = React.forwardRef<AudioFilePreviewDerivedComponen
} }
> >
<Slider <Slider
className="w-full bg-negative text-base"
className="bg-negative text-base flex-auto"
ref={seekRef} ref={seekRef}
onMouseDown={startSeek} onMouseDown={startSeek}
onMouseUp={endSeek} onMouseUp={endSeek}
@@ -304,6 +315,7 @@ export const AudioFilePreview = React.forwardRef<AudioFilePreviewDerivedComponen
className="flex-shrink-0 w-12 flex items-center" className="flex-shrink-0 w-12 flex items-center"
> >
<Slider <Slider
className="flex-auto"
ref={volumeRef} ref={volumeRef}
max={1} max={1}
min={0} min={0}


+ 2
- 1
packages/web-kitchensink-reactnext/src/categories/blob/react/components/VideoFilePreview/index.tsx ファイルの表示

@@ -195,7 +195,7 @@ export const VideoFilePreview = React.forwardRef<VideoFilePreviewDerivedComponen
} }
> >
<Slider <Slider
className="w-full bg-negative text-base"
className="flex-auto bg-negative text-base"
ref={seekRef} ref={seekRef}
onMouseDown={startSeek} onMouseDown={startSeek}
onMouseUp={endSeek} onMouseUp={endSeek}
@@ -217,6 +217,7 @@ export const VideoFilePreview = React.forwardRef<VideoFilePreviewDerivedComponen
max={1} max={1}
min={0} min={0}
onChange={adjustVolume} onChange={adjustVolume}
className="flex-auto"
step="any" step="any"
defaultValue="1" defaultValue="1"
title="Volume" title="Volume"


+ 3
- 8
packages/web-kitchensink-reactnext/src/categories/blob/react/hooks/interactive/media.ts ファイルの表示

@@ -17,7 +17,7 @@ export const useMediaControls = <T extends HTMLMediaElement>({
const seekRef = React.useRef<HTMLInputElement>(null); const seekRef = React.useRef<HTMLInputElement>(null);
const volumeRef = React.useRef<HTMLInputElement>(null); const volumeRef = React.useRef<HTMLInputElement>(null);
const filenameRef = React.useRef<HTMLElement>(null); const filenameRef = React.useRef<HTMLElement>(null);
const [visualizationMode, setVisualizationMode] = React.useState(initialVisualizationMode);
const visualizationId = React.useId();
const [isPlaying, setIsPlaying] = React.useState(false); const [isPlaying, setIsPlaying] = React.useState(false);
const [isSeeking, setIsSeeking] = React.useState(false); const [isSeeking, setIsSeeking] = React.useState(false);
const [currentTimeDisplay, setCurrentTimeDisplay] = React.useState<number>(); const [currentTimeDisplay, setCurrentTimeDisplay] = React.useState<number>();
@@ -128,9 +128,6 @@ export const useMediaControls = <T extends HTMLMediaElement>({
downloadLink.click(); downloadLink.click();
}, [ref, filenameRef]); }, [ref, filenameRef]);


const handleVisualizationModeChange: React.ChangeEventHandler<HTMLInputElement> = React.useCallback((e) => {
setVisualizationMode(e.currentTarget.value);
}, []);


const actions = React.useMemo(() => ({ const actions = React.useMemo(() => ({
togglePlayback, togglePlayback,
@@ -245,8 +242,7 @@ export const useMediaControls = <T extends HTMLMediaElement>({
mediaControllerRef: ref, mediaControllerRef: ref,
handleAction, handleAction,
filenameRef, filenameRef,
visualizationMode,
handleVisualizationModeChange,
visualizationId,
}), [ }), [
refreshControls, refreshControls,
isPlaying, isPlaying,
@@ -264,7 +260,6 @@ export const useMediaControls = <T extends HTMLMediaElement>({
ref, ref,
handleAction, handleAction,
filenameRef, filenameRef,
visualizationMode,
handleVisualizationModeChange,
visualizationId,
]); ]);
}; };

+ 1
- 1
packages/web-kitchensink-reactnext/src/pages/_document.tsx ファイルの表示

@@ -3,7 +3,7 @@ import theme from '@/styles/theme'


export default function Document() { export default function Document() {
return ( return (
<Html lang="en" className="bg-negative text-positive mt-8 mb-16 md:mt-16 md:mb-32">
<Html lang="en" className="bg-negative text-positive mt-8 mb-16 md:mt-16 md:mb-32 tracking-normal font-semi-expanded">
<Head className="block"> <Head className="block">
<style <style
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{


読み込み中…
キャンセル
保存