diff --git a/.eslintrc.js b/.eslintrc.js index 559b272c05..786a3229d1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -172,6 +172,13 @@ const rules = { '`with` is disallowed in strict mode because it makes code impossible to predict and optimize.', }, ], + + 'react-hooks/exhaustive-deps': [ + 'error', + { + additionalHooks: '^(useSpring|useSprings)$', + }, + ], }; const typescriptRules = { diff --git a/stylesheets/components/StoryProgressSegment.scss b/stylesheets/components/StoryProgressSegment.scss new file mode 100644 index 0000000000..5d791698f1 --- /dev/null +++ b/stylesheets/components/StoryProgressSegment.scss @@ -0,0 +1,26 @@ +// Copyright 2024 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +.StoryProgressSegment { + background: $color-white-alpha-40; + border-radius: 2px; + height: 2px; + margin-block: 12px 0; + margin-inline: 1px; + overflow: hidden; + width: 100%; +} + +.StoryProgressSegment__bar { + background: $color-white; + border-radius: 2px; + height: 100%; + &:dir(ltr) { + // stylelint-disable-next-line declaration-property-value-disallowed-list + transform: translateX(-100%); + } + &:dir(rtl) { + // stylelint-disable-next-line declaration-property-value-disallowed-list + transform: translateX(100%); + } +} diff --git a/stylesheets/components/StoryViewer.scss b/stylesheets/components/StoryViewer.scss index 3eee6ee19b..819dcdc3ce 100644 --- a/stylesheets/components/StoryViewer.scss +++ b/stylesheets/components/StoryViewer.scss @@ -303,30 +303,6 @@ &__progress { display: flex; - - &--container { - background: $color-white-alpha-40; - border-radius: 2px; - height: 2px; - margin-block: 12px 0; - margin-inline: 1px; - overflow: hidden; - width: 100%; - } - - &--bar { - background: $color-white; - border-radius: 2px; - height: 100%; - &:dir(ltr) { - // stylelint-disable-next-line declaration-property-value-disallowed-list - transform: translateX(-100%); - } - &:dir(rtl) { - // stylelint-disable-next-line declaration-property-value-disallowed-list - transform: translateX(100%); - } - } } &__animated-emojis { diff --git a/stylesheets/manifest.scss b/stylesheets/manifest.scss index 54b673b8a9..d51eff8990 100644 --- a/stylesheets/manifest.scss +++ b/stylesheets/manifest.scss @@ -162,6 +162,7 @@ @import './components/StoryImage.scss'; @import './components/StoryLinkPreview.scss'; @import './components/StoryListItem.scss'; +@import './components/StoryProgressSegment.scss'; @import './components/StoryReplyQuote.scss'; @import './components/StoryViewer.scss'; @import './components/StoryViewsNRepliesModal.scss'; diff --git a/ts/components/CallingRaisedHandsList.tsx b/ts/components/CallingRaisedHandsList.tsx index fa279860fa..aa77e281cf 100644 --- a/ts/components/CallingRaisedHandsList.tsx +++ b/ts/components/CallingRaisedHandsList.tsx @@ -174,6 +174,7 @@ export function CallingRaisedHandsListButton({ }: CallingRaisedHandsListButtonPropsType): JSX.Element | null { const [isVisible, setIsVisible] = React.useState(raisedHandsCount > 0); + // eslint-disable-next-line react-hooks/exhaustive-deps -- FIXME const [opacitySpringProps, opacitySpringApi] = useSpring( { from: { opacity: 0 }, @@ -182,6 +183,7 @@ export function CallingRaisedHandsListButton({ }, [] ); + // eslint-disable-next-line react-hooks/exhaustive-deps -- FIXME const [scaleSpringProps, scaleSpringApi] = useSpring( { from: { scale: 0.9 }, diff --git a/ts/components/Lightbox.tsx b/ts/components/Lightbox.tsx index ce339826c2..84e528aa26 100644 --- a/ts/components/Lightbox.tsx +++ b/ts/components/Lightbox.tsx @@ -322,6 +322,7 @@ export function Lightbox({ const thumbnailsMarginInlineStart = 0 - (selectedIndex * THUMBNAIL_FULL_WIDTH + THUMBNAIL_WIDTH / 2); + // eslint-disable-next-line react-hooks/exhaustive-deps -- FIXME const [thumbnailsStyle, thumbnailsAnimation] = useSpring( { config: THUMBNAIL_SPRING_CONFIG, diff --git a/ts/components/PlaybackButton.tsx b/ts/components/PlaybackButton.tsx index c66ac08aa8..89b9545a46 100644 --- a/ts/components/PlaybackButton.tsx +++ b/ts/components/PlaybackButton.tsx @@ -27,6 +27,7 @@ export type ButtonProps = { export const PlaybackButton = React.forwardRef( function ButtonInner(props, ref) { const { mod, label, variant, onClick, context, visible = true } = props; + // eslint-disable-next-line react-hooks/exhaustive-deps -- FIXME const [animProps] = useSpring( { config: SPRING_CONFIG, diff --git a/ts/components/PlaybackRateButton.tsx b/ts/components/PlaybackRateButton.tsx index 2f118d65ec..bb121bde7c 100644 --- a/ts/components/PlaybackRateButton.tsx +++ b/ts/components/PlaybackRateButton.tsx @@ -31,6 +31,7 @@ export function PlaybackRateButton({ }: Props): JSX.Element { const [isDown, setIsDown] = useState(false); + // eslint-disable-next-line react-hooks/exhaustive-deps -- FIXME const [animProps] = useSpring( { config: SPRING_CONFIG, diff --git a/ts/components/StoryImage.tsx b/ts/components/StoryImage.tsx index 7b33a54bd5..809366c127 100644 --- a/ts/components/StoryImage.tsx +++ b/ts/components/StoryImage.tsx @@ -124,7 +124,7 @@ export function StoryImage({ storyElement = (