mirror of
https://github.com/mastodon/mastodon.git
synced 2025-11-27 10:00:50 +00:00
Update to latest eslint-plugin-react-hooks (#36702)
Co-authored-by: diondiondion <mail@diondiondion.com>
This commit is contained in:
parent
4ddddc2573
commit
9addad8ce5
|
|
@ -47,7 +47,7 @@ export const AltTextBadge: React.FC<{ description: string }> = ({
|
||||||
rootClose
|
rootClose
|
||||||
onHide={handleClose}
|
onHide={handleClose}
|
||||||
show={open}
|
show={open}
|
||||||
target={anchorRef.current}
|
target={anchorRef}
|
||||||
placement='top-end'
|
placement='top-end'
|
||||||
flip
|
flip
|
||||||
offset={offset}
|
offset={offset}
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,11 @@ export const Carousel = <
|
||||||
// Handle slide change
|
// Handle slide change
|
||||||
const [slideIndex, setSlideIndex] = useState(0);
|
const [slideIndex, setSlideIndex] = useState(0);
|
||||||
const wrapperRef = useRef<HTMLDivElement>(null);
|
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||||
|
// Handle slide heights
|
||||||
|
const [currentSlideHeight, setCurrentSlideHeight] = useState(
|
||||||
|
() => wrapperRef.current?.scrollHeight ?? 0,
|
||||||
|
);
|
||||||
|
const previousSlideHeight = usePrevious(currentSlideHeight);
|
||||||
const handleSlideChange = useCallback(
|
const handleSlideChange = useCallback(
|
||||||
(direction: number) => {
|
(direction: number) => {
|
||||||
setSlideIndex((prev) => {
|
setSlideIndex((prev) => {
|
||||||
|
|
@ -101,16 +106,11 @@ export const Carousel = <
|
||||||
[items.length, onChangeSlide],
|
[items.length, onChangeSlide],
|
||||||
);
|
);
|
||||||
|
|
||||||
// Handle slide heights
|
const observerRef = useRef<ResizeObserver | null>(null);
|
||||||
const [currentSlideHeight, setCurrentSlideHeight] = useState(
|
observerRef.current ??= new ResizeObserver(() => {
|
||||||
wrapperRef.current?.scrollHeight ?? 0,
|
|
||||||
);
|
|
||||||
const previousSlideHeight = usePrevious(currentSlideHeight);
|
|
||||||
const observerRef = useRef<ResizeObserver>(
|
|
||||||
new ResizeObserver(() => {
|
|
||||||
handleSlideChange(0);
|
handleSlideChange(0);
|
||||||
}),
|
});
|
||||||
);
|
|
||||||
const wrapperStyles = useSpring({
|
const wrapperStyles = useSpring({
|
||||||
x: `-${slideIndex * 100}%`,
|
x: `-${slideIndex * 100}%`,
|
||||||
height: currentSlideHeight,
|
height: currentSlideHeight,
|
||||||
|
|
@ -200,7 +200,7 @@ export const Carousel = <
|
||||||
};
|
};
|
||||||
|
|
||||||
type CarouselSlideWrapperProps<SlideProps extends CarouselSlideProps> = {
|
type CarouselSlideWrapperProps<SlideProps extends CarouselSlideProps> = {
|
||||||
observer: ResizeObserver;
|
observer: ResizeObserver | null;
|
||||||
className: string;
|
className: string;
|
||||||
active: boolean;
|
active: boolean;
|
||||||
item: SlideProps;
|
item: SlideProps;
|
||||||
|
|
@ -217,7 +217,7 @@ const CarouselSlideWrapper = <SlideProps extends CarouselSlideProps>({
|
||||||
}: CarouselSlideWrapperProps<SlideProps>) => {
|
}: CarouselSlideWrapperProps<SlideProps>) => {
|
||||||
const handleRef = useCallback(
|
const handleRef = useCallback(
|
||||||
(instance: HTMLDivElement | null) => {
|
(instance: HTMLDivElement | null) => {
|
||||||
if (instance) {
|
if (observer && instance) {
|
||||||
observer.observe(instance);
|
observer.observe(instance);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useCallback, useState, useEffect, useRef } from 'react';
|
import { useCallback, useState, useRef } from 'react';
|
||||||
|
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
|
@ -12,11 +12,15 @@ export const ColumnSearchHeader: React.FC<{
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
const [value, setValue] = useState('');
|
const [value, setValue] = useState('');
|
||||||
|
|
||||||
useEffect(() => {
|
// Reset the component when it turns from active to inactive.
|
||||||
|
// [More on this pattern](https://react.dev/learn/you-might-not-need-an-effect#adjusting-some-state-when-a-prop-changes)
|
||||||
|
const [previousActive, setPreviousActive] = useState(active);
|
||||||
|
if (active !== previousActive) {
|
||||||
|
setPreviousActive(active);
|
||||||
if (!active) {
|
if (!active) {
|
||||||
setValue('');
|
setValue('');
|
||||||
}
|
}
|
||||||
}, [active]);
|
}
|
||||||
|
|
||||||
const handleChange = useCallback(
|
const handleChange = useCallback(
|
||||||
({ target: { value } }: React.ChangeEvent<HTMLInputElement>) => {
|
({ target: { value } }: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ export const Dropdown: FC<
|
||||||
placement='bottom-start'
|
placement='bottom-start'
|
||||||
onHide={handleClose}
|
onHide={handleClose}
|
||||||
flip
|
flip
|
||||||
target={buttonRef.current}
|
target={buttonRef}
|
||||||
popperConfig={{
|
popperConfig={{
|
||||||
strategy: 'fixed',
|
strategy: 'fixed',
|
||||||
modifiers: [matchWidth],
|
modifiers: [matchWidth],
|
||||||
|
|
|
||||||
|
|
@ -27,22 +27,23 @@ export const ExitAnimationWrapper: React.FC<{
|
||||||
*/
|
*/
|
||||||
children: (delayedIsActive: boolean) => React.ReactNode;
|
children: (delayedIsActive: boolean) => React.ReactNode;
|
||||||
}> = ({ isActive = false, delayMs = 500, withEntryDelay, children }) => {
|
}> = ({ isActive = false, delayMs = 500, withEntryDelay, children }) => {
|
||||||
const [delayedIsActive, setDelayedIsActive] = useState(false);
|
const [delayedIsActive, setDelayedIsActive] = useState(
|
||||||
|
isActive && !withEntryDelay,
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isActive && !withEntryDelay) {
|
const withDelay = !isActive || withEntryDelay;
|
||||||
setDelayedIsActive(true);
|
|
||||||
|
|
||||||
return () => '';
|
const timeout = setTimeout(
|
||||||
} else {
|
() => {
|
||||||
const timeout = setTimeout(() => {
|
|
||||||
setDelayedIsActive(isActive);
|
setDelayedIsActive(isActive);
|
||||||
}, delayMs);
|
},
|
||||||
|
withDelay ? delayMs : 0,
|
||||||
|
);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
};
|
};
|
||||||
}
|
|
||||||
}, [isActive, delayMs, withEntryDelay]);
|
}, [isActive, delayMs, withEntryDelay]);
|
||||||
|
|
||||||
if (!isActive && !delayedIsActive) {
|
if (!isActive && !delayedIsActive) {
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ export const HoverCardController: React.FC = () => {
|
||||||
const [setLeaveTimeout, cancelLeaveTimeout] = useTimeout();
|
const [setLeaveTimeout, cancelLeaveTimeout] = useTimeout();
|
||||||
const [setEnterTimeout, cancelEnterTimeout, delayEnterTimeout] = useTimeout();
|
const [setEnterTimeout, cancelEnterTimeout, delayEnterTimeout] = useTimeout();
|
||||||
const [setScrollTimeout] = useTimeout();
|
const [setScrollTimeout] = useTimeout();
|
||||||
const location = useLocation();
|
|
||||||
|
|
||||||
const handleClose = useCallback(() => {
|
const handleClose = useCallback(() => {
|
||||||
cancelEnterTimeout();
|
cancelEnterTimeout();
|
||||||
|
|
@ -36,9 +35,12 @@ export const HoverCardController: React.FC = () => {
|
||||||
setAnchor(null);
|
setAnchor(null);
|
||||||
}, [cancelEnterTimeout, cancelLeaveTimeout, setOpen, setAnchor]);
|
}, [cancelEnterTimeout, cancelLeaveTimeout, setOpen, setAnchor]);
|
||||||
|
|
||||||
useEffect(() => {
|
const location = useLocation();
|
||||||
|
const [previousLocation, setPreviousLocation] = useState(location);
|
||||||
|
if (location !== previousLocation) {
|
||||||
|
setPreviousLocation(location);
|
||||||
handleClose();
|
handleClose();
|
||||||
}, [handleClose, location]);
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let isScrolling = false;
|
let isScrolling = false;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useState, useEffect, useCallback, forwardRef } from 'react';
|
import { useCallback, forwardRef } from 'react';
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
|
@ -55,23 +55,6 @@ export const IconButton = forwardRef<HTMLButtonElement, Props>(
|
||||||
},
|
},
|
||||||
buttonRef,
|
buttonRef,
|
||||||
) => {
|
) => {
|
||||||
const [activate, setActivate] = useState(false);
|
|
||||||
const [deactivate, setDeactivate] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!animate) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (activate && !active) {
|
|
||||||
setActivate(false);
|
|
||||||
setDeactivate(true);
|
|
||||||
} else if (!activate && active) {
|
|
||||||
setActivate(true);
|
|
||||||
setDeactivate(false);
|
|
||||||
}
|
|
||||||
}, [setActivate, setDeactivate, animate, active, activate]);
|
|
||||||
|
|
||||||
const handleClick: React.MouseEventHandler<HTMLButtonElement> = useCallback(
|
const handleClick: React.MouseEventHandler<HTMLButtonElement> = useCallback(
|
||||||
(e) => {
|
(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
@ -112,8 +95,8 @@ export const IconButton = forwardRef<HTMLButtonElement, Props>(
|
||||||
active,
|
active,
|
||||||
disabled,
|
disabled,
|
||||||
inverted,
|
inverted,
|
||||||
activate,
|
activate: animate && active,
|
||||||
deactivate,
|
deactivate: animate && !active,
|
||||||
overlayed: overlay,
|
overlayed: overlay,
|
||||||
'icon-button--with-counter': typeof counter !== 'undefined',
|
'icon-button--with-counter': typeof counter !== 'undefined',
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,9 @@ const messages = defineMessages({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isPollExpired = (expiresAt: Model.Poll['expires_at']) =>
|
||||||
|
new Date(expiresAt).getTime() < Date.now();
|
||||||
|
|
||||||
interface PollProps {
|
interface PollProps {
|
||||||
pollId: string;
|
pollId: string;
|
||||||
status: Status;
|
status: Status;
|
||||||
|
|
@ -58,8 +61,7 @@ export const Poll: React.FC<PollProps> = ({ pollId, disabled, status }) => {
|
||||||
if (!poll) {
|
if (!poll) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const expiresAt = poll.expires_at;
|
return poll.expired || isPollExpired(poll.expires_at);
|
||||||
return poll.expired || new Date(expiresAt).getTime() < Date.now();
|
|
||||||
}, [poll]);
|
}, [poll]);
|
||||||
const timeRemaining = useMemo(() => {
|
const timeRemaining = useMemo(() => {
|
||||||
if (!poll) {
|
if (!poll) {
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ export const RemoveQuoteHint: React.FC<{
|
||||||
|
|
||||||
if (!firstHintId) {
|
if (!firstHintId) {
|
||||||
firstHintId = uniqueId;
|
firstHintId = uniqueId;
|
||||||
|
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||||
setIsOnlyHint(true);
|
setIsOnlyHint(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,8 +65,8 @@ export const RemoveQuoteHint: React.FC<{
|
||||||
flip
|
flip
|
||||||
offset={[12, 10]}
|
offset={[12, 10]}
|
||||||
placement='bottom-end'
|
placement='bottom-end'
|
||||||
target={anchorRef.current}
|
target={anchorRef}
|
||||||
container={anchorRef.current}
|
container={anchorRef}
|
||||||
>
|
>
|
||||||
{({ props, placement }) => (
|
{({ props, placement }) => (
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,7 @@ export const ScrollContext: React.FC<ScrollContextProps> = ({
|
||||||
) =>
|
) =>
|
||||||
// Hack to allow accessing scrollBehavior._stateStorage
|
// Hack to allow accessing scrollBehavior._stateStorage
|
||||||
shouldUpdateScroll.call(
|
shouldUpdateScroll.call(
|
||||||
|
// eslint-disable-next-line react-hooks/immutability
|
||||||
scrollBehavior,
|
scrollBehavior,
|
||||||
prevLocationContext,
|
prevLocationContext,
|
||||||
locationContext,
|
locationContext,
|
||||||
|
|
|
||||||
|
|
@ -101,16 +101,17 @@ const Preview: React.FC<{
|
||||||
position: FocalPoint;
|
position: FocalPoint;
|
||||||
onPositionChange: (arg0: FocalPoint) => void;
|
onPositionChange: (arg0: FocalPoint) => void;
|
||||||
}> = ({ mediaId, position, onPositionChange }) => {
|
}> = ({ mediaId, position, onPositionChange }) => {
|
||||||
const draggingRef = useRef<boolean>(false);
|
|
||||||
const nodeRef = useRef<HTMLImageElement | HTMLVideoElement | null>(null);
|
const nodeRef = useRef<HTMLImageElement | HTMLVideoElement | null>(null);
|
||||||
|
|
||||||
|
const [dragging, setDragging] = useState<'started' | 'moving' | null>(null);
|
||||||
|
|
||||||
const [x, y] = position;
|
const [x, y] = position;
|
||||||
const style = useSpring({
|
const style = useSpring({
|
||||||
to: {
|
to: {
|
||||||
left: `${x * 100}%`,
|
left: `${x * 100}%`,
|
||||||
top: `${y * 100}%`,
|
top: `${y * 100}%`,
|
||||||
},
|
},
|
||||||
immediate: draggingRef.current,
|
immediate: dragging === 'moving',
|
||||||
});
|
});
|
||||||
const media = useAppSelector((state) =>
|
const media = useAppSelector((state) =>
|
||||||
(
|
(
|
||||||
|
|
@ -123,8 +124,6 @@ const Preview: React.FC<{
|
||||||
me ? state.accounts.get(me) : undefined,
|
me ? state.accounts.get(me) : undefined,
|
||||||
);
|
);
|
||||||
|
|
||||||
const [dragging, setDragging] = useState(false);
|
|
||||||
|
|
||||||
const setRef = useCallback(
|
const setRef = useCallback(
|
||||||
(e: HTMLImageElement | HTMLVideoElement | null) => {
|
(e: HTMLImageElement | HTMLVideoElement | null) => {
|
||||||
nodeRef.current = e;
|
nodeRef.current = e;
|
||||||
|
|
@ -140,20 +139,20 @@ const Preview: React.FC<{
|
||||||
|
|
||||||
const handleMouseMove = (e: MouseEvent) => {
|
const handleMouseMove = (e: MouseEvent) => {
|
||||||
const { x, y } = getPointerPosition(nodeRef.current, e);
|
const { x, y } = getPointerPosition(nodeRef.current, e);
|
||||||
draggingRef.current = true; // This will disable the animation for quicker feedback, only do this if the mouse actually moves
|
|
||||||
|
setDragging('moving'); // This will disable the animation for quicker feedback, only do this if the mouse actually moves
|
||||||
onPositionChange([x, y]);
|
onPositionChange([x, y]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMouseUp = () => {
|
const handleMouseUp = () => {
|
||||||
setDragging(false);
|
setDragging(null);
|
||||||
draggingRef.current = false;
|
|
||||||
document.removeEventListener('mouseup', handleMouseUp);
|
document.removeEventListener('mouseup', handleMouseUp);
|
||||||
document.removeEventListener('mousemove', handleMouseMove);
|
document.removeEventListener('mousemove', handleMouseMove);
|
||||||
};
|
};
|
||||||
|
|
||||||
const { x, y } = getPointerPosition(nodeRef.current, e.nativeEvent);
|
const { x, y } = getPointerPosition(nodeRef.current, e.nativeEvent);
|
||||||
|
|
||||||
setDragging(true);
|
setDragging('started');
|
||||||
onPositionChange([x, y]);
|
onPositionChange([x, y]);
|
||||||
|
|
||||||
document.addEventListener('mouseup', handleMouseUp);
|
document.addEventListener('mouseup', handleMouseUp);
|
||||||
|
|
|
||||||
|
|
@ -31,15 +31,13 @@ export const AnnualReport: React.FC<{
|
||||||
year: string;
|
year: string;
|
||||||
}> = ({ year }) => {
|
}> = ({ year }) => {
|
||||||
const [response, setResponse] = useState<AnnualReportResponse | null>(null);
|
const [response, setResponse] = useState<AnnualReportResponse | null>(null);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(true);
|
||||||
const currentAccount = useAppSelector((state) =>
|
const currentAccount = useAppSelector((state) =>
|
||||||
me ? state.accounts.get(me) : undefined,
|
me ? state.accounts.get(me) : undefined,
|
||||||
);
|
);
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setLoading(true);
|
|
||||||
|
|
||||||
apiRequestGet<AnnualReportResponse>(`v1/annual_reports/${year}`)
|
apiRequestGet<AnnualReportResponse>(`v1/annual_reports/${year}`)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
dispatch(importFetchedStatuses(data.statuses));
|
dispatch(importFetchedStatuses(data.statuses));
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,8 @@ const getFrequentlyUsedLanguages = createSelector(
|
||||||
.toArray(),
|
.toArray(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const isTextLongEnoughForGuess = (text: string) => text.length > 20;
|
||||||
|
|
||||||
const LanguageDropdownMenu: React.FC<{
|
const LanguageDropdownMenu: React.FC<{
|
||||||
value: string;
|
value: string;
|
||||||
guess?: string;
|
guess?: string;
|
||||||
|
|
@ -375,14 +377,27 @@ export const LanguageDropdown: React.FC = () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (text.length > 20) {
|
if (isTextLongEnoughForGuess(text)) {
|
||||||
debouncedGuess(text, setGuess);
|
debouncedGuess(text, setGuess);
|
||||||
} else {
|
} else {
|
||||||
debouncedGuess.cancel();
|
debouncedGuess.cancel();
|
||||||
setGuess('');
|
|
||||||
}
|
}
|
||||||
}, [text, setGuess]);
|
}, [text, setGuess]);
|
||||||
|
|
||||||
|
// Keeping track of the previous render's text length here
|
||||||
|
// to be able to reset the guess when the text length drops
|
||||||
|
// below the threshold needed to make a guess
|
||||||
|
const [wasLongText, setWasLongText] = useState(() =>
|
||||||
|
isTextLongEnoughForGuess(text),
|
||||||
|
);
|
||||||
|
if (wasLongText !== isTextLongEnoughForGuess(text)) {
|
||||||
|
setWasLongText(isTextLongEnoughForGuess(text));
|
||||||
|
|
||||||
|
if (wasLongText) {
|
||||||
|
setGuess('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={targetRef}>
|
<div ref={targetRef}>
|
||||||
<button
|
<button
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useCallback, useState, useRef, useEffect } from 'react';
|
import { useCallback, useState, useRef, useEffect, useMemo } from 'react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
defineMessages,
|
defineMessages,
|
||||||
|
|
@ -97,19 +97,29 @@ export const Search: React.FC<{
|
||||||
const [expanded, setExpanded] = useState(false);
|
const [expanded, setExpanded] = useState(false);
|
||||||
const [selectedOption, setSelectedOption] = useState(-1);
|
const [selectedOption, setSelectedOption] = useState(-1);
|
||||||
const [quickActions, setQuickActions] = useState<SearchOption[]>([]);
|
const [quickActions, setQuickActions] = useState<SearchOption[]>([]);
|
||||||
useEffect(() => {
|
|
||||||
setValue(initialValue ?? '');
|
|
||||||
setQuickActions([]);
|
|
||||||
}, [initialValue]);
|
|
||||||
const searchOptions: SearchOption[] = [];
|
|
||||||
|
|
||||||
const unfocus = useCallback(() => {
|
const unfocus = useCallback(() => {
|
||||||
document.querySelector('.ui')?.parentElement?.focus();
|
document.querySelector('.ui')?.parentElement?.focus();
|
||||||
setExpanded(false);
|
setExpanded(false);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (searchEnabled) {
|
const insertText = useCallback((text: string) => {
|
||||||
searchOptions.push(
|
setValue((currentValue) => {
|
||||||
|
if (currentValue === '') {
|
||||||
|
return text;
|
||||||
|
} else if (currentValue.endsWith(' ')) {
|
||||||
|
return `${currentValue}${text}`;
|
||||||
|
} else {
|
||||||
|
return `${currentValue} ${text}`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const searchOptions = useMemo(() => {
|
||||||
|
if (!searchEnabled) {
|
||||||
|
return [];
|
||||||
|
} else {
|
||||||
|
const options: SearchOption[] = [
|
||||||
{
|
{
|
||||||
key: 'prompt-has',
|
key: 'prompt-has',
|
||||||
label: (
|
label: (
|
||||||
|
|
@ -131,7 +141,10 @@ export const Search: React.FC<{
|
||||||
label: (
|
label: (
|
||||||
<>
|
<>
|
||||||
<mark>is:</mark>{' '}
|
<mark>is:</mark>{' '}
|
||||||
<FormattedList type='disjunction' value={['reply', 'sensitive']} />
|
<FormattedList
|
||||||
|
type='disjunction'
|
||||||
|
value={['reply', 'sensitive']}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
action: (e) => {
|
action: (e) => {
|
||||||
|
|
@ -232,10 +245,14 @@ export const Search: React.FC<{
|
||||||
insertText('in:');
|
insertText('in:');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
];
|
||||||
|
return options;
|
||||||
}
|
}
|
||||||
|
}, [insertText]);
|
||||||
|
|
||||||
const recentOptions: SearchOption[] = recent.map((search) => ({
|
const recentOptions: SearchOption[] = useMemo(
|
||||||
|
() =>
|
||||||
|
recent.map((search) => ({
|
||||||
key: `${search.type}/${search.q}`,
|
key: `${search.type}/${search.q}`,
|
||||||
label: labelForRecentSearch(search),
|
label: labelForRecentSearch(search),
|
||||||
action: () => {
|
action: () => {
|
||||||
|
|
@ -248,7 +265,10 @@ export const Search: React.FC<{
|
||||||
} else {
|
} else {
|
||||||
const queryParams = new URLSearchParams({ q: search.q });
|
const queryParams = new URLSearchParams({ q: search.q });
|
||||||
if (search.type) queryParams.set('type', search.type);
|
if (search.type) queryParams.set('type', search.type);
|
||||||
history.push({ pathname: '/search', search: queryParams.toString() });
|
history.push({
|
||||||
|
pathname: '/search',
|
||||||
|
search: queryParams.toString(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
unfocus();
|
unfocus();
|
||||||
|
|
@ -257,23 +277,17 @@ export const Search: React.FC<{
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
void dispatch(forgetSearchResult(search));
|
void dispatch(forgetSearchResult(search));
|
||||||
},
|
},
|
||||||
}));
|
})),
|
||||||
|
[dispatch, history, recent, unfocus],
|
||||||
|
);
|
||||||
|
|
||||||
const navigableOptions = hasValue
|
const navigableOptions: SearchOption[] = useMemo(
|
||||||
|
() =>
|
||||||
|
hasValue
|
||||||
? quickActions.concat(searchOptions)
|
? quickActions.concat(searchOptions)
|
||||||
: recentOptions.concat(quickActions, searchOptions);
|
: recentOptions.concat(quickActions, searchOptions),
|
||||||
|
[hasValue, quickActions, recentOptions, searchOptions],
|
||||||
const insertText = (text: string) => {
|
);
|
||||||
setValue((currentValue) => {
|
|
||||||
if (currentValue === '') {
|
|
||||||
return text;
|
|
||||||
} else if (currentValue.endsWith(' ')) {
|
|
||||||
return `${currentValue}${text}`;
|
|
||||||
} else {
|
|
||||||
return `${currentValue} ${text}`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const submit = useCallback(
|
const submit = useCallback(
|
||||||
(q: string, type?: SearchType) => {
|
(q: string, type?: SearchType) => {
|
||||||
|
|
|
||||||
|
|
@ -19,14 +19,12 @@ const messages = defineMessages({
|
||||||
const Blocks: React.FC<{ multiColumn: boolean }> = ({ multiColumn }) => {
|
const Blocks: React.FC<{ multiColumn: boolean }> = ({ multiColumn }) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const [domains, setDomains] = useState<string[]>([]);
|
const [domains, setDomains] = useState<string[]>([]);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(true);
|
||||||
const [next, setNext] = useState<string | undefined>();
|
const [next, setNext] = useState<string | undefined>();
|
||||||
const hasMore = !!next;
|
const hasMore = !!next;
|
||||||
const columnRef = useRef<ColumnRef>(null);
|
const columnRef = useRef<ColumnRef>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setLoading(true);
|
|
||||||
|
|
||||||
void apiGetDomainBlocks()
|
void apiGetDomainBlocks()
|
||||||
.then(({ domains, links }) => {
|
.then(({ domains, links }) => {
|
||||||
const next = links.refs.find((link) => link.rel === 'next');
|
const next = links.refs.find((link) => link.rel === 'next');
|
||||||
|
|
@ -40,7 +38,7 @@ const Blocks: React.FC<{ multiColumn: boolean }> = ({ multiColumn }) => {
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
});
|
});
|
||||||
}, [setLoading, setDomains, setNext]);
|
}, []);
|
||||||
|
|
||||||
const handleLoadMore = useCallback(() => {
|
const handleLoadMore = useCallback(() => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
|
||||||
|
|
@ -35,12 +35,17 @@ export const Announcement: FC<AnnouncementProps> = ({
|
||||||
}, [active, id, dispatch, read]);
|
}, [active, id, dispatch, read]);
|
||||||
|
|
||||||
// But visually show the announcement as read only when it goes out of view.
|
// But visually show the announcement as read only when it goes out of view.
|
||||||
const [unread, setUnread] = useState(!read);
|
const [isVisuallyRead, setIsVisuallyRead] = useState(read);
|
||||||
useEffect(() => {
|
const [previousActive, setPreviousActive] = useState(active);
|
||||||
if (!active && unread !== !read) {
|
if (active !== previousActive) {
|
||||||
setUnread(!read);
|
setPreviousActive(active);
|
||||||
|
|
||||||
|
// This marks the announcement as read in the UI only after it
|
||||||
|
// went from active to inactive.
|
||||||
|
if (!active && isVisuallyRead !== read) {
|
||||||
|
setIsVisuallyRead(read);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [active, unread, read]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AnimateEmojiProvider>
|
<AnimateEmojiProvider>
|
||||||
|
|
@ -63,7 +68,7 @@ export const Announcement: FC<AnnouncementProps> = ({
|
||||||
|
|
||||||
<ReactionsBar reactions={announcement.reactions} id={announcement.id} />
|
<ReactionsBar reactions={announcement.reactions} id={announcement.id} />
|
||||||
|
|
||||||
{unread && <span className='announcements__unread' />}
|
{!isVisuallyRead && <span className='announcements__unread' />}
|
||||||
</AnimateEmojiProvider>
|
</AnimateEmojiProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -164,12 +164,11 @@ const ListMembers: React.FC<{
|
||||||
const [searching, setSearching] = useState(false);
|
const [searching, setSearching] = useState(false);
|
||||||
const [accountIds, setAccountIds] = useState<string[]>([]);
|
const [accountIds, setAccountIds] = useState<string[]>([]);
|
||||||
const [searchAccountIds, setSearchAccountIds] = useState<string[]>([]);
|
const [searchAccountIds, setSearchAccountIds] = useState<string[]>([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(!!id);
|
||||||
const [mode, setMode] = useState<Mode>('remove');
|
const [mode, setMode] = useState<Mode>('remove');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (id) {
|
if (id) {
|
||||||
setLoading(true);
|
|
||||||
dispatch(fetchList(id));
|
dispatch(fetchList(id));
|
||||||
|
|
||||||
void apiGetAccounts(id)
|
void apiGetAccounts(id)
|
||||||
|
|
|
||||||
|
|
@ -27,17 +27,15 @@ export const ListPanel: React.FC = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const lists = useAppSelector((state) => getOrderedLists(state));
|
const lists = useAppSelector((state) => getOrderedLists(state));
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setLoading(true);
|
|
||||||
|
|
||||||
void dispatch(fetchLists()).then(() => {
|
void dispatch(fetchLists()).then(() => {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
});
|
});
|
||||||
}, [dispatch, setLoading]);
|
}, [dispatch]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CollapsiblePanel
|
<CollapsiblePanel
|
||||||
|
|
|
||||||
|
|
@ -225,7 +225,7 @@ export const SearchResults: React.FC<{ multiColumn: boolean }> = ({
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className='explore__search-header'>
|
<div className='explore__search-header'>
|
||||||
<Search singleColumn initialValue={trimmedValue} />
|
<Search singleColumn initialValue={trimmedValue} key={trimmedValue} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='account__section-headline'>
|
<div className='account__section-headline'>
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,6 @@ export const DomainBlockModal: React.FC<{
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setLoading(true);
|
|
||||||
|
|
||||||
apiRequest<DomainBlockPreviewResponse>('GET', 'v1/domain_blocks/preview', {
|
apiRequest<DomainBlockPreviewResponse>('GET', 'v1/domain_blocks/preview', {
|
||||||
params: { domain },
|
params: { domain },
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
|
|
@ -68,7 +66,7 @@ export const DomainBlockModal: React.FC<{
|
||||||
setPreview('error');
|
setPreview('error');
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
});
|
});
|
||||||
}, [setPreview, setLoading, domain]);
|
}, [domain]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='modal-root__modal safety-action-modal' aria-live='polite'>
|
<div className='modal-root__modal safety-action-modal' aria-live='polite'>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useEffect, useRef, useState, useCallback, useMemo } from 'react';
|
import { useEffect, useState, useCallback, useMemo } from 'react';
|
||||||
|
|
||||||
import { useIntl, defineMessages } from 'react-intl';
|
import { useIntl, defineMessages } from 'react-intl';
|
||||||
|
|
||||||
|
|
@ -41,40 +41,44 @@ const isHashtagLink = (
|
||||||
};
|
};
|
||||||
|
|
||||||
interface TargetParams {
|
interface TargetParams {
|
||||||
hashtag?: string;
|
element: HTMLAnchorElement | null;
|
||||||
accountId?: string;
|
hashtag: string;
|
||||||
|
accountId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const HashtagMenuController: React.FC = () => {
|
export const HashtagMenuController: React.FC = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { signedIn } = useIdentity();
|
const { signedIn } = useIdentity();
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
const [{ accountId, hashtag }, setTargetParams] = useState<TargetParams>({});
|
const [target, setTarget] = useState<TargetParams | null>(null);
|
||||||
const targetRef = useRef<HTMLAnchorElement | null>(null);
|
const { element = null, accountId, hashtag } = target ?? {};
|
||||||
const location = useLocation();
|
const open = !!element;
|
||||||
|
|
||||||
const account = useAppSelector((state) =>
|
const account = useAppSelector((state) =>
|
||||||
accountId ? state.accounts.get(accountId) : undefined,
|
accountId ? state.accounts.get(accountId) : undefined,
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
const location = useLocation();
|
||||||
setOpen(false);
|
const [previousLocation, setPreviousLocation] = useState(location);
|
||||||
targetRef.current = null;
|
if (location !== previousLocation) {
|
||||||
}, [setOpen, location]);
|
setPreviousLocation(location);
|
||||||
|
setTarget(null);
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleClick = (e: MouseEvent) => {
|
const handleClick = (e: MouseEvent) => {
|
||||||
const target = (e.target as HTMLElement).closest('a');
|
const targetElement = (e.target as HTMLElement).closest('a');
|
||||||
|
|
||||||
if (e.button !== 0 || e.ctrlKey || e.metaKey) {
|
if (e.button !== 0 || e.ctrlKey || e.metaKey) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isHashtagLink(target)) {
|
if (!isHashtagLink(targetElement)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hashtag = target.text.replace(/^#/, '');
|
const hashtag = targetElement.text.replace(/^#/, '');
|
||||||
const accountId = target.getAttribute('data-menu-hashtag');
|
const accountId = targetElement.getAttribute('data-menu-hashtag');
|
||||||
|
|
||||||
if (!hashtag || !accountId) {
|
if (!hashtag || !accountId) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -82,9 +86,7 @@ export const HashtagMenuController: React.FC = () => {
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
targetRef.current = target;
|
setTarget({ element: targetElement, hashtag, accountId });
|
||||||
setOpen(true);
|
|
||||||
setTargetParams({ hashtag, accountId });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
document.addEventListener('click', handleClick, { capture: true });
|
document.addEventListener('click', handleClick, { capture: true });
|
||||||
|
|
@ -92,12 +94,11 @@ export const HashtagMenuController: React.FC = () => {
|
||||||
return () => {
|
return () => {
|
||||||
document.removeEventListener('click', handleClick);
|
document.removeEventListener('click', handleClick);
|
||||||
};
|
};
|
||||||
}, [setTargetParams, setOpen]);
|
}, []);
|
||||||
|
|
||||||
const handleClose = useCallback(() => {
|
const handleClose = useCallback(() => {
|
||||||
setOpen(false);
|
setTarget(null);
|
||||||
targetRef.current = null;
|
}, []);
|
||||||
}, [setOpen]);
|
|
||||||
|
|
||||||
const menu = useMemo(() => {
|
const menu = useMemo(() => {
|
||||||
const arr: MenuItem[] = [
|
const arr: MenuItem[] = [
|
||||||
|
|
@ -139,7 +140,7 @@ export const HashtagMenuController: React.FC = () => {
|
||||||
offset={offset}
|
offset={offset}
|
||||||
placement='bottom'
|
placement='bottom'
|
||||||
flip
|
flip
|
||||||
target={targetRef}
|
target={element}
|
||||||
popperConfig={popperConfig}
|
popperConfig={popperConfig}
|
||||||
>
|
>
|
||||||
{({ props, arrowProps, placement }) => (
|
{({ props, arrowProps, placement }) => (
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ export const MediaModal: FC<MediaModalProps> = forwardRef<
|
||||||
_ref,
|
_ref,
|
||||||
) => {
|
) => {
|
||||||
const [index, setIndex] = useState(startIndex);
|
const [index, setIndex] = useState(startIndex);
|
||||||
|
const [zoomedIn, setZoomedIn] = useState(false);
|
||||||
const currentMedia = media.get(index);
|
const currentMedia = media.get(index);
|
||||||
|
|
||||||
const handleChangeIndex = useCallback(
|
const handleChangeIndex = useCallback(
|
||||||
|
|
@ -134,7 +135,6 @@ export const MediaModal: FC<MediaModalProps> = forwardRef<
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const [zoomedIn, setZoomedIn] = useState(false);
|
|
||||||
const zoomable =
|
const zoomable =
|
||||||
currentMedia?.get('type') === 'image' &&
|
currentMedia?.get('type') === 'image' &&
|
||||||
((currentMedia.getIn(['meta', 'original', 'width']) as number) >
|
((currentMedia.getIn(['meta', 'original', 'width']) as number) >
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useState, useEffect } from 'react';
|
import { useSyncExternalStore } from 'react';
|
||||||
|
|
||||||
const breakpoints = {
|
const breakpoints = {
|
||||||
narrow: 479, // Device width under which horizontal space is constrained
|
narrow: 479, // Device width under which horizontal space is constrained
|
||||||
|
|
@ -9,25 +9,20 @@ const breakpoints = {
|
||||||
type Breakpoint = keyof typeof breakpoints;
|
type Breakpoint = keyof typeof breakpoints;
|
||||||
|
|
||||||
export const useBreakpoint = (breakpoint: Breakpoint) => {
|
export const useBreakpoint = (breakpoint: Breakpoint) => {
|
||||||
const [isMatching, setIsMatching] = useState(false);
|
const query = `(max-width: ${breakpoints[breakpoint]}px)`;
|
||||||
|
|
||||||
useEffect(() => {
|
const isMatching = useSyncExternalStore(
|
||||||
const mediaWatcher = window.matchMedia(
|
(callback) => {
|
||||||
`(max-width: ${breakpoints[breakpoint]}px)`,
|
const mediaWatcher = window.matchMedia(query);
|
||||||
);
|
|
||||||
|
|
||||||
setIsMatching(mediaWatcher.matches);
|
mediaWatcher.addEventListener('change', callback);
|
||||||
|
|
||||||
const handleChange = (e: MediaQueryListEvent) => {
|
|
||||||
setIsMatching(e.matches);
|
|
||||||
};
|
|
||||||
|
|
||||||
mediaWatcher.addEventListener('change', handleChange);
|
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
mediaWatcher.removeEventListener('change', handleChange);
|
mediaWatcher.removeEventListener('change', callback);
|
||||||
};
|
};
|
||||||
}, [breakpoint, setIsMatching]);
|
},
|
||||||
|
() => window.matchMedia(query).matches,
|
||||||
|
);
|
||||||
|
|
||||||
return isMatching;
|
return isMatching;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useRef, useEffect } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the previous state of the passed in value.
|
* Returns the previous state of the passed in value.
|
||||||
|
|
@ -6,11 +6,21 @@ import { useRef, useEffect } from 'react';
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function usePrevious<T>(value: T): T | undefined {
|
export function usePrevious<T>(value: T): T | undefined {
|
||||||
const ref = useRef<T>();
|
const [{ previous, current }, setMemory] = useState<{
|
||||||
|
previous: T | undefined;
|
||||||
|
current: T;
|
||||||
|
}>(() => ({ previous: undefined, current: value }));
|
||||||
|
|
||||||
useEffect(() => {
|
let result = previous;
|
||||||
ref.current = value;
|
|
||||||
}, [value]);
|
|
||||||
|
|
||||||
return ref.current;
|
if (value !== current) {
|
||||||
|
setMemory({
|
||||||
|
previous: current,
|
||||||
|
current: value,
|
||||||
|
});
|
||||||
|
// Ensure that the returned result updates synchronously
|
||||||
|
result = current;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,7 @@ export default tseslint.config([
|
||||||
]),
|
]),
|
||||||
react.configs.flat.recommended,
|
react.configs.flat.recommended,
|
||||||
react.configs.flat['jsx-runtime'],
|
react.configs.flat['jsx-runtime'],
|
||||||
reactHooks.configs['recommended-latest'],
|
reactHooks.configs.flat.recommended,
|
||||||
jsxA11Y.flatConfigs.recommended,
|
jsxA11Y.flatConfigs.recommended,
|
||||||
importPlugin.flatConfigs.react,
|
importPlugin.flatConfigs.react,
|
||||||
// @ts-expect-error -- For some reason the formatjs package exports an empty object?
|
// @ts-expect-error -- For some reason the formatjs package exports an empty object?
|
||||||
|
|
@ -329,7 +329,7 @@ export default tseslint.config([
|
||||||
tseslint.configs.stylisticTypeChecked,
|
tseslint.configs.stylisticTypeChecked,
|
||||||
react.configs.flat.recommended,
|
react.configs.flat.recommended,
|
||||||
react.configs.flat['jsx-runtime'],
|
react.configs.flat['jsx-runtime'],
|
||||||
reactHooks.configs['recommended-latest'],
|
reactHooks.configs.flat.recommended,
|
||||||
jsxA11Y.flatConfigs.recommended,
|
jsxA11Y.flatConfigs.recommended,
|
||||||
importPlugin.flatConfigs.react,
|
importPlugin.flatConfigs.react,
|
||||||
importPlugin.flatConfigs.typescript,
|
importPlugin.flatConfigs.typescript,
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,7 @@
|
||||||
"eslint-plugin-jsx-a11y": "~6.10.2",
|
"eslint-plugin-jsx-a11y": "~6.10.2",
|
||||||
"eslint-plugin-promise": "~7.2.1",
|
"eslint-plugin-promise": "~7.2.1",
|
||||||
"eslint-plugin-react": "^7.37.4",
|
"eslint-plugin-react": "^7.37.4",
|
||||||
"eslint-plugin-react-hooks": "^5.2.0",
|
"eslint-plugin-react-hooks": "^7.0.1",
|
||||||
"eslint-plugin-storybook": "^10.0.2",
|
"eslint-plugin-storybook": "^10.0.2",
|
||||||
"fake-indexeddb": "^6.0.1",
|
"fake-indexeddb": "^6.0.1",
|
||||||
"globals": "^16.0.0",
|
"globals": "^16.0.0",
|
||||||
|
|
|
||||||
76
yarn.lock
76
yarn.lock
|
|
@ -299,10 +299,10 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@babel/helper-validator-identifier@npm:^7.27.1":
|
"@babel/helper-validator-identifier@npm:^7.27.1, @babel/helper-validator-identifier@npm:^7.28.5":
|
||||||
version: 7.27.1
|
version: 7.28.5
|
||||||
resolution: "@babel/helper-validator-identifier@npm:7.27.1"
|
resolution: "@babel/helper-validator-identifier@npm:7.28.5"
|
||||||
checksum: 10c0/c558f11c4871d526498e49d07a84752d1800bf72ac0d3dad100309a2eaba24efbf56ea59af5137ff15e3a00280ebe588560534b0e894a4750f8b1411d8f78b84
|
checksum: 10c0/42aaebed91f739a41f3d80b72752d1f95fd7c72394e8e4bd7cdd88817e0774d80a432451bcba17c2c642c257c483bf1d409dd4548883429ea9493a3bc4ab0847
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
@ -334,14 +334,14 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.25.4, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.3, @babel/parser@npm:^7.28.4":
|
"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.24.4, @babel/parser@npm:^7.25.4, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.3, @babel/parser@npm:^7.28.4":
|
||||||
version: 7.28.4
|
version: 7.28.5
|
||||||
resolution: "@babel/parser@npm:7.28.4"
|
resolution: "@babel/parser@npm:7.28.5"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/types": "npm:^7.28.4"
|
"@babel/types": "npm:^7.28.5"
|
||||||
bin:
|
bin:
|
||||||
parser: ./bin/babel-parser.js
|
parser: ./bin/babel-parser.js
|
||||||
checksum: 10c0/58b239a5b1477ac7ed7e29d86d675cc81075ca055424eba6485872626db2dc556ce63c45043e5a679cd925e999471dba8a3ed4864e7ab1dbf64306ab72c52707
|
checksum: 10c0/5bbe48bf2c79594ac02b490a41ffde7ef5aa22a9a88ad6bcc78432a6ba8a9d638d531d868bd1f104633f1f6bba9905746e15185b8276a3756c42b765d131b1ef
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
@ -1209,13 +1209,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.3, @babel/types@npm:^7.25.4, @babel/types@npm:^7.26.10, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4, @babel/types@npm:^7.4.4":
|
"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.3, @babel/types@npm:^7.25.4, @babel/types@npm:^7.26.10, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4, @babel/types@npm:^7.28.5, @babel/types@npm:^7.4.4":
|
||||||
version: 7.28.4
|
version: 7.28.5
|
||||||
resolution: "@babel/types@npm:7.28.4"
|
resolution: "@babel/types@npm:7.28.5"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/helper-string-parser": "npm:^7.27.1"
|
"@babel/helper-string-parser": "npm:^7.27.1"
|
||||||
"@babel/helper-validator-identifier": "npm:^7.27.1"
|
"@babel/helper-validator-identifier": "npm:^7.28.5"
|
||||||
checksum: 10c0/ac6f909d6191319e08c80efbfac7bd9a25f80cc83b43cd6d82e7233f7a6b9d6e7b90236f3af7400a3f83b576895bcab9188a22b584eb0f224e80e6d4e95f4517
|
checksum: 10c0/a5a483d2100befbf125793640dec26b90b95fd233a94c19573325898a5ce1e52cdfa96e495c7dcc31b5eca5b66ce3e6d4a0f5a4a62daec271455959f208ab08a
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
@ -2796,7 +2796,7 @@ __metadata:
|
||||||
eslint-plugin-jsx-a11y: "npm:~6.10.2"
|
eslint-plugin-jsx-a11y: "npm:~6.10.2"
|
||||||
eslint-plugin-promise: "npm:~7.2.1"
|
eslint-plugin-promise: "npm:~7.2.1"
|
||||||
eslint-plugin-react: "npm:^7.37.4"
|
eslint-plugin-react: "npm:^7.37.4"
|
||||||
eslint-plugin-react-hooks: "npm:^5.2.0"
|
eslint-plugin-react-hooks: "npm:^7.0.1"
|
||||||
eslint-plugin-storybook: "npm:^10.0.2"
|
eslint-plugin-storybook: "npm:^10.0.2"
|
||||||
fake-indexeddb: "npm:^6.0.1"
|
fake-indexeddb: "npm:^6.0.1"
|
||||||
fast-glob: "npm:^3.3.3"
|
fast-glob: "npm:^3.3.3"
|
||||||
|
|
@ -7178,12 +7178,18 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"eslint-plugin-react-hooks@npm:^5.2.0":
|
"eslint-plugin-react-hooks@npm:^7.0.1":
|
||||||
version: 5.2.0
|
version: 7.0.1
|
||||||
resolution: "eslint-plugin-react-hooks@npm:5.2.0"
|
resolution: "eslint-plugin-react-hooks@npm:7.0.1"
|
||||||
|
dependencies:
|
||||||
|
"@babel/core": "npm:^7.24.4"
|
||||||
|
"@babel/parser": "npm:^7.24.4"
|
||||||
|
hermes-parser: "npm:^0.25.1"
|
||||||
|
zod: "npm:^3.25.0 || ^4.0.0"
|
||||||
|
zod-validation-error: "npm:^3.5.0 || ^4.0.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0
|
eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0
|
||||||
checksum: 10c0/1c8d50fa5984c6dea32470651807d2922cc3934cf3425e78f84a24c2dfd972e7f019bee84aefb27e0cf2c13fea0ac1d4473267727408feeb1c56333ca1489385
|
checksum: 10c0/1e711d1a9d1fa9cfc51fa1572500656577201199c70c795c6a27adfc1df39e5c598f69aab6aa91117753d23cc1f11388579a2bed14921cf9a4efe60ae8618496
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
@ -8090,6 +8096,22 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"hermes-estree@npm:0.25.1":
|
||||||
|
version: 0.25.1
|
||||||
|
resolution: "hermes-estree@npm:0.25.1"
|
||||||
|
checksum: 10c0/48be3b2fa37a0cbc77a112a89096fa212f25d06de92781b163d67853d210a8a5c3784fac23d7d48335058f7ed283115c87b4332c2a2abaaccc76d0ead1a282ac
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"hermes-parser@npm:^0.25.1":
|
||||||
|
version: 0.25.1
|
||||||
|
resolution: "hermes-parser@npm:0.25.1"
|
||||||
|
dependencies:
|
||||||
|
hermes-estree: "npm:0.25.1"
|
||||||
|
checksum: 10c0/3abaa4c6f1bcc25273f267297a89a4904963ea29af19b8e4f6eabe04f1c2c7e9abd7bfc4730ddb1d58f2ea04b6fee74053d8bddb5656ec6ebf6c79cc8d14202c
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"history@npm:^4.10.1, history@npm:^4.9.0":
|
"history@npm:^4.10.1, history@npm:^4.9.0":
|
||||||
version: 4.10.1
|
version: 4.10.1
|
||||||
resolution: "history@npm:4.10.1"
|
resolution: "history@npm:4.10.1"
|
||||||
|
|
@ -14736,3 +14758,19 @@ __metadata:
|
||||||
checksum: 10c0/2d110bfcb0f8b8dbf225423f6556da9c5bca95c8b849c1218983676158a24b5cd0350357e0c4d504e27f8c7e18d471d9712576f35114a81a51bcf83453f02beb
|
checksum: 10c0/2d110bfcb0f8b8dbf225423f6556da9c5bca95c8b849c1218983676158a24b5cd0350357e0c4d504e27f8c7e18d471d9712576f35114a81a51bcf83453f02beb
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"zod-validation-error@npm:^3.5.0 || ^4.0.0":
|
||||||
|
version: 4.0.2
|
||||||
|
resolution: "zod-validation-error@npm:4.0.2"
|
||||||
|
peerDependencies:
|
||||||
|
zod: ^3.25.0 || ^4.0.0
|
||||||
|
checksum: 10c0/0ccfec48c46de1be440b719cd02044d4abb89ed0e14c13e637cd55bf29102f67ccdba373f25def0fc7130e5f15025be4d557a7edcc95d5a3811599aade689e1b
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"zod@npm:^3.25.0 || ^4.0.0":
|
||||||
|
version: 4.1.12
|
||||||
|
resolution: "zod@npm:4.1.12"
|
||||||
|
checksum: 10c0/b64c1feb19e99d77075261eaf613e0b2be4dfcd3551eff65ad8b4f2a079b61e379854d066f7d447491fcf193f45babd8095551a9d47973d30b46b6d8e2c46774
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user