mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2026-01-21 06:35:58 +08:00
Merge remote-tracking branch 'upstream/main' into enhance-message-context-menu
This commit is contained in:
@@ -352,6 +352,12 @@
|
||||
border-radius: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.chat-model-name {
|
||||
font-size: 12px;
|
||||
color: var(--black);
|
||||
margin-left: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.chat-message-container {
|
||||
|
||||
@@ -38,6 +38,8 @@ import BottomIcon from "../icons/bottom.svg";
|
||||
import StopIcon from "../icons/pause.svg";
|
||||
import RobotIcon from "../icons/robot.svg";
|
||||
import SizeIcon from "../icons/size.svg";
|
||||
import QualityIcon from "../icons/hd.svg";
|
||||
import StyleIcon from "../icons/palette.svg";
|
||||
import PluginIcon from "../icons/plugin.svg";
|
||||
|
||||
import {
|
||||
@@ -69,7 +71,7 @@ import { uploadImage as uploadImageRemote } from "@/app/utils/chat";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
import { ChatControllerPool } from "../client/controller";
|
||||
import { DalleSize } from "../typing";
|
||||
import { DalleSize, DalleQuality, DalleStyle } from "../typing";
|
||||
import { Prompt, usePromptStore } from "../store/prompt";
|
||||
import Locale from "../locales";
|
||||
|
||||
@@ -587,9 +589,17 @@ export function ChatActions(props: {
|
||||
const [showUploadImage, setShowUploadImage] = useState(false);
|
||||
|
||||
const [showSizeSelector, setShowSizeSelector] = useState(false);
|
||||
const [showQualitySelector, setShowQualitySelector] = useState(false);
|
||||
const [showStyleSelector, setShowStyleSelector] = useState(false);
|
||||
const dalle3Sizes: DalleSize[] = ["1024x1024", "1792x1024", "1024x1792"];
|
||||
const dalle3Qualitys: DalleQuality[] = ["standard", "hd"];
|
||||
const dalle3Styles: DalleStyle[] = ["vivid", "natural"];
|
||||
const currentSize =
|
||||
chatStore.currentSession().mask.modelConfig?.size ?? "1024x1024";
|
||||
const currentQuality =
|
||||
chatStore.currentSession().mask.modelConfig?.quality ?? "standard";
|
||||
const currentStyle =
|
||||
chatStore.currentSession().mask.modelConfig?.style ?? "vivid";
|
||||
|
||||
useEffect(() => {
|
||||
const show = isVisionModel(currentModel);
|
||||
@@ -761,6 +771,60 @@ export function ChatActions(props: {
|
||||
/>
|
||||
)}
|
||||
|
||||
{isDalle3(currentModel) && (
|
||||
<ChatAction
|
||||
onClick={() => setShowQualitySelector(true)}
|
||||
text={currentQuality}
|
||||
icon={<QualityIcon />}
|
||||
/>
|
||||
)}
|
||||
|
||||
{showQualitySelector && (
|
||||
<Selector
|
||||
defaultSelectedValue={currentQuality}
|
||||
items={dalle3Qualitys.map((m) => ({
|
||||
title: m,
|
||||
value: m,
|
||||
}))}
|
||||
onClose={() => setShowQualitySelector(false)}
|
||||
onSelection={(q) => {
|
||||
if (q.length === 0) return;
|
||||
const quality = q[0];
|
||||
chatStore.updateCurrentSession((session) => {
|
||||
session.mask.modelConfig.quality = quality;
|
||||
});
|
||||
showToast(quality);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{isDalle3(currentModel) && (
|
||||
<ChatAction
|
||||
onClick={() => setShowStyleSelector(true)}
|
||||
text={currentStyle}
|
||||
icon={<StyleIcon />}
|
||||
/>
|
||||
)}
|
||||
|
||||
{showStyleSelector && (
|
||||
<Selector
|
||||
defaultSelectedValue={currentStyle}
|
||||
items={dalle3Styles.map((m) => ({
|
||||
title: m,
|
||||
value: m,
|
||||
}))}
|
||||
onClose={() => setShowStyleSelector(false)}
|
||||
onSelection={(s) => {
|
||||
if (s.length === 0) return;
|
||||
const style = s[0];
|
||||
chatStore.updateCurrentSession((session) => {
|
||||
session.mask.modelConfig.style = style;
|
||||
});
|
||||
showToast(style);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
<ChatAction
|
||||
onClick={() => setShowPluginSelector(true)}
|
||||
text={Locale.Plugin.Name}
|
||||
@@ -1584,6 +1648,11 @@ function _Chat() {
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
{!isUser && (
|
||||
<div className={styles["chat-model-name"]}>
|
||||
{message.model}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{showActions && (
|
||||
<ChatMessageActions
|
||||
|
||||
@@ -156,6 +156,46 @@ export function PreCode(props: { children: any }) {
|
||||
);
|
||||
}
|
||||
|
||||
function CustomCode(props: { children: any }) {
|
||||
const ref = useRef<HTMLPreElement>(null);
|
||||
const [collapsed, setCollapsed] = useState(true);
|
||||
const [showToggle, setShowToggle] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (ref.current) {
|
||||
const codeHeight = ref.current.scrollHeight;
|
||||
setShowToggle(codeHeight > 400);
|
||||
ref.current.scrollTop = ref.current.scrollHeight;
|
||||
}
|
||||
}, [props.children]);
|
||||
|
||||
const toggleCollapsed = () => {
|
||||
setCollapsed((collapsed) => !collapsed);
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<code
|
||||
ref={ref}
|
||||
style={{
|
||||
maxHeight: collapsed ? "400px" : "none",
|
||||
overflowY: "hidden",
|
||||
}}
|
||||
>
|
||||
{props.children}
|
||||
{showToggle && collapsed && (
|
||||
<div
|
||||
className={`show-hide-button ${
|
||||
collapsed ? "collapsed" : "expanded"
|
||||
}`}
|
||||
>
|
||||
<button onClick={toggleCollapsed}>查看全部</button>
|
||||
</div>
|
||||
)}
|
||||
</code>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function escapeDollarNumber(text: string) {
|
||||
let escapedText = "";
|
||||
|
||||
@@ -211,6 +251,7 @@ function _MarkDownContent(props: { content: string }) {
|
||||
]}
|
||||
components={{
|
||||
pre: PreCode,
|
||||
code: CustomCode,
|
||||
p: (pProps) => <p {...pProps} dir="auto" />,
|
||||
a: (aProps) => {
|
||||
const href = aProps.href || "";
|
||||
|
||||
Reference in New Issue
Block a user