Compare commits
5 Commits
515527efd9
...
pro
| Author | SHA1 | Date | |
|---|---|---|---|
| 43c2e8ed39 | |||
| c66defa337 | |||
| dcf079db65 | |||
| 49fffe8cbe | |||
| 329b9c7c95 |
@@ -27,6 +27,26 @@
|
|||||||
fill: white !important;
|
fill: white !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.danger {
|
||||||
|
color: rgba($color: red, $alpha: 0.8);
|
||||||
|
border-color: rgba($color: red, $alpha: 0.5);
|
||||||
|
background-color: rgba($color: red, $alpha: 0.05);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: red;
|
||||||
|
background-color: rgba($color: red, $alpha: 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
path {
|
||||||
|
fill: red !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
border-color: var(--primary);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.shadow {
|
.shadow {
|
||||||
@@ -37,10 +57,6 @@
|
|||||||
border: var(--border-in-light);
|
border: var(--border-in-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-button:hover {
|
|
||||||
border-color: var(--primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-button-icon {
|
.icon-button-icon {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
@@ -56,9 +72,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.icon-button-text {
|
.icon-button-text {
|
||||||
margin-left: 5px;
|
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
|
&:not(:first-child) {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,16 +2,20 @@ import * as React from "react";
|
|||||||
|
|
||||||
import styles from "./button.module.scss";
|
import styles from "./button.module.scss";
|
||||||
|
|
||||||
|
export type ButtonType = "primary" | "danger" | null;
|
||||||
|
|
||||||
export function IconButton(props: {
|
export function IconButton(props: {
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
icon?: JSX.Element;
|
icon?: JSX.Element;
|
||||||
type?: "primary" | "danger";
|
type?: ButtonType;
|
||||||
text?: string;
|
text?: string;
|
||||||
bordered?: boolean;
|
bordered?: boolean;
|
||||||
shadow?: boolean;
|
shadow?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
tabIndex?: number;
|
||||||
|
autoFocus?: boolean;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
@@ -25,6 +29,8 @@ export function IconButton(props: {
|
|||||||
title={props.title}
|
title={props.title}
|
||||||
disabled={props.disabled}
|
disabled={props.disabled}
|
||||||
role="button"
|
role="button"
|
||||||
|
tabIndex={props.tabIndex}
|
||||||
|
autoFocus={props.autoFocus}
|
||||||
>
|
>
|
||||||
{props.icon && (
|
{props.icon && (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import { ModelType } from "../store";
|
|||||||
import BotIcon from "../icons/bot.svg";
|
import BotIcon from "../icons/bot.svg";
|
||||||
import BlackBotIcon from "../icons/black-bot.svg";
|
import BlackBotIcon from "../icons/black-bot.svg";
|
||||||
|
|
||||||
|
import Image from 'next/image';
|
||||||
|
|
||||||
export function getEmojiUrl(unified: string, style: EmojiStyle) {
|
export function getEmojiUrl(unified: string, style: EmojiStyle) {
|
||||||
return `https://cdn.staticfile.org/emoji-datasource-apple/14.0.0/img/${style}/64/${unified}.png`;
|
return `https://cdn.staticfile.org/emoji-datasource-apple/14.0.0/img/${style}/64/${unified}.png`;
|
||||||
}
|
}
|
||||||
@@ -29,6 +31,15 @@ export function AvatarPicker(props: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function Avatar(props: { model?: ModelType; avatar?: string }) {
|
export function Avatar(props: { model?: ModelType; avatar?: string }) {
|
||||||
|
const isSvg = (url: string) => {
|
||||||
|
return url.toLowerCase().endsWith('.svg');
|
||||||
|
};
|
||||||
|
|
||||||
|
const isRegularImage = (url: string) => {
|
||||||
|
const regex = /\.(jpe?g|png|gif)$/i;
|
||||||
|
return regex.test(url);
|
||||||
|
};
|
||||||
|
|
||||||
if (props.model) {
|
if (props.model) {
|
||||||
return (
|
return (
|
||||||
<div className="no-dark">
|
<div className="no-dark">
|
||||||
@@ -43,7 +54,25 @@ export function Avatar(props: { model?: ModelType; avatar?: string }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="user-avatar">
|
<div className="user-avatar">
|
||||||
{props.avatar && <EmojiAvatar avatar={props.avatar} />}
|
{props.avatar && isRegularImage(props.avatar) && (
|
||||||
|
<Image
|
||||||
|
src={props.avatar}
|
||||||
|
alt="User Avatar"
|
||||||
|
width={30}
|
||||||
|
height={30}
|
||||||
|
className="user-avatar"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{props.avatar && isSvg(props.avatar) && (
|
||||||
|
<img
|
||||||
|
src={props.avatar}
|
||||||
|
alt="User Avatar"
|
||||||
|
className="user-avatar"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{props.avatar && !isSvg(props.avatar) && !isRegularImage(props.avatar) && (
|
||||||
|
<EmojiAvatar avatar={props.avatar} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ import { Path, SlotID } from "../constant";
|
|||||||
import { ErrorBoundary } from "./error";
|
import { ErrorBoundary } from "./error";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
HashRouter as Router,
|
// HashRouter as Router,
|
||||||
|
BrowserRouter as Router,
|
||||||
Routes,
|
Routes,
|
||||||
Route,
|
Route,
|
||||||
useLocation,
|
useLocation,
|
||||||
@@ -35,9 +36,9 @@ export function Loading(props: { noLogo?: boolean }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// const Settings = dynamic(async () => (await import("./settings")).Settings, {
|
const Settings = dynamic(async () => (await import("./settings")).Settings, {
|
||||||
// loading: () => <Loading noLogo />,
|
loading: () => <Loading noLogo />,
|
||||||
// });
|
});
|
||||||
|
|
||||||
const Chat = dynamic(async () => (await import("./chat")).Chat, {
|
const Chat = dynamic(async () => (await import("./chat")).Chat, {
|
||||||
loading: () => <Loading noLogo />,
|
loading: () => <Loading noLogo />,
|
||||||
@@ -141,7 +142,7 @@ function Screen() {
|
|||||||
<Route path={Path.NewChat} element={<NewChat />} />
|
<Route path={Path.NewChat} element={<NewChat />} />
|
||||||
<Route path={Path.Masks} element={<MaskPage />} />
|
<Route path={Path.Masks} element={<MaskPage />} />
|
||||||
<Route path={Path.Chat} element={<Chat />} />
|
<Route path={Path.Chat} element={<Chat />} />
|
||||||
{/* <Route path={Path.Settings} element={<Settings />} /> */}
|
<Route path={Path.Settings} element={<Settings />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
.settings {
|
.settings {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
|
.logout-button {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
|
|||||||
@@ -1 +1,73 @@
|
|||||||
export {};
|
import { useEffect } from "react";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
|
import { IconButton } from "./button";
|
||||||
|
import { showConfirm } from "./ui-lib";
|
||||||
|
|
||||||
|
import Locale from "../locales";
|
||||||
|
import { Path } from "../constant";
|
||||||
|
import { ErrorBoundary } from "./error";
|
||||||
|
|
||||||
|
import styles from "./settings.module.scss";
|
||||||
|
|
||||||
|
import CloseIcon from "../icons/close.svg";
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
|
import { faRightFromBracket } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
||||||
|
export function Settings() {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const keydownEvent = (e: KeyboardEvent) => {
|
||||||
|
if (e.key === "Escape") {
|
||||||
|
navigate(Path.Home);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
document.addEventListener("keydown", keydownEvent);
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener("keydown", keydownEvent);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ErrorBoundary>
|
||||||
|
<div className="window-header">
|
||||||
|
<div className="window-header-title">
|
||||||
|
<div className="window-header-main-title">
|
||||||
|
{Locale.Settings.Title}
|
||||||
|
</div>
|
||||||
|
<div className="window-header-sub-title">
|
||||||
|
{Locale.Settings.SubTitle}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="window-actions">
|
||||||
|
<div className="window-action-button"></div>
|
||||||
|
<div className="window-action-button"></div>
|
||||||
|
<div className="window-action-button">
|
||||||
|
<IconButton
|
||||||
|
icon={<CloseIcon />}
|
||||||
|
onClick={() => navigate(Path.Home)}
|
||||||
|
bordered
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={styles["settings"]}>
|
||||||
|
<div className={styles["logout-button"]}>
|
||||||
|
<IconButton
|
||||||
|
icon={<FontAwesomeIcon icon={faRightFromBracket} />}
|
||||||
|
text={Locale.Settings.Danger.Logout.Action}
|
||||||
|
onClick={async () => {
|
||||||
|
if (await showConfirm(Locale.Settings.Danger.Logout.Confirm)) {
|
||||||
|
// navigate(Path.Logout);
|
||||||
|
window.location.href = '/logout';
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
type="danger"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</ErrorBoundary>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { useEffect, useRef } from "react";
|
|||||||
import styles from "./home.module.scss";
|
import styles from "./home.module.scss";
|
||||||
|
|
||||||
import { IconButton } from "./button";
|
import { IconButton } from "./button";
|
||||||
// import SettingsIcon from "../icons/settings.svg";
|
import SettingsIcon from "../icons/settings.svg";
|
||||||
// import GithubIcon from "../icons/github.svg";
|
// import GithubIcon from "../icons/github.svg";
|
||||||
import ChatGptIcon from "../icons/chatgpt.svg";
|
import ChatGptIcon from "../icons/chatgpt.svg";
|
||||||
import AddIcon from "../icons/add.svg";
|
import AddIcon from "../icons/add.svg";
|
||||||
@@ -168,15 +168,15 @@ export function SideBar(props: { className?: string }) {
|
|||||||
/> */}
|
/> */}
|
||||||
</div>
|
</div>
|
||||||
<div className={styles["sidebar-action"]}>
|
<div className={styles["sidebar-action"]}>
|
||||||
{/* <Link to={Path.Settings}>
|
<Link to={Path.Settings}>
|
||||||
<IconButton icon={<SettingsIcon />} shadow />
|
<IconButton icon={<SettingsIcon />} shadow />
|
||||||
</Link> */}
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles["sidebar-action"]}>
|
{/* <div className={styles["sidebar-action"]}>
|
||||||
{/* <a href={REPO_URL} target="_blank">
|
<a href={REPO_URL} target="_blank">
|
||||||
<IconButton icon={<GithubIcon />} shadow />
|
<IconButton icon={<GithubIcon />} shadow />
|
||||||
</a> */}
|
</a>
|
||||||
</div>
|
</div> */}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
|||||||
@@ -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 {
|
||||||
@@ -72,11 +73,26 @@
|
|||||||
box-shadow: var(--card-shadow);
|
box-shadow: var(--card-shadow);
|
||||||
background-color: var(--white);
|
background-color: var(--white);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
width: 60vw;
|
width: 80vw;
|
||||||
|
max-width: 900px;
|
||||||
|
min-width: 300px;
|
||||||
animation: slide-in ease 0.3s;
|
animation: slide-in ease 0.3s;
|
||||||
|
|
||||||
--modal-padding: 20px;
|
--modal-padding: 20px;
|
||||||
|
|
||||||
|
&-max {
|
||||||
|
width: 95vw;
|
||||||
|
max-width: unset;
|
||||||
|
height: 95vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
max-height: unset !important;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.modal-header {
|
.modal-header {
|
||||||
padding: var(--modal-padding);
|
padding: var(--modal-padding);
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -89,11 +105,19 @@
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-close-btn {
|
.modal-header-actions {
|
||||||
cursor: pointer;
|
display: flex;
|
||||||
|
|
||||||
&:hover {
|
.modal-header-action {
|
||||||
filter: brightness(1.2);
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:not(:last-child) {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
filter: brightness(1.2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -207,7 +231,7 @@
|
|||||||
.select-with-icon {
|
.select-with-icon {
|
||||||
position: relative;
|
position: relative;
|
||||||
max-width: fit-content;
|
max-width: fit-content;
|
||||||
|
|
||||||
.select-with-icon-select {
|
.select-with-icon-select {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border: var(--border-in-light);
|
border: var(--border-in-light);
|
||||||
@@ -227,4 +251,57 @@
|
|||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal-input {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: var(--border-in-light);
|
||||||
|
box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.03);
|
||||||
|
background-color: var(--white);
|
||||||
|
color: var(--black);
|
||||||
|
font-family: inherit;
|
||||||
|
padding: 10px;
|
||||||
|
resize: none;
|
||||||
|
outline: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
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;
|
||||||
|
z-index: 999;
|
||||||
|
|
||||||
|
&-content {
|
||||||
|
.list {
|
||||||
|
max-height: 90vh;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
.list-item {
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: var(--white);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
filter: brightness(0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
filter: brightness(0.9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,11 @@ import EyeIcon from "../icons/eye.svg";
|
|||||||
import EyeOffIcon from "../icons/eye-off.svg";
|
import EyeOffIcon from "../icons/eye-off.svg";
|
||||||
import DownIcon from "../icons/down.svg";
|
import DownIcon from "../icons/down.svg";
|
||||||
|
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
|
import { faCheck, faBan } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
||||||
|
import Locale from "../locales";
|
||||||
|
|
||||||
import { createRoot } from "react-dom/client";
|
import { createRoot } from "react-dom/client";
|
||||||
import React, { HTMLProps, useEffect, useState } from "react";
|
import React, { HTMLProps, useEffect, useState } from "react";
|
||||||
import { IconButton } from "./button";
|
import { IconButton } from "./button";
|
||||||
@@ -262,3 +267,56 @@ export function Select(
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function showConfirm(content: any) {
|
||||||
|
const div = document.createElement("div");
|
||||||
|
div.className = "modal-mask";
|
||||||
|
document.body.appendChild(div);
|
||||||
|
|
||||||
|
const root = createRoot(div);
|
||||||
|
const closeModal = () => {
|
||||||
|
root.unmount();
|
||||||
|
div.remove();
|
||||||
|
};
|
||||||
|
|
||||||
|
return new Promise<boolean>((resolve) => {
|
||||||
|
root.render(
|
||||||
|
<Modal
|
||||||
|
title={Locale.UI.Confirm}
|
||||||
|
actions={[
|
||||||
|
<IconButton
|
||||||
|
key="cancel"
|
||||||
|
text={Locale.UI.Cancel}
|
||||||
|
onClick={() => {
|
||||||
|
resolve(false);
|
||||||
|
closeModal();
|
||||||
|
}}
|
||||||
|
// icon={<CancelIcon />}
|
||||||
|
icon={<FontAwesomeIcon icon={faBan} />}
|
||||||
|
tabIndex={0}
|
||||||
|
bordered
|
||||||
|
shadow
|
||||||
|
></IconButton>,
|
||||||
|
<IconButton
|
||||||
|
key="confirm"
|
||||||
|
text={Locale.UI.Confirm}
|
||||||
|
type="primary"
|
||||||
|
onClick={() => {
|
||||||
|
resolve(true);
|
||||||
|
closeModal();
|
||||||
|
}}
|
||||||
|
// icon={<ConfirmIcon />}
|
||||||
|
icon={<FontAwesomeIcon icon={faCheck} />}
|
||||||
|
tabIndex={0}
|
||||||
|
autoFocus
|
||||||
|
bordered
|
||||||
|
shadow
|
||||||
|
></IconButton>,
|
||||||
|
]}
|
||||||
|
onClose={closeModal}
|
||||||
|
>
|
||||||
|
{content}
|
||||||
|
</Modal>,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ export enum Path {
|
|||||||
NewChat = "/new-chat",
|
NewChat = "/new-chat",
|
||||||
Masks = "/masks",
|
Masks = "/masks",
|
||||||
Auth = "/auth",
|
Auth = "/auth",
|
||||||
|
Logout = "/logout",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum SlotID {
|
export enum SlotID {
|
||||||
|
|||||||
+8
-2
@@ -36,7 +36,7 @@ const cn = {
|
|||||||
dark: "深色模式",
|
dark: "深色模式",
|
||||||
},
|
},
|
||||||
Prompt: "快捷指令",
|
Prompt: "快捷指令",
|
||||||
Masks: "所有面具",
|
Masks: "所有角色",
|
||||||
Clear: "清除聊天",
|
Clear: "清除聊天",
|
||||||
Settings: "对话设置",
|
Settings: "对话设置",
|
||||||
AIPaint: "AI绘画",
|
AIPaint: "AI绘画",
|
||||||
@@ -198,6 +198,12 @@ const cn = {
|
|||||||
Title: "话题新鲜度 (presence_penalty)",
|
Title: "话题新鲜度 (presence_penalty)",
|
||||||
SubTitle: "值越大,越有可能扩展到新话题",
|
SubTitle: "值越大,越有可能扩展到新话题",
|
||||||
},
|
},
|
||||||
|
Danger: {
|
||||||
|
Logout: {
|
||||||
|
Action: "退出登录",
|
||||||
|
Confirm: "确定要退出登录吗?",
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Store: {
|
Store: {
|
||||||
DefaultTopic: "新的聊天",
|
DefaultTopic: "新的聊天",
|
||||||
@@ -266,7 +272,7 @@ const cn = {
|
|||||||
Skip: "直接开始",
|
Skip: "直接开始",
|
||||||
NotShow: "不再展示",
|
NotShow: "不再展示",
|
||||||
ConfirmNoShow: "确认禁用?禁用后可以随时在设置中重新启用。",
|
ConfirmNoShow: "确认禁用?禁用后可以随时在设置中重新启用。",
|
||||||
Title: "挑选一个面具",
|
Title: "挑选一个角色",
|
||||||
SubTitle: "现在开始,与面具背后的灵魂思维碰撞",
|
SubTitle: "现在开始,与面具背后的灵魂思维碰撞",
|
||||||
More: "查看全部",
|
More: "查看全部",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -200,6 +200,12 @@ const en: RequiredLocaleType = {
|
|||||||
SubTitle:
|
SubTitle:
|
||||||
"A larger value increases the likelihood to talk about new topics",
|
"A larger value increases the likelihood to talk about new topics",
|
||||||
},
|
},
|
||||||
|
Danger: {
|
||||||
|
Logout: {
|
||||||
|
Action: "Log out",
|
||||||
|
Confirm: "Are you sure you want to log out?",
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Store: {
|
Store: {
|
||||||
DefaultTopic: "New Conversation",
|
DefaultTopic: "New Conversation",
|
||||||
|
|||||||
+34
-1
@@ -1,6 +1,39 @@
|
|||||||
import { BuiltinMask } from "./typing";
|
import { BuiltinMask } from "./typing";
|
||||||
|
|
||||||
export const CN_MASKS: BuiltinMask[] = [];
|
export const CN_MASKS: BuiltinMask[] = [
|
||||||
|
{
|
||||||
|
avatar: "/avatar/chatgpt.png",
|
||||||
|
name: "gpt3.5",
|
||||||
|
context: [],
|
||||||
|
modelConfig: {
|
||||||
|
model: "gpt-3.5-turbo",
|
||||||
|
temperature: 0.5,
|
||||||
|
max_tokens: 2000,
|
||||||
|
presence_penalty: 0,
|
||||||
|
sendMemory: true,
|
||||||
|
historyMessageCount: 64,
|
||||||
|
compressMessageLengthThreshold: 2000,
|
||||||
|
},
|
||||||
|
lang: "cn",
|
||||||
|
builtin: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
avatar: "/avatar/chatgpt4.png",
|
||||||
|
name: "gpt4",
|
||||||
|
context: [],
|
||||||
|
modelConfig: {
|
||||||
|
model: "gpt-4",
|
||||||
|
temperature: 0.5,
|
||||||
|
max_tokens: 2000,
|
||||||
|
presence_penalty: 0,
|
||||||
|
sendMemory: true,
|
||||||
|
historyMessageCount: 32,
|
||||||
|
compressMessageLengthThreshold: 500,
|
||||||
|
},
|
||||||
|
lang: "cn",
|
||||||
|
builtin: true,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
// export const CN_MASKS: BuiltinMask[] = [
|
// export const CN_MASKS: BuiltinMask[] = [
|
||||||
// {
|
// {
|
||||||
|
|||||||
+34
-1
@@ -1,6 +1,39 @@
|
|||||||
import { BuiltinMask } from "./typing";
|
import { BuiltinMask } from "./typing";
|
||||||
|
|
||||||
export const EN_MASKS: BuiltinMask[] = [];
|
export const EN_MASKS: BuiltinMask[] = [
|
||||||
|
{
|
||||||
|
avatar: "/avatar/chatgpt.png",
|
||||||
|
name: "gpt3.5",
|
||||||
|
context: [],
|
||||||
|
modelConfig: {
|
||||||
|
model: "gpt-3.5-turbo",
|
||||||
|
temperature: 0.5,
|
||||||
|
max_tokens: 2000,
|
||||||
|
presence_penalty: 0,
|
||||||
|
sendMemory: true,
|
||||||
|
historyMessageCount: 64,
|
||||||
|
compressMessageLengthThreshold: 2000,
|
||||||
|
},
|
||||||
|
lang: "en",
|
||||||
|
builtin: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
avatar: "/avatar/chatgpt4.png",
|
||||||
|
name: "gpt4",
|
||||||
|
context: [],
|
||||||
|
modelConfig: {
|
||||||
|
model: "gpt-4",
|
||||||
|
temperature: 0.5,
|
||||||
|
max_tokens: 2000,
|
||||||
|
presence_penalty: 0,
|
||||||
|
sendMemory: true,
|
||||||
|
historyMessageCount: 32,
|
||||||
|
compressMessageLengthThreshold: 500,
|
||||||
|
},
|
||||||
|
lang: "en",
|
||||||
|
builtin: true,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
// export const EN_MASKS: BuiltinMask[] = [
|
// export const EN_MASKS: BuiltinMask[] = [
|
||||||
// {
|
// {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
# docker compose -f docker-compose.prod.yml up --build -d
|
||||||
version: '3'
|
version: '3'
|
||||||
services:
|
services:
|
||||||
prod:
|
prod:
|
||||||
@@ -11,5 +12,5 @@ services:
|
|||||||
- OPENAI_API_KEY=$OPENAI_API_KEY
|
- OPENAI_API_KEY=$OPENAI_API_KEY
|
||||||
- BASE_URL=$BASE_URL
|
- BASE_URL=$BASE_URL
|
||||||
ports:
|
ports:
|
||||||
- 8038:3000
|
- 127.0.0.1:8038:3000
|
||||||
command: /run-app.sh
|
command: /run-app.sh
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "chatgpt-pro",
|
"name": "chatgpt-pro",
|
||||||
"version": "1.2",
|
"version": "1.5",
|
||||||
"private": false,
|
"private": false,
|
||||||
"license": "CC-BY-NC-SA-4.0",
|
"license": "CC-BY-NC-SA-4.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 5.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.5 KiB |
Reference in New Issue
Block a user