|
|
|
@ -3,10 +3,12 @@ import { useState, useEffect, useMemo, HTMLProps, useRef } from "react";
|
|
|
|
|
import styles from "./settings.module.scss";
|
|
|
|
|
|
|
|
|
|
import ResetIcon from "../icons/reload.svg";
|
|
|
|
|
import AddIcon from "../icons/add.svg";
|
|
|
|
|
import CloseIcon from "../icons/close.svg";
|
|
|
|
|
import CopyIcon from "../icons/copy.svg";
|
|
|
|
|
import ClearIcon from "../icons/clear.svg";
|
|
|
|
|
import EditIcon from "../icons/edit.svg";
|
|
|
|
|
import EyeIcon from "../icons/eye.svg";
|
|
|
|
|
import { Input, List, ListItem, Modal, PasswordInput, Popover } from "./ui-lib";
|
|
|
|
|
import { ModelConfigList } from "./model-config";
|
|
|
|
|
|
|
|
|
@ -30,6 +32,55 @@ import { InputRange } from "./input-range";
|
|
|
|
|
import { useNavigate } from "react-router-dom";
|
|
|
|
|
import { Avatar, AvatarPicker } from "./emoji";
|
|
|
|
|
|
|
|
|
|
function EditPromptModal(props: { id: number; onClose: () => void }) {
|
|
|
|
|
const promptStore = usePromptStore();
|
|
|
|
|
const prompt = promptStore.get(props.id);
|
|
|
|
|
|
|
|
|
|
return prompt ? (
|
|
|
|
|
<div className="modal-mask">
|
|
|
|
|
<Modal
|
|
|
|
|
title={Locale.Settings.Prompt.EditModal.Title}
|
|
|
|
|
onClose={props.onClose}
|
|
|
|
|
actions={[
|
|
|
|
|
<IconButton
|
|
|
|
|
key=""
|
|
|
|
|
onClick={props.onClose}
|
|
|
|
|
text={Locale.UI.Confirm}
|
|
|
|
|
bordered
|
|
|
|
|
/>,
|
|
|
|
|
]}
|
|
|
|
|
>
|
|
|
|
|
<div className={styles["edit-prompt-modal"]}>
|
|
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
value={prompt.title}
|
|
|
|
|
readOnly={!prompt.isUser}
|
|
|
|
|
className={styles["edit-prompt-title"]}
|
|
|
|
|
onInput={(e) =>
|
|
|
|
|
promptStore.update(
|
|
|
|
|
props.id,
|
|
|
|
|
(prompt) => (prompt.title = e.currentTarget.value),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
></input>
|
|
|
|
|
<Input
|
|
|
|
|
value={prompt.content}
|
|
|
|
|
readOnly={!prompt.isUser}
|
|
|
|
|
className={styles["edit-prompt-content"]}
|
|
|
|
|
rows={10}
|
|
|
|
|
onInput={(e) =>
|
|
|
|
|
promptStore.update(
|
|
|
|
|
props.id,
|
|
|
|
|
(prompt) => (prompt.content = e.currentTarget.value),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
></Input>
|
|
|
|
|
</div>
|
|
|
|
|
</Modal>
|
|
|
|
|
</div>
|
|
|
|
|
) : null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function UserPromptModal(props: { onClose?: () => void }) {
|
|
|
|
|
const promptStore = usePromptStore();
|
|
|
|
|
const userPrompts = promptStore.getUserPrompts();
|
|
|
|
@ -39,6 +90,8 @@ function UserPromptModal(props: { onClose?: () => void }) {
|
|
|
|
|
const [searchPrompts, setSearchPrompts] = useState<Prompt[]>([]);
|
|
|
|
|
const prompts = searchInput.length > 0 ? searchPrompts : allPrompts;
|
|
|
|
|
|
|
|
|
|
const [editingPromptId, setEditingPromptId] = useState<number>();
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (searchInput.length > 0) {
|
|
|
|
|
const searchResult = SearchService.search(searchInput);
|
|
|
|
@ -56,8 +109,13 @@ function UserPromptModal(props: { onClose?: () => void }) {
|
|
|
|
|
actions={[
|
|
|
|
|
<IconButton
|
|
|
|
|
key="add"
|
|
|
|
|
onClick={() => promptStore.add({ title: "", content: "" })}
|
|
|
|
|
icon={<ClearIcon />}
|
|
|
|
|
onClick={() =>
|
|
|
|
|
promptStore.add({
|
|
|
|
|
title: "Empty Prompt",
|
|
|
|
|
content: "Empty Prompt Content",
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
icon={<AddIcon />}
|
|
|
|
|
bordered
|
|
|
|
|
text={Locale.Settings.Prompt.Modal.Add}
|
|
|
|
|
/>,
|
|
|
|
@ -76,57 +134,51 @@ function UserPromptModal(props: { onClose?: () => void }) {
|
|
|
|
|
{prompts.map((v, _) => (
|
|
|
|
|
<div className={styles["user-prompt-item"]} key={v.id ?? v.title}>
|
|
|
|
|
<div className={styles["user-prompt-header"]}>
|
|
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
className={styles["user-prompt-title"]}
|
|
|
|
|
value={v.title}
|
|
|
|
|
readOnly={!v.isUser}
|
|
|
|
|
onChange={(e) => {
|
|
|
|
|
if (v.isUser) {
|
|
|
|
|
promptStore.updateUserPrompts(
|
|
|
|
|
v.id!,
|
|
|
|
|
(prompt) => (prompt.title = e.currentTarget.value),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
></input>
|
|
|
|
|
|
|
|
|
|
<div className={styles["user-prompt-buttons"]}>
|
|
|
|
|
{v.isUser && (
|
|
|
|
|
<IconButton
|
|
|
|
|
icon={<ClearIcon />}
|
|
|
|
|
bordered
|
|
|
|
|
className={styles["user-prompt-button"]}
|
|
|
|
|
onClick={() => promptStore.remove(v.id!)}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
<div className={styles["user-prompt-title"]}>{v.title}</div>
|
|
|
|
|
<div className={styles["user-prompt-content"] + " one-line"}>
|
|
|
|
|
{v.content}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className={styles["user-prompt-buttons"]}>
|
|
|
|
|
{v.isUser && (
|
|
|
|
|
<IconButton
|
|
|
|
|
icon={<CopyIcon />}
|
|
|
|
|
bordered
|
|
|
|
|
icon={<ClearIcon />}
|
|
|
|
|
className={styles["user-prompt-button"]}
|
|
|
|
|
onClick={() => copyToClipboard(v.content)}
|
|
|
|
|
onClick={() => promptStore.remove(v.id!)}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
{v.isUser ? (
|
|
|
|
|
<IconButton
|
|
|
|
|
icon={<EditIcon />}
|
|
|
|
|
className={styles["user-prompt-button"]}
|
|
|
|
|
onClick={() => setEditingPromptId(v.id)}
|
|
|
|
|
/>
|
|
|
|
|
) : (
|
|
|
|
|
<IconButton
|
|
|
|
|
icon={<EyeIcon />}
|
|
|
|
|
className={styles["user-prompt-button"]}
|
|
|
|
|
onClick={() => setEditingPromptId(v.id)}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
<IconButton
|
|
|
|
|
icon={<CopyIcon />}
|
|
|
|
|
className={styles["user-prompt-button"]}
|
|
|
|
|
onClick={() => copyToClipboard(v.content)}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<Input
|
|
|
|
|
rows={2}
|
|
|
|
|
value={v.content}
|
|
|
|
|
className={styles["user-prompt-content"]}
|
|
|
|
|
readOnly={!v.isUser}
|
|
|
|
|
onChange={(e) => {
|
|
|
|
|
if (v.isUser) {
|
|
|
|
|
promptStore.updateUserPrompts(
|
|
|
|
|
v.id!,
|
|
|
|
|
(prompt) => (prompt.content = e.currentTarget.value),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</Modal>
|
|
|
|
|
|
|
|
|
|
{editingPromptId !== undefined && (
|
|
|
|
|
<EditPromptModal
|
|
|
|
|
id={editingPromptId!}
|
|
|
|
|
onClose={() => setEditingPromptId(undefined)}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|