Implement group story reply deletion
This commit is contained in:
parent
7164b603e9
commit
4445ef80eb
26 changed files with 1218 additions and 934 deletions
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { useCallback, useRef, useEffect, useState } from 'react';
|
||||
import type { RefObject, ReactNode } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { noop } from 'lodash';
|
||||
import { animated, useSpring } from '@react-spring/web';
|
||||
|
@ -18,6 +19,7 @@ import type { ActiveAudioPlayerStateType } from '../../state/ducks/audioPlayer';
|
|||
|
||||
export type OwnProps = Readonly<{
|
||||
active: ActiveAudioPlayerStateType | undefined;
|
||||
buttonRef: RefObject<HTMLButtonElement>;
|
||||
renderingContext: string;
|
||||
i18n: LocalizerType;
|
||||
attachment: AttachmentType;
|
||||
|
@ -66,6 +68,7 @@ type ButtonProps = {
|
|||
onClick: () => void;
|
||||
onMouseDown?: () => void;
|
||||
onMouseUp?: () => void;
|
||||
children?: ReactNode;
|
||||
};
|
||||
|
||||
enum State {
|
||||
|
@ -122,73 +125,77 @@ const timeToText = (time: number): string => {
|
|||
* Handles animations, key events, and stoping event propagation
|
||||
* for play button and playback rate button
|
||||
*/
|
||||
const Button: React.FC<ButtonProps> = props => {
|
||||
const {
|
||||
i18n,
|
||||
variant,
|
||||
mod,
|
||||
label,
|
||||
children,
|
||||
onClick,
|
||||
visible = true,
|
||||
animateClick = true,
|
||||
} = props;
|
||||
const [isDown, setIsDown] = useState(false);
|
||||
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
(props, ref) => {
|
||||
const {
|
||||
i18n,
|
||||
variant,
|
||||
mod,
|
||||
label,
|
||||
children,
|
||||
onClick,
|
||||
visible = true,
|
||||
animateClick = true,
|
||||
} = props;
|
||||
const [isDown, setIsDown] = useState(false);
|
||||
|
||||
const [animProps] = useSpring(
|
||||
{
|
||||
config: SPRING_CONFIG,
|
||||
to: isDown && animateClick ? { scale: 1.3 } : { scale: visible ? 1 : 0 },
|
||||
},
|
||||
[visible, isDown, animateClick]
|
||||
);
|
||||
const [animProps] = useSpring(
|
||||
{
|
||||
config: SPRING_CONFIG,
|
||||
to:
|
||||
isDown && animateClick ? { scale: 1.3 } : { scale: visible ? 1 : 0 },
|
||||
},
|
||||
[visible, isDown, animateClick]
|
||||
);
|
||||
|
||||
// Clicking button toggle playback
|
||||
const onButtonClick = useCallback(
|
||||
(event: React.MouseEvent) => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
// Clicking button toggle playback
|
||||
const onButtonClick = useCallback(
|
||||
(event: React.MouseEvent) => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
onClick();
|
||||
},
|
||||
[onClick]
|
||||
);
|
||||
onClick();
|
||||
},
|
||||
[onClick]
|
||||
);
|
||||
|
||||
// Keyboard playback toggle
|
||||
const onButtonKeyDown = useCallback(
|
||||
(event: React.KeyboardEvent) => {
|
||||
if (event.key !== 'Enter' && event.key !== 'Space') {
|
||||
return;
|
||||
}
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
// Keyboard playback toggle
|
||||
const onButtonKeyDown = useCallback(
|
||||
(event: React.KeyboardEvent) => {
|
||||
if (event.key !== 'Enter' && event.key !== 'Space') {
|
||||
return;
|
||||
}
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
onClick();
|
||||
},
|
||||
[onClick]
|
||||
);
|
||||
onClick();
|
||||
},
|
||||
[onClick]
|
||||
);
|
||||
|
||||
return (
|
||||
<animated.div style={animProps}>
|
||||
<button
|
||||
type="button"
|
||||
className={classNames(
|
||||
`${CSS_BASE}__${variant}-button`,
|
||||
mod ? `${CSS_BASE}__${variant}-button--${mod}` : undefined
|
||||
)}
|
||||
onClick={onButtonClick}
|
||||
onKeyDown={onButtonKeyDown}
|
||||
onMouseDown={() => setIsDown(true)}
|
||||
onMouseUp={() => setIsDown(false)}
|
||||
onMouseLeave={() => setIsDown(false)}
|
||||
tabIndex={0}
|
||||
aria-label={i18n(label)}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
</animated.div>
|
||||
);
|
||||
};
|
||||
return (
|
||||
<animated.div style={animProps}>
|
||||
<button
|
||||
type="button"
|
||||
ref={ref}
|
||||
className={classNames(
|
||||
`${CSS_BASE}__${variant}-button`,
|
||||
mod ? `${CSS_BASE}__${variant}-button--${mod}` : undefined
|
||||
)}
|
||||
onClick={onButtonClick}
|
||||
onKeyDown={onButtonKeyDown}
|
||||
onMouseDown={() => setIsDown(true)}
|
||||
onMouseUp={() => setIsDown(false)}
|
||||
onMouseLeave={() => setIsDown(false)}
|
||||
tabIndex={0}
|
||||
aria-label={i18n(label)}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
</animated.div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
const PlayedDot = ({
|
||||
played,
|
||||
|
@ -242,6 +249,7 @@ const PlayedDot = ({
|
|||
export const MessageAudio: React.FC<Props> = (props: Props) => {
|
||||
const {
|
||||
active,
|
||||
buttonRef,
|
||||
i18n,
|
||||
renderingContext,
|
||||
attachment,
|
||||
|
@ -506,6 +514,7 @@ export const MessageAudio: React.FC<Props> = (props: Props) => {
|
|||
} else if (state === State.NotDownloaded) {
|
||||
button = (
|
||||
<Button
|
||||
ref={buttonRef}
|
||||
i18n={i18n}
|
||||
variant="play"
|
||||
mod="download"
|
||||
|
@ -518,6 +527,7 @@ export const MessageAudio: React.FC<Props> = (props: Props) => {
|
|||
// State.Normal
|
||||
button = (
|
||||
<Button
|
||||
ref={buttonRef}
|
||||
i18n={i18n}
|
||||
variant="play"
|
||||
mod={isPlaying ? 'pause' : 'play'}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue