This commit is contained in:
GH Action - Upstream Sync
2023-06-28 00:45:50 +00:00
5 changed files with 208 additions and 30 deletions

View File

@@ -281,15 +281,13 @@
border: var(--border-in-light);
position: relative;
transition: all ease 0.3s;
min-width: 0;
&:hover {
min-width: 330px;
.chat-message-actions {
height: 40px;
opacity: 1;
transform: translateY(0px);
max-width: 100%;
height: 40px;
.chat-message-action-date {
opacity: 0.3;
@@ -299,7 +297,6 @@
.chat-message-actions {
display: flex;
width: 100%;
box-sizing: border-box;
font-size: 12px;
align-items: flex-end;
@@ -308,11 +305,21 @@
transform: translateY(10px);
opacity: 0;
height: 0;
max-width: 0;
.chat-input-actions {
display: flex;
flex-wrap: nowrap;
}
}
.chat-message-action-date {
white-space: nowrap;
transition: all ease 0.6s;
color: var(--black);
opacity: 0;
text-align: right;
margin-left: 20px;
}
}

View File

@@ -294,8 +294,8 @@ function ChatAction(props: {
const iconRef = useRef<HTMLDivElement>(null);
const textRef = useRef<HTMLDivElement>(null);
const [width, setWidth] = useState({
full: 20,
icon: 20,
full: 16,
icon: 16,
});
function updateWidth() {
@@ -309,10 +309,6 @@ function ChatAction(props: {
});
}
useEffect(() => {
updateWidth();
}, []);
return (
<div
className={`${styles["chat-input-action"]} clickable`}
@@ -320,6 +316,8 @@ function ChatAction(props: {
props.onClick();
setTimeout(updateWidth, 1);
}}
onMouseEnter={updateWidth}
onTouchStart={updateWidth}
style={
{
"--icon-width": `${width.icon}px`,
@@ -515,14 +513,6 @@ export function Chat() {
{ leading: true, trailing: true },
);
const onPromptSelect = (prompt: Prompt) => {
setTimeout(() => {
setPromptHints([]);
setUserInput(prompt.content);
inputRef.current?.focus();
}, 30);
};
// auto grow input
const [inputRows, setInputRows] = useState(2);
const measure = useDebouncedCallback(
@@ -595,6 +585,23 @@ export function Chat() {
setAutoScroll(true);
};
const onPromptSelect = (prompt: Prompt) => {
setTimeout(() => {
setPromptHints([]);
const matchedChatCommand = chatCommands.match(prompt.content);
if (matchedChatCommand.matched) {
// if user is selecting a chat command, just trigger it
matchedChatCommand.invoke();
setUserInput("");
} else {
// or fill the prompt
setUserInput(prompt.content);
}
inputRef.current?.focus();
}, 30);
};
// stop response
const onUserStop = (messageId: number) => {
ChatControllerPool.stop(sessionIndex, messageId);
@@ -937,30 +944,30 @@ export function Chat() {
/>
) : (
<>
<ChatAction
text={Locale.Chat.Actions.Delete}
icon={<DeleteIcon />}
onClick={() => onDelete(message.id ?? i)}
/>
<ChatAction
text={Locale.Chat.Actions.Retry}
icon={<ResetIcon />}
onClick={() => onResend(message.id ?? i)}
/>
<ChatAction
text={Locale.Chat.Actions.Delete}
icon={<DeleteIcon />}
onClick={() => onDelete(message.id ?? i)}
/>
<ChatAction
text={Locale.Chat.Actions.Pin}
icon={<PinIcon />}
onClick={() => onPinMessage(message)}
/>
<ChatAction
text={Locale.Chat.Actions.Copy}
icon={<CopyIcon />}
onClick={() => copyToClipboard(message.content)}
/>
</>
)}
<ChatAction
text={Locale.Chat.Actions.Copy}
icon={<CopyIcon />}
onClick={() => copyToClipboard(message.content)}
/>
</div>
<div className={styles["chat-message-action-date"]}>

View File

@@ -46,6 +46,7 @@ import { InputRange } from "./input-range";
import { useNavigate } from "react-router-dom";
import { Avatar, AvatarPicker } from "./emoji";
import { getClientConfig } from "../config/client";
import { useSyncStore } from "../store/sync";
function EditPromptModal(props: { id: number; onClose: () => void }) {
const promptStore = usePromptStore();
@@ -198,6 +199,78 @@ function UserPromptModal(props: { onClose?: () => void }) {
);
}
function SyncItems() {
const syncStore = useSyncStore();
const webdav = syncStore.webDavConfig;
// not ready: https://github.com/Yidadaa/ChatGPT-Next-Web/issues/920#issuecomment-1609866332
return null;
return (
<List>
<ListItem
title={"上次同步:" + new Date().toLocaleString()}
subTitle={"20 次对话100 条消息200 提示词20 面具"}
>
<IconButton
icon={<ResetIcon />}
text="同步"
onClick={() => {
syncStore.check().then(console.log);
}}
/>
</ListItem>
<ListItem
title={"本地备份"}
subTitle={"20 次对话100 条消息200 提示词20 面具"}
></ListItem>
<ListItem
title={"Web Dav Server"}
subTitle={Locale.Settings.AccessCode.SubTitle}
>
<input
value={webdav.server}
type="text"
placeholder={"https://example.com"}
onChange={(e) => {
syncStore.update(
(config) => (config.server = e.currentTarget.value),
);
}}
/>
</ListItem>
<ListItem title="Web Dav User Name" subTitle="user name here">
<input
value={webdav.username}
type="text"
placeholder={"username"}
onChange={(e) => {
syncStore.update(
(config) => (config.username = e.currentTarget.value),
);
}}
/>
</ListItem>
<ListItem title="Web Dav Password" subTitle="password here">
<input
value={webdav.password}
type="text"
placeholder={"password"}
onChange={(e) => {
syncStore.update(
(config) => (config.password = e.currentTarget.value),
);
}}
/>
</ListItem>
</List>
);
}
function formatVersionDate(t: string) {
const d = new Date(+t);
const year = d.getUTCFullYear();
@@ -556,6 +629,7 @@ export function Settings() {
<input
type="text"
value={accessStore.openaiUrl}
placeholder="https://api.openai.com/"
onChange={(e) =>
accessStore.updateOpenAiUrl(e.currentTarget.value)
}
@@ -596,6 +670,8 @@ export function Settings() {
</ListItem>
</List>
<SyncItems />
<List>
<ModelConfigList
modelConfig={config.modelConfig}