mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-10-01 07:36:39 +08:00
Merge remote-tracking branch 'upstream/main' into dev
# Conflicts: # app/components/settings.tsx # app/components/ui-lib.module.scss # app/constant.ts # app/locales/ar.ts # app/locales/bn.ts # app/locales/cn.ts # app/locales/cs.ts # app/locales/de.ts # app/locales/en.ts # app/locales/es.ts # app/locales/fr.ts # app/locales/id.ts # app/locales/it.ts # app/locales/jp.ts # app/locales/ko.ts # app/locales/no.ts # app/locales/pt.ts # app/locales/ru.ts # app/locales/sk.ts # app/locales/tr.ts # app/locales/tw.ts # app/locales/vi.ts
This commit is contained in:
commit
c09aaf0f66
@ -12,15 +12,18 @@ One-Click to get a well-designed cross-platform ChatGPT web UI, with GPT3, GPT4
|
||||
|
||||
一键免费部署你的跨平台私人 ChatGPT 应用, 支持 GPT3, GPT4 & Gemini Pro 模型。
|
||||
|
||||
[![Saas][Saas-image]][saas-url]
|
||||
[![Web][Web-image]][web-url]
|
||||
[![Windows][Windows-image]][download-url]
|
||||
[![MacOS][MacOS-image]][download-url]
|
||||
[![Linux][Linux-image]][download-url]
|
||||
|
||||
[Web App](https://app.nextchat.dev/) / [Desktop App](https://github.com/Yidadaa/ChatGPT-Next-Web/releases) / [Discord](https://discord.gg/YCkeafCafC) / [Enterprise Edition](#enterprise-edition) / [Twitter](https://twitter.com/NextChatDev)
|
||||
[NextChatAI](https://nextchat.dev/chat) / [Web App](https://app.nextchat.dev) / [Desktop App](https://github.com/Yidadaa/ChatGPT-Next-Web/releases) / [Discord](https://discord.gg/YCkeafCafC) / [Enterprise Edition](#enterprise-edition) / [Twitter](https://twitter.com/NextChatDev)
|
||||
|
||||
[网页版](https://app.nextchat.dev/) / [客户端](https://github.com/Yidadaa/ChatGPT-Next-Web/releases) / [企业版](#%E4%BC%81%E4%B8%9A%E7%89%88) / [反馈](https://github.com/Yidadaa/ChatGPT-Next-Web/issues)
|
||||
[NextChatAI](https://nextchat.dev/chat) / [网页版](https://app.nextchat.dev) / [客户端](https://github.com/Yidadaa/ChatGPT-Next-Web/releases) / [企业版](#%E4%BC%81%E4%B8%9A%E7%89%88) / [反馈](https://github.com/Yidadaa/ChatGPT-Next-Web/issues)
|
||||
|
||||
[saas-url]: https://nextchat.dev/chat
|
||||
[saas-image]: https://img.shields.io/badge/NextChat-Saas-green?logo=microsoftedge
|
||||
[web-url]: https://app.nextchat.dev/
|
||||
[download-url]: https://github.com/Yidadaa/ChatGPT-Next-Web/releases
|
||||
[Web-image]: https://img.shields.io/badge/Web-PWA-orange?logo=microsoftedge
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
一键免费部署你的私人 ChatGPT 网页应用,支持 GPT3, GPT4 & Gemini Pro 模型。
|
||||
|
||||
[企业版](#%E4%BC%81%E4%B8%9A%E7%89%88) /[演示 Demo](https://chat-gpt-next-web.vercel.app/) / [反馈 Issues](https://github.com/Yidadaa/ChatGPT-Next-Web/issues) / [加入 Discord](https://discord.gg/zrhvHCr79N)
|
||||
[NextChatAI](https://nextchat.dev/chat) / [企业版](#%E4%BC%81%E4%B8%9A%E7%89%88) / [演示 Demo](https://chat-gpt-next-web.vercel.app/) / [反馈 Issues](https://github.com/Yidadaa/ChatGPT-Next-Web/issues) / [加入 Discord](https://discord.gg/zrhvHCr79N)
|
||||
|
||||
[<img src="https://vercel.com/button" alt="Deploy on Zeabur" height="30">](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FChatGPTNextWeb%2FChatGPT-Next-Web&env=OPENAI_API_KEY&env=CODE&project-name=nextchat&repository-name=NextChat) [<img src="https://zeabur.com/button.svg" alt="Deploy on Zeabur" height="30">](https://zeabur.com/templates/ZBUEFA) [<img src="https://gitpod.io/button/open-in-gitpod.svg" alt="Open in Gitpod" height="30">](https://gitpod.io/#https://github.com/Yidadaa/ChatGPT-Next-Web)
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
ワンクリックで無料であなた専用の ChatGPT ウェブアプリをデプロイ。GPT3、GPT4 & Gemini Pro モデルをサポート。
|
||||
|
||||
[企業版](#企業版) / [デモ](https://chat-gpt-next-web.vercel.app/) / [フィードバック](https://github.com/Yidadaa/ChatGPT-Next-Web/issues) / [Discordに参加](https://discord.gg/zrhvHCr79N)
|
||||
[NextChatAI](https://nextchat.dev/chat) / [企業版](#企業版) / [デモ](https://chat-gpt-next-web.vercel.app/) / [フィードバック](https://github.com/Yidadaa/ChatGPT-Next-Web/issues) / [Discordに参加](https://discord.gg/zrhvHCr79N)
|
||||
|
||||
[<img src="https://vercel.com/button" alt="Zeaburでデプロイ" height="30">](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FChatGPTNextWeb%2FChatGPT-Next-Web&env=OPENAI_API_KEY&env=CODE&project-name=nextchat&repository-name=NextChat) [<img src="https://zeabur.com/button.svg" alt="Zeaburでデプロイ" height="30">](https://zeabur.com/templates/ZBUEFA) [<img src="https://gitpod.io/button/open-in-gitpod.svg" alt="Gitpodで開く" height="30">](https://gitpod.io/#https://github.com/Yidadaa/ChatGPT-Next-Web)
|
||||
|
||||
|
@ -1,12 +1,70 @@
|
||||
.auth-page {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
.top-banner {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 12px 64px;
|
||||
box-sizing: border-box;
|
||||
background: var(--second);
|
||||
.top-banner-inner {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
line-height: 150%;
|
||||
span {
|
||||
gap: 8px;
|
||||
a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
margin-left: 8px;
|
||||
color: var(--primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
.top-banner-close {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 48px;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.top-banner {
|
||||
padding: 12px 24px 12px 12px;
|
||||
.top-banner-close {
|
||||
right: 10px;
|
||||
}
|
||||
.top-banner-inner {
|
||||
.top-banner-logo {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.auth-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
animation: slide-in-from-top ease 0.3s;
|
||||
}
|
||||
|
||||
.auth-logo {
|
||||
margin-top: 10vh;
|
||||
transform: scale(1.4);
|
||||
}
|
||||
|
||||
@ -14,6 +72,7 @@
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
line-height: 2;
|
||||
margin-bottom: 1vh;
|
||||
}
|
||||
|
||||
.auth-tips {
|
||||
@ -24,6 +83,10 @@
|
||||
margin: 3vh 0;
|
||||
}
|
||||
|
||||
.auth-input-second {
|
||||
margin: 0 0 3vh 0;
|
||||
}
|
||||
|
||||
.auth-actions {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
@ -1,21 +1,34 @@
|
||||
import styles from "./auth.module.scss";
|
||||
import { IconButton } from "./button";
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Path } from "../constant";
|
||||
import { Path, SAAS_CHAT_URL } from "../constant";
|
||||
import { useAccessStore } from "../store";
|
||||
import Locale from "../locales";
|
||||
|
||||
import Delete from "../icons/close.svg";
|
||||
import Arrow from "../icons/arrow.svg";
|
||||
import Logo from "../icons/logo.svg";
|
||||
import { useMobileScreen } from "@/app/utils";
|
||||
import BotIcon from "../icons/bot.svg";
|
||||
import { useEffect } from "react";
|
||||
import { getClientConfig } from "../config/client";
|
||||
import LeftIcon from "@/app/icons/left.svg";
|
||||
import { safeLocalStorage } from "@/app/utils";
|
||||
import {
|
||||
trackSettingsPageGuideToCPaymentClick,
|
||||
trackAuthorizationPageButtonToCPaymentClick,
|
||||
} from "../utils/auth-settings-events";
|
||||
const storage = safeLocalStorage();
|
||||
|
||||
export function AuthPage() {
|
||||
const navigate = useNavigate();
|
||||
const accessStore = useAccessStore();
|
||||
|
||||
const goHome = () => navigate(Path.Home);
|
||||
const goChat = () => navigate(Path.Chat);
|
||||
const goSaas = () => {
|
||||
trackAuthorizationPageButtonToCPaymentClick();
|
||||
window.location.href = SAAS_CHAT_URL;
|
||||
};
|
||||
|
||||
const resetAccessCode = () => {
|
||||
accessStore.update((access) => {
|
||||
access.openaiApiKey = "";
|
||||
@ -32,6 +45,14 @@ export function AuthPage() {
|
||||
|
||||
return (
|
||||
<div className={styles["auth-page"]}>
|
||||
<TopBanner></TopBanner>
|
||||
<div className={styles["auth-header"]}>
|
||||
<IconButton
|
||||
icon={<LeftIcon />}
|
||||
text={Locale.Auth.Return}
|
||||
onClick={() => navigate(Path.Home)}
|
||||
></IconButton>
|
||||
</div>
|
||||
<div className={`no-dark ${styles["auth-logo"]}`}>
|
||||
<BotIcon />
|
||||
</div>
|
||||
@ -65,7 +86,7 @@ export function AuthPage() {
|
||||
}}
|
||||
/>
|
||||
<input
|
||||
className={styles["auth-input"]}
|
||||
className={styles["auth-input-second"]}
|
||||
type="password"
|
||||
placeholder={Locale.Settings.Access.Google.ApiKey.Placeholder}
|
||||
value={accessStore.googleApiKey}
|
||||
@ -85,13 +106,74 @@ export function AuthPage() {
|
||||
onClick={goChat}
|
||||
/>
|
||||
<IconButton
|
||||
text={Locale.Auth.Later}
|
||||
text={Locale.Auth.SaasTips}
|
||||
onClick={() => {
|
||||
resetAccessCode();
|
||||
goHome();
|
||||
goSaas();
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function TopBanner() {
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
const [isVisible, setIsVisible] = useState(true);
|
||||
const isMobile = useMobileScreen();
|
||||
useEffect(() => {
|
||||
// 检查 localStorage 中是否有标记
|
||||
const bannerDismissed = storage.getItem("bannerDismissed");
|
||||
// 如果标记不存在,存储默认值并显示横幅
|
||||
if (!bannerDismissed) {
|
||||
storage.setItem("bannerDismissed", "false");
|
||||
setIsVisible(true); // 显示横幅
|
||||
} else if (bannerDismissed === "true") {
|
||||
// 如果标记为 "true",则隐藏横幅
|
||||
setIsVisible(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleMouseEnter = () => {
|
||||
setIsHovered(true);
|
||||
};
|
||||
|
||||
const handleMouseLeave = () => {
|
||||
setIsHovered(false);
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setIsVisible(false);
|
||||
storage.setItem("bannerDismissed", "true");
|
||||
};
|
||||
|
||||
if (!isVisible) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<div
|
||||
className={styles["top-banner"]}
|
||||
onMouseEnter={handleMouseEnter}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
>
|
||||
<div className={`${styles["top-banner-inner"]} no-dark`}>
|
||||
<Logo className={styles["top-banner-logo"]}></Logo>
|
||||
<span>
|
||||
{Locale.Auth.TopTips}
|
||||
<a
|
||||
href={SAAS_CHAT_URL}
|
||||
rel="stylesheet"
|
||||
onClick={() => {
|
||||
trackSettingsPageGuideToCPaymentClick();
|
||||
}}
|
||||
>
|
||||
{Locale.Settings.Access.SaasStart.ChatNow}
|
||||
<Arrow style={{ marginLeft: "4px" }} />
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
{(isHovered || isMobile) && (
|
||||
<Delete className={styles["top-banner-close"]} onClick={handleClose} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -5,7 +5,6 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px;
|
||||
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
overflow: hidden;
|
||||
|
@ -21,6 +21,7 @@ import {
|
||||
} from "./artifacts";
|
||||
import { useChatStore } from "../store";
|
||||
import { IconButton } from "./button";
|
||||
|
||||
import { useAppConfig } from "../store/config";
|
||||
|
||||
export function Mermaid(props: { code: string }) {
|
||||
|
7
app/components/model-config.module.scss
Normal file
7
app/components/model-config.module.scss
Normal file
@ -0,0 +1,7 @@
|
||||
.select-compress-model {
|
||||
width: 60%;
|
||||
select {
|
||||
max-width: 100%;
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ import { InputRange } from "./input-range";
|
||||
import { ListItem, Select } from "./ui-lib";
|
||||
import { useAllModels } from "../utils/hooks";
|
||||
import { groupBy } from "lodash-es";
|
||||
import styles from "./model-config.module.scss";
|
||||
|
||||
export function ModelConfigList(props: {
|
||||
modelConfig: ModelConfig;
|
||||
@ -242,6 +243,7 @@ export function ModelConfigList(props: {
|
||||
subTitle={Locale.Settings.CompressModel.SubTitle}
|
||||
>
|
||||
<Select
|
||||
className={styles["select-compress-model"]}
|
||||
aria-label={Locale.Settings.CompressModel.Title}
|
||||
value={compressModelValue}
|
||||
onChange={(e) => {
|
||||
|
@ -72,3 +72,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.subtitle-button {
|
||||
button {
|
||||
overflow:visible ;
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import CopyIcon from "../icons/copy.svg";
|
||||
import ClearIcon from "../icons/clear.svg";
|
||||
import LoadingIcon from "../icons/three-dots.svg";
|
||||
import EditIcon from "../icons/edit.svg";
|
||||
import FireIcon from "../icons/fire.svg";
|
||||
import EyeIcon from "../icons/eye.svg";
|
||||
import DownloadIcon from "../icons/download.svg";
|
||||
import UploadIcon from "../icons/upload.svg";
|
||||
@ -16,7 +17,7 @@ import ConfirmIcon from "../icons/confirm.svg";
|
||||
import ConnectionIcon from "../icons/connection.svg";
|
||||
import CloudSuccessIcon from "../icons/cloud-success.svg";
|
||||
import CloudFailIcon from "../icons/cloud-fail.svg";
|
||||
|
||||
import { trackSettingsPageGuideToCPaymentClick } from "../utils/auth-settings-events";
|
||||
import {
|
||||
Input,
|
||||
List,
|
||||
@ -63,6 +64,7 @@ import {
|
||||
UPDATE_URL,
|
||||
Stability,
|
||||
Iflytek,
|
||||
SAAS_CHAT_URL,
|
||||
} from "../constant";
|
||||
import { Prompt, SearchService, usePromptStore } from "../store/prompt";
|
||||
import { ErrorBoundary } from "./error";
|
||||
@ -680,6 +682,31 @@ export function Settings() {
|
||||
</ListItem>
|
||||
);
|
||||
|
||||
const saasStartComponent = (
|
||||
<ListItem
|
||||
className={styles["subtitle-button"]}
|
||||
title={
|
||||
Locale.Settings.Access.SaasStart.Title +
|
||||
`${Locale.Settings.Access.SaasStart.Label}`
|
||||
}
|
||||
subTitle={Locale.Settings.Access.SaasStart.SubTitle}
|
||||
>
|
||||
<IconButton
|
||||
aria={
|
||||
Locale.Settings.Access.SaasStart.Title +
|
||||
Locale.Settings.Access.SaasStart.ChatNow
|
||||
}
|
||||
icon={<FireIcon />}
|
||||
type={"primary"}
|
||||
text={Locale.Settings.Access.SaasStart.ChatNow}
|
||||
onClick={() => {
|
||||
trackSettingsPageGuideToCPaymentClick();
|
||||
window.location.href = SAAS_CHAT_URL;
|
||||
}}
|
||||
/>
|
||||
</ListItem>
|
||||
);
|
||||
|
||||
const useCustomConfigComponent = // Conditionally render the following ListItem based on clientConfig.isApp
|
||||
!clientConfig?.isApp && ( // only show if isApp is false
|
||||
<ListItem
|
||||
@ -1552,6 +1579,7 @@ export function Settings() {
|
||||
</List>
|
||||
|
||||
{/*<List id={SlotID.CustomModel}>*/}
|
||||
{/* {saasStartComponent}*/}
|
||||
{/* {accessCodeComponent}*/}
|
||||
|
||||
{/* {!accessStore.hideUserApiKey && (*/}
|
||||
|
@ -62,14 +62,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.vertical{
|
||||
&.vertical {
|
||||
flex-direction: column;
|
||||
align-items: start;
|
||||
.list-header{
|
||||
.list-item-title{
|
||||
.list-header {
|
||||
.list-item-title {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.list-item-sub-title{
|
||||
.list-item-sub-title {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
}
|
||||
@ -310,7 +310,7 @@
|
||||
justify-content: center;
|
||||
z-index: 999;
|
||||
|
||||
.selector-item-disabled{
|
||||
.selector-item-disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
|
@ -518,6 +518,9 @@ export const PLUGINS = [
|
||||
{ name: "Search Chat", path: Path.SearchChat },
|
||||
];
|
||||
|
||||
export const SAAS_CHAT_URL = "https://nextchat.dev/chat";
|
||||
export const SAAS_CHAT_UTM_URL = "https://nextchat.dev/chat?utm=github";
|
||||
|
||||
export const DISABLE_MODELS = DEFAULT_MODELS.filter(
|
||||
(item) => !item.available,
|
||||
).map((item2) => item2.name);
|
||||
|
1
app/icons/arrow.svg
Normal file
1
app/icons/arrow.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg class="icon--SJP_d" width="16" height="16" fill="none" viewBox="0 0 16 16" style="min-width: 16px; min-height: 16px;"><g><path data-follow-fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M5.248 14.444a.625.625 0 0 1-.005-.884l5.068-5.12a.625.625 0 0 0 0-.88L5.243 2.44a.625.625 0 1 1 .889-.88l5.067 5.121c.723.73.723 1.907 0 2.638l-5.067 5.12a.625.625 0 0 1-.884.005Z" fill="currentColor"></path></g></svg>
|
After Width: | Height: | Size: 426 B |
1
app/icons/fire.svg
Normal file
1
app/icons/fire.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M12.832 21.801c3.126-.626 7.168-2.875 7.168-8.69c0-5.291-3.873-8.815-6.658-10.434c-.619-.36-1.342.113-1.342.828v1.828c0 1.442-.606 4.074-2.29 5.169c-.86.559-1.79-.278-1.894-1.298l-.086-.838c-.1-.974-1.092-1.565-1.87-.971C4.461 8.46 3 10.33 3 13.11C3 20.221 8.289 22 10.933 22q.232 0 .484-.015C10.111 21.874 8 21.064 8 18.444c0-2.05 1.495-3.435 2.631-4.11c.306-.18.663.055.663.41v.59c0 .45.175 1.155.59 1.637c.47.546 1.159-.026 1.214-.744c.018-.226.246-.37.442-.256c.641.375 1.46 1.175 1.46 2.473c0 2.048-1.129 2.99-2.168 3.357"/></svg>
|
After Width: | Height: | Size: 648 B |
19
app/icons/logo.svg
Normal file
19
app/icons/logo.svg
Normal file
@ -0,0 +1,19 @@
|
||||
<svg width="38.73" height="42" viewBox="0 0 221 240" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="160.697" y="38.125" width="65.007" height="145.932" rx="32.503" transform="rotate(21.987 160.697 38.125)" fill="url(#logo_svg__a)"></rect>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="m48.642 79.125-25.92 71.213c-6.139 16.869 2.558 35.52 19.427 41.66 16.868 6.14 35.52-2.558 41.66-19.426L94.23 143.94l-36.658-37.439a32.42 32.42 0 0 1-9.244-23.497c.033-1.326.14-2.62.314-3.879Z" fill="url(#logo_svg__b)"></path>
|
||||
<path d="M172.578 132.787a32.765 32.765 0 0 1 8.981 24.238c-1.458 28.748-36.622 41.778-56.46 20.92l-67.644-71.122a32.763 32.763 0 0 1-8.981-24.238c1.457-28.748 36.622-41.778 56.46-20.92l67.644 71.122Z" fill="url(#logo_svg__c)" fill-opacity="0.96"></path>
|
||||
<defs>
|
||||
<linearGradient id="logo_svg__a" x1="215.063" y1="59.628" x2="160.714" y2="157.96" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#3EADFE"></stop>
|
||||
<stop offset="1" stop-color="#2A7AFF"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient id="logo_svg__b" x1="105.376" y1="84.416" x2="19.745" y2="131.163" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#01B3FF"></stop>
|
||||
<stop offset="1" stop-color="#59ECFA"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient id="logo_svg__c" x1="102.734" y1="136.396" x2="192.577" y2="155.859" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#023BFF" stop-opacity="0.82"></stop>
|
||||
<stop offset="0.88" stop-color="#2D86FF" stop-opacity="0.76"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
@ -1,5 +1,6 @@
|
||||
import { getClientConfig } from "../config/client";
|
||||
import { SubmitKey } from "../store/config";
|
||||
import { SAAS_CHAT_UTM_URL } from "@/app/constant";
|
||||
|
||||
const isApp = !!getClientConfig()?.isApp;
|
||||
|
||||
@ -7,18 +8,28 @@ const cn = {
|
||||
WIP: "该功能仍在开发中……",
|
||||
Error: {
|
||||
Unauthorized: isApp
|
||||
? "检测到无效 API Key,请前往[设置](/#/settings)页检查 API Key 是否配置正确。"
|
||||
: "访问密码不正确或为空,请前往[登录](/login)页输入正确的访问密码,或者在[设置](/#/settings)页填入你自己的 OpenAI API Key。",
|
||||
? `😆 对话遇到了一些问题,不用慌:
|
||||
\\ 1️⃣ 想要零配置开箱即用,[点击这里立刻开启对话 🚀](${SAAS_CHAT_UTM_URL})
|
||||
\\ 2️⃣ 如果你想消耗自己的 OpenAI 资源,点击[这里](/#/settings)修改设置 ⚙️`
|
||||
: `😆 对话遇到了一些问题,不用慌:
|
||||
\ 1️⃣ 想要零配置开箱即用,[点击这里立刻开启对话 🚀](${SAAS_CHAT_UTM_URL})
|
||||
\ 2️⃣ 如果你正在使用私有部署版本,点击[这里](/#/auth)输入访问秘钥 🔑
|
||||
\ 3️⃣ 如果你想消耗自己的 OpenAI 资源,点击[这里](/#/settings)修改设置 ⚙️
|
||||
`,
|
||||
NOT_FOUND_ERR: "404 not found. 页面有错误,可以尝试多刷新几次",
|
||||
BACKEND_ERR: "后端请求错误,更换 **模型** 试一下吧。",
|
||||
},
|
||||
Auth: {
|
||||
Return: "返回",
|
||||
Title: "需要密码",
|
||||
Tips: "管理员开启了密码验证,请在下方填入访问码",
|
||||
SubTips: "或者输入你的 OpenAI 或 Google API 密钥",
|
||||
SubTips: "或者输入你的 OpenAI 或 Google AI 密钥",
|
||||
Input: "在此处填写访问码",
|
||||
Confirm: "确认",
|
||||
Later: "稍后再说",
|
||||
SaasTips: "配置太麻烦,想要立即使用",
|
||||
TopTips:
|
||||
"🥳 NextChat AI 首发优惠,立刻解锁 OpenAI o1, GPT-4o, Claude-3.5 等最新大模型",
|
||||
},
|
||||
Midjourney: {
|
||||
SelectImgMax: (max: number) => `最多可选择 ${max} 张图片`,
|
||||
@ -342,6 +353,13 @@ const cn = {
|
||||
},
|
||||
|
||||
Access: {
|
||||
SaasStart: {
|
||||
Title: "使用 NextChat AI",
|
||||
Label: "(性价比最高的方案)",
|
||||
SubTitle:
|
||||
"由 NextChat 官方维护, 零配置开箱即用,支持 OpenAI o1, GPT-4o, Claude-3.5 等最新大模型",
|
||||
ChatNow: "立刻对话",
|
||||
},
|
||||
AccessCode: {
|
||||
Title: "访问密码",
|
||||
SubTitle: "管理员已开启加密访问",
|
||||
@ -405,7 +423,7 @@ const cn = {
|
||||
ApiKey: {
|
||||
Title: "API 密钥",
|
||||
SubTitle: "从 Google AI 获取您的 API 密钥",
|
||||
Placeholder: "输入您的 Google AI Studio API 密钥",
|
||||
Placeholder: "Google AI API KEY",
|
||||
},
|
||||
|
||||
Endpoint: {
|
||||
|
19
app/utils/auth-settings-events.ts
Normal file
19
app/utils/auth-settings-events.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { sendGAEvent } from "@next/third-parties/google";
|
||||
|
||||
export function trackConversationGuideToCPaymentClick() {
|
||||
sendGAEvent("event", "ConversationGuideToCPaymentClick", { value: 1 });
|
||||
}
|
||||
|
||||
export function trackAuthorizationPageButtonToCPaymentClick() {
|
||||
sendGAEvent("event", "AuthorizationPageButtonToCPaymentClick", { value: 1 });
|
||||
}
|
||||
|
||||
export function trackAuthorizationPageBannerToCPaymentClick() {
|
||||
sendGAEvent("event", "AuthorizationPageBannerToCPaymentClick", {
|
||||
value: 1,
|
||||
});
|
||||
}
|
||||
|
||||
export function trackSettingsPageGuideToCPaymentClick() {
|
||||
sendGAEvent("event", "SettingsPageGuideToCPaymentClick", { value: 1 });
|
||||
}
|
@ -9,7 +9,7 @@
|
||||
},
|
||||
"package": {
|
||||
"productName": "NextChat",
|
||||
"version": "2.15.2"
|
||||
"version": "2.15.3"
|
||||
},
|
||||
"tauri": {
|
||||
"allowlist": {
|
||||
|
Loading…
Reference in New Issue
Block a user