forked from XiaoMo/ChatGPT-Next-Web
feat: close #2266 use modal to switch model
This commit is contained in:
parent
b718285125
commit
0373b2c9dd
@ -61,7 +61,14 @@ import Locale from "../locales";
|
|||||||
import { IconButton } from "./button";
|
import { IconButton } from "./button";
|
||||||
import styles from "./chat.module.scss";
|
import styles from "./chat.module.scss";
|
||||||
|
|
||||||
import { ListItem, Modal, showConfirm, showPrompt, showToast } from "./ui-lib";
|
import {
|
||||||
|
ListItem,
|
||||||
|
Modal,
|
||||||
|
Selector,
|
||||||
|
showConfirm,
|
||||||
|
showPrompt,
|
||||||
|
showToast,
|
||||||
|
} from "./ui-lib";
|
||||||
import { useLocation, useNavigate } from "react-router-dom";
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
import { LAST_INPUT_KEY, Path, REQUEST_TIMEOUT_MS } from "../constant";
|
import { LAST_INPUT_KEY, Path, REQUEST_TIMEOUT_MS } from "../constant";
|
||||||
import { Avatar } from "./emoji";
|
import { Avatar } from "./emoji";
|
||||||
@ -404,16 +411,11 @@ export function ChatActions(props: {
|
|||||||
|
|
||||||
// switch model
|
// switch model
|
||||||
const currentModel = chatStore.currentSession().mask.modelConfig.model;
|
const currentModel = chatStore.currentSession().mask.modelConfig.model;
|
||||||
function nextModel() {
|
const models = useMemo(
|
||||||
const models = config.models.filter((m) => m.available).map((m) => m.name);
|
() => config.models.filter((m) => m.available).map((m) => m.name),
|
||||||
const modelIndex = models.indexOf(currentModel);
|
[config.models],
|
||||||
const nextIndex = (modelIndex + 1) % models.length;
|
);
|
||||||
const nextModel = models[nextIndex];
|
const [showModelSelector, setShowModelSelector] = useState(false);
|
||||||
chatStore.updateCurrentSession((session) => {
|
|
||||||
session.mask.modelConfig.model = nextModel as ModelType;
|
|
||||||
session.mask.syncGlobalConfig = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles["chat-input-actions"]}>
|
<div className={styles["chat-input-actions"]}>
|
||||||
@ -485,10 +487,28 @@ export function ChatActions(props: {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<ChatAction
|
<ChatAction
|
||||||
onClick={nextModel}
|
onClick={() => setShowModelSelector(true)}
|
||||||
text={currentModel}
|
text={currentModel}
|
||||||
icon={<RobotIcon />}
|
icon={<RobotIcon />}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{showModelSelector && (
|
||||||
|
<Selector
|
||||||
|
items={models.map((m) => ({
|
||||||
|
title: m,
|
||||||
|
value: m,
|
||||||
|
}))}
|
||||||
|
onClose={() => setShowModelSelector(false)}
|
||||||
|
onSelection={(s) => {
|
||||||
|
if (s.length === 0) return;
|
||||||
|
chatStore.updateCurrentSession((session) => {
|
||||||
|
session.mask.modelConfig.model = s[0] as ModelType;
|
||||||
|
session.mask.syncGlobalConfig = false;
|
||||||
|
});
|
||||||
|
showToast(s[0]);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,7 @@
|
|||||||
box-shadow: var(--card-shadow);
|
box-shadow: var(--card-shadow);
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
animation: slide-in ease 0.3s;
|
animation: slide-in ease 0.3s;
|
||||||
|
background: var(--white);
|
||||||
}
|
}
|
||||||
|
|
||||||
.list .list-item:last-child {
|
.list .list-item:last-child {
|
||||||
@ -270,3 +271,34 @@
|
|||||||
border: 1px solid var(--primary);
|
border: 1px solid var(--primary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.selector {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 100vh;
|
||||||
|
width: 100vw;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
&-content {
|
||||||
|
.list {
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.list-item {
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: var(--white);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
filter: brightness(0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
filter: brightness(0.9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -47,9 +47,13 @@ export function ListItem(props: {
|
|||||||
children?: JSX.Element | JSX.Element[];
|
children?: JSX.Element | JSX.Element[];
|
||||||
icon?: JSX.Element;
|
icon?: JSX.Element;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
onClick?: () => void;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div className={styles["list-item"] + ` ${props.className || ""}`}>
|
<div
|
||||||
|
className={styles["list-item"] + ` ${props.className || ""}`}
|
||||||
|
onClick={props.onClick}
|
||||||
|
>
|
||||||
<div className={styles["list-header"]}>
|
<div className={styles["list-header"]}>
|
||||||
{props.icon && <div className={styles["list-icon"]}>{props.icon}</div>}
|
{props.icon && <div className={styles["list-icon"]}>{props.icon}</div>}
|
||||||
<div className={styles["list-item-title"]}>
|
<div className={styles["list-item-title"]}>
|
||||||
@ -432,3 +436,37 @@ export function showImageModal(img: string) {
|
|||||||
),
|
),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function Selector<T>(props: {
|
||||||
|
items: Array<{
|
||||||
|
title: string;
|
||||||
|
subTitle?: string;
|
||||||
|
value: T;
|
||||||
|
}>;
|
||||||
|
onSelection?: (selection: T[]) => void;
|
||||||
|
onClose?: () => void;
|
||||||
|
multiple?: boolean;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className={styles["selector"]}>
|
||||||
|
<div className={styles["selector-content"]}>
|
||||||
|
<List>
|
||||||
|
{props.items.map((item, i) => {
|
||||||
|
return (
|
||||||
|
<ListItem
|
||||||
|
className={styles["selector-item"]}
|
||||||
|
key={i}
|
||||||
|
title={item.title}
|
||||||
|
subTitle={item.subTitle}
|
||||||
|
onClick={() => {
|
||||||
|
props.onSelection?.([item.value]);
|
||||||
|
props.onClose?.();
|
||||||
|
}}
|
||||||
|
></ListItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</List>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user