mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-10-08 19:16:37 +08:00
Merge branch 'main' of https://github.com/Yidadaa/ChatGPT-Next-Web
This commit is contained in:
commit
37f2cc1424
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<h1 align="center">ChatGPT Next Web</h1>
|
<h1 align="center">ChatGPT Next Web</h1>
|
||||||
|
|
||||||
One-Click to deploy your own ChatGPT web UI.
|
One-Click to deploy well-designed ChatGPT web UI on Vercel.
|
||||||
|
|
||||||
一键免费部署你的私人 ChatGPT 网页应用。
|
一键免费部署你的私人 ChatGPT 网页应用。
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ async function makeRequest(req: NextRequest) {
|
|||||||
const api = await requestOpenai(req);
|
const api = await requestOpenai(req);
|
||||||
const res = new NextResponse(api.body);
|
const res = new NextResponse(api.body);
|
||||||
res.headers.set("Content-Type", "application/json");
|
res.headers.set("Content-Type", "application/json");
|
||||||
|
res.headers.set("Cache-Control", "no-cache");
|
||||||
return res;
|
return res;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("[OpenAI] ", req.body, e);
|
console.error("[OpenAI] ", req.body, e);
|
||||||
@ -16,7 +17,7 @@ async function makeRequest(req: NextRequest) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
status: 500,
|
status: 500,
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
7
app/components/input-range.module.scss
Normal file
7
app/components/input-range.module.scss
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
.input-range {
|
||||||
|
border: var(--border-in-light);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 5px 15px 5px 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
display: flex;
|
||||||
|
}
|
37
app/components/input-range.tsx
Normal file
37
app/components/input-range.tsx
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import styles from "./input-range.module.scss";
|
||||||
|
|
||||||
|
interface InputRangeProps {
|
||||||
|
onChange: React.ChangeEventHandler<HTMLInputElement>;
|
||||||
|
title?: string;
|
||||||
|
value: number | string;
|
||||||
|
className?: string;
|
||||||
|
min: string;
|
||||||
|
max: string;
|
||||||
|
step: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function InputRange({
|
||||||
|
onChange,
|
||||||
|
title,
|
||||||
|
value,
|
||||||
|
className,
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
step,
|
||||||
|
}: InputRangeProps) {
|
||||||
|
return (
|
||||||
|
<div className={styles["input-range"] + ` ${className ?? ""}`}>
|
||||||
|
{title || value}
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
title={title}
|
||||||
|
value={value}
|
||||||
|
min={min}
|
||||||
|
max={max}
|
||||||
|
step={step}
|
||||||
|
onChange={onChange}
|
||||||
|
></input>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -32,6 +32,7 @@ import { UPDATE_URL } from "../constant";
|
|||||||
import { SearchService, usePromptStore } from "../store/prompt";
|
import { SearchService, usePromptStore } from "../store/prompt";
|
||||||
import { requestUsage } from "../requests";
|
import { requestUsage } from "../requests";
|
||||||
import { ErrorBoundary } from "./error";
|
import { ErrorBoundary } from "./error";
|
||||||
|
import { InputRange } from "./input-range";
|
||||||
|
|
||||||
function SettingItem(props: {
|
function SettingItem(props: {
|
||||||
title: string;
|
title: string;
|
||||||
@ -274,8 +275,7 @@ export function Settings(props: { closeSettings: () => void }) {
|
|||||||
title={Locale.Settings.FontSize.Title}
|
title={Locale.Settings.FontSize.Title}
|
||||||
subTitle={Locale.Settings.FontSize.SubTitle}
|
subTitle={Locale.Settings.FontSize.SubTitle}
|
||||||
>
|
>
|
||||||
<input
|
<InputRange
|
||||||
type="range"
|
|
||||||
title={`${config.fontSize ?? 14}px`}
|
title={`${config.fontSize ?? 14}px`}
|
||||||
value={config.fontSize}
|
value={config.fontSize}
|
||||||
min="12"
|
min="12"
|
||||||
@ -287,7 +287,7 @@ export function Settings(props: { closeSettings: () => void }) {
|
|||||||
(config.fontSize = Number.parseInt(e.currentTarget.value)),
|
(config.fontSize = Number.parseInt(e.currentTarget.value)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
></input>
|
></InputRange>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
|
|
||||||
<SettingItem title={Locale.Settings.TightBorder}>
|
<SettingItem title={Locale.Settings.TightBorder}>
|
||||||
@ -407,8 +407,7 @@ export function Settings(props: { closeSettings: () => void }) {
|
|||||||
title={Locale.Settings.HistoryCount.Title}
|
title={Locale.Settings.HistoryCount.Title}
|
||||||
subTitle={Locale.Settings.HistoryCount.SubTitle}
|
subTitle={Locale.Settings.HistoryCount.SubTitle}
|
||||||
>
|
>
|
||||||
<input
|
<InputRange
|
||||||
type="range"
|
|
||||||
title={config.historyMessageCount.toString()}
|
title={config.historyMessageCount.toString()}
|
||||||
value={config.historyMessageCount}
|
value={config.historyMessageCount}
|
||||||
min="0"
|
min="0"
|
||||||
@ -420,7 +419,7 @@ export function Settings(props: { closeSettings: () => void }) {
|
|||||||
(config.historyMessageCount = e.target.valueAsNumber),
|
(config.historyMessageCount = e.target.valueAsNumber),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
></input>
|
></InputRange>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
|
|
||||||
<SettingItem
|
<SettingItem
|
||||||
@ -467,8 +466,7 @@ export function Settings(props: { closeSettings: () => void }) {
|
|||||||
title={Locale.Settings.Temperature.Title}
|
title={Locale.Settings.Temperature.Title}
|
||||||
subTitle={Locale.Settings.Temperature.SubTitle}
|
subTitle={Locale.Settings.Temperature.SubTitle}
|
||||||
>
|
>
|
||||||
<input
|
<InputRange
|
||||||
type="range"
|
|
||||||
value={config.modelConfig.temperature?.toFixed(1)}
|
value={config.modelConfig.temperature?.toFixed(1)}
|
||||||
min="0"
|
min="0"
|
||||||
max="2"
|
max="2"
|
||||||
@ -482,7 +480,7 @@ export function Settings(props: { closeSettings: () => void }) {
|
|||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
></input>
|
></InputRange>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
<SettingItem
|
<SettingItem
|
||||||
title={Locale.Settings.MaxTokens.Title}
|
title={Locale.Settings.MaxTokens.Title}
|
||||||
@ -508,8 +506,7 @@ export function Settings(props: { closeSettings: () => void }) {
|
|||||||
title={Locale.Settings.PresencePenlty.Title}
|
title={Locale.Settings.PresencePenlty.Title}
|
||||||
subTitle={Locale.Settings.PresencePenlty.SubTitle}
|
subTitle={Locale.Settings.PresencePenlty.SubTitle}
|
||||||
>
|
>
|
||||||
<input
|
<InputRange
|
||||||
type="range"
|
|
||||||
value={config.modelConfig.presence_penalty?.toFixed(1)}
|
value={config.modelConfig.presence_penalty?.toFixed(1)}
|
||||||
min="-2"
|
min="-2"
|
||||||
max="2"
|
max="2"
|
||||||
@ -523,7 +520,7 @@ export function Settings(props: { closeSettings: () => void }) {
|
|||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
></input>
|
></InputRange>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
</List>
|
</List>
|
||||||
</div>
|
</div>
|
||||||
|
@ -149,6 +149,7 @@
|
|||||||
background-color: var(--white);
|
background-color: var(--white);
|
||||||
color: var(--black);
|
color: var(--black);
|
||||||
resize: none;
|
resize: none;
|
||||||
|
min-width: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 600px) {
|
@media only screen and (max-width: 600px) {
|
||||||
@ -159,4 +160,4 @@
|
|||||||
max-height: 50vh;
|
max-height: 50vh;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -9,7 +9,7 @@ const makeRequestParam = (
|
|||||||
options?: {
|
options?: {
|
||||||
filterBot?: boolean;
|
filterBot?: boolean;
|
||||||
stream?: boolean;
|
stream?: boolean;
|
||||||
},
|
}
|
||||||
): ChatRequest => {
|
): ChatRequest => {
|
||||||
let sendMessages = messages.map((v) => ({
|
let sendMessages = messages.map((v) => ({
|
||||||
role: v.role,
|
role: v.role,
|
||||||
@ -46,11 +46,10 @@ function getHeaders() {
|
|||||||
|
|
||||||
export function requestOpenaiClient(path: string) {
|
export function requestOpenaiClient(path: string) {
|
||||||
return (body: any, method = "POST") =>
|
return (body: any, method = "POST") =>
|
||||||
fetch("/api/openai", {
|
fetch("/api/openai?_vercel_no_cache=1", {
|
||||||
method,
|
method,
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"Cache-Control": "no-cache",
|
|
||||||
path,
|
path,
|
||||||
...getHeaders(),
|
...getHeaders(),
|
||||||
},
|
},
|
||||||
@ -77,7 +76,7 @@ export async function requestUsage() {
|
|||||||
.getDate()
|
.getDate()
|
||||||
.toString()
|
.toString()
|
||||||
.padStart(2, "0")}`;
|
.padStart(2, "0")}`;
|
||||||
const ONE_DAY = 24 * 60 * 60 * 1000;
|
const ONE_DAY = 2 * 24 * 60 * 60 * 1000;
|
||||||
const now = new Date(Date.now() + ONE_DAY);
|
const now = new Date(Date.now() + ONE_DAY);
|
||||||
const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
|
const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
|
||||||
const startDate = formatDate(startOfMonth);
|
const startDate = formatDate(startOfMonth);
|
||||||
@ -85,7 +84,7 @@ export async function requestUsage() {
|
|||||||
|
|
||||||
const [used, subs] = await Promise.all([
|
const [used, subs] = await Promise.all([
|
||||||
requestOpenaiClient(
|
requestOpenaiClient(
|
||||||
`dashboard/billing/usage?start_date=${startDate}&end_date=${endDate}`,
|
`dashboard/billing/usage?start_date=${startDate}&end_date=${endDate}`
|
||||||
)(null, "GET"),
|
)(null, "GET"),
|
||||||
requestOpenaiClient("dashboard/billing/subscription")(null, "GET"),
|
requestOpenaiClient("dashboard/billing/subscription")(null, "GET"),
|
||||||
]);
|
]);
|
||||||
@ -125,7 +124,7 @@ export async function requestChatStream(
|
|||||||
onMessage: (message: string, done: boolean) => void;
|
onMessage: (message: string, done: boolean) => void;
|
||||||
onError: (error: Error, statusCode?: number) => void;
|
onError: (error: Error, statusCode?: number) => void;
|
||||||
onController?: (controller: AbortController) => void;
|
onController?: (controller: AbortController) => void;
|
||||||
},
|
}
|
||||||
) {
|
) {
|
||||||
const req = makeRequestParam(messages, {
|
const req = makeRequestParam(messages, {
|
||||||
stream: true,
|
stream: true,
|
||||||
@ -214,7 +213,7 @@ export const ControllerPool = {
|
|||||||
addController(
|
addController(
|
||||||
sessionIndex: number,
|
sessionIndex: number,
|
||||||
messageId: number,
|
messageId: number,
|
||||||
controller: AbortController,
|
controller: AbortController
|
||||||
) {
|
) {
|
||||||
const key = this.key(sessionIndex, messageId);
|
const key = this.key(sessionIndex, messageId);
|
||||||
this.controllers[key] = controller;
|
this.controllers[key] = controller;
|
||||||
|
@ -159,19 +159,11 @@ input[type="checkbox"]:checked::after {
|
|||||||
|
|
||||||
input[type="range"] {
|
input[type="range"] {
|
||||||
appearance: none;
|
appearance: none;
|
||||||
border: var(--border-in-light);
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 5px 15px 5px 10px;
|
|
||||||
background-color: var(--white);
|
background-color: var(--white);
|
||||||
color: var(--black);
|
color: var(--black);
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: attr(value);
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="range"]::-webkit-slider-thumb {
|
@mixin thumb() {
|
||||||
appearance: none;
|
appearance: none;
|
||||||
height: 8px;
|
height: 8px;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
@ -180,11 +172,36 @@ input[type="range"]::-webkit-slider-thumb {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all ease 0.3s;
|
transition: all ease 0.3s;
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="range"]::-webkit-slider-thumb {
|
||||||
|
@include thumb();
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="range"]::-moz-range-thumb {
|
||||||
|
@include thumb();
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="range"]::-ms-thumb {
|
||||||
|
@include thumb();
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin thumbHover() {
|
||||||
|
transform: scaleY(1.2);
|
||||||
|
width: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="range"]::-webkit-slider-thumb:hover {
|
input[type="range"]::-webkit-slider-thumb:hover {
|
||||||
transform: scaleY(1.2);
|
@include thumbHover();
|
||||||
width: 24px;
|
}
|
||||||
|
|
||||||
|
input[type="range"]::-moz-range-thumb:hover {
|
||||||
|
@include thumbHover();
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="range"]::-ms-thumb:hover {
|
||||||
|
@include thumbHover();
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="number"],
|
input[type="number"],
|
||||||
|
Loading…
Reference in New Issue
Block a user