0
+ ? renderedHeight.current
+ : "auto",
+ }}
ref={mdRef}
onContextMenu={props.onContextMenu}
onDoubleClickCapture={props.onDoubleClickCapture}
>
- {shouldLoading ? (
-
- ) : (
-
- {props.content}
-
- )}
+ {inView.current &&
+ (props.loading ? (
+
+ ) : (
+
+ ))}
);
}
diff --git a/app/components/mask.module.scss b/app/components/mask.module.scss
index 0618cc06..d66d9886 100644
--- a/app/components/mask.module.scss
+++ b/app/components/mask.module.scss
@@ -1,16 +1,4 @@
@import "../styles/animation.scss";
-
-@keyframes search-in {
- from {
- opacity: 0;
- transform: translateY(5vh) scaleX(0.5);
- }
- to {
- opacity: 1;
- transform: translateY(0) scaleX(1);
- }
-}
-
.mask-page {
height: 100%;
display: flex;
@@ -23,8 +11,9 @@
.mask-filter {
width: 100%;
max-width: 100%;
- margin-bottom: 10px;
- animation: search-in ease 0.3s;
+ margin-bottom: 20px;
+ animation: slide-in ease 0.3s;
+ height: 40px;
display: flex;
@@ -32,8 +21,6 @@
flex-grow: 1;
max-width: 100%;
min-width: 0;
- margin-bottom: 20px;
- animation: search-in ease 0.3s;
}
.mask-filter-lang {
@@ -45,10 +32,7 @@
height: 100%;
margin-left: 10px;
box-sizing: border-box;
-
- button {
- padding: 10px;
- }
+ min-width: 80px;
}
}
diff --git a/app/components/mask.tsx b/app/components/mask.tsx
index bfaab2b7..c980c48c 100644
--- a/app/components/mask.tsx
+++ b/app/components/mask.tsx
@@ -291,14 +291,16 @@ export function MaskPage() {
))}
-
diff --git a/app/components/new-chat.module.scss b/app/components/new-chat.module.scss
index 36f447bb..b0e472ea 100644
--- a/app/components/new-chat.module.scss
+++ b/app/components/new-chat.module.scss
@@ -59,10 +59,9 @@
display: flex;
justify-content: center;
- .search-bar {
+ .more {
font-size: 12px;
- margin-right: 10px;
- width: 40vw;
+ margin-left: 10px;
}
}
diff --git a/app/components/new-chat.tsx b/app/components/new-chat.tsx
index 8cb4d35e..42612e0a 100644
--- a/app/components/new-chat.tsx
+++ b/app/components/new-chat.tsx
@@ -5,10 +5,11 @@ import { EmojiAvatar } from "./emoji";
import styles from "./new-chat.module.scss";
import LeftIcon from "../icons/left.svg";
-import AddIcon from "../icons/lightning.svg";
+import LightningIcon from "../icons/lightning.svg";
+import EyeIcon from "../icons/eye.svg";
import { useLocation, useNavigate } from "react-router-dom";
-import { createEmptyMask, Mask, useMaskStore } from "../store/mask";
+import { Mask, useMaskStore } from "../store/mask";
import Locale from "../locales";
import { useAppConfig, useChatStore } from "../store";
import { MaskAvatar } from "./mask";
@@ -148,20 +149,22 @@ export function NewChat() {
{Locale.NewChat.SubTitle}
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/components/sidebar.tsx b/app/components/sidebar.tsx
index 47a31172..77621964 100644
--- a/app/components/sidebar.tsx
+++ b/app/components/sidebar.tsx
@@ -138,7 +138,11 @@ export function SideBar(props: { className?: string }) {
diff --git a/app/components/ui-lib.tsx b/app/components/ui-lib.tsx
index 5b6ed959..c16f94a4 100644
--- a/app/components/ui-lib.tsx
+++ b/app/components/ui-lib.tsx
@@ -158,6 +158,7 @@ export type ToastProps = {
text: string;
onClick: () => void;
};
+ onClose?: () => void;
};
export function Toast(props: ToastProps) {
@@ -167,7 +168,10 @@ export function Toast(props: ToastProps) {
{props.content}
{props.action && (