ChatGPT-Next-Web/app/store/mask.ts

135 lines
3.4 KiB
TypeScript
Raw Normal View History

2023-04-23 17:15:44 +00:00
import { create } from "zustand";
import { persist } from "zustand/middleware";
2023-04-26 17:16:21 +00:00
import { BUILTIN_MASKS } from "../masks";
2023-04-23 17:15:44 +00:00
import { getLang, Lang } from "../locales";
import { DEFAULT_TOPIC, ChatMessage } from "./chat";
2023-06-23 16:18:27 +00:00
import { ModelConfig, useAppConfig } from "./config";
2023-04-26 18:00:22 +00:00
import { StoreKey } from "../constant";
2023-07-09 11:37:42 +00:00
import { nanoid } from "nanoid";
2023-04-23 17:15:44 +00:00
export type Mask = {
2023-07-09 11:37:42 +00:00
id: string;
createdAt: number;
2023-04-23 17:15:44 +00:00
avatar: string;
name: string;
hideContext?: boolean;
context: ChatMessage[];
syncGlobalConfig?: boolean;
2023-04-24 16:49:27 +00:00
modelConfig: ModelConfig;
2023-04-23 17:15:44 +00:00
lang: Lang;
2023-04-26 17:16:21 +00:00
builtin: boolean;
2023-04-23 17:15:44 +00:00
};
export const DEFAULT_MASK_STATE = {
2023-07-09 11:37:42 +00:00
masks: {} as Record<string, Mask>,
2023-04-23 17:15:44 +00:00
};
export type MaskState = typeof DEFAULT_MASK_STATE;
type MaskStore = MaskState & {
2023-04-25 18:02:46 +00:00
create: (mask?: Partial<Mask>) => Mask;
2023-07-09 11:37:42 +00:00
update: (id: string, updater: (mask: Mask) => void) => void;
delete: (id: string) => void;
2023-04-23 17:15:44 +00:00
search: (text: string) => Mask[];
2023-07-09 11:37:42 +00:00
get: (id?: string) => Mask | null;
2023-04-23 17:15:44 +00:00
getAll: () => Mask[];
};
2023-04-24 16:49:27 +00:00
export const DEFAULT_MASK_AVATAR = "gpt-bot";
export const createEmptyMask = () =>
({
2023-07-09 11:37:42 +00:00
id: nanoid(),
2023-04-24 16:49:27 +00:00
avatar: DEFAULT_MASK_AVATAR,
name: DEFAULT_TOPIC,
context: [],
syncGlobalConfig: true, // use global config as default
2023-04-25 18:02:46 +00:00
modelConfig: { ...useAppConfig.getState().modelConfig },
2023-04-24 16:49:27 +00:00
lang: getLang(),
2023-04-26 17:16:21 +00:00
builtin: false,
2023-07-09 11:37:42 +00:00
createdAt: Date.now(),
2023-04-24 16:49:27 +00:00
} as Mask);
2023-04-23 17:15:44 +00:00
export const useMaskStore = create<MaskStore>()(
persist(
(set, get) => ({
...DEFAULT_MASK_STATE,
create(mask) {
const masks = get().masks;
2023-07-09 11:37:42 +00:00
const id = nanoid();
2023-04-23 17:15:44 +00:00
masks[id] = {
2023-04-24 16:49:27 +00:00
...createEmptyMask(),
2023-04-23 17:15:44 +00:00
...mask,
2023-04-26 17:16:21 +00:00
id,
2023-05-04 14:31:10 +00:00
builtin: false,
2023-04-23 17:15:44 +00:00
};
set(() => ({ masks }));
return masks[id];
},
update(id, updater) {
const masks = get().masks;
const mask = masks[id];
if (!mask) return;
const updateMask = { ...mask };
updater(updateMask);
masks[id] = updateMask;
set(() => ({ masks }));
},
delete(id) {
const masks = get().masks;
delete masks[id];
set(() => ({ masks }));
},
2023-04-25 18:02:46 +00:00
get(id) {
return get().masks[id ?? 1145141919810];
},
2023-04-23 17:15:44 +00:00
getAll() {
2023-04-26 17:16:21 +00:00
const userMasks = Object.values(get().masks).sort(
2023-07-09 11:37:42 +00:00
(a, b) => b.createdAt - a.createdAt,
2023-04-26 17:16:21 +00:00
);
2023-06-23 16:18:27 +00:00
const config = useAppConfig.getState();
2023-07-05 14:39:25 +00:00
if (config.hideBuiltinMasks) return userMasks;
2023-06-23 16:18:27 +00:00
const buildinMasks = BUILTIN_MASKS.map(
(m) =>
({
...m,
modelConfig: {
...config.modelConfig,
...m.modelConfig,
},
} as Mask),
);
return userMasks.concat(buildinMasks);
2023-04-23 17:15:44 +00:00
},
search(text) {
return Object.values(get().masks);
},
}),
{
2023-04-26 18:00:22 +00:00
name: StoreKey.Mask,
2023-07-11 13:02:09 +00:00
version: 3.1,
2023-07-09 11:37:42 +00:00
migrate(state, version) {
const newState = JSON.parse(JSON.stringify(state)) as MaskState;
// migrate mask id to nanoid
if (version < 3) {
Object.values(newState.masks).forEach((m) => (m.id = nanoid()));
}
2023-07-11 13:02:09 +00:00
if (version < 3.1) {
const updatedMasks: Record<string, Mask> = {};
Object.values(newState.masks).forEach((m) => {
updatedMasks[m.id] = m;
});
newState.masks = updatedMasks;
}
2023-07-09 11:37:42 +00:00
return newState as any;
},
2023-04-23 17:15:44 +00:00
},
),
);