Refined UI,code logic for improved user experience
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import DeleteIcon from "../icons/delete.svg";
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import { faPen } from '@fortawesome/free-solid-svg-icons'
|
||||
import BotIcon from "../icons/bot.svg";
|
||||
|
||||
import styles from "./home.module.scss";
|
||||
@@ -20,6 +22,7 @@ import { useRef, useEffect } from "react";
|
||||
|
||||
export function ChatItem(props: {
|
||||
onClick?: () => void;
|
||||
onRename?: () => void;
|
||||
onDelete?: () => void;
|
||||
title: string;
|
||||
count: number;
|
||||
@@ -77,6 +80,14 @@ export function ChatItem(props: {
|
||||
</>
|
||||
)}
|
||||
|
||||
<div
|
||||
className={styles["chat-item-rename"]}
|
||||
onClickCapture={props.onRename}
|
||||
>
|
||||
{/* <RenameIcon /> */}
|
||||
<FontAwesomeIcon icon={faPen} />
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={styles["chat-item-delete"]}
|
||||
onClickCapture={props.onDelete}
|
||||
|
||||
+31
-15
@@ -22,12 +22,18 @@ import ResetIcon from "../icons/reload.svg";
|
||||
import ClearIcon from "../icons/clear.svg";
|
||||
import SettingsIcon from "../icons/chat-settings.svg";
|
||||
|
||||
import Image from 'next/image'
|
||||
import AvatarIcon from "../icons/star/happy.png";
|
||||
|
||||
import LightIcon from "../icons/light.svg";
|
||||
import DarkIcon from "../icons/dark.svg";
|
||||
import AutoIcon from "../icons/auto.svg";
|
||||
import BottomIcon from "../icons/bottom.svg";
|
||||
import StopIcon from "../icons/pause.svg";
|
||||
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import { faPaintbrush, faTrashCan, faCircleHalfStroke } from '@fortawesome/free-solid-svg-icons'
|
||||
|
||||
import {
|
||||
ChatMessage,
|
||||
SubmitKey,
|
||||
@@ -174,11 +180,11 @@ function useSubmitHandler() {
|
||||
if (e.key !== "Enter") return false;
|
||||
if (e.key === "Enter" && e.nativeEvent.isComposing) return false;
|
||||
return (
|
||||
(config.submitKey === SubmitKey.AltEnter && e.altKey) ||
|
||||
(config.submitKey === SubmitKey.CtrlEnter && e.ctrlKey) ||
|
||||
(config.submitKey === SubmitKey.ShiftEnter && e.shiftKey) ||
|
||||
(config.submitKey === SubmitKey.MetaEnter && e.metaKey) ||
|
||||
(config.submitKey === SubmitKey.Enter &&
|
||||
(submitKey === SubmitKey.AltEnter && e.altKey) ||
|
||||
(submitKey === SubmitKey.CtrlEnter && e.ctrlKey) ||
|
||||
(submitKey === SubmitKey.ShiftEnter && e.shiftKey) ||
|
||||
(submitKey === SubmitKey.MetaEnter && e.metaKey) ||
|
||||
(submitKey === SubmitKey.Enter &&
|
||||
!e.altKey &&
|
||||
!e.ctrlKey &&
|
||||
!e.shiftKey &&
|
||||
@@ -401,13 +407,19 @@ export function ChatActions(props: {
|
||||
icon={<BottomIcon />}
|
||||
/>
|
||||
)}
|
||||
{props.hitBottom && (
|
||||
{/* {props.hitBottom && (
|
||||
<ChatAction
|
||||
onClick={props.showPromptModal}
|
||||
text={Locale.Chat.InputActions.Settings}
|
||||
icon={<SettingsIcon />}
|
||||
/>
|
||||
)}
|
||||
)} */}
|
||||
|
||||
<ChatAction
|
||||
onClick={() => {}} // todo: add ai painting action
|
||||
text={Locale.Chat.InputActions.AIPaint}
|
||||
icon={<FontAwesomeIcon icon={faPaintbrush} />}
|
||||
/>
|
||||
|
||||
<ChatAction
|
||||
onClick={nextTheme}
|
||||
@@ -415,7 +427,8 @@ export function ChatActions(props: {
|
||||
icon={
|
||||
<>
|
||||
{theme === Theme.Auto ? (
|
||||
<AutoIcon />
|
||||
// <FontAwesomeIcon icon="fa-solid fa-circle-half-stroke" />
|
||||
<FontAwesomeIcon icon={faCircleHalfStroke} />
|
||||
) : theme === Theme.Light ? (
|
||||
<LightIcon />
|
||||
) : theme === Theme.Dark ? (
|
||||
@@ -431,17 +444,18 @@ export function ChatActions(props: {
|
||||
icon={<PromptIcon />}
|
||||
/>
|
||||
|
||||
<ChatAction
|
||||
{/* <ChatAction
|
||||
onClick={() => {
|
||||
navigate(Path.Masks);
|
||||
}}
|
||||
text={Locale.Chat.InputActions.Masks}
|
||||
icon={<MaskIcon />}
|
||||
/>
|
||||
/> */}
|
||||
|
||||
<ChatAction
|
||||
text={Locale.Chat.InputActions.Clear}
|
||||
icon={<ClearIcon />}
|
||||
// icon={<FontAwesomeIcon icon="fa-regular fa-trash-can" />}
|
||||
icon={<FontAwesomeIcon icon={faTrashCan} />}
|
||||
onClick={() => {
|
||||
chatStore.updateCurrentSession((session) => {
|
||||
if (session.clearContextIndex === session.messages.length) {
|
||||
@@ -820,7 +834,8 @@ export function Chat() {
|
||||
<div className={styles["chat-message-container"]}>
|
||||
<div className={styles["chat-message-avatar"]}>
|
||||
{message.role === "user" ? (
|
||||
<Avatar avatar={config.avatar} />
|
||||
// <Avatar avatar={config.avatar} />
|
||||
<Image src={AvatarIcon} alt="Avatar" width={32} height={32} />
|
||||
) : (
|
||||
<MaskAvatar mask={session.mask} />
|
||||
)}
|
||||
@@ -848,12 +863,12 @@ export function Chat() {
|
||||
>
|
||||
{Locale.Chat.Actions.Delete}
|
||||
</div>
|
||||
<div
|
||||
{/* <div
|
||||
className={styles["chat-message-top-action"]}
|
||||
onClick={() => onResend(message.id ?? i)}
|
||||
>
|
||||
{Locale.Chat.Actions.Retry}
|
||||
</div>
|
||||
</div> */}
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -930,7 +945,8 @@ export function Chat() {
|
||||
/>
|
||||
<IconButton
|
||||
icon={<SendWhiteIcon />}
|
||||
text={Locale.Chat.Send}
|
||||
// text={Locale.Chat.Send}
|
||||
text=''
|
||||
className={styles["chat-input-send"]}
|
||||
type="primary"
|
||||
onClick={() => doSubmit(userInput)}
|
||||
|
||||
@@ -183,6 +183,24 @@
|
||||
animation: slide-in ease 0.3s;
|
||||
}
|
||||
|
||||
.chat-item-rename {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 30px;
|
||||
transition: all ease 0.3s;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.chat-item:hover > .chat-item-rename {
|
||||
opacity: 0.5;
|
||||
transform: translateX(-10px);
|
||||
}
|
||||
|
||||
.chat-item:hover > .chat-item-rename:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.chat-item-delete {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
@@ -283,8 +301,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
.chat-item-rename {
|
||||
top: 15px;
|
||||
right: 35px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.chat-item:hover > .chat-item-rename {
|
||||
opacity: 0.5;
|
||||
right: 30px;
|
||||
}
|
||||
|
||||
.chat-item-delete {
|
||||
top: 15px;
|
||||
opacity: 1; // 手机模式下始终显示
|
||||
}
|
||||
|
||||
.chat-item:hover > .chat-item-delete {
|
||||
|
||||
@@ -158,14 +158,14 @@ export function SideBar(props: { className?: string }) {
|
||||
<div className={styles["sidebar-tail"]}>
|
||||
<div className={styles["sidebar-actions"]}>
|
||||
<div className={styles["sidebar-action"] + " " + styles.mobile}>
|
||||
<IconButton
|
||||
{/* <IconButton
|
||||
icon={<CloseIcon />}
|
||||
onClick={() => {
|
||||
if (confirm(Locale.Home.DeleteChat)) {
|
||||
chatStore.deleteSession(chatStore.currentSessionIndex);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
/> */}
|
||||
</div>
|
||||
<div className={styles["sidebar-action"]}>
|
||||
{/* <Link to={Path.Settings}>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 128 KiB |
+3
-1
@@ -39,6 +39,7 @@ const cn = {
|
||||
Masks: "所有面具",
|
||||
Clear: "清除聊天",
|
||||
Settings: "对话设置",
|
||||
AIPaint: "AI绘画",
|
||||
},
|
||||
Rename: "重命名对话",
|
||||
Typing: "正在输入…",
|
||||
@@ -47,7 +48,8 @@ const cn = {
|
||||
if (submitKey === String(SubmitKey.Enter)) {
|
||||
inputHints += ",Shift + Enter 换行";
|
||||
}
|
||||
return inputHints + ",/ 触发补全";
|
||||
// return inputHints + ",/ 触发补全";
|
||||
return inputHints;
|
||||
},
|
||||
Send: "发送",
|
||||
Config: {
|
||||
|
||||
+3
-1
@@ -40,6 +40,7 @@ const en: RequiredLocaleType = {
|
||||
Masks: "Masks",
|
||||
Clear: "Clear Context",
|
||||
Settings: "Settings",
|
||||
AIPaint: "AI Paint",
|
||||
},
|
||||
Rename: "Rename Chat",
|
||||
Typing: "Typing…",
|
||||
@@ -48,7 +49,8 @@ const en: RequiredLocaleType = {
|
||||
if (submitKey === String(SubmitKey.Enter)) {
|
||||
inputHints += ", Shift + Enter to wrap";
|
||||
}
|
||||
return inputHints + ", / to search prompts";
|
||||
// return inputHints + ", / to search prompts";
|
||||
return inputHints;
|
||||
},
|
||||
Send: "Send",
|
||||
Config: {
|
||||
|
||||
+44
-29
@@ -19,7 +19,7 @@ export enum Theme {
|
||||
|
||||
export const DEFAULT_CONFIG = {
|
||||
// submitKey: SubmitKey.CtrlEnter as SubmitKey,
|
||||
submitKey: SubmitKey.Enter as SubmitKey,
|
||||
submitKey: SubmitKey.Enter,
|
||||
avatar: "1f603",
|
||||
fontSize: 14,
|
||||
theme: Theme.Auto as Theme,
|
||||
@@ -156,35 +156,50 @@ export const ModalConfigValidator = {
|
||||
},
|
||||
};
|
||||
|
||||
export const useAppConfig = create<ChatConfigStore>()(
|
||||
persist(
|
||||
(set, get) => ({
|
||||
...DEFAULT_CONFIG,
|
||||
// export const useAppConfig = create<ChatConfigStore>()(
|
||||
// persist(
|
||||
// (set, get) => ({
|
||||
// ...DEFAULT_CONFIG,
|
||||
|
||||
reset() {
|
||||
set(() => ({ ...DEFAULT_CONFIG }));
|
||||
},
|
||||
// reset() {
|
||||
// set(() => ({ ...DEFAULT_CONFIG }));
|
||||
// },
|
||||
|
||||
update(updater) {
|
||||
const config = { ...get() };
|
||||
updater(config);
|
||||
set(() => config);
|
||||
},
|
||||
}),
|
||||
{
|
||||
name: StoreKey.Config,
|
||||
version: 2,
|
||||
migrate(persistedState, version) {
|
||||
if (version === 2) return persistedState as any;
|
||||
// update(updater) {
|
||||
// const config = { ...get() };
|
||||
// updater(config);
|
||||
// set(() => config);
|
||||
// },
|
||||
// }),
|
||||
// {
|
||||
// name: StoreKey.Config,
|
||||
// version: 2,
|
||||
// migrate(persistedState, version) {
|
||||
// if (version === 2) return persistedState as any;
|
||||
|
||||
const state = persistedState as ChatConfig;
|
||||
state.modelConfig.sendMemory = true;
|
||||
state.modelConfig.historyMessageCount = 4;
|
||||
state.modelConfig.compressMessageLengthThreshold = 1000;
|
||||
state.dontShowMaskSplashScreen = false;
|
||||
// const state = persistedState as ChatConfig;
|
||||
// state.modelConfig.sendMemory = true;
|
||||
// state.modelConfig.historyMessageCount = 4;
|
||||
// state.modelConfig.compressMessageLengthThreshold = 1000;
|
||||
// state.dontShowMaskSplashScreen = false;
|
||||
|
||||
return state;
|
||||
},
|
||||
},
|
||||
),
|
||||
);
|
||||
// return state;
|
||||
// },
|
||||
// },
|
||||
// ),
|
||||
// );
|
||||
|
||||
// 取消 AppConfig 的持久化
|
||||
export const useAppConfig = create<ChatConfigStore>((set, get) => ({
|
||||
...DEFAULT_CONFIG,
|
||||
|
||||
reset() {
|
||||
set(() => ({ ...DEFAULT_CONFIG }));
|
||||
},
|
||||
|
||||
update(updater) {
|
||||
const config = { ...get() };
|
||||
updater(config);
|
||||
set(() => config);
|
||||
},
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user