Hey is a decentralized and permissionless social media app built with Lens Protocol 🌿

Introduce tracked store helper (#5792)

authored by yoginth.com and committed by

GitHub 7a42b11f aeb51ab3

+213 -217
+26
apps/web/src/store/createTrackedStore.ts
··· 1 + import { createTrackedSelector } from "react-tracked"; 2 + import { create } from "zustand"; 3 + import type { StateCreator, StoreApi } from "zustand"; 4 + import { type PersistOptions, persist } from "zustand/middleware"; 5 + 6 + interface TrackedStore<State> { 7 + store: StoreApi<State>; 8 + useStore: () => State; 9 + } 10 + 11 + export const createTrackedStore = <State>( 12 + initializer: StateCreator<State> 13 + ): TrackedStore<State> => { 14 + const store = create<State>(initializer); 15 + const useStore = createTrackedSelector(store); 16 + return { store, useStore }; 17 + }; 18 + 19 + export const createPersistedTrackedStore = <State>( 20 + initializer: StateCreator<State>, 21 + options: PersistOptions<State> 22 + ): TrackedStore<State> => { 23 + const store = create(persist<State>(initializer, options)); 24 + const useStore = createTrackedSelector(store); 25 + return { store, useStore }; 26 + };
+3 -4
apps/web/src/store/non-persisted/alert/useBlockAlertStore.ts
··· 1 + import { createTrackedStore } from "@/store/createTrackedStore"; 1 2 import type { AccountFragment } from "@hey/indexer"; 2 - import { createTrackedSelector } from "react-tracked"; 3 - import { create } from "zustand"; 4 3 5 4 interface State { 6 5 blockingOrUnblockingAccount?: AccountFragment; ··· 11 10 ) => void; 12 11 } 13 12 14 - const store = create<State>((set) => ({ 13 + const { useStore: useBlockAlertStore } = createTrackedStore<State>((set) => ({ 15 14 blockingOrUnblockingAccount: undefined, 16 15 showBlockOrUnblockAlert: false, 17 16 setShowBlockOrUnblockAlert: ( ··· 20 19 ) => set(() => ({ blockingOrUnblockingAccount, showBlockOrUnblockAlert })) 21 20 })); 22 21 23 - export const useBlockAlertStore = createTrackedSelector(store); 22 + export { useBlockAlertStore };
+10 -9
apps/web/src/store/non-persisted/alert/useDeletePostAlertStore.ts
··· 1 + import { createTrackedStore } from "@/store/createTrackedStore"; 1 2 import type { PostFragment } from "@hey/indexer"; 2 - import { createTrackedSelector } from "react-tracked"; 3 - import { create } from "zustand"; 4 3 5 4 interface State { 6 5 deletingPost?: PostFragment; ··· 11 10 ) => void; 12 11 } 13 12 14 - const store = create<State>((set) => ({ 15 - deletingPost: undefined, 16 - showPostDeleteAlert: false, 17 - setShowPostDeleteAlert: (showPostDeleteAlert, deletingPost) => 18 - set(() => ({ deletingPost, showPostDeleteAlert })) 19 - })); 13 + const { useStore: useDeletePostAlertStore } = createTrackedStore<State>( 14 + (set) => ({ 15 + deletingPost: undefined, 16 + showPostDeleteAlert: false, 17 + setShowPostDeleteAlert: (showPostDeleteAlert, deletingPost) => 18 + set(() => ({ deletingPost, showPostDeleteAlert })) 19 + }) 20 + ); 20 21 21 - export const useDeletePostAlertStore = createTrackedSelector(store); 22 + export { useDeletePostAlertStore };
+3 -4
apps/web/src/store/non-persisted/alert/useMuteAlertStore.ts
··· 1 + import { createTrackedStore } from "@/store/createTrackedStore"; 1 2 import type { AccountFragment } from "@hey/indexer"; 2 - import { createTrackedSelector } from "react-tracked"; 3 - import { create } from "zustand"; 4 3 5 4 interface State { 6 5 mutingOrUnmutingAccount?: AccountFragment; ··· 11 10 ) => void; 12 11 } 13 12 14 - const store = create<State>((set) => ({ 13 + const { useStore: useMuteAlertStore } = createTrackedStore<State>((set) => ({ 15 14 mutingOrUnmutingAccount: undefined, 16 15 showMuteOrUnmuteAlert: false, 17 16 setShowMuteOrUnmuteAlert: (showMuteOrUnmuteAlert, mutingOrUnmutingAccount) => 18 17 set(() => ({ mutingOrUnmutingAccount, showMuteOrUnmuteAlert })) 19 18 })); 20 19 21 - export const useMuteAlertStore = createTrackedSelector(store); 20 + export { useMuteAlertStore };
+3 -4
apps/web/src/store/non-persisted/modal/useAuthModalStore.ts
··· 1 - import { createTrackedSelector } from "react-tracked"; 2 - import { create } from "zustand"; 1 + import { createTrackedStore } from "@/store/createTrackedStore"; 3 2 4 3 type AuthModalType = "login" | "signup"; 5 4 ··· 12 11 ) => void; 13 12 } 14 13 15 - const store = create<State>((set) => ({ 14 + const { useStore: useAuthModalStore } = createTrackedStore<State>((set) => ({ 16 15 showAuthModal: false, 17 16 authModalType: "login", 18 17 setShowAuthModal: (showAuthModal, authModalType) => 19 18 set(() => ({ showAuthModal, authModalType })) 20 19 })); 21 20 22 - export const useAuthModalStore = createTrackedSelector(store); 21 + export { useAuthModalStore };
+3 -4
apps/web/src/store/non-persisted/modal/useFundModalStore.ts
··· 1 - import { createTrackedSelector } from "react-tracked"; 1 + import { createTrackedStore } from "@/store/createTrackedStore"; 2 2 import type { Address } from "viem"; 3 - import { create } from "zustand"; 4 3 5 4 export interface FundingToken { 6 5 contractAddress: Address; ··· 24 23 }: TopUpAmount) => void; 25 24 } 26 25 27 - const store = create<State>((set) => ({ 26 + const { useStore: useFundModalStore } = createTrackedStore<State>((set) => ({ 28 27 showFundModal: false, 29 28 token: undefined, 30 29 amountToTopUp: undefined, ··· 32 31 set(() => ({ showFundModal, token, amountToTopUp })) 33 32 })); 34 33 35 - export const useFundModalStore = createTrackedSelector(store); 34 + export { useFundModalStore };
+8 -7
apps/web/src/store/non-persisted/modal/useMobileDrawerModalStore.ts
··· 1 - import { createTrackedSelector } from "react-tracked"; 2 - import { create } from "zustand"; 1 + import { createTrackedStore } from "@/store/createTrackedStore"; 3 2 4 3 interface State { 5 4 showMobileDrawer: boolean; 6 5 setShowMobileDrawer: (showMobileDrawer: boolean) => void; 7 6 } 8 7 9 - const store = create<State>((set) => ({ 10 - showMobileDrawer: false, 11 - setShowMobileDrawer: (showMobileDrawer) => set(() => ({ showMobileDrawer })) 12 - })); 8 + const { useStore: useMobileDrawerModalStore } = createTrackedStore<State>( 9 + (set) => ({ 10 + showMobileDrawer: false, 11 + setShowMobileDrawer: (showMobileDrawer) => set(() => ({ showMobileDrawer })) 12 + }) 13 + ); 13 14 14 - export const useMobileDrawerModalStore = createTrackedSelector(store); 15 + export { useMobileDrawerModalStore };
+3 -4
apps/web/src/store/non-persisted/modal/useNewPostModalStore.ts
··· 1 - import { createTrackedSelector } from "react-tracked"; 2 - import { create } from "zustand"; 1 + import { createTrackedStore } from "@/store/createTrackedStore"; 3 2 4 3 interface State { 5 4 showNewPostModal: boolean; 6 5 setShowNewPostModal: (showNewPostModal: boolean) => void; 7 6 } 8 7 9 - const store = create<State>((set) => ({ 8 + const { useStore: useNewPostModalStore } = createTrackedStore<State>((set) => ({ 10 9 showNewPostModal: false, 11 10 setShowNewPostModal: (showNewPostModal) => set(() => ({ showNewPostModal })) 12 11 })); 13 12 14 - export const useNewPostModalStore = createTrackedSelector(store); 13 + export { useNewPostModalStore };
+3 -4
apps/web/src/store/non-persisted/modal/useProModalStore.ts
··· 1 - import { createTrackedSelector } from "react-tracked"; 2 - import { create } from "zustand"; 1 + import { createTrackedStore } from "@/store/createTrackedStore"; 3 2 4 3 interface State { 5 4 showProModal: boolean; 6 5 setShowProModal: (showProModal: boolean) => void; 7 6 } 8 7 9 - const store = create<State>((set) => ({ 8 + const { useStore: useProModalStore } = createTrackedStore<State>((set) => ({ 10 9 showProModal: false, 11 10 setShowProModal: (showProModal) => set(() => ({ showProModal })) 12 11 })); 13 12 14 - export const useProModalStore = createTrackedSelector(store); 13 + export { useProModalStore };
+10 -9
apps/web/src/store/non-persisted/modal/useReportAccountModalStore.ts
··· 1 + import { createTrackedStore } from "@/store/createTrackedStore"; 1 2 import type { AccountFragment } from "@hey/indexer"; 2 - import { createTrackedSelector } from "react-tracked"; 3 - import { create } from "zustand"; 4 3 5 4 interface State { 6 5 showReportAccountModal: boolean; ··· 11 10 ) => void; 12 11 } 13 12 14 - const store = create<State>((set) => ({ 15 - showReportAccountModal: false, 16 - reportingAccount: undefined, 17 - setShowReportAccountModal: (showReportAccountModal, reportingAccount) => 18 - set(() => ({ showReportAccountModal, reportingAccount })) 19 - })); 13 + const { useStore: useReportAccountModalStore } = createTrackedStore<State>( 14 + (set) => ({ 15 + showReportAccountModal: false, 16 + reportingAccount: undefined, 17 + setShowReportAccountModal: (showReportAccountModal, reportingAccount) => 18 + set(() => ({ showReportAccountModal, reportingAccount })) 19 + }) 20 + ); 20 21 21 - export const useReportAccountModalStore = createTrackedSelector(store); 22 + export { useReportAccountModalStore };
+10 -9
apps/web/src/store/non-persisted/modal/useReportPostModalStore.ts
··· 1 - import { createTrackedSelector } from "react-tracked"; 2 - import { create } from "zustand"; 1 + import { createTrackedStore } from "@/store/createTrackedStore"; 3 2 4 3 interface State { 5 4 showReportPostModal: boolean; ··· 10 9 ) => void; 11 10 } 12 11 13 - const store = create<State>((set) => ({ 14 - showReportPostModal: false, 15 - reportingPostId: undefined, 16 - setShowReportPostModal: (showReportPostModal, reportingPostId) => 17 - set(() => ({ showReportPostModal, reportingPostId })) 18 - })); 12 + const { useStore: useReportPostModalStore } = createTrackedStore<State>( 13 + (set) => ({ 14 + showReportPostModal: false, 15 + reportingPostId: undefined, 16 + setShowReportPostModal: (showReportPostModal, reportingPostId) => 17 + set(() => ({ showReportPostModal, reportingPostId })) 18 + }) 19 + ); 19 20 20 - export const useReportPostModalStore = createTrackedSelector(store); 21 + export { useReportPostModalStore };
+10 -9
apps/web/src/store/non-persisted/modal/useSuperFollowModalStore.ts
··· 1 + import { createTrackedStore } from "@/store/createTrackedStore"; 1 2 import type { AccountFragment } from "@hey/indexer"; 2 - import { createTrackedSelector } from "react-tracked"; 3 - import { create } from "zustand"; 4 3 5 4 interface State { 6 5 showSuperFollowModal: boolean; ··· 11 10 ) => void; 12 11 } 13 12 14 - const store = create<State>((set) => ({ 15 - showSuperFollowModal: false, 16 - superFollowingAccount: undefined, 17 - setShowSuperFollowModal: (showSuperFollowModal, superFollowingAccount) => 18 - set(() => ({ showSuperFollowModal, superFollowingAccount })) 19 - })); 13 + const { useStore: useSuperFollowModalStore } = createTrackedStore<State>( 14 + (set) => ({ 15 + showSuperFollowModal: false, 16 + superFollowingAccount: undefined, 17 + setShowSuperFollowModal: (showSuperFollowModal, superFollowingAccount) => 18 + set(() => ({ showSuperFollowModal, superFollowingAccount })) 19 + }) 20 + ); 20 21 21 - export const useSuperFollowModalStore = createTrackedSelector(store); 22 + export { useSuperFollowModalStore };
+10 -9
apps/web/src/store/non-persisted/modal/useSuperJoinModalStore.ts
··· 1 + import { createTrackedStore } from "@/store/createTrackedStore"; 1 2 import type { GroupFragment } from "@hey/indexer"; 2 - import { createTrackedSelector } from "react-tracked"; 3 - import { create } from "zustand"; 4 3 5 4 interface State { 6 5 showSuperJoinModal: boolean; ··· 11 10 ) => void; 12 11 } 13 12 14 - const store = create<State>((set) => ({ 15 - showSuperJoinModal: false, 16 - superJoiningGroup: undefined, 17 - setShowSuperJoinModal: (showSuperJoinModal, superJoiningGroup) => 18 - set(() => ({ showSuperJoinModal, superJoiningGroup })) 19 - })); 13 + const { useStore: useSuperJoinModalStore } = createTrackedStore<State>( 14 + (set) => ({ 15 + showSuperJoinModal: false, 16 + superJoiningGroup: undefined, 17 + setShowSuperJoinModal: (showSuperJoinModal, superJoiningGroup) => 18 + set(() => ({ showSuperJoinModal, superJoiningGroup })) 19 + }) 20 + ); 20 21 21 - export const useSuperJoinModalStore = createTrackedSelector(store); 22 + export { useSuperJoinModalStore };
+9 -8
apps/web/src/store/non-persisted/modal/useSwitchAccountModalStore.ts
··· 1 - import { createTrackedSelector } from "react-tracked"; 2 - import { create } from "zustand"; 1 + import { createTrackedStore } from "@/store/createTrackedStore"; 3 2 4 3 interface State { 5 4 showSwitchAccountModal: boolean; 6 5 setShowSwitchAccountModal: (showSwitchAccountModal: boolean) => void; 7 6 } 8 7 9 - const store = create<State>((set) => ({ 10 - showSwitchAccountModal: false, 11 - setShowSwitchAccountModal: (showSwitchAccountModal) => 12 - set(() => ({ showSwitchAccountModal })) 13 - })); 8 + const { useStore: useSwitchAccountModalStore } = createTrackedStore<State>( 9 + (set) => ({ 10 + showSwitchAccountModal: false, 11 + setShowSwitchAccountModal: (showSwitchAccountModal) => 12 + set(() => ({ showSwitchAccountModal })) 13 + }) 14 + ); 14 15 15 - export const useSwitchAccountModalStore = createTrackedSelector(store); 16 + export { useSwitchAccountModalStore };
+3 -4
apps/web/src/store/non-persisted/navigation/useAccountLinkStore.ts
··· 1 + import { createTrackedStore } from "@/store/createTrackedStore"; 1 2 import type { AccountFragment } from "@hey/indexer"; 2 - import { createTrackedSelector } from "react-tracked"; 3 - import { create } from "zustand"; 4 3 5 4 interface State { 6 5 cachedAccount: AccountFragment | null; 7 6 setCachedAccount: (account: AccountFragment | null) => void; 8 7 } 9 8 10 - const store = create<State>((set) => ({ 9 + const { useStore: useAccountLinkStore } = createTrackedStore<State>((set) => ({ 11 10 cachedAccount: null, 12 11 setCachedAccount: (account) => set(() => ({ cachedAccount: account })) 13 12 })); 14 13 15 - export const useAccountLinkStore = createTrackedSelector(store); 14 + export { useAccountLinkStore };
+3 -4
apps/web/src/store/non-persisted/navigation/usePostLinkStore.ts
··· 1 + import { createTrackedStore } from "@/store/createTrackedStore"; 1 2 import type { AnyPostFragment } from "@hey/indexer"; 2 - import { createTrackedSelector } from "react-tracked"; 3 - import { create } from "zustand"; 4 3 5 4 interface State { 6 5 cachedPost: AnyPostFragment | null; 7 6 setCachedPost: (post: AnyPostFragment | null) => void; 8 7 } 9 8 10 - const store = create<State>((set) => ({ 9 + const { useStore: usePostLinkStore } = createTrackedStore<State>((set) => ({ 11 10 cachedPost: null, 12 11 setCachedPost: (post) => set(() => ({ cachedPost: post })) 13 12 })); 14 13 15 - export const usePostLinkStore = createTrackedSelector(store); 14 + export { usePostLinkStore };
+3 -4
apps/web/src/store/non-persisted/post/usePostAudioStore.ts
··· 1 - import { createTrackedSelector } from "react-tracked"; 2 - import { create } from "zustand"; 1 + import { createTrackedStore } from "@/store/createTrackedStore"; 3 2 4 3 interface AudioPost { 5 4 artist: string; ··· 20 19 setAudioPost: (audioPost: AudioPost) => void; 21 20 } 22 21 23 - const store = create<State>((set) => ({ 22 + const { useStore: usePostAudioStore } = createTrackedStore<State>((set) => ({ 24 23 audioPost: DEFAULT_AUDIO_POST, 25 24 setAudioPost: (audioPost) => set(() => ({ audioPost })) 26 25 })); 27 26 28 - export const usePostAudioStore = createTrackedSelector(store); 27 + export { usePostAudioStore };
+3 -4
apps/web/src/store/non-persisted/post/usePostLicenseStore.ts
··· 1 + import { createTrackedStore } from "@/store/createTrackedStore"; 1 2 import type { MetadataLicenseType } from "@hey/indexer"; 2 - import { createTrackedSelector } from "react-tracked"; 3 - import { create } from "zustand"; 4 3 5 4 interface State { 6 5 license: MetadataLicenseType | null; 7 6 setLicense: (license: MetadataLicenseType | null) => void; 8 7 } 9 8 10 - const store = create<State>((set) => ({ 9 + const { useStore: usePostLicenseStore } = createTrackedStore<State>((set) => ({ 11 10 license: null, 12 11 setLicense: (license) => set(() => ({ license })) 13 12 })); 14 13 15 - export const usePostLicenseStore = createTrackedSelector(store); 14 + export { usePostLicenseStore };
+3 -4
apps/web/src/store/non-persisted/post/usePostLiveStore.ts
··· 1 - import { createTrackedSelector } from "react-tracked"; 2 - import { create } from "zustand"; 1 + import { createTrackedStore } from "@/store/createTrackedStore"; 3 2 4 3 interface State { 5 4 liveVideoConfig: { ··· 17 16 showLiveVideoEditor: boolean; 18 17 } 19 18 20 - const store = create<State>((set) => ({ 19 + const { useStore: usePostLiveStore } = createTrackedStore<State>((set) => ({ 21 20 liveVideoConfig: { id: "", playbackId: "", streamKey: "" }, 22 21 resetLiveVideoConfig: () => 23 22 set(() => ({ liveVideoConfig: { id: "", playbackId: "", streamKey: "" } })), ··· 27 26 showLiveVideoEditor: false 28 27 })); 29 28 30 - export const usePostLiveStore = createTrackedSelector(store); 29 + export { usePostLiveStore };
+3 -4
apps/web/src/store/non-persisted/post/usePostRulesStore.ts
··· 1 + import { createTrackedStore } from "@/store/createTrackedStore"; 1 2 import type { FollowersOnlyPostRuleConfig } from "@hey/indexer"; 2 - import { createTrackedSelector } from "react-tracked"; 3 - import { create } from "zustand"; 4 3 5 4 interface State { 6 5 rules?: FollowersOnlyPostRuleConfig; 7 6 setRules: (rules?: FollowersOnlyPostRuleConfig) => void; 8 7 } 9 8 10 - const store = create<State>((set) => ({ 9 + const { useStore: usePostRulesStore } = createTrackedStore<State>((set) => ({ 11 10 rules: undefined, 12 11 setRules: (rules) => set(() => ({ rules })) 13 12 })); 14 13 15 - export const usePostRulesStore = createTrackedSelector(store); 14 + export { usePostRulesStore };
+3 -4
apps/web/src/store/non-persisted/post/usePostStore.ts
··· 1 + import { createTrackedStore } from "@/store/createTrackedStore"; 1 2 import type { PostFragment } from "@hey/indexer"; 2 - import { createTrackedSelector } from "react-tracked"; 3 - import { create } from "zustand"; 4 3 5 4 interface State { 6 5 postContent: string; ··· 11 10 setEditingPost: (editingPost?: PostFragment) => void; 12 11 } 13 12 14 - const store = create<State>((set) => ({ 13 + const { useStore: usePostStore } = createTrackedStore<State>((set) => ({ 15 14 postContent: "", 16 15 quotedPost: undefined, 17 16 editingPost: undefined, ··· 20 19 setEditingPost: (editingPost) => set(() => ({ editingPost })) 21 20 })); 22 21 23 - export const usePostStore = createTrackedSelector(store); 22 + export { usePostStore };
+3 -4
apps/web/src/store/non-persisted/post/usePostVideoStore.ts
··· 1 - import { createTrackedSelector } from "react-tracked"; 2 - import { create } from "zustand"; 1 + import { createTrackedStore } from "@/store/createTrackedStore"; 3 2 4 3 interface VideoThumbnail { 5 4 mimeType: string; ··· 20 19 videoThumbnail: VideoThumbnail; 21 20 } 22 21 23 - const store = create<State>((set) => ({ 22 + const { useStore: usePostVideoStore } = createTrackedStore<State>((set) => ({ 24 23 setVideoDurationInSeconds: (videoDurationInSeconds) => 25 24 set(() => ({ videoDurationInSeconds })), 26 25 setVideoThumbnail: (videoThumbnail) => set(() => ({ videoThumbnail })), ··· 28 27 videoThumbnail: DEFAULT_VIDEO_THUMBNAIL 29 28 })); 30 29 31 - export const usePostVideoStore = createTrackedSelector(store); 30 + export { usePostVideoStore };
+10 -14
apps/web/src/store/persisted/useAccountStore.ts
··· 1 + import { createPersistedTrackedStore } from "@/store/createTrackedStore"; 1 2 import { Localstorage } from "@hey/data/storage"; 2 3 import type { AccountFragment } from "@hey/indexer"; 3 - import { createTrackedSelector } from "react-tracked"; 4 - import { create } from "zustand"; 5 - import { persist } from "zustand/middleware"; 6 4 7 5 interface State { 8 6 currentAccount?: AccountFragment; ··· 10 8 hydrateAccount: () => AccountFragment | undefined; 11 9 } 12 10 13 - const store = create( 14 - persist<State>( 15 - (set, get) => ({ 16 - currentAccount: undefined, 17 - setCurrentAccount: (currentAccount?: AccountFragment) => 18 - set(() => ({ currentAccount })), 19 - hydrateAccount: () => get().currentAccount 20 - }), 21 - { name: Localstorage.AccountStore } 22 - ) 11 + const { useStore: useAccountStore, store } = createPersistedTrackedStore<State>( 12 + (set, get) => ({ 13 + currentAccount: undefined, 14 + setCurrentAccount: (currentAccount?: AccountFragment) => 15 + set(() => ({ currentAccount })), 16 + hydrateAccount: () => get().currentAccount 17 + }), 18 + { name: Localstorage.AccountStore } 23 19 ); 24 20 25 - export const useAccountStore = createTrackedSelector(store); 21 + export { useAccountStore }; 26 22 export const hydrateAccount = () => store.getState().hydrateAccount();
+21 -24
apps/web/src/store/persisted/useAuthStore.ts
··· 1 + import { createPersistedTrackedStore } from "@/store/createTrackedStore"; 1 2 import { Localstorage } from "@hey/data/storage"; 2 - import { create } from "zustand"; 3 - import { persist } from "zustand/middleware"; 4 3 5 4 interface Tokens { 6 5 accessToken: null | string; ··· 18 17 signOut: () => void; 19 18 } 20 19 21 - const store = create( 22 - persist<State>( 23 - (set, get) => ({ 24 - accessToken: null, 25 - hydrateAuthTokens: () => { 26 - const { accessToken, refreshToken } = get(); 27 - return { accessToken, refreshToken }; 28 - }, 29 - refreshToken: null, 30 - signIn: ({ accessToken, refreshToken }) => 31 - set({ accessToken, refreshToken }), 32 - signOut: async () => { 33 - // Clear Localstorage 34 - const allLocalstorageStores = Object.values(Localstorage).filter( 35 - (value) => value !== Localstorage.SearchStore 36 - ); 37 - for (const store of allLocalstorageStores) { 38 - localStorage.removeItem(store); 39 - } 20 + const { store } = createPersistedTrackedStore<State>( 21 + (set, get) => ({ 22 + accessToken: null, 23 + hydrateAuthTokens: () => { 24 + const { accessToken, refreshToken } = get(); 25 + return { accessToken, refreshToken }; 26 + }, 27 + refreshToken: null, 28 + signIn: ({ accessToken, refreshToken }) => 29 + set({ accessToken, refreshToken }), 30 + signOut: async () => { 31 + // Clear Localstorage 32 + const allLocalstorageStores = Object.values(Localstorage).filter( 33 + (value) => value !== Localstorage.SearchStore 34 + ); 35 + for (const store of allLocalstorageStores) { 36 + localStorage.removeItem(store); 40 37 } 41 - }), 42 - { name: Localstorage.AuthStore } 43 - ) 38 + } 39 + }), 40 + { name: Localstorage.AuthStore } 44 41 ); 45 42 46 43 export const signIn = (tokens: {
+8 -12
apps/web/src/store/persisted/useHomeTabStore.ts
··· 1 + import { createPersistedTrackedStore } from "@/store/createTrackedStore"; 1 2 import { HomeFeedType } from "@hey/data/enums"; 2 3 import { Localstorage } from "@hey/data/storage"; 3 - import { createTrackedSelector } from "react-tracked"; 4 - import { create } from "zustand"; 5 - import { persist } from "zustand/middleware"; 6 4 7 5 interface State { 8 6 feedType: HomeFeedType; 9 7 setFeedType: (feedType: HomeFeedType) => void; 10 8 } 11 9 12 - const store = create( 13 - persist<State>( 14 - (set) => ({ 15 - feedType: HomeFeedType.FOLLOWING, 16 - setFeedType: (feedType) => set(() => ({ feedType })) 17 - }), 18 - { name: Localstorage.HomeTabStore } 19 - ) 10 + const { useStore: useHomeTabStore } = createPersistedTrackedStore<State>( 11 + (set) => ({ 12 + feedType: HomeFeedType.FOLLOWING, 13 + setFeedType: (feedType) => set(() => ({ feedType })) 14 + }), 15 + { name: Localstorage.HomeTabStore } 20 16 ); 21 17 22 - export const useHomeTabStore = createTrackedSelector(store); 18 + export { useHomeTabStore };
+11 -15
apps/web/src/store/persisted/usePreferencesStore.ts
··· 1 + import { createPersistedTrackedStore } from "@/store/createTrackedStore"; 1 2 import { Localstorage } from "@hey/data/storage"; 2 - import { createTrackedSelector } from "react-tracked"; 3 - import { create } from "zustand"; 4 - import { persist } from "zustand/middleware"; 5 3 6 4 interface State { 7 5 appIcon: number; ··· 11 9 setIncludeLowScore: (includeLowScore: boolean) => void; 12 10 } 13 11 14 - const store = create( 15 - persist<State>( 16 - (set) => ({ 17 - appIcon: 0, 18 - includeLowScore: false, 19 - resetPreferences: () => set(() => ({ includeLowScore: false })), 20 - setAppIcon: (appIcon) => set(() => ({ appIcon })), 21 - setIncludeLowScore: (includeLowScore) => set(() => ({ includeLowScore })) 22 - }), 23 - { name: Localstorage.PreferencesStore } 24 - ) 12 + const { useStore: usePreferencesStore } = createPersistedTrackedStore<State>( 13 + (set) => ({ 14 + appIcon: 0, 15 + includeLowScore: false, 16 + resetPreferences: () => set(() => ({ includeLowScore: false })), 17 + setAppIcon: (appIcon) => set(() => ({ appIcon })), 18 + setIncludeLowScore: (includeLowScore) => set(() => ({ includeLowScore })) 19 + }), 20 + { name: Localstorage.PreferencesStore } 25 21 ); 26 22 27 - export const usePreferencesStore = createTrackedSelector(store); 23 + export { usePreferencesStore };
+9 -13
apps/web/src/store/persisted/useProStore.ts
··· 1 + import { createPersistedTrackedStore } from "@/store/createTrackedStore"; 1 2 import { Localstorage } from "@hey/data/storage"; 2 - import { createTrackedSelector } from "react-tracked"; 3 - import { create } from "zustand"; 4 - import { persist } from "zustand/middleware"; 5 3 6 4 interface State { 7 5 proBannerDismissed: boolean; 8 6 setProBannerDismissed: (proBannerDismissed: boolean) => void; 9 7 } 10 8 11 - const store = create( 12 - persist<State>( 13 - (set) => ({ 14 - proBannerDismissed: false, 15 - setProBannerDismissed: (proBannerDismissed: boolean) => 16 - set(() => ({ proBannerDismissed })) 17 - }), 18 - { name: Localstorage.ProStore } 19 - ) 9 + const { useStore: useProStore } = createPersistedTrackedStore<State>( 10 + (set) => ({ 11 + proBannerDismissed: false, 12 + setProBannerDismissed: (proBannerDismissed: boolean) => 13 + set(() => ({ proBannerDismissed })) 14 + }), 15 + { name: Localstorage.ProStore } 20 16 ); 21 17 22 - export const useProStore = createTrackedSelector(store); 18 + export { useProStore };
+19 -23
apps/web/src/store/persisted/useSearchStore.ts
··· 1 + import { createPersistedTrackedStore } from "@/store/createTrackedStore"; 1 2 import { Localstorage } from "@hey/data/storage"; 2 - import { createTrackedSelector } from "react-tracked"; 3 - import { create } from "zustand"; 4 - import { persist } from "zustand/middleware"; 5 3 6 4 interface State { 7 5 addAccount: (account: string) => void; ··· 10 8 accounts: string[]; 11 9 } 12 10 13 - const store = create( 14 - persist<State>( 15 - (set) => ({ 16 - addAccount: (account) => 17 - set((state) => { 18 - // Remove the account if it already exists 19 - const filteredAccounts = state.accounts.filter((a) => a !== account); 20 - // Add the new account to the start of the array and ensure the total is at most 5 21 - return { accounts: [account, ...filteredAccounts].slice(0, 5) }; 22 - }), 23 - clearAccount: (account) => 24 - set((state) => ({ 25 - accounts: state.accounts.filter((a) => a !== account) 26 - })), 27 - clearAccounts: () => set({ accounts: [] }), 28 - accounts: [] 29 - }), 30 - { name: Localstorage.SearchStore } 31 - ) 11 + const { useStore: useSearchStore } = createPersistedTrackedStore<State>( 12 + (set) => ({ 13 + addAccount: (account) => 14 + set((state) => { 15 + // Remove the account if it already exists 16 + const filteredAccounts = state.accounts.filter((a) => a !== account); 17 + // Add the new account to the start of the array and ensure the total is at most 5 18 + return { accounts: [account, ...filteredAccounts].slice(0, 5) }; 19 + }), 20 + clearAccount: (account) => 21 + set((state) => ({ 22 + accounts: state.accounts.filter((a) => a !== account) 23 + })), 24 + clearAccounts: () => set({ accounts: [] }), 25 + accounts: [] 26 + }), 27 + { name: Localstorage.SearchStore } 32 28 ); 33 29 34 - export const useSearchStore = createTrackedSelector(store); 30 + export { useSearchStore };