Skip to content

Commit

Permalink
fix: safaLocalStorage
Browse files Browse the repository at this point in the history
  • Loading branch information
Dogtiti committed Sep 8, 2024
1 parent 23ac2ef commit 992c3a5
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 26 deletions.
7 changes: 5 additions & 2 deletions app/components/chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import {
isVisionModel,
isDalle3,
showPlugins,
safeLocalStorage,
} from "../utils";

import { uploadImage as uploadImageRemote } from "@/app/utils/chat";
Expand Down Expand Up @@ -109,6 +110,8 @@ import { getClientConfig } from "../config/client";
import { useAllModels } from "../utils/hooks";
import { MultimodalContent } from "../client/api";

const localStorage = safeLocalStorage();

const Markdown = dynamic(async () => (await import("./markdown")).Markdown, {
loading: () => <LoadingIcon />,
});
Expand Down Expand Up @@ -941,7 +944,7 @@ function _Chat() {
.onUserInput(userInput, attachImages)
.then(() => setIsLoading(false));
setAttachImages([]);
localStorage.setItem(LAST_INPUT_KEY, userInput);
chatStore.setLastInput(userInput);
setUserInput("");
setPromptHints([]);
if (!isMobileScreen) inputRef.current?.focus();
Expand Down Expand Up @@ -1007,7 +1010,7 @@ function _Chat() {
userInput.length <= 0 &&
!(e.metaKey || e.altKey || e.ctrlKey)
) {
setUserInput(localStorage.getItem(LAST_INPUT_KEY) ?? "");
setUserInput(chatStore.lastInput ?? "");
e.preventDefault();
return;
}
Expand Down
4 changes: 2 additions & 2 deletions app/components/error.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ISSUE_URL } from "../constant";
import Locale from "../locales";
import { showConfirm } from "./ui-lib";
import { useSyncStore } from "../store/sync";
import { useChatStore } from "../store/chat";

