mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-10-03 16:46:40 +08:00
Merge branch 'main' of https://github.com/Yidadaa/ChatGPT-Next-Web
This commit is contained in:
commit
86ce434902
@ -14,10 +14,11 @@
|
||||
padding: 4px 10px;
|
||||
animation: slide-in ease 0.3s;
|
||||
box-shadow: var(--card-shadow);
|
||||
transition: all ease 0.3s;
|
||||
transition: width ease 0.3s;
|
||||
align-items: center;
|
||||
height: 16px;
|
||||
width: var(--icon-width);
|
||||
overflow: hidden;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: 5px;
|
||||
@ -29,14 +30,16 @@
|
||||
opacity: 0;
|
||||
transform: translateX(-5px);
|
||||
transition: all ease 0.3s;
|
||||
transition-delay: 0.1s;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
--delay: 0.5s;
|
||||
width: var(--full-width);
|
||||
transition-delay: var(--delay);
|
||||
|
||||
.text {
|
||||
transition-delay: var(--delay);
|
||||
opacity: 1;
|
||||
transform: translate(0);
|
||||
}
|
||||
|
@ -370,18 +370,27 @@ function ChatAction(props: {
|
||||
function useScrollToBottom() {
|
||||
// for auto-scroll
|
||||
const scrollRef = useRef<HTMLDivElement>(null);
|
||||
const [autoScroll, setAutoScroll] = useState(true);
|
||||
const autoScroll = useRef(true);
|
||||
const scrollToBottom = useCallback(() => {
|
||||
const dom = scrollRef.current;
|
||||
if (dom) {
|
||||
requestAnimationFrame(() => dom.scrollTo(0, dom.scrollHeight));
|
||||
}
|
||||
}, []);
|
||||
const setAutoScroll = (enable: boolean) => {
|
||||
autoScroll.current = enable;
|
||||
};
|
||||
|
||||
// auto scroll
|
||||
useEffect(() => {
|
||||
autoScroll && scrollToBottom();
|
||||
});
|
||||
const intervalId = setInterval(() => {
|
||||
if (autoScroll.current) {
|
||||
scrollToBottom();
|
||||
}
|
||||
}, 30);
|
||||
return () => clearInterval(intervalId);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
return {
|
||||
scrollRef,
|
||||
@ -504,6 +513,7 @@ export function ChatActions(props: {
|
||||
|
||||
{showModelSelector && (
|
||||
<Selector
|
||||
defaultSelectedValue={currentModel}
|
||||
items={models.map((m) => ({
|
||||
title: m,
|
||||
value: m,
|
||||
@ -531,7 +541,7 @@ export function EditMessageModal(props: { onClose: () => void }) {
|
||||
return (
|
||||
<div className="modal-mask">
|
||||
<Modal
|
||||
title={Locale.UI.Edit}
|
||||
title={Locale.Chat.EditMessage.Title}
|
||||
onClose={props.onClose}
|
||||
actions={[
|
||||
<IconButton
|
||||
@ -589,10 +599,7 @@ export function Chat() {
|
||||
type RenderMessage = ChatMessage & { preview?: boolean };
|
||||
|
||||
const chatStore = useChatStore();
|
||||
const [session, sessionIndex] = useChatStore((state) => [
|
||||
state.currentSession(),
|
||||
state.currentSessionIndex,
|
||||
]);
|
||||
const session = chatStore.currentSession();
|
||||
const config = useAppConfig();
|
||||
const fontSize = config.fontSize;
|
||||
|
||||
@ -607,9 +614,14 @@ export function Chat() {
|
||||
const isMobileScreen = useMobileScreen();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const lastBodyScroolTop = useRef(0);
|
||||
const onChatBodyScroll = (e: HTMLElement) => {
|
||||
const isTouchBottom = e.scrollTop + e.clientHeight >= e.scrollHeight - 10;
|
||||
setHitBottom(isTouchBottom);
|
||||
|
||||
// only enable auto scroll when scroll down and touched bottom
|
||||
setAutoScroll(e.scrollTop >= lastBodyScroolTop.current && isTouchBottom);
|
||||
lastBodyScroolTop.current = e.scrollTop;
|
||||
};
|
||||
|
||||
// prompt hints
|
||||
@ -1035,7 +1047,6 @@ export function Chat() {
|
||||
ref={scrollRef}
|
||||
onScroll={(e) => onChatBodyScroll(e.currentTarget)}
|
||||
onMouseDown={() => inputRef.current?.blur()}
|
||||
onWheel={(e) => setAutoScroll(hitBottom && e.deltaY > 0)}
|
||||
onTouchStart={() => {
|
||||
inputRef.current?.blur();
|
||||
setAutoScroll(false);
|
||||
@ -1147,7 +1158,7 @@ export function Chat() {
|
||||
}}
|
||||
fontSize={fontSize}
|
||||
parentRef={scrollRef}
|
||||
defaultShow={i >= messages.length - 10}
|
||||
defaultShow={i >= messages.length - 6}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -1192,7 +1203,6 @@ export function Chat() {
|
||||
value={userInput}
|
||||
onKeyDown={onInputKeyDown}
|
||||
onFocus={() => setAutoScroll(true)}
|
||||
onBlur={() => setAutoScroll(false)}
|
||||
rows={inputRows}
|
||||
autoFocus={autoFocus}
|
||||
style={{
|
||||
|
@ -76,7 +76,7 @@ export function ModelConfigList(props: {
|
||||
<input
|
||||
type="number"
|
||||
min={100}
|
||||
max={32000}
|
||||
max={100000}
|
||||
value={props.modelConfig.max_tokens}
|
||||
onChange={(e) =>
|
||||
props.updateConfig(
|
||||
@ -169,7 +169,7 @@ export function ModelConfigList(props: {
|
||||
title={props.modelConfig.historyMessageCount.toString()}
|
||||
value={props.modelConfig.historyMessageCount}
|
||||
min="0"
|
||||
max="32"
|
||||
max="64"
|
||||
step="1"
|
||||
onChange={(e) =>
|
||||
props.updateConfig(
|
||||
|
@ -443,6 +443,7 @@ export function Selector<T>(props: {
|
||||
subTitle?: string;
|
||||
value: T;
|
||||
}>;
|
||||
defaultSelectedValue?: T;
|
||||
onSelection?: (selection: T[]) => void;
|
||||
onClose?: () => void;
|
||||
multiple?: boolean;
|
||||
@ -452,6 +453,7 @@ export function Selector<T>(props: {
|
||||
<div className={styles["selector-content"]}>
|
||||
<List>
|
||||
{props.items.map((item, i) => {
|
||||
const selected = props.defaultSelectedValue === item.value;
|
||||
return (
|
||||
<ListItem
|
||||
className={styles["selector-item"]}
|
||||
@ -462,7 +464,20 @@ export function Selector<T>(props: {
|
||||
props.onSelection?.([item.value]);
|
||||
props.onClose?.();
|
||||
}}
|
||||
></ListItem>
|
||||
>
|
||||
{selected ? (
|
||||
<div
|
||||
style={{
|
||||
height: 10,
|
||||
width: 10,
|
||||
backgroundColor: "var(--primary)",
|
||||
borderRadius: 10,
|
||||
}}
|
||||
></div>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</ListItem>
|
||||
);
|
||||
})}
|
||||
</List>
|
||||
|
@ -19,6 +19,7 @@ const cn = {
|
||||
Chat: {
|
||||
SubTitle: (count: number) => `与 SoulShellGPT 的 ${count} 条对话`,
|
||||
EditMessage: {
|
||||
Title: "编辑消息记录",
|
||||
Topic: {
|
||||
Title: "聊天主题",
|
||||
SubTitle: "更改当前聊天主题",
|
||||
@ -274,7 +275,7 @@ const cn = {
|
||||
Context: {
|
||||
Toast: (x: any) => `包含 ${x} 条预设提示词`,
|
||||
Edit: "当前对话设置",
|
||||
Add: "新增预设对话",
|
||||
Add: "新增一条对话",
|
||||
Clear: "上下文已清除",
|
||||
Revert: "恢复上下文",
|
||||
},
|
||||
|
@ -5,7 +5,7 @@ const cs: PartialLocaleType = {
|
||||
WIP: "V přípravě...",
|
||||
Error: {
|
||||
Unauthorized:
|
||||
"Neoprávněný přístup, zadejte přístupový kód na stránce nastavení.",
|
||||
"Neoprávněný přístup, zadejte přístupový kód na [stránce](/#/auth) nastavení.",
|
||||
},
|
||||
ChatItem: {
|
||||
ChatItemCount: (count: number) => `${count} zpráv`,
|
||||
|
@ -5,7 +5,7 @@ const de: PartialLocaleType = {
|
||||
WIP: "In Bearbeitung...",
|
||||
Error: {
|
||||
Unauthorized:
|
||||
"Unbefugter Zugriff, bitte geben Sie den Zugangscode auf der Einstellungsseite ein.",
|
||||
"Unbefugter Zugriff, bitte geben Sie den Zugangscode auf der [Einstellungsseite](/#/auth) ein.",
|
||||
},
|
||||
ChatItem: {
|
||||
ChatItemCount: (count: number) => `${count} Nachrichten`,
|
||||
|
@ -21,6 +21,7 @@ const en: LocaleType = {
|
||||
Chat: {
|
||||
SubTitle: (count: number) => `${count} messages with SoulShellGPT`,
|
||||
EditMessage: {
|
||||
Title: "Edit All Messages",
|
||||
Topic: {
|
||||
Title: "Topic",
|
||||
SubTitle: "Change the current topic",
|
||||
|
@ -5,7 +5,7 @@ const es: PartialLocaleType = {
|
||||
WIP: "En construcción...",
|
||||
Error: {
|
||||
Unauthorized:
|
||||
"Acceso no autorizado, por favor ingrese el código de acceso en la página de configuración.",
|
||||
"Acceso no autorizado, por favor ingrese el código de acceso en la [página](/#/auth) de configuración.",
|
||||
},
|
||||
ChatItem: {
|
||||
ChatItemCount: (count: number) => `${count} mensajes`,
|
||||
|
@ -5,7 +5,7 @@ const fr: PartialLocaleType = {
|
||||
WIP: "Prochainement...",
|
||||
Error: {
|
||||
Unauthorized:
|
||||
"Accès non autorisé, veuillez saisir le code d'accès dans la page des paramètres.",
|
||||
"Accès non autorisé, veuillez saisir le code d'accès dans la [page](/#/auth) des paramètres.",
|
||||
},
|
||||
ChatItem: {
|
||||
ChatItemCount: (count: number) => `${count} messages en total`,
|
||||
|
@ -5,7 +5,7 @@ const it: PartialLocaleType = {
|
||||
WIP: "Work in progress...",
|
||||
Error: {
|
||||
Unauthorized:
|
||||
"Accesso non autorizzato, inserire il codice di accesso nella pagina delle impostazioni.",
|
||||
"Accesso non autorizzato, inserire il codice di accesso nella [pagina](/#/auth) delle impostazioni.",
|
||||
},
|
||||
ChatItem: {
|
||||
ChatItemCount: (count: number) => `${count} messaggi`,
|
||||
|
@ -5,7 +5,8 @@ import type { PartialLocaleType } from "./index";
|
||||
const ko: PartialLocaleType = {
|
||||
WIP: "곧 출시 예정...",
|
||||
Error: {
|
||||
Unauthorized: "권한이 없습니다. 설정 페이지에서 액세스 코드를 입력하세요.",
|
||||
Unauthorized:
|
||||
"권한이 없습니다. 설정 페이지에서 액세스 코드를 [입력하세요](/#/auth).",
|
||||
},
|
||||
ChatItem: {
|
||||
ChatItemCount: (count: number) => `${count}개의 메시지`,
|
||||
|
@ -4,7 +4,8 @@ import type { PartialLocaleType } from "./index";
|
||||
const no: PartialLocaleType = {
|
||||
WIP: "Arbeid pågår ...",
|
||||
Error: {
|
||||
Unauthorized: "Du har ikke tilgang. Vennlig oppgi tildelt adgangskode.",
|
||||
Unauthorized:
|
||||
"Du har ikke tilgang. [Vennlig oppgi tildelt adgangskode](/#/auth).",
|
||||
},
|
||||
ChatItem: {
|
||||
ChatItemCount: (count: number) => `${count} meldinger`,
|
||||
|
@ -5,7 +5,7 @@ const ru: PartialLocaleType = {
|
||||
WIP: "Скоро...",
|
||||
Error: {
|
||||
Unauthorized:
|
||||
"Несанкционированный доступ. Пожалуйста, введите код доступа на странице настроек.",
|
||||
"Несанкционированный доступ. Пожалуйста, введите код доступа на [странице](/#/auth) настроек.",
|
||||
},
|
||||
ChatItem: {
|
||||
ChatItemCount: (count: number) => `${count} сообщений`,
|
||||
|
@ -5,7 +5,7 @@ const tr: PartialLocaleType = {
|
||||
WIP: "Çalışma devam ediyor...",
|
||||
Error: {
|
||||
Unauthorized:
|
||||
"Yetkisiz erişim, lütfen erişim kodunu ayarlar sayfasından giriniz.",
|
||||
"Yetkisiz erişim, lütfen erişim kodunu ayarlar [sayfasından](/#/auth) giriniz.",
|
||||
},
|
||||
ChatItem: {
|
||||
ChatItemCount: (count: number) => `${count} mesaj`,
|
||||
|
@ -4,7 +4,7 @@ import type { PartialLocaleType } from "./index";
|
||||
const tw: PartialLocaleType = {
|
||||
WIP: "該功能仍在開發中……",
|
||||
Error: {
|
||||
Unauthorized: "目前您的狀態是未授權,請前往設定頁面輸入授權碼。",
|
||||
Unauthorized: "目前您的狀態是未授權,請前往[設定頁面](/#/auth)輸入授權碼。",
|
||||
},
|
||||
ChatItem: {
|
||||
ChatItemCount: (count: number) => `${count} 條對話`,
|
||||
|
@ -81,7 +81,7 @@ export const ModalConfigValidator = {
|
||||
return x as ModelType;
|
||||
},
|
||||
max_tokens(x: number) {
|
||||
return limitNumber(x, 0, 32000, 2000);
|
||||
return limitNumber(x, 0, 100000, 2000);
|
||||
},
|
||||
presence_penalty(x: number) {
|
||||
return limitNumber(x, -2, 2, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user