From 83754497af1ae3796134a7fddc874ea2575ed8d4 Mon Sep 17 00:00:00 2001 From: Yuzu Date: Tue, 30 Jun 2026 01:58:33 +0700 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20persist=20tab/search=20stat?= =?UTF-8?q?e=20across=20navigation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../features/account/AccountSettingsView.tsx | 4 ++-- .../src/features/avatar/AvatarsView.tsx | 5 ++-- .../src/features/navigation/NavContext.tsx | 23 ++++++++++++++++++- .../src/features/profile/MyWorldsView.tsx | 4 ++-- .../src/features/profile/ProfileView.tsx | 3 ++- .../src/features/search/SearchView.tsx | 6 ++--- .../src/features/settings/SettingsView.tsx | 3 ++- 7 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/renderer/src/features/account/AccountSettingsView.tsx b/src/renderer/src/features/account/AccountSettingsView.tsx index 2259b4c..85ee2ab 100644 --- a/src/renderer/src/features/account/AccountSettingsView.tsx +++ b/src/renderer/src/features/account/AccountSettingsView.tsx @@ -1,7 +1,7 @@ -import { useState } from "react"; import { Trans } from "react-i18next"; import { useI18n } from "../../lib/i18n"; import { Banner, Loader, PAGE_TITLE, Tabs } from "../../components/ui"; +import { useViewState } from "../navigation/NavContext"; import { useAccountSettings } from "./useAccountSettings"; import { DisplayNameSection } from "./sections/DisplayNameSection"; import { EmailSection } from "./sections/EmailSection"; @@ -22,7 +22,7 @@ type AccountTab = "account" | "security" | "privacy" | "data"; export function AccountSettingsView() { const { t } = useI18n(); const { state, set } = useAccountSettings(); - const [tab, setTab] = useState("account"); + const [tab, setTab] = useViewState("account:tab", "account"); if (state.status === "loading") return ; if (state.status === "error") diff --git a/src/renderer/src/features/avatar/AvatarsView.tsx b/src/renderer/src/features/avatar/AvatarsView.tsx index 51cffce..eac1a06 100644 --- a/src/renderer/src/features/avatar/AvatarsView.tsx +++ b/src/renderer/src/features/avatar/AvatarsView.tsx @@ -21,6 +21,7 @@ import { type FavoriteFolder, } from "../../store/avatars"; import { useSelf, useSocial } from "../../store/social"; +import { useViewState } from "../navigation/NavContext"; import { AvatarCard } from "./AvatarCard"; import { FolderEditModal } from "./FolderEditModal"; @@ -41,8 +42,8 @@ function matchAvatar(query: string): AvatarFilter { export function AvatarsView() { const t = useT(); - const [tab, setTab] = useState("uploaded"); - const [query, setQuery] = useState(""); + const [tab, setTab] = useViewState("avatars:tab", "uploaded"); + const [query, setQuery] = useViewState("avatars:query", ""); const filter = useMemo(() => matchAvatar(query), [query]); const selfId = useSocial((s) => s.selfId); diff --git a/src/renderer/src/features/navigation/NavContext.tsx b/src/renderer/src/features/navigation/NavContext.tsx index 7533258..a3da536 100644 --- a/src/renderer/src/features/navigation/NavContext.tsx +++ b/src/renderer/src/features/navigation/NavContext.tsx @@ -1,4 +1,4 @@ -import { createContext, useContext, useMemo, useState } from "react"; +import { createContext, useCallback, useContext, useMemo, useRef, useState } from "react"; export type View = | { kind: "user"; id: "me" | string } @@ -30,12 +30,15 @@ interface Nav { openGallery: () => void; openSearch: () => void; back: () => void; + getViewState: (key: string) => unknown; + setViewState: (key: string, value: unknown) => void; } const NavCtx = createContext