diff --git a/web/src/App.tsx b/web/src/App.tsx index 3e20e0fc..59259c7a 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -6,14 +6,14 @@ import storage from "./helpers/storage"; import { getSystemColorScheme } from "./helpers/utils"; import useNavigateTo from "./hooks/useNavigateTo"; import { useGlobalStore } from "./store/module"; -import { useUserV1Store } from "./store/v1"; +import { useUserStore } from "./store/v1"; const App = () => { const { i18n } = useTranslation(); const navigateTo = useNavigateTo(); const { mode, setMode } = useColorScheme(); const globalStore = useGlobalStore(); - const userV1Store = useUserV1Store(); + const userStore = useUserStore(); const [loading, setLoading] = useState(true); const { appearance, locale, systemStatus } = globalStore.state; @@ -27,7 +27,7 @@ const App = () => { useEffect(() => { const initialState = async () => { try { - await userV1Store.fetchCurrentUser(); + await userStore.fetchCurrentUser(); } catch (error) { // Do nothing. } diff --git a/web/src/components/ChangeMemberPasswordDialog.tsx b/web/src/components/ChangeMemberPasswordDialog.tsx index 259e6799..98300cb0 100644 --- a/web/src/components/ChangeMemberPasswordDialog.tsx +++ b/web/src/components/ChangeMemberPasswordDialog.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from "react"; import { toast } from "react-hot-toast"; -import { useUserV1Store } from "@/store/v1"; +import { useUserStore } from "@/store/v1"; import { User } from "@/types/proto/api/v2/user_service"; import { useTranslate } from "@/utils/i18n"; import { generateDialog } from "./Dialog"; @@ -13,7 +13,7 @@ interface Props extends DialogProps { const ChangeMemberPasswordDialog: React.FC = (props: Props) => { const { user, destroy } = props; const t = useTranslate(); - const userV1Store = useUserV1Store(); + const userStore = useUserStore(); const [newPassword, setNewPassword] = useState(""); const [newPasswordAgain, setNewPasswordAgain] = useState(""); @@ -48,7 +48,7 @@ const ChangeMemberPasswordDialog: React.FC = (props: Props) => { } try { - await userV1Store.updateUser( + await userStore.updateUser( { name: user.name, password: newPassword, diff --git a/web/src/components/ChangeMemoCreatedTsDialog.tsx b/web/src/components/ChangeMemoCreatedTsDialog.tsx index 4d80d377..5fbdc94d 100644 --- a/web/src/components/ChangeMemoCreatedTsDialog.tsx +++ b/web/src/components/ChangeMemoCreatedTsDialog.tsx @@ -2,7 +2,7 @@ import { Button } from "@mui/joy"; import { useEffect, useState } from "react"; import { toast } from "react-hot-toast"; import { getNormalizedTimeString, getUnixTime } from "@/helpers/datetime"; -import { useMemoV1Store } from "@/store/v1"; +import { useMemoStore } from "@/store/v1"; import { useTranslate } from "@/utils/i18n"; import { generateDialog } from "./Dialog"; import Icon from "./Icon"; @@ -14,7 +14,7 @@ interface Props extends DialogProps { const ChangeMemoCreatedTsDialog: React.FC = (props: Props) => { const t = useTranslate(); const { destroy, memoId } = props; - const memoStore = useMemoV1Store(); + const memoStore = useMemoStore(); const [createdAt, setCreatedAt] = useState(""); const maxDatetimeValue = getNormalizedTimeString(); diff --git a/web/src/components/ChangePasswordDialog.tsx b/web/src/components/ChangePasswordDialog.tsx index 5a5a954f..9b377f6c 100644 --- a/web/src/components/ChangePasswordDialog.tsx +++ b/web/src/components/ChangePasswordDialog.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from "react"; import { toast } from "react-hot-toast"; import useCurrentUser from "@/hooks/useCurrentUser"; import { useGlobalStore } from "@/store/module"; -import { useUserV1Store } from "@/store/v1"; +import { useUserStore } from "@/store/v1"; import { useTranslate } from "@/utils/i18n"; import { generateDialog } from "./Dialog"; import Icon from "./Icon"; @@ -12,7 +12,7 @@ type Props = DialogProps; const ChangePasswordDialog: React.FC = ({ destroy }: Props) => { const t = useTranslate(); const currentUser = useCurrentUser(); - const userV1Store = useUserV1Store(); + const userStore = useUserStore(); const globalStore = useGlobalStore(); const profile = globalStore.state.systemStatus.profile; const [newPassword, setNewPassword] = useState(""); @@ -52,7 +52,7 @@ const ChangePasswordDialog: React.FC = ({ destroy }: Props) => { } try { - await userV1Store.updateUser( + await userStore.updateUser( { name: currentUser.name, password: newPassword, diff --git a/web/src/components/MemoEditor/RelationListView.tsx b/web/src/components/MemoEditor/RelationListView.tsx index 3974b495..be697fb2 100644 --- a/web/src/components/MemoEditor/RelationListView.tsx +++ b/web/src/components/MemoEditor/RelationListView.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from "react"; -import { useMemoV1Store } from "@/store/v1"; +import { useMemoStore } from "@/store/v1"; import { MemoRelation, MemoRelation_Type } from "@/types/proto/api/v2/memo_relation_service"; import { Memo } from "@/types/proto/api/v2/memo_service"; import Icon from "../Icon"; @@ -11,7 +11,7 @@ interface Props { const RelationListView = (props: Props) => { const { relationList, setRelationList } = props; - const memoStore = useMemoV1Store(); + const memoStore = useMemoStore(); const [referencingMemoList, setReferencingMemoList] = useState([]); useEffect(() => { diff --git a/web/src/components/MemoEditor/index.tsx b/web/src/components/MemoEditor/index.tsx index 8df1e042..f444f064 100644 --- a/web/src/components/MemoEditor/index.tsx +++ b/web/src/components/MemoEditor/index.tsx @@ -7,7 +7,7 @@ import useLocalStorage from "react-use/lib/useLocalStorage"; import { memoServiceClient } from "@/grpcweb"; import { TAB_SPACE_WIDTH, UNKNOWN_ID } from "@/helpers/consts"; import { useGlobalStore, useResourceStore } from "@/store/module"; -import { useMemoV1Store, useUserV1Store } from "@/store/v1"; +import { useMemoStore, useUserStore } from "@/store/v1"; import { MemoRelation, MemoRelation_Type } from "@/types/proto/api/v2/memo_relation_service"; import { Visibility } from "@/types/proto/api/v2/memo_service"; import { Resource } from "@/types/proto/api/v2/resource_service"; @@ -49,8 +49,8 @@ const MemoEditor = (props: Props) => { const { state: { systemStatus }, } = useGlobalStore(); - const userV1Store = useUserV1Store(); - const memoStore = useMemoV1Store(); + const userStore = useUserStore(); + const memoStore = useMemoStore(); const resourceStore = useResourceStore(); const [state, setState] = useState({ memoVisibility: Visibility.PRIVATE, @@ -61,7 +61,7 @@ const MemoEditor = (props: Props) => { }); const [hasContent, setHasContent] = useState(false); const editorRef = useRef(null); - const userSetting = userV1Store.userSetting as UserSetting; + const userSetting = userStore.userSetting as UserSetting; const referenceRelations = memoId ? state.relationList.filter( (relation) => relation.memoId === memoId && relation.relatedMemoId !== memoId && relation.type === MemoRelation_Type.REFERENCE diff --git a/web/src/components/MemoRelationListView.tsx b/web/src/components/MemoRelationListView.tsx index 0a0de8a2..bd539881 100644 --- a/web/src/components/MemoRelationListView.tsx +++ b/web/src/components/MemoRelationListView.tsx @@ -1,7 +1,7 @@ import { Tooltip } from "@mui/joy"; import { useEffect, useState } from "react"; import { Link } from "react-router-dom"; -import { useMemoV1Store } from "@/store/v1"; +import { useMemoStore } from "@/store/v1"; import { MemoRelation } from "@/types/proto/api/v2/memo_relation_service"; import { Memo } from "@/types/proto/api/v2/memo_service"; import Icon from "./Icon"; @@ -13,7 +13,7 @@ interface Props { const MemoRelationListView = (props: Props) => { const { memo, relationList } = props; - const memoStore = useMemoV1Store(); + const memoStore = useMemoStore(); const [referencingMemoList, setReferencingMemoList] = useState([]); const [referencedMemoList, setReferencedMemoList] = useState([]); diff --git a/web/src/components/MemoView.tsx b/web/src/components/MemoView.tsx index 5e37397b..c9a12915 100644 --- a/web/src/components/MemoView.tsx +++ b/web/src/components/MemoView.tsx @@ -8,7 +8,7 @@ import { getRelativeTimeString, getTimeStampByDate } from "@/helpers/datetime"; import useCurrentUser from "@/hooks/useCurrentUser"; import useNavigateTo from "@/hooks/useNavigateTo"; import { useFilterStore } from "@/store/module"; -import { useUserV1Store, extractUsernameFromName, useMemoV1Store } from "@/store/v1"; +import { useUserStore, extractUsernameFromName, useMemoStore } from "@/store/v1"; import { RowStatus } from "@/types/proto/api/v2/common"; import { MemoRelation_Type } from "@/types/proto/api/v2/memo_relation_service"; import { Memo, Visibility } from "@/types/proto/api/v2/memo_service"; @@ -42,12 +42,12 @@ const MemoView: React.FC = (props: Props) => { const navigateTo = useNavigateTo(); const { i18n } = useTranslation(); const filterStore = useFilterStore(); - const memoStore = useMemoV1Store(); - const userV1Store = useUserV1Store(); + const memoStore = useMemoStore(); + const userStore = useUserStore(); const user = useCurrentUser(); const [shouldRender, setShouldRender] = useState(lazyRendering ? false : true); const [displayTime, setDisplayTime] = useState(getRelativeTimeString(getTimeStampByDate(memo.displayTime))); - const [creator, setCreator] = useState(userV1Store.getUserByUsername(extractUsernameFromName(memo.creator))); + const [creator, setCreator] = useState(userStore.getUserByUsername(extractUsernameFromName(memo.creator))); const [parentMemo, setParentMemo] = useState(undefined); const memoContainerRef = useRef(null); const referenceRelations = memo.relations.filter((relation) => relation.type === MemoRelation_Type.REFERENCE); @@ -58,7 +58,7 @@ const MemoView: React.FC = (props: Props) => { if (creator) return; (async () => { - const user = await userV1Store.getOrFetchUserByUsername(extractUsernameFromName(memo.creator)); + const user = await userStore.getOrFetchUserByUsername(extractUsernameFromName(memo.creator)); setCreator(user); })(); }, [memo.creator]); diff --git a/web/src/components/Settings/MemberSection.tsx b/web/src/components/Settings/MemberSection.tsx index b186571a..ab7aac82 100644 --- a/web/src/components/Settings/MemberSection.tsx +++ b/web/src/components/Settings/MemberSection.tsx @@ -3,7 +3,7 @@ import React, { useEffect, useState } from "react"; import { toast } from "react-hot-toast"; import { userServiceClient } from "@/grpcweb"; import useCurrentUser from "@/hooks/useCurrentUser"; -import { UserNamePrefix, extractUsernameFromName, useUserV1Store } from "@/store/v1"; +import { UserNamePrefix, extractUsernameFromName, useUserStore } from "@/store/v1"; import { RowStatus } from "@/types/proto/api/v2/common"; import { User, User_Role } from "@/types/proto/api/v2/user_service"; import { useTranslate } from "@/utils/i18n"; @@ -19,7 +19,7 @@ interface State { const MemberSection = () => { const t = useTranslate(); const currentUser = useCurrentUser(); - const userV1Store = useUserV1Store(); + const userStore = useUserStore(); const [state, setState] = useState({ createUserUsername: "", createUserPassword: "", @@ -31,7 +31,7 @@ const MemberSection = () => { }, []); const fetchUserList = async () => { - const users = await userV1Store.fetchUsers(); + const users = await userStore.fetchUsers(); setUserList(users); }; @@ -114,7 +114,7 @@ const MemberSection = () => { style: "danger", dialogName: "delete-user-dialog", onConfirm: async () => { - await userV1Store.deleteUser(user.name); + await userStore.deleteUser(user.name); fetchUserList(); }, }); diff --git a/web/src/components/Settings/PreferencesSection.tsx b/web/src/components/Settings/PreferencesSection.tsx index 544d85da..2aa6c2c2 100644 --- a/web/src/components/Settings/PreferencesSection.tsx +++ b/web/src/components/Settings/PreferencesSection.tsx @@ -3,7 +3,7 @@ import { useState } from "react"; import { toast } from "react-hot-toast"; import { Link } from "react-router-dom"; import { useGlobalStore } from "@/store/module"; -import { useUserV1Store } from "@/store/v1"; +import { useUserStore } from "@/store/v1"; import { Visibility } from "@/types/proto/api/v2/memo_service"; import { UserSetting } from "@/types/proto/api/v2/user_service"; import { useTranslate } from "@/utils/i18n"; @@ -18,13 +18,13 @@ import "@/less/settings/preferences-section.less"; const PreferencesSection = () => { const t = useTranslate(); const globalStore = useGlobalStore(); - const userV1Store = useUserV1Store(); + const userStore = useUserStore(); const { appearance, locale } = globalStore.state; - const setting = userV1Store.userSetting as UserSetting; + const setting = userStore.userSetting as UserSetting; const [telegramUserId, setTelegramUserId] = useState(setting.telegramUserId); const handleLocaleSelectChange = async (locale: Locale) => { - await userV1Store.updateUserSetting( + await userStore.updateUserSetting( { locale, }, @@ -34,7 +34,7 @@ const PreferencesSection = () => { }; const handleAppearanceSelectChange = async (appearance: Appearance) => { - await userV1Store.updateUserSetting( + await userStore.updateUserSetting( { appearance, }, @@ -44,7 +44,7 @@ const PreferencesSection = () => { }; const handleDefaultMemoVisibilityChanged = async (value: string) => { - await userV1Store.updateUserSetting( + await userStore.updateUserSetting( { memoVisibility: value, }, @@ -54,7 +54,7 @@ const PreferencesSection = () => { const handleSaveTelegramUserId = async () => { try { - await userV1Store.updateUserSetting( + await userStore.updateUserSetting( { telegramUserId: telegramUserId, }, diff --git a/web/src/components/ShareMemoDialog.tsx b/web/src/components/ShareMemoDialog.tsx index fbe61a9e..438b7544 100644 --- a/web/src/components/ShareMemoDialog.tsx +++ b/web/src/components/ShareMemoDialog.tsx @@ -5,7 +5,7 @@ import { toast } from "react-hot-toast"; import { getDateTimeString, getTimeString } from "@/helpers/datetime"; import useLoading from "@/hooks/useLoading"; import toImage from "@/labs/html2image"; -import { useUserV1Store, extractUsernameFromName } from "@/store/v1"; +import { useUserStore, extractUsernameFromName } from "@/store/v1"; import { Memo } from "@/types/proto/api/v2/memo_service"; import { useTranslate } from "@/utils/i18n"; import { generateDialog } from "./Dialog"; @@ -22,15 +22,15 @@ interface Props extends DialogProps { const ShareMemoDialog: React.FC = (props: Props) => { const { memo, destroy } = props; const t = useTranslate(); - const userV1Store = useUserV1Store(); + const userStore = useUserStore(); const downloadingImageState = useLoading(false); const loadingState = useLoading(); const memoElRef = useRef(null); - const user = userV1Store.getUserByUsername(extractUsernameFromName(memo.creator)); + const user = userStore.getUserByUsername(extractUsernameFromName(memo.creator)); useEffect(() => { (async () => { - await userV1Store.getOrFetchUserByUsername(extractUsernameFromName(memo.creator)); + await userStore.getOrFetchUserByUsername(extractUsernameFromName(memo.creator)); loadingState.setFinish(); })(); }, []); diff --git a/web/src/components/UpdateAccountDialog.tsx b/web/src/components/UpdateAccountDialog.tsx index afd9d1ba..9b7fc5fa 100644 --- a/web/src/components/UpdateAccountDialog.tsx +++ b/web/src/components/UpdateAccountDialog.tsx @@ -3,7 +3,7 @@ import { useEffect, useState } from "react"; import { toast } from "react-hot-toast"; import { convertFileToBase64 } from "@/helpers/utils"; import useCurrentUser from "@/hooks/useCurrentUser"; -import { UserNamePrefix, useUserV1Store } from "@/store/v1"; +import { UserNamePrefix, useUserStore } from "@/store/v1"; import { User as UserPb } from "@/types/proto/api/v2/user_service"; import { useTranslate } from "@/utils/i18n"; import { generateDialog } from "./Dialog"; @@ -22,7 +22,7 @@ interface State { const UpdateAccountDialog: React.FC = ({ destroy }: Props) => { const t = useTranslate(); const currentUser = useCurrentUser(); - const userV1Store = useUserV1Store(); + const userStore = useUserStore(); const [state, setState] = useState({ avatarUrl: currentUser.avatarUrl, username: currentUser.name.replace(UserNamePrefix, ""), @@ -108,7 +108,7 @@ const UpdateAccountDialog: React.FC = ({ destroy }: Props) => { if (!isEqual(currentUser.email, state.email)) { updateMask.push("email"); } - await userV1Store.updateUser( + await userStore.updateUser( UserPb.fromPartial({ name: `${UserNamePrefix}${state.username}`, id: currentUser.id, diff --git a/web/src/components/UsageHeatMap.tsx b/web/src/components/UsageHeatMap.tsx index be4a1cbb..17b4e0d3 100644 --- a/web/src/components/UsageHeatMap.tsx +++ b/web/src/components/UsageHeatMap.tsx @@ -6,7 +6,7 @@ import * as utils from "@/helpers/utils"; import useCurrentUser from "@/hooks/useCurrentUser"; import useNavigateTo from "@/hooks/useNavigateTo"; import { useGlobalStore } from "@/store/module"; -import { useUserV1Store, extractUsernameFromName, useMemoV1Store } from "@/store/v1"; +import { useUserStore, extractUsernameFromName, useMemoStore } from "@/store/v1"; import { useTranslate, Translations } from "@/utils/i18n"; import "@/less/usage-heat-map.less"; @@ -34,9 +34,9 @@ interface DailyUsageStat { const UsageHeatMap = () => { const t = useTranslate(); const navigateTo = useNavigateTo(); - const userV1Store = useUserV1Store(); + const userStore = useUserStore(); const user = useCurrentUser(); - const memoStore = useMemoV1Store(); + const memoStore = useMemoStore(); const todayTimeStamp = getDateStampByDate(Date.now()); const weekDay = new Date(todayTimeStamp).getDay(); const weekFromMonday = ["zh-Hans", "ko"].includes(useGlobalStore().state.locale); @@ -49,10 +49,10 @@ const UsageHeatMap = () => { const [createdDays, setCreatedDays] = useState(0); const [allStat, setAllStat] = useState(getInitialUsageStat(usedDaysAmount, beginDayTimestamp)); const containerElRef = useRef(null); - const memos = Array.from(memoStore.getState().memoById.values()); + const memos = Object.values(memoStore.getState().memoMapById); useEffect(() => { - userV1Store.getOrFetchUserByUsername(extractUsernameFromName(user.name)).then((user) => { + userStore.getOrFetchUserByUsername(extractUsernameFromName(user.name)).then((user) => { if (!user) { return; } diff --git a/web/src/hooks/useCurrentUser.ts b/web/src/hooks/useCurrentUser.ts index db3e28c8..43f55697 100644 --- a/web/src/hooks/useCurrentUser.ts +++ b/web/src/hooks/useCurrentUser.ts @@ -1,9 +1,9 @@ -import { useUserV1Store } from "@/store/v1"; +import { useUserStore } from "@/store/v1"; import { User } from "@/types/proto/api/v2/user_service"; const useCurrentUser = () => { - const userV1Store = useUserV1Store(); - return userV1Store.currentUser as User; + const userStore = useUserStore(); + return userStore.currentUser as User; }; export default useCurrentUser; diff --git a/web/src/pages/Archived.tsx b/web/src/pages/Archived.tsx index b1d549be..6f5ff6d2 100644 --- a/web/src/pages/Archived.tsx +++ b/web/src/pages/Archived.tsx @@ -10,7 +10,7 @@ import { memoServiceClient } from "@/grpcweb"; import { getDateTimeString } from "@/helpers/datetime"; import useCurrentUser from "@/hooks/useCurrentUser"; import useLoading from "@/hooks/useLoading"; -import { useMemoV1Store } from "@/store/v1"; +import { useMemoStore } from "@/store/v1"; import { RowStatus } from "@/types/proto/api/v2/common"; import { Memo } from "@/types/proto/api/v2/memo_service"; import { useTranslate } from "@/utils/i18n"; @@ -19,7 +19,7 @@ const Archived = () => { const t = useTranslate(); const loadingState = useLoading(); const user = useCurrentUser(); - const memoStore = useMemoV1Store(); + const memoStore = useMemoStore(); const [archivedMemos, setArchivedMemos] = useState([]); useEffect(() => { diff --git a/web/src/pages/AuthCallback.tsx b/web/src/pages/AuthCallback.tsx index b017b1fd..04f5c100 100644 --- a/web/src/pages/AuthCallback.tsx +++ b/web/src/pages/AuthCallback.tsx @@ -6,7 +6,7 @@ import Icon from "@/components/Icon"; import * as api from "@/helpers/api"; import { absolutifyLink } from "@/helpers/utils"; import useNavigateTo from "@/hooks/useNavigateTo"; -import { useUserV1Store } from "@/store/v1"; +import { useUserStore } from "@/store/v1"; import { useTranslate } from "@/utils/i18n"; interface State { @@ -18,7 +18,7 @@ const AuthCallback = () => { const t = useTranslate(); const navigateTo = useNavigateTo(); const [searchParams] = useSearchParams(); - const userV1Store = useUserV1Store(); + const userStore = useUserStore(); const [state, setState] = useState({ loading: true, errorMessage: "", @@ -40,7 +40,7 @@ const AuthCallback = () => { errorMessage: "", }); if (user) { - await userV1Store.fetchCurrentUser(); + await userStore.fetchCurrentUser(); navigateTo("/"); } else { toast.error(t("message.login-failed")); diff --git a/web/src/pages/Explore.tsx b/web/src/pages/Explore.tsx index c4e0da18..3e53deb3 100644 --- a/web/src/pages/Explore.tsx +++ b/web/src/pages/Explore.tsx @@ -7,14 +7,14 @@ import { DEFAULT_MEMO_LIMIT } from "@/helpers/consts"; import { getTimeStampByDate } from "@/helpers/datetime"; import useCurrentUser from "@/hooks/useCurrentUser"; import { useFilterStore } from "@/store/module"; -import { useMemoList, useMemoV1Store } from "@/store/v1"; +import { useMemoList, useMemoStore } from "@/store/v1"; import { useTranslate } from "@/utils/i18n"; const Explore = () => { const t = useTranslate(); const user = useCurrentUser(); const filterStore = useFilterStore(); - const memoStore = useMemoV1Store(); + const memoStore = useMemoStore(); const memoList = useMemoList(); const [isRequesting, setIsRequesting] = useState(true); const [isComplete, setIsComplete] = useState(false); diff --git a/web/src/pages/Home.tsx b/web/src/pages/Home.tsx index bb3b799c..fcaba405 100644 --- a/web/src/pages/Home.tsx +++ b/web/src/pages/Home.tsx @@ -11,7 +11,7 @@ import { getTimeStampByDate } from "@/helpers/datetime"; import useCurrentUser from "@/hooks/useCurrentUser"; import useResponsiveWidth from "@/hooks/useResponsiveWidth"; import { useFilterStore } from "@/store/module"; -import { useMemoList, useMemoV1Store } from "@/store/v1"; +import { useMemoList, useMemoStore } from "@/store/v1"; import { useTranslate } from "@/utils/i18n"; const Home = () => { @@ -19,7 +19,7 @@ const Home = () => { const { md } = useResponsiveWidth(); const user = useCurrentUser(); const filterStore = useFilterStore(); - const memoStore = useMemoV1Store(); + const memoStore = useMemoStore(); const memoList = useMemoList(); const [isRequesting, setIsRequesting] = useState(true); const [isComplete, setIsComplete] = useState(false); diff --git a/web/src/pages/MemoDetail.tsx b/web/src/pages/MemoDetail.tsx index df26dcf3..ba2a8e23 100644 --- a/web/src/pages/MemoDetail.tsx +++ b/web/src/pages/MemoDetail.tsx @@ -18,7 +18,7 @@ import { UNKNOWN_ID } from "@/helpers/consts"; import { getDateTimeString } from "@/helpers/datetime"; import useCurrentUser from "@/hooks/useCurrentUser"; import useNavigateTo from "@/hooks/useNavigateTo"; -import { useUserV1Store, useMemoV1Store, extractUsernameFromName } from "@/store/v1"; +import { useUserStore, useMemoStore, extractUsernameFromName } from "@/store/v1"; import { MemoRelation_Type } from "@/types/proto/api/v2/memo_relation_service"; import { Memo, Visibility } from "@/types/proto/api/v2/memo_service"; import { User } from "@/types/proto/api/v2/user_service"; @@ -30,8 +30,8 @@ const MemoDetail = () => { const params = useParams(); const navigateTo = useNavigateTo(); const currentUser = useCurrentUser(); - const memoStore = useMemoV1Store(); - const userV1Store = useUserV1Store(); + const memoStore = useMemoStore(); + const userStore = useUserStore(); const [creator, setCreator] = useState(); const memoId = Number(params.memoId); const memo = memoStore.getMemoById(memoId); @@ -48,7 +48,7 @@ const MemoDetail = () => { memoStore .getOrFetchMemoById(memoId) .then(async (memo) => { - const user = await userV1Store.getOrFetchUserByUsername(extractUsernameFromName(memo.creator)); + const user = await userStore.getOrFetchUserByUsername(extractUsernameFromName(memo.creator)); setCreator(user); }) .catch((error) => { diff --git a/web/src/pages/SignIn.tsx b/web/src/pages/SignIn.tsx index 80899b1e..aee729db 100644 --- a/web/src/pages/SignIn.tsx +++ b/web/src/pages/SignIn.tsx @@ -9,14 +9,14 @@ import { absolutifyLink } from "@/helpers/utils"; import useLoading from "@/hooks/useLoading"; import useNavigateTo from "@/hooks/useNavigateTo"; import { useGlobalStore } from "@/store/module"; -import { useUserV1Store } from "@/store/v1"; +import { useUserStore } from "@/store/v1"; import { useTranslate } from "@/utils/i18n"; const SignIn = () => { const t = useTranslate(); const navigateTo = useNavigateTo(); const globalStore = useGlobalStore(); - const userV1Store = useUserV1Store(); + const userStore = useUserStore(); const actionBtnLoadingState = useLoading(false); const { appearance, locale, systemStatus } = globalStore.state; const mode = systemStatus.profile.mode; @@ -77,7 +77,7 @@ const SignIn = () => { actionBtnLoadingState.setLoading(); const { data: user } = await api.signin(username, password, remember); if (user) { - await userV1Store.fetchCurrentUser(); + await userStore.fetchCurrentUser(); navigateTo("/"); } else { toast.error(t("message.login-failed")); diff --git a/web/src/pages/SignUp.tsx b/web/src/pages/SignUp.tsx index 790801cb..731c3ac6 100644 --- a/web/src/pages/SignUp.tsx +++ b/web/src/pages/SignUp.tsx @@ -8,14 +8,14 @@ import * as api from "@/helpers/api"; import useLoading from "@/hooks/useLoading"; import useNavigateTo from "@/hooks/useNavigateTo"; import { useGlobalStore } from "@/store/module"; -import { useUserV1Store } from "@/store/v1"; +import { useUserStore } from "@/store/v1"; import { useTranslate } from "@/utils/i18n"; const SignUp = () => { const t = useTranslate(); const navigateTo = useNavigateTo(); const globalStore = useGlobalStore(); - const userV1Store = useUserV1Store(); + const userStore = useUserStore(); const actionBtnLoadingState = useLoading(false); const { appearance, locale, systemStatus } = globalStore.state; const [username, setUsername] = useState(""); @@ -57,7 +57,7 @@ const SignUp = () => { actionBtnLoadingState.setLoading(); const { data: user } = await api.signup(username, password); if (user) { - await userV1Store.fetchCurrentUser(); + await userStore.fetchCurrentUser(); navigateTo("/"); } else { toast.error(t("message.signup-failed")); diff --git a/web/src/pages/Timeline.tsx b/web/src/pages/Timeline.tsx index 7e52ee79..457ec626 100644 --- a/web/src/pages/Timeline.tsx +++ b/web/src/pages/Timeline.tsx @@ -11,14 +11,14 @@ import DatePicker from "@/components/kit/DatePicker"; import { DAILY_TIMESTAMP } from "@/helpers/consts"; import { getDateStampByDate, getNormalizedDateString, getTimeStampByDate } from "@/helpers/datetime"; import useCurrentUser from "@/hooks/useCurrentUser"; -import { useMemoList, useMemoV1Store } from "@/store/v1"; +import { useMemoList, useMemoStore } from "@/store/v1"; import { useTranslate } from "@/utils/i18n"; const Timeline = () => { const t = useTranslate(); const [searchParams, setSearchParams] = useSearchParams(); const user = useCurrentUser(); - const memoStore = useMemoV1Store(); + const memoStore = useMemoStore(); const memoList = useMemoList(); const currentDateStamp = getDateStampByDate(getNormalizedDateString()) as number; const [selectedDateStamp, setSelectedDateStamp] = useState( diff --git a/web/src/pages/UserProfile.tsx b/web/src/pages/UserProfile.tsx index 1aadeae3..378ca4ff 100644 --- a/web/src/pages/UserProfile.tsx +++ b/web/src/pages/UserProfile.tsx @@ -9,18 +9,18 @@ import { DEFAULT_MEMO_LIMIT } from "@/helpers/consts"; import { getTimeStampByDate } from "@/helpers/datetime"; import useLoading from "@/hooks/useLoading"; import { useFilterStore } from "@/store/module"; -import { useMemoList, useMemoV1Store, useUserV1Store } from "@/store/v1"; +import { useMemoList, useMemoStore, useUserStore } from "@/store/v1"; import { User } from "@/types/proto/api/v2/user_service"; import { useTranslate } from "@/utils/i18n"; const UserProfile = () => { const t = useTranslate(); const params = useParams(); - const userV1Store = useUserV1Store(); + const userStore = useUserStore(); const loadingState = useLoading(); const [user, setUser] = useState(); const filterStore = useFilterStore(); - const memoStore = useMemoV1Store(); + const memoStore = useMemoStore(); const memoList = useMemoList(); const [isRequesting, setIsRequesting] = useState(true); const [isComplete, setIsComplete] = useState(false); @@ -35,7 +35,7 @@ const UserProfile = () => { throw new Error("username is required"); } - userV1Store + userStore .getOrFetchUserByUsername(username) .then((user) => { setUser(user); diff --git a/web/src/store/v1/inbox.ts b/web/src/store/v1/inbox.ts index b6510d73..5804bac0 100644 --- a/web/src/store/v1/inbox.ts +++ b/web/src/store/v1/inbox.ts @@ -1,30 +1,34 @@ import { create } from "zustand"; +import { combine } from "zustand/middleware"; import { inboxServiceClient } from "@/grpcweb"; import { Inbox } from "@/types/proto/api/v2/inbox_service"; -interface InboxStore { +interface State { inboxes: Inbox[]; - fetchInboxes: () => Promise; - updateInbox: (inbox: Partial, updateMask: string[]) => Promise; } -export const useInboxStore = create()((set, get) => ({ +const getDefaultState = (): State => ({ inboxes: [], - fetchInboxes: async () => { - const { inboxes } = await inboxServiceClient.listInboxes({}); - set({ inboxes }); - return inboxes; - }, - updateInbox: async (inbox: Partial, updateMask: string[]) => { - const { inbox: updatedInbox } = await inboxServiceClient.updateInbox({ - inbox, - updateMask, - }); - if (!updatedInbox) { - throw new Error("Inbox not found"); - } - const inboxes = get().inboxes; - set({ inboxes: inboxes.map((i) => (i.name === updatedInbox.name ? updatedInbox : i)) }); - return updatedInbox; - }, -})); +}); + +export const useInboxStore = create( + combine(getDefaultState(), (set, get) => ({ + fetchInboxes: async () => { + const { inboxes } = await inboxServiceClient.listInboxes({}); + set({ inboxes }); + return inboxes; + }, + updateInbox: async (inbox: Partial, updateMask: string[]) => { + const { inbox: updatedInbox } = await inboxServiceClient.updateInbox({ + inbox, + updateMask, + }); + if (!updatedInbox) { + throw new Error("Inbox not found"); + } + const inboxes = get().inboxes; + set({ inboxes: inboxes.map((i) => (i.name === updatedInbox.name ? updatedInbox : i)) }); + return updatedInbox; + }, + })) +); diff --git a/web/src/store/v1/memo.ts b/web/src/store/v1/memo.ts index 93c5dfc8..530183df 100644 --- a/web/src/store/v1/memo.ts +++ b/web/src/store/v1/memo.ts @@ -1,29 +1,32 @@ -import { cloneDeep } from "lodash-es"; import { create } from "zustand"; import { combine } from "zustand/middleware"; import { memoServiceClient } from "@/grpcweb"; import { CreateMemoRequest, ListMemosRequest, Memo } from "@/types/proto/api/v2/memo_service"; interface State { - memoById: Map; + memoMapById: Record; } -export const useMemoV1Store = create( - combine({ memoById: new Map() }, (set, get) => ({ +const getDefaultState = (): State => ({ + memoMapById: {}, +}); + +export const useMemoStore = create( + combine(getDefaultState(), (set, get) => ({ setState: (state: State) => set(state), getState: () => get(), fetchMemos: async (request: Partial) => { const { memos } = await memoServiceClient.listMemos(request); - set((state) => { - for (const memo of memos) { - state.memoById.set(memo.id, memo); - } - return cloneDeep(state); - }); + const memoMap = get().memoMapById; + for (const memo of memos) { + memoMap[memo.id] = memo; + } + set({ memoMapById: memoMap }); return memos; }, getOrFetchMemoById: async (id: number, options?: { skipCache?: boolean; skipStore?: boolean }) => { - const memo = get().memoById.get(id); + const memoMap = get().memoMapById; + const memo = memoMap[id]; if (memo && !options?.skipCache) { return memo; } @@ -36,15 +39,13 @@ export const useMemoV1Store = create( } if (!options?.skipStore) { - set((state) => { - state.memoById.set(id, res.memo as Memo); - return cloneDeep(state); - }); + memoMap[id] = res.memo; + set({ memoMapById: memoMap }); } return res.memo; }, getMemoById: (id: number) => { - return get().memoById.get(id); + return get().memoMapById[id]; }, createMemo: async (request: CreateMemoRequest) => { const { memo } = await memoServiceClient.createMemo(request); @@ -52,10 +53,9 @@ export const useMemoV1Store = create( throw new Error("Memo not found"); } - set((state) => { - state.memoById.set(memo.id, memo); - return cloneDeep(state); - }); + const memoMap = get().memoMapById; + memoMap[memo.id] = memo; + set({ memoMapById: memoMap }); return memo; }, updateMemo: async (update: Partial, updateMask: string[]) => { @@ -68,10 +68,9 @@ export const useMemoV1Store = create( throw new Error("Memo not found"); } - set((state) => { - state.memoById.set(memo.id, memo); - return cloneDeep(state); - }); + const memoMap = get().memoMapById; + memoMap[memo.id] = memo; + set({ memoMapById: memoMap }); return memo; }, deleteMemo: async (id: number) => { @@ -79,24 +78,23 @@ export const useMemoV1Store = create( id: id, }); - set((state) => { - state.memoById.delete(id); - return cloneDeep(state); - }); + const memoMap = get().memoMapById; + delete memoMap[id]; + set({ memoMapById: memoMap }); }, })) ); export const useMemoList = () => { - const memoStore = useMemoV1Store(); - const memos = Array.from(memoStore.getState().memoById.values()); + const memoStore = useMemoStore(); + const memos = Object.values(memoStore.getState().memoMapById); const reset = () => { - memoStore.setState({ memoById: new Map() }); + memoStore.setState({ memoMapById: {} }); }; const size = () => { - return memoStore.getState().memoById.size; + return Object.keys(memoStore.getState().memoMapById).length; }; return { diff --git a/web/src/store/v1/user.ts b/web/src/store/v1/user.ts index f9baa667..fd1a2226 100644 --- a/web/src/store/v1/user.ts +++ b/web/src/store/v1/user.ts @@ -27,7 +27,7 @@ const getDefaultUserSetting = () => { // Request cache is used to prevent multiple requests. const requestCache = new Map>(); -export const useUserV1Store = create( +export const useUserStore = create( combine(getDefaultState(), (set, get) => ({ fetchUsers: async () => { const { users } = await userServiceClient.listUsers({});