mirror of
https://github.com/Yidadaa/ChatGPT-Next-Web.git
synced 2025-08-08 19:26:54 +08:00
feat: #920 migrate id to nanoid
This commit is contained in:
@@ -26,7 +26,7 @@ export function ChatItem(props: {
|
||||
count: number;
|
||||
time: string;
|
||||
selected: boolean;
|
||||
id: number;
|
||||
id: string;
|
||||
index: number;
|
||||
narrow?: boolean;
|
||||
mask: Mask;
|
||||
|
@@ -221,9 +221,11 @@ function useSubmitHandler() {
|
||||
};
|
||||
}
|
||||
|
||||
export type RenderPompt = Pick<Prompt, "title" | "content">;
|
||||
|
||||
export function PromptHints(props: {
|
||||
prompts: Prompt[];
|
||||
onPromptSelect: (prompt: Prompt) => void;
|
||||
prompts: RenderPompt[];
|
||||
onPromptSelect: (prompt: RenderPompt) => void;
|
||||
}) {
|
||||
const noPrompts = props.prompts.length === 0;
|
||||
const [selectIndex, setSelectIndex] = useState(0);
|
||||
@@ -542,7 +544,7 @@ export function Chat() {
|
||||
|
||||
// prompt hints
|
||||
const promptStore = usePromptStore();
|
||||
const [promptHints, setPromptHints] = useState<Prompt[]>([]);
|
||||
const [promptHints, setPromptHints] = useState<RenderPompt[]>([]);
|
||||
const onSearch = useDebouncedCallback(
|
||||
(text: string) => {
|
||||
const matchedPrompts = promptStore.search(text);
|
||||
@@ -624,7 +626,7 @@ export function Chat() {
|
||||
setAutoScroll(true);
|
||||
};
|
||||
|
||||
const onPromptSelect = (prompt: Prompt) => {
|
||||
const onPromptSelect = (prompt: RenderPompt) => {
|
||||
setTimeout(() => {
|
||||
setPromptHints([]);
|
||||
|
||||
@@ -642,8 +644,8 @@ export function Chat() {
|
||||
};
|
||||
|
||||
// stop response
|
||||
const onUserStop = (messageId: number) => {
|
||||
ChatControllerPool.stop(sessionIndex, messageId);
|
||||
const onUserStop = (messageId: string) => {
|
||||
ChatControllerPool.stop(session.id, messageId);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -703,7 +705,7 @@ export function Chat() {
|
||||
}
|
||||
};
|
||||
|
||||
const findLastUserIndex = (messageId: number) => {
|
||||
const findLastUserIndex = (messageId: string) => {
|
||||
// find last user input message and resend
|
||||
let lastUserMessageIndex: number | null = null;
|
||||
for (let i = 0; i < session.messages.length; i += 1) {
|
||||
@@ -719,14 +721,14 @@ export function Chat() {
|
||||
return lastUserMessageIndex;
|
||||
};
|
||||
|
||||
const deleteMessage = (msgId?: number) => {
|
||||
const deleteMessage = (msgId?: string) => {
|
||||
chatStore.updateCurrentSession(
|
||||
(session) =>
|
||||
(session.messages = session.messages.filter((m) => m.id !== msgId)),
|
||||
);
|
||||
};
|
||||
|
||||
const onDelete = (msgId: number) => {
|
||||
const onDelete = (msgId: string) => {
|
||||
deleteMessage(msgId);
|
||||
};
|
||||
|
||||
|
@@ -8,7 +8,6 @@ import {
|
||||
Modal,
|
||||
Select,
|
||||
showImageModal,
|
||||
showModal,
|
||||
showToast,
|
||||
} from "./ui-lib";
|
||||
import { IconButton } from "./button";
|
||||
@@ -149,7 +148,7 @@ export function MessageExporter() {
|
||||
if (exportConfig.includeContext) {
|
||||
ret.push(...session.mask.context);
|
||||
}
|
||||
ret.push(...session.messages.filter((m, i) => selection.has(m.id ?? i)));
|
||||
ret.push(...session.messages.filter((m, i) => selection.has(m.id)));
|
||||
return ret;
|
||||
}, [
|
||||
exportConfig.includeContext,
|
||||
@@ -244,9 +243,10 @@ export function RenderExport(props: {
|
||||
return;
|
||||
}
|
||||
|
||||
const renderMsgs = messages.map((v) => {
|
||||
const renderMsgs = messages.map((v, i) => {
|
||||
const [_, role] = v.id.split(":");
|
||||
return {
|
||||
id: i.toString(),
|
||||
role: role as any,
|
||||
content: v.innerHTML,
|
||||
date: "",
|
||||
|
@@ -13,7 +13,13 @@ import EyeIcon from "../icons/eye.svg";
|
||||
import CopyIcon from "../icons/copy.svg";
|
||||
|
||||
import { DEFAULT_MASK_AVATAR, Mask, useMaskStore } from "../store/mask";
|
||||
import { ChatMessage, ModelConfig, useAppConfig, useChatStore } from "../store";
|
||||
import {
|
||||
ChatMessage,
|
||||
createMessage,
|
||||
ModelConfig,
|
||||
useAppConfig,
|
||||
useChatStore,
|
||||
} from "../store";
|
||||
import { ROLES } from "../client/api";
|
||||
import {
|
||||
Input,
|
||||
@@ -35,6 +41,7 @@ import { Updater } from "../typing";
|
||||
import { ModelConfigList } from "./model-config";
|
||||
import { FileName, Path } from "../constant";
|
||||
import { BUILTIN_MASK_STORE } from "../masks";
|
||||
import { nanoid } from "nanoid";
|
||||
|
||||
export function MaskAvatar(props: { mask: Mask }) {
|
||||
return props.mask.avatar !== DEFAULT_MASK_AVATAR ? (
|
||||
@@ -279,11 +286,13 @@ export function ContextPrompts(props: {
|
||||
bordered
|
||||
className={chatStyle["context-prompt-button"]}
|
||||
onClick={() =>
|
||||
addContextPrompt({
|
||||
role: "user",
|
||||
content: "",
|
||||
date: "",
|
||||
})
|
||||
addContextPrompt(
|
||||
createMessage({
|
||||
role: "user",
|
||||
content: "",
|
||||
date: "",
|
||||
}),
|
||||
)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
@@ -319,7 +328,7 @@ export function MaskPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const [editingMaskId, setEditingMaskId] = useState<number | undefined>();
|
||||
const [editingMaskId, setEditingMaskId] = useState<string | undefined>();
|
||||
const editingMask =
|
||||
maskStore.get(editingMaskId) ?? BUILTIN_MASK_STORE.get(editingMaskId);
|
||||
const closeMaskModal = () => setEditingMaskId(undefined);
|
||||
|
@@ -51,9 +51,9 @@ function useShiftRange() {
|
||||
}
|
||||
|
||||
export function useMessageSelector() {
|
||||
const [selection, setSelection] = useState(new Set<number>());
|
||||
const updateSelection: Updater<Set<number>> = (updater) => {
|
||||
const newSelection = new Set<number>(selection);
|
||||
const [selection, setSelection] = useState(new Set<string>());
|
||||
const updateSelection: Updater<Set<string>> = (updater) => {
|
||||
const newSelection = new Set<string>(selection);
|
||||
updater(newSelection);
|
||||
setSelection(newSelection);
|
||||
};
|
||||
@@ -65,8 +65,8 @@ export function useMessageSelector() {
|
||||
}
|
||||
|
||||
export function MessageSelector(props: {
|
||||
selection: Set<number>;
|
||||
updateSelection: Updater<Set<number>>;
|
||||
selection: Set<string>;
|
||||
updateSelection: Updater<Set<string>>;
|
||||
defaultSelectAll?: boolean;
|
||||
onSelected?: (messages: ChatMessage[]) => void;
|
||||
}) {
|
||||
@@ -83,12 +83,12 @@ export function MessageSelector(props: {
|
||||
const config = useAppConfig();
|
||||
|
||||
const [searchInput, setSearchInput] = useState("");
|
||||
const [searchIds, setSearchIds] = useState(new Set<number>());
|
||||
const isInSearchResult = (id: number) => {
|
||||
const [searchIds, setSearchIds] = useState(new Set<string>());
|
||||
const isInSearchResult = (id: string) => {
|
||||
return searchInput.length === 0 || searchIds.has(id);
|
||||
};
|
||||
const doSearch = (text: string) => {
|
||||
const searchResults = new Set<number>();
|
||||
const searchResults = new Set<string>();
|
||||
if (text.length > 0) {
|
||||
messages.forEach((m) =>
|
||||
m.content.includes(text) ? searchResults.add(m.id!) : null,
|
||||
|
@@ -103,8 +103,7 @@ export function NewChat() {
|
||||
useCommand({
|
||||
mask: (id) => {
|
||||
try {
|
||||
const intId = parseInt(id);
|
||||
const mask = maskStore.get(intId) ?? BUILTIN_MASK_STORE.get(intId);
|
||||
const mask = maskStore.get(id) ?? BUILTIN_MASK_STORE.get(id);
|
||||
startChat(mask ?? undefined);
|
||||
} catch {
|
||||
console.error("[New Chat] failed to create chat from mask id=", id);
|
||||
|
@@ -48,8 +48,9 @@ import { useNavigate } from "react-router-dom";
|
||||
import { Avatar, AvatarPicker } from "./emoji";
|
||||
import { getClientConfig } from "../config/client";
|
||||
import { useSyncStore } from "../store/sync";
|
||||
import { nanoid } from "nanoid";
|
||||
|
||||
function EditPromptModal(props: { id: number; onClose: () => void }) {
|
||||
function EditPromptModal(props: { id: string; onClose: () => void }) {
|
||||
const promptStore = usePromptStore();
|
||||
const prompt = promptStore.get(props.id);
|
||||
|
||||
@@ -107,7 +108,7 @@ function UserPromptModal(props: { onClose?: () => void }) {
|
||||
const [searchPrompts, setSearchPrompts] = useState<Prompt[]>([]);
|
||||
const prompts = searchInput.length > 0 ? searchPrompts : allPrompts;
|
||||
|
||||
const [editingPromptId, setEditingPromptId] = useState<number>();
|
||||
const [editingPromptId, setEditingPromptId] = useState<string>();
|
||||
|
||||
useEffect(() => {
|
||||
if (searchInput.length > 0) {
|
||||
@@ -128,6 +129,8 @@ function UserPromptModal(props: { onClose?: () => void }) {
|
||||
key="add"
|
||||
onClick={() =>
|
||||
promptStore.add({
|
||||
id: nanoid(),
|
||||
createdAt: Date.now(),
|
||||
title: "Empty Prompt",
|
||||
content: "Empty Prompt Content",
|
||||
})
|
||||
|
Reference in New Issue
Block a user