Skip to content

Commit

Permalink
feat: migrate state from v1 to v2
Browse files Browse the repository at this point in the history
  • Loading branch information
Yidadaa committed Apr 26, 2023
1 parent 401c136 commit 30040a0
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 27 deletions.
42 changes: 37 additions & 5 deletions app/components/error.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import React from "react";
import { IconButton } from "./button";
import GithubIcon from "../icons/github.svg";
import { ISSUE_URL } from "../constant";
import ResetIcon from "../icons/reload.svg";
import { ISSUE_URL, StoreKey } from "../constant";
import Locale from "../locales";
import { downloadAs } from "../utils";

interface IErrorBoundaryState {
hasError: boolean;
Expand All @@ -20,6 +23,25 @@ export class ErrorBoundary extends React.Component<any, IErrorBoundaryState> {
this.setState({ hasError: true, error, info });
}

clearAndSaveData() {
const snapshot: Record<string, any> = {};
Object.values(StoreKey).forEach((key) => {
snapshot[key] = localStorage.getItem(key);

if (snapshot[key]) {
try {
snapshot[key] = JSON.parse(snapshot[key]);
} catch {}
}
});

try {
downloadAs(JSON.stringify(snapshot), "chatgpt-next-web-snapshot.json");
} catch {}

localStorage.clear();
}

render() {
if (this.state.hasError) {
// Render error message
Expand All @@ -31,13 +53,23 @@ export class ErrorBoundary extends React.Component<any, IErrorBoundaryState> {
<code>{this.state.info?.componentStack}</code>
</pre>

<a href={ISSUE_URL} className="report">
<div style={{ display: "flex", justifyContent: "space-between" }}>
<a href={ISSUE_URL} className="report">
<IconButton
text="Report This Error"
icon={<GithubIcon />}
bordered
/>
</a>
<IconButton
text="Report This Error"
icon={<GithubIcon />}
icon={<ResetIcon />}
text="Clear All Data"
onClick={() =>
confirm(Locale.Store.ConfirmClearAll) && this.clearAndSaveData()
}
bordered
/>
</a>
</div>
</div>
);
}
Expand Down
9 changes: 9 additions & 0 deletions app/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ export enum FileName {
Prompts = "prompts.json",
}

export enum StoreKey {
Chat = "chat-next-web-store",
Access = "access-control",
Config = "app-config",
Mask = "mask-store",
Prompt = "prompt-store",
Update = "chat-update",
}

export const MAX_SIDEBAR_WIDTH = 500;
export const MIN_SIDEBAR_WIDTH = 230;
export const NARROW_SIDEBAR_WIDTH = 100;
5 changes: 2 additions & 3 deletions app/store/access.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { create } from "zustand";
import { persist } from "zustand/middleware";
import { StoreKey } from "../constant";

export interface AccessControlStore {
accessCode: string;
Expand All @@ -14,8 +15,6 @@ export interface AccessControlStore {
fetch: () => void;
}

export const ACCESS_KEY = "access-control";

let fetchState = 0; // 0 not fetch, 1 fetching, 2 done

export const useAccessStore = create<AccessControlStore>()(
Expand Down Expand Up @@ -62,7 +61,7 @@ export const useAccessStore = create<AccessControlStore>()(
},
}),
{
name: ACCESS_KEY,
name: StoreKey.Access,
version: 1,
},
),
Expand Down
24 changes: 18 additions & 6 deletions app/store/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Locale from "../locales";
import { showToast } from "../components/ui-lib";
import { DEFAULT_CONFIG, ModelConfig, ModelType, useAppConfig } from "./config";
import { createEmptyMask, Mask } from "./mask";
import { StoreKey } from "../constant";

export type Message = ChatCompletionResponseMessage & {
date: string;
Expand Down Expand Up @@ -109,8 +110,6 @@ function countMessages(msgs: Message[]) {
return msgs.reduce((pre, cur) => pre + cur.content.length, 0);
}

const LOCAL_KEY = "chat-next-web-store";

export const useChatStore = create<ChatStore>()(
persist(
(set, get) => ({
Expand Down Expand Up @@ -489,16 +488,29 @@ export const useChatStore = create<ChatStore>()(
},
}),
{
name: LOCAL_KEY,
name: StoreKey.Chat,
version: 2,
migrate(persistedState, version) {
const state = persistedState as ChatStore;
const state = persistedState as any;
const newState = JSON.parse(JSON.stringify(state)) as ChatStore;

if (version < 2) {
state.sessions.forEach((s) => (s.mask = createEmptyMask()));
newState.globalId = 0;
newState.sessions = [];

const oldSessions = state.sessions;
for (const oldSession of oldSessions) {
const newSession = createEmptySession();
newSession.topic = oldSession.topic;
newSession.messages = [...oldSession.messages];
newSession.mask.modelConfig.sendMemory = true;
newSession.mask.modelConfig.historyMessageCount = 4;
newSession.mask.modelConfig.compressMessageLengthThreshold = 1000;
newState.sessions.push(newSession);
}
}

return state;
return newState;
},
},
),
Expand Down
16 changes: 13 additions & 3 deletions app/store/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { create } from "zustand";
import { persist } from "zustand/middleware";
import { StoreKey } from "../constant";

export enum SubmitKey {
Enter = "Enter",
Expand Down Expand Up @@ -112,8 +113,6 @@ export const ModalConfigValidator = {
},
};

const CONFIG_KEY = "app-config";

export const useAppConfig = create<ChatConfigStore>()(
persist(
(set, get) => ({
Expand All @@ -130,7 +129,18 @@ export const useAppConfig = create<ChatConfigStore>()(
},
}),
{
name: CONFIG_KEY,
name: StoreKey.Config,
version: 2,
migrate(persistedState, version) {
if (version === 2) return persistedState as any;

const state = persistedState as ChatConfig;
state.modelConfig.sendMemory = true;
state.modelConfig.historyMessageCount = 4;
state.modelConfig.compressMessageLengthThreshold = 1000;

return state;
},
},
),
);
5 changes: 2 additions & 3 deletions app/store/mask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import { BUILTIN_MASKS } from "../masks";
import { getLang, Lang } from "../locales";
import { DEFAULT_TOPIC, Message } from "./chat";
import { ModelConfig, ModelType, useAppConfig } from "./config";

export const MASK_KEY = "mask-store";
import { StoreKey } from "../constant";

export type Mask = {
id: number;
Expand Down Expand Up @@ -93,7 +92,7 @@ export const useMaskStore = create<MaskStore>()(
},
}),
{
name: MASK_KEY,
name: StoreKey.Mask,
version: 2,
},
),
Expand Down
5 changes: 2 additions & 3 deletions app/store/prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { create } from "zustand";
import { persist } from "zustand/middleware";
import Fuse from "fuse.js";
import { getLang } from "../locales";
import { StoreKey } from "../constant";

export interface Prompt {
id?: number;
Expand All @@ -23,8 +24,6 @@ export interface PromptStore {
updateUserPrompts: (id: number, updater: (prompt: Prompt) => void) => void;
}

export const PROMPT_KEY = "prompt-store";

export const SearchService = {
ready: false,
builtinEngine: new Fuse<Prompt>([], { keys: ["title"] }),
Expand Down Expand Up @@ -123,7 +122,7 @@ export const usePromptStore = create<PromptStore>()(
},
}),
{
name: PROMPT_KEY,
name: StoreKey.Prompt,
version: 1,
onRehydrateStorage(state) {
const PROMPT_URL = "./prompts.json";
Expand Down
6 changes: 2 additions & 4 deletions app/store/update.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { create } from "zustand";
import { persist } from "zustand/middleware";
import { FETCH_COMMIT_URL, FETCH_TAG_URL } from "../constant";
import { FETCH_COMMIT_URL, FETCH_TAG_URL, StoreKey } from "../constant";
import { requestUsage } from "../requests";

export interface UpdateStore {
Expand All @@ -16,8 +16,6 @@ export interface UpdateStore {
updateUsage: (force?: boolean) => Promise<void>;
}

export const UPDATE_KEY = "chat-update";

function queryMeta(key: string, defaultValue?: string): string {
let ret: string;
if (document) {
Expand Down Expand Up @@ -84,7 +82,7 @@ export const useUpdateStore = create<UpdateStore>()(
},
}),
{
name: UPDATE_KEY,
name: StoreKey.Update,
version: 1,
},
),
Expand Down

0 comments on commit 30040a0

Please sign in to comment.