mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-04-11 21:29:26 +02:00
store the filter state in route state
This commit is contained in:
parent
0396b8d2ad
commit
66f351e944
60
src/hooks/use-route-state-value.ts
Normal file
60
src/hooks/use-route-state-value.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import { useCallback, useRef } from "react";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
|
||||
type Actions<T> = {
|
||||
setValue: (v: T | ((v: T | undefined) => T)) => void;
|
||||
clearValue: () => void;
|
||||
};
|
||||
|
||||
export default function useRouteStateValue<T extends unknown>(key: string, fallback: T): { value: T } & Actions<T>;
|
||||
export default function useRouteStateValue<T extends unknown>(
|
||||
key: string,
|
||||
fallback?: T,
|
||||
): { value: T | undefined } & Actions<T>;
|
||||
export default function useRouteStateValue<T extends unknown>(key: string, fallback?: T) {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
const stateRef = useRef<Record<string, any>>(location.state ?? {});
|
||||
stateRef.current = location.state ?? {};
|
||||
const valueRef = useRef<T>(stateRef.current[key] ?? fallback);
|
||||
valueRef.current = stateRef.current[key] ?? fallback;
|
||||
|
||||
const setValue = useCallback(
|
||||
(valueOrSetter: T | ((v: T) => T)) => {
|
||||
const newState = { ...stateRef.current };
|
||||
if (typeof valueOrSetter === "function") {
|
||||
// @ts-ignore
|
||||
newState[key] = valueOrSetter(valueRef.current);
|
||||
} else newState[key] = valueOrSetter;
|
||||
|
||||
if (stateRef.current[key] !== newState[key]) {
|
||||
navigate(".", { state: newState, replace: true });
|
||||
}
|
||||
},
|
||||
[key],
|
||||
);
|
||||
const clearValue = useCallback(() => {
|
||||
const newState = { ...stateRef.current };
|
||||
delete newState[key];
|
||||
navigate(".", newState);
|
||||
}, [key]);
|
||||
|
||||
return { value: valueRef.current, setValue, clearValue };
|
||||
}
|
||||
|
||||
export function useRouteStateBoolean(key: string, fallback?: boolean) {
|
||||
const stateValue = useRouteStateValue<boolean>(key, fallback ?? false);
|
||||
|
||||
const onOpen = useCallback(() => {
|
||||
stateValue.setValue(true);
|
||||
}, [stateValue.setValue]);
|
||||
const onClose = useCallback(() => {
|
||||
stateValue.setValue(false);
|
||||
}, [stateValue.setValue]);
|
||||
const onToggle = useCallback(() => {
|
||||
stateValue.setValue((v) => !v);
|
||||
}, [stateValue.setValue]);
|
||||
|
||||
return { isOpen: stateValue.value, onOpen, onClose, onToggle };
|
||||
}
|
@ -5,12 +5,9 @@ import {
|
||||
EditableInput,
|
||||
EditablePreview,
|
||||
Flex,
|
||||
FormControl,
|
||||
FormLabel,
|
||||
IconButton,
|
||||
Input,
|
||||
Spacer,
|
||||
useDisclosure,
|
||||
useEditableControls,
|
||||
} from "@chakra-ui/react";
|
||||
import { CloseIcon } from "@chakra-ui/icons";
|
||||
@ -30,6 +27,7 @@ import useClientSideMuteFilter from "../../hooks/use-client-side-mute-filter";
|
||||
import PeopleListProvider, { usePeopleListContext } from "../../providers/people-list-provider";
|
||||
import PeopleListSelection from "../../components/people-list-selection/people-list-selection";
|
||||
import NoteFilterTypeButtons from "../../components/note-filter-type-buttons";
|
||||
import { useRouteStateBoolean } from "../../hooks/use-route-state-value";
|
||||
|
||||
function EditableControls() {
|
||||
const { isEditing, getSubmitButtonProps, getCancelButtonProps, getEditButtonProps } = useEditableControls();
|
||||
@ -53,8 +51,8 @@ function HashTagPage() {
|
||||
|
||||
useAppTitle("#" + hashtag);
|
||||
|
||||
const showReplies = useDisclosure({ defaultIsOpen: true });
|
||||
const showReposts = useDisclosure({ defaultIsOpen: true });
|
||||
const showReplies = useRouteStateBoolean("show-replies", true);
|
||||
const showReposts = useRouteStateBoolean("show-reposts", true);
|
||||
|
||||
const readRelays = useRelaySelectionRelays();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { useCallback } from "react";
|
||||
import { Flex, Spacer, useDisclosure } from "@chakra-ui/react";
|
||||
import { Flex, Spacer } from "@chakra-ui/react";
|
||||
import { useOutletContext } from "react-router-dom";
|
||||
import { Kind } from "nostr-tools";
|
||||
|
||||
@ -12,13 +12,14 @@ import { STREAM_KIND } from "../../helpers/nostr/stream";
|
||||
import TimelineViewType from "../../components/timeline-page/timeline-view-type";
|
||||
import TimelinePage, { useTimelinePageEventFilter } from "../../components/timeline-page";
|
||||
import NoteFilterTypeButtons from "../../components/note-filter-type-buttons";
|
||||
import { useRouteStateBoolean } from "../../hooks/use-route-state-value";
|
||||
|
||||
export default function UserNotesTab() {
|
||||
const { pubkey } = useOutletContext() as { pubkey: string };
|
||||
const readRelays = useAdditionalRelayContext();
|
||||
|
||||
const showReplies = useDisclosure();
|
||||
const showReposts = useDisclosure({ defaultIsOpen: true });
|
||||
const showReplies = useRouteStateBoolean("show-replies", false);
|
||||
const showReposts = useRouteStateBoolean("show-reposts", true);
|
||||
|
||||
const timelineEventFilter = useTimelinePageEventFilter();
|
||||
const eventFilter = useCallback(
|
||||
|
Loading…
x
Reference in New Issue
Block a user