diff --git a/app/components/settings.module.scss b/app/components/settings.module.scss
index 30abc36d..f257a3ca 100644
--- a/app/components/settings.module.scss
+++ b/app/components/settings.module.scss
@@ -7,6 +7,20 @@
cursor: pointer;
}
+.edit-prompt-modal {
+ display: flex;
+ flex-direction: column;
+
+ .edit-prompt-title {
+ max-width: unset;
+ margin-bottom: 20px;
+ text-align: left;
+ }
+ .edit-prompt-content {
+ max-width: unset;
+ }
+}
+
.user-prompt-modal {
min-height: 40vh;
@@ -18,47 +32,42 @@
}
.user-prompt-list {
- padding: 10px 0;
+ border: var(--border-in-light);
+ border-radius: 10px;
.user-prompt-item {
- margin-bottom: 10px;
- widows: 100%;
+ display: flex;
+ justify-content: space-between;
+ padding: 10px;
+
+ &:not(:last-child) {
+ border-bottom: var(--border-in-light);
+ }
.user-prompt-header {
- display: flex;
- widows: 100%;
- margin-bottom: 5px;
+ max-width: calc(100% - 100px);
.user-prompt-title {
- flex-grow: 1;
- max-width: 100%;
- margin-right: 5px;
- padding: 5px;
- font-size: 12px;
- text-align: left;
+ font-size: 14px;
+ line-height: 2;
+ font-weight: bold;
}
-
- .user-prompt-buttons {
- display: flex;
- align-items: center;
-
- .user-prompt-button {
- height: 100%;
-
- &:not(:last-child) {
- margin-right: 5px;
- }
- }
+ .user-prompt-content {
+ font-size: 12px;
}
}
- .user-prompt-content {
- width: 100%;
- box-sizing: border-box;
- padding: 5px;
- margin-right: 10px;
- font-size: 12px;
- flex-grow: 1;
+ .user-prompt-buttons {
+ display: flex;
+ align-items: center;
+
+ .user-prompt-button {
+ height: 100%;
+
+ &:not(:last-child) {
+ margin-right: 5px;
+ }
+ }
}
}
}
diff --git a/app/components/settings.tsx b/app/components/settings.tsx
index 385fc323..5d0a663f 100644
--- a/app/components/settings.tsx
+++ b/app/components/settings.tsx
@@ -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 ? (
+
+ ) : 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([]);
const prompts = searchInput.length > 0 ? searchPrompts : allPrompts;
+ const [editingPromptId, setEditingPromptId] = useState();
+
useEffect(() => {
if (searchInput.length > 0) {
const searchResult = SearchService.search(searchInput);
@@ -56,8 +109,13 @@ function UserPromptModal(props: { onClose?: () => void }) {
actions={[
promptStore.add({ title: "", content: "" })}
- icon={}
+ onClick={() =>
+ promptStore.add({
+ title: "Empty Prompt",
+ content: "Empty Prompt Content",
+ })
+ }
+ icon={}
bordered
text={Locale.Settings.Prompt.Modal.Add}
/>,
@@ -76,57 +134,51 @@ function UserPromptModal(props: { onClose?: () => void }) {
{prompts.map((v, _) => (
-
{
- if (v.isUser) {
- promptStore.updateUserPrompts(
- v.id!,
- (prompt) => (prompt.title = e.currentTarget.value),
- );
- }
- }}
- >
-
-
- {v.isUser && (
-
}
- bordered
- className={styles["user-prompt-button"]}
- onClick={() => promptStore.remove(v.id!)}
- />
- )}
-
}
- bordered
- className={styles["user-prompt-button"]}
- onClick={() => copyToClipboard(v.content)}
- />
+
{v.title}
+
+ {v.content}
-
{
- if (v.isUser) {
- promptStore.updateUserPrompts(
- v.id!,
- (prompt) => (prompt.content = e.currentTarget.value),
- );
- }
- }}
- />
+
+
+ {v.isUser && (
+ }
+ className={styles["user-prompt-button"]}
+ onClick={() => promptStore.remove(v.id!)}
+ />
+ )}
+ {v.isUser ? (
+ }
+ className={styles["user-prompt-button"]}
+ onClick={() => setEditingPromptId(v.id)}
+ />
+ ) : (
+ }
+ className={styles["user-prompt-button"]}
+ onClick={() => setEditingPromptId(v.id)}
+ />
+ )}
+ }
+ className={styles["user-prompt-button"]}
+ onClick={() => copyToClipboard(v.content)}
+ />
+
))}
+
+ {editingPromptId !== undefined && (
+ setEditingPromptId(undefined)}
+ />
+ )}
);
}
diff --git a/app/locales/cn.ts b/app/locales/cn.ts
index 208752c1..45dc10a9 100644
--- a/app/locales/cn.ts
+++ b/app/locales/cn.ts
@@ -116,9 +116,12 @@ const cn = {
Edit: "编辑",
Modal: {
Title: "提示词列表",
- Add: "增加一条",
+ Add: "新建",
Search: "搜索提示词",
},
+ EditModal: {
+ Title: "编辑提示词",
+ },
},
HistoryCount: {
Title: "附带历史消息数",
@@ -223,6 +226,14 @@ const cn = {
SubTitle: "现在开始,与面具背后的灵魂思维碰撞",
More: "搜索更多",
},
+
+ UI: {
+ Confirm: "确认",
+ Cancel: "取消",
+ Close: "关闭",
+ Create: "新建",
+ Edit: "编辑",
+ },
};
export type LocaleType = typeof cn;
diff --git a/app/locales/de.ts b/app/locales/de.ts
index 1981944f..048e575c 100644
--- a/app/locales/de.ts
+++ b/app/locales/de.ts
@@ -121,6 +121,9 @@ const de: LocaleType = {
Add: "Add One",
Search: "Search Prompts",
},
+ EditModal: {
+ Title: "Edit Prompt",
+ },
},
HistoryCount: {
Title: "Anzahl der angehängten Nachrichten",
@@ -230,6 +233,14 @@ const de: LocaleType = {
NotShow: "Not Show Again",
ConfirmNoShow: "Confirm to disable?You can enable it in settings later.",
},
+
+ UI: {
+ Confirm: "Confirm",
+ Cancel: "Cancel",
+ Close: "Close",
+ Create: "Create",
+ Edit: "Edit",
+ },
};
export default de;
diff --git a/app/locales/en.ts b/app/locales/en.ts
index d7357731..e424d9b4 100644
--- a/app/locales/en.ts
+++ b/app/locales/en.ts
@@ -120,6 +120,9 @@ const en: LocaleType = {
Add: "Add One",
Search: "Search Prompts",
},
+ EditModal: {
+ Title: "Edit Prompt",
+ },
},
HistoryCount: {
Title: "Attached Messages Count",
@@ -226,6 +229,14 @@ const en: LocaleType = {
NotShow: "Not Show Again",
ConfirmNoShow: "Confirm to disable?You can enable it in settings later.",
},
+
+ UI: {
+ Confirm: "Confirm",
+ Cancel: "Cancel",
+ Close: "Close",
+ Create: "Create",
+ Edit: "Edit",
+ },
};
export default en;
diff --git a/app/locales/es.ts b/app/locales/es.ts
index 783cd6e9..46d18a54 100644
--- a/app/locales/es.ts
+++ b/app/locales/es.ts
@@ -120,6 +120,9 @@ const es: LocaleType = {
Add: "Add One",
Search: "Search Prompts",
},
+ EditModal: {
+ Title: "Edit Prompt",
+ },
},
HistoryCount: {
Title: "Cantidad de mensajes adjuntos",
@@ -227,6 +230,14 @@ const es: LocaleType = {
NotShow: "Not Show Again",
ConfirmNoShow: "Confirm to disable?You can enable it in settings later.",
},
+
+ UI: {
+ Confirm: "Confirm",
+ Cancel: "Cancel",
+ Close: "Close",
+ Create: "Create",
+ Edit: "Edit",
+ },
};
export default es;
diff --git a/app/locales/it.ts b/app/locales/it.ts
index 3fcc80ec..ee9a2c2b 100644
--- a/app/locales/it.ts
+++ b/app/locales/it.ts
@@ -120,6 +120,9 @@ const it: LocaleType = {
Add: "Add One",
Search: "Search Prompts",
},
+ EditModal: {
+ Title: "Edit Prompt",
+ },
},
HistoryCount: {
Title: "Conteggio dei messaggi allegati",
@@ -228,6 +231,14 @@ const it: LocaleType = {
NotShow: "Not Show Again",
ConfirmNoShow: "Confirm to disable?You can enable it in settings later.",
},
+
+ UI: {
+ Confirm: "Confirm",
+ Cancel: "Cancel",
+ Close: "Close",
+ Create: "Create",
+ Edit: "Edit",
+ },
};
export default it;
diff --git a/app/locales/jp.ts b/app/locales/jp.ts
index 4bbe0512..fb693cf5 100644
--- a/app/locales/jp.ts
+++ b/app/locales/jp.ts
@@ -122,6 +122,9 @@ const jp: LocaleType = {
Add: "新規追加",
Search: "プロンプトワード検索",
},
+ EditModal: {
+ Title: "编辑提示词",
+ },
},
HistoryCount: {
Title: "履歴メッセージ数を添付",
@@ -226,6 +229,14 @@ const jp: LocaleType = {
NotShow: "不再展示",
ConfirmNoShow: "确认禁用?禁用后可以随时在设置中重新启用。",
},
+
+ UI: {
+ Confirm: "确认",
+ Cancel: "取消",
+ Close: "关闭",
+ Create: "新建",
+ Edit: "编辑",
+ },
};
export default jp;
diff --git a/app/locales/tr.ts b/app/locales/tr.ts
index a658fcc4..5eb4fe3e 100644
--- a/app/locales/tr.ts
+++ b/app/locales/tr.ts
@@ -120,6 +120,9 @@ const tr: LocaleType = {
Add: "Add One",
Search: "Search Prompts",
},
+ EditModal: {
+ Title: "Edit Prompt",
+ },
},
HistoryCount: {
Title: "Ekli Mesaj Sayısı",
@@ -228,6 +231,14 @@ const tr: LocaleType = {
NotShow: "Not Show Again",
ConfirmNoShow: "Confirm to disable?You can enable it in settings later.",
},
+
+ UI: {
+ Confirm: "Confirm",
+ Cancel: "Cancel",
+ Close: "Close",
+ Create: "Create",
+ Edit: "Edit",
+ },
};
export default tr;
diff --git a/app/locales/tw.ts b/app/locales/tw.ts
index 9a0e9eac..de964fc3 100644
--- a/app/locales/tw.ts
+++ b/app/locales/tw.ts
@@ -118,6 +118,9 @@ const tw: LocaleType = {
Add: "新增一條",
Search: "搜尋提示詞",
},
+ EditModal: {
+ Title: "编辑提示词",
+ },
},
HistoryCount: {
Title: "附帶歷史訊息數",
@@ -219,6 +222,13 @@ const tw: LocaleType = {
NotShow: "不再展示",
ConfirmNoShow: "确认禁用?禁用后可以随时在设置中重新启用。",
},
+ UI: {
+ Confirm: "确认",
+ Cancel: "取消",
+ Close: "关闭",
+ Create: "新建",
+ Edit: "编辑",
+ },
};
export default tw;
diff --git a/app/store/prompt.ts b/app/store/prompt.ts
index e3a2eedd..98d4193b 100644
--- a/app/store/prompt.ts
+++ b/app/store/prompt.ts
@@ -17,11 +17,12 @@ export interface PromptStore {
prompts: Record;
add: (prompt: Prompt) => number;
+ get: (id: number) => Prompt | undefined;
remove: (id: number) => void;
search: (text: string) => Prompt[];
+ update: (id: number, updater: (prompt: Prompt) => void) => void;
getUserPrompts: () => Prompt[];
- updateUserPrompts: (id: number, updater: (prompt: Prompt) => void) => void;
}
export const SearchService = {
@@ -81,6 +82,16 @@ export const usePromptStore = create()(
return prompt.id!;
},
+ get(id) {
+ const targetPrompt = get().prompts[id];
+
+ if (!targetPrompt) {
+ return SearchService.builtinPrompts.find((v) => v.id === id);
+ }
+
+ return targetPrompt;
+ },
+
remove(id) {
const prompts = get().prompts;
delete prompts[id];
@@ -98,7 +109,7 @@ export const usePromptStore = create()(
return userPrompts;
},
- updateUserPrompts(id: number, updater) {
+ update(id: number, updater) {
const prompt = get().prompts[id] ?? {
title: "",
content: "",
diff --git a/scripts/init-proxy.sh b/scripts/init-proxy.sh
index acba064f..32e55921 100644
--- a/scripts/init-proxy.sh
+++ b/scripts/init-proxy.sh
@@ -1,5 +1,6 @@
dir="$(dirname "$0")"
config=$dir/proxychains.conf
host_ip=$(grep nameserver /etc/resolv.conf | sed 's/nameserver //')
+echo "proxying to $host_ip"
cp $dir/proxychains.template.conf $config
sed -i "\$s/.*/http $host_ip 7890/" $config