interface IErrorBoundaryState {
hasError: boolean;
Expand All @@ -30,8 +31,7 @@ export class ErrorBoundary extends React.Component<any, IErrorBoundaryState> {
try {
useSyncStore.getState().export();
} finally {
localStorage.clear();
location.reload();
useChatStore.getState().clearAllData();
}
}

Expand Down
15 changes: 3 additions & 12 deletions app/components/mask.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -426,16 +426,7 @@ export function MaskPage() {
const maskStore = useMaskStore();
const chatStore = useChatStore();

const [filterLang, setFilterLang] = useState<Lang | undefined>(
() => localStorage.getItem("Mask-language") as Lang | undefined,
);
useEffect(() => {
if (filterLang) {
localStorage.setItem("Mask-language", filterLang);
} else {
localStorage.removeItem("Mask-language");
}
}, [filterLang]);
const filterLang = maskStore.language;

const allMasks = maskStore
.getAll()
Expand Down Expand Up @@ -542,9 +533,9 @@ export function MaskPage() {
onChange={(e) => {
const value = e.currentTarget.value;
if (value === Locale.Settings.Lang.All) {
setFilterLang(undefined);
maskStore.setLanguage(undefined);
} else {
setFilterLang(value as Lang);
maskStore.setLanguage(value as Lang);
}
}}
>
Expand Down
13 changes: 5 additions & 8 deletions app/locales/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ import ar from "./ar";
import bn from "./bn";
import sk from "./sk";
import { merge } from "../utils/merge";
import { safeLocalStorage } from "@/app/utils";

import type { LocaleType } from "./cn";
export type { LocaleType, PartialLocaleType } from "./cn";

const localStorage = safeLocalStorage();

const ALL_LANGS = {
cn,
en,
Expand Down Expand Up @@ -82,17 +85,11 @@ merge(fallbackLang, targetLang);
export default fallbackLang as LocaleType;

function getItem(key: string) {
try {
return localStorage.getItem(key);
} catch {
return null;
}
return localStorage.getItem(key);
}

function setItem(key: string, value: string) {
try {
localStorage.setItem(key, value);
} catch {}
localStorage.setItem(key, value);
}

function getLanguage() {
Expand Down
10 changes: 9 additions & 1 deletion app/store/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ import { nanoid } from "nanoid";
import { createPersistStore } from "../utils/store";
import { collectModelsWithDefaultModel } from "../utils/model";
import { useAccessStore } from "./access";
import { isDalle3 } from "../utils";
import { isDalle3, safeLocalStorage } from "../utils";
import { indexedDBStorage } from "@/app/utils/indexedDB-storage";

const localStorage = safeLocalStorage();

export type ChatMessageTool = {
id: string;
index?: number;
Expand Down Expand Up @@ -179,6 +181,7 @@ function fillTemplateWith(input: string, modelConfig: ModelConfig) {
const DEFAULT_CHAT_STATE = {
sessions: [createEmptySession()],
currentSessionIndex: 0,
lastInput: "",
};

export const useChatStore = createPersistStore(
Expand Down Expand Up @@ -700,6 +703,11 @@ export const useChatStore = createPersistStore(
localStorage.clear();
location.reload();
},
setLastInput(lastInput: string) {
set({
lastInput,
});
},
};

return methods;
Expand Down
10 changes: 9 additions & 1 deletion app/store/mask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ export type Mask = {

export const DEFAULT_MASK_STATE = {
masks: {} as Record<string, Mask>,
language: undefined as Lang | undefined,
};

export type MaskState = typeof DEFAULT_MASK_STATE;
export type MaskState = typeof DEFAULT_MASK_STATE & {
language?: Lang | undefined;
};

export const DEFAULT_MASK_AVATAR = "gpt-bot";
export const createEmptyMask = () =>
Expand Down Expand Up @@ -102,6 +105,11 @@ export const useMaskStore = createPersistStore(
search(text: string) {
return Object.values(get().masks);
},
setLanguage(language: Lang | undefined) {
set({
language,
});
},
}),
{
name: StoreKey.Mask,
Expand Down
60 changes: 60 additions & 0 deletions app/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,3 +318,63 @@ export function adapter(config: Record<string, unknown>) {
: path;
return fetch(fetchUrl as string, { ...rest, responseType: "text" });
}

export function safeLocalStorage(): {
getItem: (key: string) => string | null;
setItem: (key: string, value: string) => void;
removeItem: (key: string) => void;
clear: () => void;
} {
let storage: Storage | null;

try {
if (typeof window !== "undefined" && window.localStorage) {
storage = window.localStorage;
} else {
storage = null;
}
} catch (e) {
console.error("localStorage is not available:", e);
storage = null;
}

return {
getItem(key: string): string | null {
if (storage) {
return storage.getItem(key);
} else {
console.warn(
`Attempted to get item "${key}" from localStorage, but localStorage is not available.`,
);
return null;
}
},
setItem(key: string, value: string): void {
if (storage) {
storage.setItem(key, value);
} else {
console.warn(
`Attempted to set item "${key}" in localStorage, but localStorage is not available.`,
);
}
},
removeItem(key: string): void {
if (storage) {
storage.removeItem(key);
} else {
console.warn(
`Attempted to remove item "${key}" from localStorage, but localStorage is not available.`,
);
}
},
clear(): void {
if (storage) {
storage.clear();
} else {
console.warn(
"Attempted to clear localStorage, but localStorage is not available.",
);
}
},
};
}
3 changes: 3 additions & 0 deletions app/utils/indexedDB-storage.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { StateStorage } from "zustand/middleware";
import { get, set, del, clear } from "idb-keyval";
import { safeLocalStorage } from "@/app/utils";

const localStorage = safeLocalStorage();

class IndexedDBStorage implements StateStorage {
public async getItem(name: string): Promise<string | null> {
Expand Down

0 comments on commit 992c3a5

Please sign in to comment.