mirror of
https://github.com/mastodon/mastodon.git
synced 2025-05-18 07:31:11 +00:00
Add controls for touch devices
This commit is contained in:
parent
3d4ebd08de
commit
e40b555195
|
@ -49,6 +49,8 @@ const restoreVolume = (audio: HTMLAudioElement) => {
|
||||||
audio.muted = muted;
|
audio.muted = muted;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const HOVER_FADE_DELAY = 4000;
|
||||||
|
|
||||||
export const Audio: React.FC<{
|
export const Audio: React.FC<{
|
||||||
src: string;
|
src: string;
|
||||||
alt?: string;
|
alt?: string;
|
||||||
|
@ -116,6 +118,7 @@ export const Audio: React.FC<{
|
||||||
const audioRef = useRef<HTMLAudioElement | null>(null);
|
const audioRef = useRef<HTMLAudioElement | null>(null);
|
||||||
const seekRef = useRef<HTMLDivElement>(null);
|
const seekRef = useRef<HTMLDivElement>(null);
|
||||||
const volumeRef = useRef<HTMLDivElement>(null);
|
const volumeRef = useRef<HTMLDivElement>(null);
|
||||||
|
const hoverTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>();
|
||||||
const frequencyBands = useAudioVisualizer(audioRef, 3);
|
const frequencyBands = useAudioVisualizer(audioRef, 3);
|
||||||
const accessibilityId = useId();
|
const accessibilityId = useId();
|
||||||
|
|
||||||
|
@ -372,10 +375,46 @@ export const Audio: React.FC<{
|
||||||
|
|
||||||
const handleMouseEnter = useCallback(() => {
|
const handleMouseEnter = useCallback(() => {
|
||||||
setHovered(true);
|
setHovered(true);
|
||||||
|
|
||||||
|
if (hoverTimeoutRef.current) {
|
||||||
|
clearTimeout(hoverTimeoutRef.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
hoverTimeoutRef.current = setTimeout(() => {
|
||||||
|
setHovered(false);
|
||||||
|
}, HOVER_FADE_DELAY);
|
||||||
|
}, [setHovered]);
|
||||||
|
|
||||||
|
const handleMouseMove = useCallback(() => {
|
||||||
|
setHovered(true);
|
||||||
|
|
||||||
|
if (hoverTimeoutRef.current) {
|
||||||
|
clearTimeout(hoverTimeoutRef.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
hoverTimeoutRef.current = setTimeout(() => {
|
||||||
|
setHovered(false);
|
||||||
|
}, HOVER_FADE_DELAY);
|
||||||
}, [setHovered]);
|
}, [setHovered]);
|
||||||
|
|
||||||
const handleMouseLeave = useCallback(() => {
|
const handleMouseLeave = useCallback(() => {
|
||||||
setHovered(false);
|
setHovered(false);
|
||||||
|
|
||||||
|
if (hoverTimeoutRef.current) {
|
||||||
|
clearTimeout(hoverTimeoutRef.current);
|
||||||
|
}
|
||||||
|
}, [setHovered]);
|
||||||
|
|
||||||
|
const handleTouchEnd = useCallback(() => {
|
||||||
|
setHovered(true);
|
||||||
|
|
||||||
|
if (hoverTimeoutRef.current) {
|
||||||
|
clearTimeout(hoverTimeoutRef.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
hoverTimeoutRef.current = setTimeout(() => {
|
||||||
|
setHovered(false);
|
||||||
|
}, HOVER_FADE_DELAY);
|
||||||
}, [setHovered]);
|
}, [setHovered]);
|
||||||
|
|
||||||
const handleLoadedData = useCallback(() => {
|
const handleLoadedData = useCallback(() => {
|
||||||
|
@ -518,7 +557,9 @@ export const Audio: React.FC<{
|
||||||
} as React.CSSProperties
|
} as React.CSSProperties
|
||||||
}
|
}
|
||||||
onMouseEnter={handleMouseEnter}
|
onMouseEnter={handleMouseEnter}
|
||||||
|
onMouseMove={handleMouseMove}
|
||||||
onMouseLeave={handleMouseLeave}
|
onMouseLeave={handleMouseLeave}
|
||||||
|
onTouchEnd={handleTouchEnd}
|
||||||
role='button'
|
role='button'
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
onKeyDownCapture={handleKeyDown}
|
onKeyDownCapture={handleKeyDown}
|
||||||
|
@ -577,6 +618,7 @@ export const Audio: React.FC<{
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='audio-player__controls'>
|
<div className='audio-player__controls'>
|
||||||
|
<div className='audio-player__controls__play'>
|
||||||
<button
|
<button
|
||||||
type='button'
|
type='button'
|
||||||
title={intl.formatMessage(messages.skipBackward)}
|
title={intl.formatMessage(messages.skipBackward)}
|
||||||
|
@ -586,6 +628,7 @@ export const Audio: React.FC<{
|
||||||
>
|
>
|
||||||
<Icon id='' icon={Replay5Icon} />
|
<Icon id='' icon={Replay5Icon} />
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className='audio-player__controls__play'>
|
<div className='audio-player__controls__play'>
|
||||||
<svg
|
<svg
|
||||||
|
@ -680,6 +723,7 @@ export const Audio: React.FC<{
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className='audio-player__controls__play'>
|
||||||
<button
|
<button
|
||||||
type='button'
|
type='button'
|
||||||
title={intl.formatMessage(messages.skipForward)}
|
title={intl.formatMessage(messages.skipForward)}
|
||||||
|
@ -690,6 +734,7 @@ export const Audio: React.FC<{
|
||||||
<Icon id='' icon={Forward5Icon} />
|
<Icon id='' icon={Forward5Icon} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<SpoilerButton
|
<SpoilerButton
|
||||||
hidden={revealed || editable}
|
hidden={revealed || editable}
|
||||||
|
|
|
@ -6969,6 +6969,7 @@ a.status-card {
|
||||||
outline: 1px solid var(--media-outline-color);
|
outline: 1px solid var(--media-outline-color);
|
||||||
outline-offset: -1px;
|
outline-offset: -1px;
|
||||||
aspect-ratio: 16 / 9;
|
aspect-ratio: 16 / 9;
|
||||||
|
container: audio-player / inline-size;
|
||||||
|
|
||||||
&__controls {
|
&__controls {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
@ -7065,6 +7066,13 @@ a.status-card {
|
||||||
color: currentColor;
|
color: currentColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@container audio-player (max-width: 400px) {
|
||||||
|
.video-player__time,
|
||||||
|
.player-button.video-player__download__icon {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.video-player__seek::before,
|
.video-player__seek::before,
|
||||||
.video-player__seek__buffer,
|
.video-player__seek__buffer,
|
||||||
.video-player__seek__progress {
|
.video-player__seek__progress {
|
||||||
|
@ -7132,10 +7140,12 @@ a.status-card {
|
||||||
);
|
);
|
||||||
padding: 0 15px;
|
padding: 0 15px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
transition: opacity 0.1s ease;
|
transition: opacity 0.1s ease;
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user