mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-11-17 14:33:41 +08:00
cap nhat giao dien
This commit is contained in:
@@ -510,7 +510,7 @@ export function ChatActions(props: {
|
||||
const pluginStore = usePluginStore();
|
||||
const session = chatStore.currentSession();
|
||||
|
||||
// switch themes
|
||||
// Chuyển đổi giữa các chế độ giao diện sáng/tối
|
||||
const theme = config.theme;
|
||||
|
||||
function nextTheme() {
|
||||
@@ -521,11 +521,11 @@ export function ChatActions(props: {
|
||||
config.update((config) => (config.theme = nextTheme));
|
||||
}
|
||||
|
||||
// stop all responses
|
||||
// Dừng tất cả các phản hồi đang chạy
|
||||
const couldStop = ChatControllerPool.hasPending();
|
||||
const stopAll = () => ChatControllerPool.stopAll();
|
||||
|
||||
// switch model
|
||||
// Chuyển đổi giữa các mô hình AI
|
||||
const currentModel = session.mask.modelConfig.model;
|
||||
const currentProviderName =
|
||||
session.mask.modelConfig?.providerName || ServiceProvider.OpenAI;
|
||||
@@ -577,11 +577,11 @@ export function ChatActions(props: {
|
||||
props.setUploading(false);
|
||||
}
|
||||
|
||||
// if current model is not available
|
||||
// switch to first available model
|
||||
// nếu mô hình hiện tại không khả dụng
|
||||
// chuyển sang mô hình khả dụng đầu tiên
|
||||
const isUnavailableModel = !models.some((m) => m.name === currentModel);
|
||||
if (isUnavailableModel && models.length > 0) {
|
||||
// show next model to default model if exist
|
||||
// hiển thị mô hình tiếp theo là mô hình mặc định nếu có
|
||||
let nextModel = models.find((model) => model.isDefault) || models[0];
|
||||
chatStore.updateTargetSession(session, (session) => {
|
||||
session.mask.modelConfig.model = nextModel.name;
|
||||
@@ -1795,9 +1795,13 @@ function _Chat() {
|
||||
}}
|
||||
>
|
||||
{messages
|
||||
// TODO
|
||||
// .filter((m) => !m.isMcpResponse)
|
||||
.map((message, i) => {
|
||||
// Bypass rendering if message.role is "system"
|
||||
if (message.role === "system") {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isUser = message.role === "user";
|
||||
const isContext = i < context.length;
|
||||
const showActions =
|
||||
@@ -1809,6 +1813,8 @@ function _Chat() {
|
||||
const shouldShowClearContextDivider =
|
||||
i === clearContextIndex - 1;
|
||||
|
||||
console.log(message.role);
|
||||
|
||||
return (
|
||||
<Fragment key={message.id}>
|
||||
<div
|
||||
|
||||
@@ -8,30 +8,11 @@ import { ModelType } from "../store";
|
||||
|
||||
// import BotIconDefault from "../icons/llm-icons/chebichat.svg";
|
||||
|
||||
import BotIconDefault from "../icons/llm-icons/chebichat.svg";
|
||||
|
||||
import BotIconOpenAI from "../icons/llm-icons/chebichat.svg";
|
||||
import BotIconGemini from "../icons/llm-icons/gemini.svg";
|
||||
import BotIconGemma from "../icons/llm-icons/gemma.svg";
|
||||
import BotIconClaude from "../icons/llm-icons/claude.svg";
|
||||
import BotIconMeta from "../icons/llm-icons/meta.svg";
|
||||
import BotIconMistral from "../icons/llm-icons/mistral.svg";
|
||||
import BotIconDeepseek from "../icons/llm-icons/deepseek.svg";
|
||||
import BotIconMoonshot from "../icons/llm-icons/moonshot.svg";
|
||||
|
||||
// thay bang chebichat
|
||||
import BotIconQwen from "../icons/llm-icons/chebichat.svg";
|
||||
|
||||
import BotIconWenxin from "../icons/llm-icons/wenxin.svg";
|
||||
import BotIconGrok from "../icons/llm-icons/grok.svg";
|
||||
import BotIconHunyuan from "../icons/llm-icons/hunyuan.svg";
|
||||
import BotIconDoubao from "../icons/llm-icons/doubao.svg";
|
||||
import BotIconChatglm from "../icons/llm-icons/chatglm.svg";
|
||||
|
||||
export function getEmojiUrl(unified: string, style: EmojiStyle) {
|
||||
// Whoever owns this Content Delivery Network (CDN), I am using your CDN to serve emojis
|
||||
// Old CDN broken, so I had to switch to this one
|
||||
// Author: https://github.com/H0llyW00dzZ
|
||||
// Phương thức trả về đường dẫn URL của emoji dựa trên mã hóa unified và kiểu style
|
||||
// CDN mới được sử dụng để phục vụ hình ảnh emoji
|
||||
return `https://fastly.jsdelivr.net/npm/emoji-datasource-apple/img/${style}/64/${unified}.png`;
|
||||
}
|
||||
|
||||
@@ -45,78 +26,109 @@ export function AvatarPicker(props: {
|
||||
theme={EmojiTheme.AUTO}
|
||||
getEmojiUrl={getEmojiUrl}
|
||||
onEmojiClick={(e) => {
|
||||
// Gọi hàm onEmojiClick khi người dùng click vào emoji
|
||||
// Truyền giá trị unified của emoji đã chọn
|
||||
props.onEmojiClick(e.unified);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function Avatar(props: { model?: ModelType; avatar?: string }) {
|
||||
let LlmIcon = BotIconDefault;
|
||||
|
||||
if (props.model) {
|
||||
const modelName = props.model.toLowerCase();
|
||||
|
||||
if (
|
||||
modelName.startsWith("gpt") ||
|
||||
modelName.startsWith("chatgpt") ||
|
||||
modelName.startsWith("dall-e") ||
|
||||
modelName.startsWith("dalle") ||
|
||||
modelName.startsWith("o1") ||
|
||||
modelName.startsWith("o3")
|
||||
) {
|
||||
LlmIcon = BotIconOpenAI;
|
||||
} else if (modelName.startsWith("gemini")) {
|
||||
LlmIcon = BotIconGemini;
|
||||
} else if (modelName.startsWith("gemma")) {
|
||||
LlmIcon = BotIconGemma;
|
||||
} else if (modelName.startsWith("claude")) {
|
||||
LlmIcon = BotIconClaude;
|
||||
} else if (modelName.includes("llama")) {
|
||||
LlmIcon = BotIconMeta;
|
||||
} else if (
|
||||
modelName.startsWith("mixtral") ||
|
||||
modelName.startsWith("codestral")
|
||||
) {
|
||||
LlmIcon = BotIconMistral;
|
||||
} else if (modelName.includes("deepseek")) {
|
||||
LlmIcon = BotIconDeepseek;
|
||||
} else if (modelName.startsWith("moonshot")) {
|
||||
LlmIcon = BotIconMoonshot;
|
||||
} else if (modelName.startsWith("qwen")) {
|
||||
LlmIcon = BotIconQwen;
|
||||
} else if (modelName.startsWith("ernie")) {
|
||||
LlmIcon = BotIconWenxin;
|
||||
} else if (modelName.startsWith("grok")) {
|
||||
LlmIcon = BotIconGrok;
|
||||
} else if (modelName.startsWith("hunyuan")) {
|
||||
LlmIcon = BotIconHunyuan;
|
||||
} else if (modelName.startsWith("doubao") || modelName.startsWith("ep-")) {
|
||||
LlmIcon = BotIconDoubao;
|
||||
} else if (
|
||||
modelName.includes("glm") ||
|
||||
modelName.startsWith("cogview-") ||
|
||||
modelName.startsWith("cogvideox-")
|
||||
) {
|
||||
LlmIcon = BotIconChatglm;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="user-avatar">
|
||||
<LlmIcon className="user-avatar" size={48} width={48} height={48} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Function to render chebichat PNG avatar
|
||||
function chebichatAvatar() {
|
||||
return (
|
||||
<div className="user-avatar">
|
||||
{props.avatar && <EmojiAvatar avatar={props.avatar} size={48} />}
|
||||
<img
|
||||
src="/chebichat.png"
|
||||
alt="chebichat avatar"
|
||||
width={48}
|
||||
height={48}
|
||||
style={{ borderRadius: "50%" }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
//xu ly avatar cho Chebichat
|
||||
// nếu không có avatar thì trả về avatar mặc định của Chebichat
|
||||
// nếu có avatar thì trả về avatar tương ứng với tên avatar
|
||||
export function Avatar(props: { model?: ModelType; avatar?: string }) {
|
||||
// console.log("Avatar props", props);
|
||||
|
||||
if (props.avatar === "chebi-user") {
|
||||
//sau thay the bang avatar tu Chebichat Platform (Avatar Google,...)
|
||||
|
||||
// Nếu avatar là "chebi-user", trả về avatar mặc định của Chebichat
|
||||
return null;
|
||||
}
|
||||
|
||||
return chebichatAvatar();
|
||||
|
||||
// let LlmIcon = BotIconDefault;
|
||||
|
||||
//phan biệt các loại model và gán icon tương ứng
|
||||
// if (props.model) {
|
||||
// const modelName = props.model.toLowerCase();
|
||||
|
||||
// // Xác định icon phù hợp dựa trên tên model
|
||||
// if (
|
||||
// modelName.startsWith("gpt") ||
|
||||
// modelName.startsWith("chatgpt") ||
|
||||
// modelName.startsWith("dall-e") ||
|
||||
// modelName.startsWith("dalle") ||
|
||||
// modelName.startsWith("o1") ||
|
||||
// modelName.startsWith("o3")
|
||||
// ) {
|
||||
// LlmIcon = BotIconOpenAI;
|
||||
// } else if (modelName.startsWith("gemini")) {
|
||||
// LlmIcon = BotIconGemini;
|
||||
// } else if (modelName.startsWith("gemma")) {
|
||||
// LlmIcon = BotIconGemma;
|
||||
// } else if (modelName.startsWith("claude")) {
|
||||
// LlmIcon = BotIconClaude;
|
||||
// } else if (modelName.includes("llama")) {
|
||||
// LlmIcon = BotIconMeta;
|
||||
// } else if (
|
||||
// modelName.startsWith("mixtral") ||
|
||||
// modelName.startsWith("codestral")
|
||||
// ) {
|
||||
// LlmIcon = BotIconMistral;
|
||||
// } else if (modelName.includes("deepseek")) {
|
||||
// LlmIcon = BotIconDeepseek;
|
||||
// } else if (modelName.startsWith("moonshot")) {
|
||||
// LlmIcon = BotIconMoonshot;
|
||||
// } else if (modelName.startsWith("qwen")) {
|
||||
// LlmIcon = BotIconQwen;
|
||||
// } else if (modelName.startsWith("ernie")) {
|
||||
// LlmIcon = BotIconWenxin;
|
||||
// } else if (modelName.startsWith("grok")) {
|
||||
// LlmIcon = BotIconGrok;
|
||||
// } else if (modelName.startsWith("hunyuan")) {
|
||||
// LlmIcon = BotIconHunyuan;
|
||||
// } else if (modelName.startsWith("doubao") || modelName.startsWith("ep-")) {
|
||||
// LlmIcon = BotIconDoubao;
|
||||
// } else if (
|
||||
// modelName.includes("glm") ||
|
||||
// modelName.startsWith("cogview-") ||
|
||||
// modelName.startsWith("cogvideox-")
|
||||
// ) {
|
||||
// LlmIcon = BotIconChatglm;
|
||||
// }
|
||||
|
||||
// return chebichatAvatar();
|
||||
// }
|
||||
|
||||
// return (
|
||||
// console.log("Avatar", props.avatar),
|
||||
// <div className="user-avatar">
|
||||
// {props.avatar && <EmojiAvatar avatar={props.avatar} size={48} />}
|
||||
// </div>
|
||||
// );
|
||||
}
|
||||
|
||||
export function EmojiAvatar(props: { avatar: string; size?: number }) {
|
||||
return (
|
||||
// Hiển thị emoji dựa trên giá trị avatar được truyền vào
|
||||
<Emoji
|
||||
unified={props.avatar}
|
||||
size={props.size ?? 18}
|
||||
|
||||
@@ -518,8 +518,8 @@ export function ImagePreviewer(props: {
|
||||
<NextImage
|
||||
src={ChatGptIcon.src}
|
||||
alt="logo"
|
||||
width={50}
|
||||
height={50}
|
||||
width={30}
|
||||
height={30}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -45,7 +45,6 @@ import {
|
||||
readFromFile,
|
||||
} from "../utils";
|
||||
import { Updater } from "../typing";
|
||||
import { ModelConfigList } from "./model-config";
|
||||
import { FileName, Path } from "../constant";
|
||||
import { BUILTIN_MASK_STORE } from "../masks";
|
||||
import {
|
||||
@@ -246,13 +245,14 @@ export function MaskConfig(props: {
|
||||
) : null}
|
||||
</List>
|
||||
|
||||
<List>
|
||||
{/* CAU HINH MODEL */}
|
||||
{/* <List>
|
||||
<ModelConfigList
|
||||
modelConfig={{ ...props.mask.modelConfig }}
|
||||
updateConfig={updateConfig}
|
||||
/>
|
||||
{props.extraListItems}
|
||||
</List>
|
||||
</List> */}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ import {
|
||||
showConfirm,
|
||||
showToast,
|
||||
} from "./ui-lib";
|
||||
import { ModelConfigList } from "./model-config";
|
||||
|
||||
import { IconButton } from "./button";
|
||||
import {
|
||||
@@ -1873,7 +1872,8 @@ export function Settings() {
|
||||
</ListItem>
|
||||
</List>
|
||||
|
||||
<List>
|
||||
{/* CAU HINH MODEL CUSTOM */}
|
||||
{/* <List>
|
||||
<ModelConfigList
|
||||
modelConfig={config.modelConfig}
|
||||
updateConfig={(updater) => {
|
||||
@@ -1882,7 +1882,7 @@ export function Settings() {
|
||||
config.update((config) => (config.modelConfig = modelConfig));
|
||||
}}
|
||||
/>
|
||||
</List>
|
||||
</List> */}
|
||||
|
||||
{shouldShowPromptModal && (
|
||||
<UserPromptModal onClose={() => setShowPromptModal(false)} />
|
||||
|
||||
@@ -4,7 +4,6 @@ import styles from "./home.module.scss";
|
||||
|
||||
import { IconButton } from "./button";
|
||||
import SettingsIcon from "../icons/settings.svg";
|
||||
import GithubIcon from "../icons/github.svg";
|
||||
|
||||
import ChatGptIcon from "../icons/chebichat.svg";
|
||||
|
||||
@@ -25,7 +24,6 @@ import {
|
||||
MIN_SIDEBAR_WIDTH,
|
||||
NARROW_SIDEBAR_WIDTH,
|
||||
Path,
|
||||
REPO_URL,
|
||||
} from "../constant";
|
||||
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
@@ -36,8 +34,8 @@ import clsx from "clsx";
|
||||
import { isMcpEnabled } from "../mcp/actions";
|
||||
|
||||
const DISCOVERY = [
|
||||
{ name: Locale.Plugin.Name, path: Path.Plugins },
|
||||
{ name: "Stable Diffusion", path: Path.Sd },
|
||||
// { name: Locale.Plugin.Name, path: Path.Plugins },
|
||||
// { name: "Stable Diffusion", path: Path.Sd },
|
||||
{ name: Locale.SearchChat.Page.Title, path: Path.SearchChat },
|
||||
];
|
||||
|
||||
@@ -252,17 +250,20 @@ export function SideBar(props: { className?: string }) {
|
||||
{...props}
|
||||
>
|
||||
<SideBarHeader
|
||||
title="Chebi Chat"
|
||||
subTitle="Trợ lý AI học tiếng Trung"
|
||||
logo={<ChatGptIcon />}
|
||||
shouldNarrow={shouldNarrow}
|
||||
title="Chebi Chat" // Tiêu đề sidebar
|
||||
subTitle="Trợ lý AI học tiếng Trung" // Phụ đề sidebar
|
||||
logo={<ChatGptIcon />} // Logo hiển thị
|
||||
shouldNarrow={shouldNarrow} // Trạng thái thu nhỏ sidebar
|
||||
>
|
||||
{/* Thanh công cụ phía trên của sidebar */}
|
||||
<div className={styles["sidebar-header-bar"]}>
|
||||
{/* Nút chuyển sang giao diện tạo chat mới hoặc danh sách mask */}
|
||||
<IconButton
|
||||
icon={<MaskIcon />}
|
||||
text={shouldNarrow ? undefined : Locale.Mask.Name}
|
||||
className={styles["sidebar-bar-button"]}
|
||||
onClick={() => {
|
||||
// Nếu chưa tắt splash screen mask thì chuyển sang tạo chat mới, ngược lại chuyển sang danh sách mask
|
||||
if (config.dontShowMaskSplashScreen !== true) {
|
||||
navigate(Path.NewChat, { state: { fromHome: true } });
|
||||
} else {
|
||||
@@ -271,17 +272,20 @@ export function SideBar(props: { className?: string }) {
|
||||
}}
|
||||
shadow
|
||||
/>
|
||||
{/* Nếu tính năng MCP được bật thì hiển thị nút MCP */}
|
||||
{mcpEnabled && (
|
||||
<IconButton
|
||||
icon={<McpIcon />}
|
||||
text={shouldNarrow ? undefined : Locale.Mcp.Name}
|
||||
className={styles["sidebar-bar-button"]}
|
||||
onClick={() => {
|
||||
// Chuyển sang giao diện MCP Market
|
||||
navigate(Path.McpMarket, { state: { fromHome: true } });
|
||||
}}
|
||||
shadow
|
||||
/>
|
||||
)}
|
||||
{/* Nút chuyển sang giao diện Discovery */}
|
||||
<IconButton
|
||||
icon={<DiscoveryIcon />}
|
||||
text={shouldNarrow ? undefined : Locale.Discovery.Name}
|
||||
@@ -290,6 +294,7 @@ export function SideBar(props: { className?: string }) {
|
||||
shadow
|
||||
/>
|
||||
</div>
|
||||
{/* Hiển thị selector khi người dùng bấm vào Discovery */}
|
||||
{showDiscoverySelector && (
|
||||
<Selector
|
||||
items={[
|
||||
@@ -302,6 +307,7 @@ export function SideBar(props: { className?: string }) {
|
||||
]}
|
||||
onClose={() => setshowDiscoverySelector(false)}
|
||||
onSelection={(s) => {
|
||||
// Điều hướng đến trang được chọn
|
||||
navigate(s[0], { state: { fromHome: true } });
|
||||
}}
|
||||
/>
|
||||
@@ -338,7 +344,8 @@ export function SideBar(props: { className?: string }) {
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
<div className={styles["sidebar-action"]}>
|
||||
|
||||
{/* <div className={styles["sidebar-action"]}>
|
||||
<a href={REPO_URL} target="_blank" rel="noopener noreferrer">
|
||||
<IconButton
|
||||
aria={Locale.Export.MessageFromChatGPT}
|
||||
@@ -346,7 +353,7 @@ export function SideBar(props: { className?: string }) {
|
||||
shadow
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</div> */}
|
||||
</>
|
||||
}
|
||||
secondaryAction={
|
||||
|
||||
Reference in New Issue
Block a user