mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-10-01 23:56:39 +08:00
Merge remote-tracking branch 'upstream/main' into dev
# Conflicts: # package.json # yarn.lock
This commit is contained in:
commit
c60fa3cda6
@ -41,13 +41,16 @@ interface ChatCommands {
|
|||||||
del?: Command;
|
del?: Command;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ChatCommandPrefix = ":";
|
// Compatible with Chinese colon character ":"
|
||||||
|
export const ChatCommandPrefix = /^[::]/;
|
||||||
|
|
||||||
export function useChatCommand(commands: ChatCommands = {}) {
|
export function useChatCommand(commands: ChatCommands = {}) {
|
||||||
function extract(userInput: string) {
|
function extract(userInput: string) {
|
||||||
return (
|
const match = userInput.match(ChatCommandPrefix);
|
||||||
userInput.startsWith(ChatCommandPrefix) ? userInput.slice(1) : userInput
|
if (match) {
|
||||||
) as keyof ChatCommands;
|
return userInput.slice(1) as keyof ChatCommands;
|
||||||
|
}
|
||||||
|
return userInput as keyof ChatCommands;
|
||||||
}
|
}
|
||||||
|
|
||||||
function search(userInput: string) {
|
function search(userInput: string) {
|
||||||
@ -57,7 +60,7 @@ export function useChatCommand(commands: ChatCommands = {}) {
|
|||||||
.filter((c) => c.startsWith(input))
|
.filter((c) => c.startsWith(input))
|
||||||
.map((c) => ({
|
.map((c) => ({
|
||||||
title: desc[c as keyof ChatCommands],
|
title: desc[c as keyof ChatCommands],
|
||||||
content: ChatCommandPrefix + c,
|
content: ":" + c,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -839,7 +839,7 @@ function _Chat() {
|
|||||||
// clear search results
|
// clear search results
|
||||||
if (n === 0) {
|
if (n === 0) {
|
||||||
setPromptHints([]);
|
setPromptHints([]);
|
||||||
} else if (text.startsWith(ChatCommandPrefix)) {
|
} else if (text.match(ChatCommandPrefix)) {
|
||||||
setPromptHints(chatCommands.search(text));
|
setPromptHints(chatCommands.search(text));
|
||||||
} else if (!config.disablePromptHint && n < SEARCH_TEXT_LIMIT) {
|
} else if (!config.disablePromptHint && n < SEARCH_TEXT_LIMIT) {
|
||||||
// check if need to trigger auto completion
|
// check if need to trigger auto completion
|
||||||
|
@ -143,12 +143,18 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
padding-top: 20px;
|
padding-top: 20px;
|
||||||
padding-bottom: 20px;
|
padding-bottom: 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-logo {
|
.sidebar-logo {
|
||||||
position: absolute;
|
display: inline-flex;
|
||||||
right: 0;
|
}
|
||||||
bottom: 18px;
|
|
||||||
|
.sidebar-title-container {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-title {
|
.sidebar-title {
|
||||||
|
@ -96,6 +96,32 @@ export function PreCode(props: { children: any }) {
|
|||||||
[plugins],
|
[plugins],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//Wrap the paragraph for plain-text
|
||||||
|
useEffect(() => {
|
||||||
|
if (ref.current) {
|
||||||
|
const codeElements = ref.current.querySelectorAll(
|
||||||
|
"code",
|
||||||
|
) as NodeListOf<HTMLElement>;
|
||||||
|
const wrapLanguages = [
|
||||||
|
"",
|
||||||
|
"md",
|
||||||
|
"markdown",
|
||||||
|
"text",
|
||||||
|
"txt",
|
||||||
|
"plaintext",
|
||||||
|
"tex",
|
||||||
|
"latex",
|
||||||
|
];
|
||||||
|
codeElements.forEach((codeElement) => {
|
||||||
|
let languageClass = codeElement.className.match(/language-(\w+)/);
|
||||||
|
let name = languageClass ? languageClass[1] : "";
|
||||||
|
if (wrapLanguages.includes(name)) {
|
||||||
|
codeElement.style.whiteSpace = "pre-wrap";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<pre ref={ref}>
|
<pre ref={ref}>
|
||||||
|
@ -23,7 +23,6 @@ import CopyIcon from "@/app/icons/copy.svg";
|
|||||||
import PromptIcon from "@/app/icons/prompt.svg";
|
import PromptIcon from "@/app/icons/prompt.svg";
|
||||||
import ResetIcon from "@/app/icons/reload.svg";
|
import ResetIcon from "@/app/icons/reload.svg";
|
||||||
import { useSdStore } from "@/app/store/sd";
|
import { useSdStore } from "@/app/store/sd";
|
||||||
import locales from "@/app/locales";
|
|
||||||
import LoadingIcon from "@/app/icons/three-dots.svg";
|
import LoadingIcon from "@/app/icons/three-dots.svg";
|
||||||
import ErrorIcon from "@/app/icons/delete.svg";
|
import ErrorIcon from "@/app/icons/delete.svg";
|
||||||
import SDIcon from "@/app/icons/sd.svg";
|
import SDIcon from "@/app/icons/sd.svg";
|
||||||
@ -64,14 +63,14 @@ function getSdTaskStatus(item: any) {
|
|||||||
return (
|
return (
|
||||||
<p className={styles["line-1"]} title={item.error} style={{ color: color }}>
|
<p className={styles["line-1"]} title={item.error} style={{ color: color }}>
|
||||||
<span>
|
<span>
|
||||||
{locales.Sd.Status.Name}: {s}
|
{Locale.Sd.Status.Name}: {s}
|
||||||
</span>
|
</span>
|
||||||
{item.status === "error" && (
|
{item.status === "error" && (
|
||||||
<span
|
<span
|
||||||
className="clickable"
|
className="clickable"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
showModal({
|
showModal({
|
||||||
title: locales.Sd.Detail,
|
title: Locale.Sd.Detail,
|
||||||
children: (
|
children: (
|
||||||
<div style={{ color: color, userSelect: "text" }}>
|
<div style={{ color: color, userSelect: "text" }}>
|
||||||
{item.error}
|
{item.error}
|
||||||
@ -191,13 +190,13 @@ export function Sd() {
|
|||||||
className={styles["sd-img-item-info"]}
|
className={styles["sd-img-item-info"]}
|
||||||
>
|
>
|
||||||
<p className={styles["line-1"]}>
|
<p className={styles["line-1"]}>
|
||||||
{locales.SdPanel.Prompt}:{" "}
|
{Locale.SdPanel.Prompt}:{" "}
|
||||||
<span
|
<span
|
||||||
className="clickable"
|
className="clickable"
|
||||||
title={item.params.prompt}
|
title={item.params.prompt}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
showModal({
|
showModal({
|
||||||
title: locales.Sd.Detail,
|
title: Locale.Sd.Detail,
|
||||||
children: (
|
children: (
|
||||||
<div style={{ userSelect: "text" }}>
|
<div style={{ userSelect: "text" }}>
|
||||||
{item.params.prompt}
|
{item.params.prompt}
|
||||||
@ -210,7 +209,7 @@ export function Sd() {
|
|||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{locales.SdPanel.AIModel}: {item.model_name}
|
{Locale.SdPanel.AIModel}: {item.model_name}
|
||||||
</p>
|
</p>
|
||||||
{getSdTaskStatus(item)}
|
{getSdTaskStatus(item)}
|
||||||
<p>{item.created_at}</p>
|
<p>{item.created_at}</p>
|
||||||
@ -221,7 +220,7 @@ export function Sd() {
|
|||||||
icon={<PromptIcon />}
|
icon={<PromptIcon />}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
showModal({
|
showModal({
|
||||||
title: locales.Sd.GenerateParams,
|
title: Locale.Sd.GenerateParams,
|
||||||
children: (
|
children: (
|
||||||
<div style={{ userSelect: "text" }}>
|
<div style={{ userSelect: "text" }}>
|
||||||
{Object.keys(item.params).map((key) => {
|
{Object.keys(item.params).map((key) => {
|
||||||
@ -327,7 +326,7 @@ export function Sd() {
|
|||||||
);
|
);
|
||||||
})
|
})
|
||||||
) : (
|
) : (
|
||||||
<div>{locales.Sd.EmptyRecord}</div>
|
<div>{Locale.Sd.EmptyRecord}</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -196,10 +196,12 @@ export function SideBarHeader(props: {
|
|||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<div className={styles["sidebar-header"]} data-tauri-drag-region>
|
<div className={styles["sidebar-header"]} data-tauri-drag-region>
|
||||||
<div className={styles["sidebar-title"]} data-tauri-drag-region>
|
<div className={styles["sidebar-title-container"]}>
|
||||||
{title}
|
<div className={styles["sidebar-title"]} data-tauri-drag-region>
|
||||||
|
{title}
|
||||||
|
</div>
|
||||||
|
<div className={styles["sidebar-sub-title"]}>{subTitle}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles["sidebar-sub-title"]}>{subTitle}</div>
|
|
||||||
<div className={styles["sidebar-logo"] + " no-dark"}>{logo}</div>
|
<div className={styles["sidebar-logo"] + " no-dark"}>{logo}</div>
|
||||||
</div>
|
</div>
|
||||||
{children}
|
{children}
|
||||||
|
@ -4,14 +4,14 @@
|
|||||||
"license": "mit",
|
"license": "mit",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"mask": "npx tsx app/masks/build.ts",
|
"mask": "npx tsx app/masks/build.ts",
|
||||||
"mask:watch": "npx watch 'yarn mask' app/masks",
|
"mask:watch": "npx watch \"yarn mask\" app/masks",
|
||||||
"dev": "yarn run mask:watch & npx prisma generate && npx prisma db push && next dev --hostname 0.0.0.0 --port 23000",
|
"dev": "npx prisma generate && npx prisma db push && concurrently -r \"yarn run mask:watch\" \"next dev --hostname 0.0.0.0 --port 23000\"",
|
||||||
"build": "yarn mask && npx next telemetry disable && npx prisma generate && cross-env BUILD_MODE=standalone next build",
|
"build": "yarn mask && npx next telemetry disable && npx prisma generate && cross-env BUILD_MODE=standalone next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "next lint",
|
"lint": "next lint",
|
||||||
"export": "yarn mask && cross-env BUILD_MODE=export BUILD_APP=1 next build",
|
"export": "yarn mask && cross-env BUILD_MODE=export BUILD_APP=1 next build",
|
||||||
"export:dev": "yarn mask:watch & cross-env BUILD_MODE=export BUILD_APP=1 next dev",
|
"export:dev": "concurrently -r \"yarn mask:watch\" \"cross-env BUILD_MODE=export BUILD_APP=1 next dev\"",
|
||||||
"app:dev": "yarn mask:watch & yarn tauri dev",
|
"app:dev": "concurrently -r \"yarn mask:watch\" \"yarn tauri dev\"",
|
||||||
"app:build": "yarn mask && yarn tauri build",
|
"app:build": "yarn mask && yarn tauri build",
|
||||||
"prompts": "node ./scripts/fetch-prompts.mjs",
|
"prompts": "node ./scripts/fetch-prompts.mjs",
|
||||||
"prepare": "husky install",
|
"prepare": "husky install",
|
||||||
@ -75,6 +75,7 @@
|
|||||||
"@types/react-highlight-words": "0.20.0",
|
"@types/react-highlight-words": "0.20.0",
|
||||||
"@types/react-katex": "^3.0.0",
|
"@types/react-katex": "^3.0.0",
|
||||||
"@types/spark-md5": "^3.0.4",
|
"@types/spark-md5": "^3.0.4",
|
||||||
|
"concurrently": "^8.2.2",
|
||||||
"autoprefixer": "^10.4.17",
|
"autoprefixer": "^10.4.17",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"date-fns": "^3.6.0",
|
"date-fns": "^3.6.0",
|
||||||
|
Loading…
Reference in New Issue
Block a user