From 8302d1d3c17c55432eda17c249e061b1927fb36c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jul 2023 10:33:12 +0000 Subject: [PATCH 01/21] chore(deps-dev): bump @types/react-dom from 18.0.11 to 18.2.7 Bumps [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom) from 18.0.11 to 18.2.7. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom) --- updated-dependencies: - dependency-name: "@types/react-dom" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index a4c26731a..cbb51546b 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "@tauri-apps/cli": "^1.4.0", "@types/node": "^20.3.3", "@types/react": "^18.2.14", - "@types/react-dom": "^18.0.11", + "@types/react-dom": "^18.2.7", "@types/react-katex": "^3.0.0", "@types/spark-md5": "^3.0.2", "cross-env": "^7.0.3", diff --git a/yarn.lock b/yarn.lock index fee28f35b..9c7688bc5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1505,10 +1505,10 @@ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== -"@types/react-dom@^18.0.11": - version "18.0.11" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.11.tgz#321351c1459bc9ca3d216aefc8a167beec334e33" - integrity sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw== +"@types/react-dom@^18.2.7": + version "18.2.7" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.7.tgz#67222a08c0a6ae0a0da33c3532348277c70abb63" + integrity sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA== dependencies: "@types/react" "*" From 13576087f4806946ee0f93b44de6482ba010705e Mon Sep 17 00:00:00 2001 From: Yidadaa Date: Tue, 25 Jul 2023 22:59:21 +0800 Subject: [PATCH 02/21] fix: #2393 try to fix chat list lag --- app/components/home.module.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/components/home.module.scss b/app/components/home.module.scss index a90b7fd87..77f1c8538 100644 --- a/app/components/home.module.scss +++ b/app/components/home.module.scss @@ -174,6 +174,7 @@ user-select: none; border: 2px solid transparent; position: relative; + content-visibility: auto; } .chat-item:hover { From cf4f928b256a800e84778feb98dd2794d1e8cb80 Mon Sep 17 00:00:00 2001 From: fernandoxu Date: Wed, 26 Jul 2023 10:06:06 +0800 Subject: [PATCH 03/21] fix(typo): ngnix -> nginx --- docs/faq-cn.md | 2 +- docs/faq-es.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/faq-cn.md b/docs/faq-cn.md index f57befde4..e4aa1e774 100644 --- a/docs/faq-cn.md +++ b/docs/faq-cn.md @@ -39,7 +39,7 @@ Docker 版本相当于稳定版,latest Docker 总是与 latest release version > 相关讨论:[#386](https://github.com/Yidadaa/ChatGPT-Next-Web/issues/386) -如果你使用 ngnix 反向代理,需要在配置文件中增加下列代码: +如果你使用 nginx 反向代理,需要在配置文件中增加下列代码: ``` # 不缓存,支持流式输出 diff --git a/docs/faq-es.md b/docs/faq-es.md index d5bbcc111..11214a686 100644 --- a/docs/faq-es.md +++ b/docs/faq-es.md @@ -39,7 +39,7 @@ Esta es su contraseña de acceso personalizada, puede elegir: > Debates relacionados:[#386](https://github.com/Yidadaa/ChatGPT-Next-Web/issues/386) -Si utiliza el proxy inverso ngnix, debe agregar el siguiente código al archivo de configuración: +Si utiliza el proxy inverso nginx, debe agregar el siguiente código al archivo de configuración: # 不缓存,支持流式输出 proxy_cache off; # 关闭缓存 From 129e7afc160c5118d363ad10c9f937b4c6a78d40 Mon Sep 17 00:00:00 2001 From: Yidadaa Date: Mon, 31 Jul 2023 22:20:39 +0800 Subject: [PATCH 04/21] fix: #2514 should not clear the message after editing message --- app/components/ui-lib.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/components/ui-lib.tsx b/app/components/ui-lib.tsx index b96809123..bf83712da 100644 --- a/app/components/ui-lib.tsx +++ b/app/components/ui-lib.tsx @@ -377,7 +377,7 @@ export function showPrompt(content: any, value = "", rows = 3) { }; return new Promise((resolve) => { - let userInput = ""; + let userInput = value; root.render( Date: Tue, 1 Aug 2023 10:16:36 +0800 Subject: [PATCH 05/21] typo fix --- app/client/platforms/openai.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/client/platforms/openai.ts b/app/client/platforms/openai.ts index e140a1ef5..9dc92e9ae 100644 --- a/app/client/platforms/openai.ts +++ b/app/client/platforms/openai.ts @@ -178,7 +178,7 @@ export class ChatGPTApi implements LLMApi { options.onFinish(message); } } catch (e) { - console.log("[Request] failed to make a chat reqeust", e); + console.log("[Request] failed to make a chat request", e); options.onError?.(e as Error); } } From d975daf3f021d419bef5e845df3e5263a542ea1d Mon Sep 17 00:00:00 2001 From: Levi Borodenko Date: Tue, 1 Aug 2023 16:17:26 +0200 Subject: [PATCH 06/21] locale: add link to authentication page in i18n --- app/locales/cs.ts | 2 +- app/locales/de.ts | 2 +- app/locales/es.ts | 2 +- app/locales/fr.ts | 2 +- app/locales/it.ts | 2 +- app/locales/ko.ts | 3 ++- app/locales/no.ts | 3 ++- app/locales/ru.ts | 2 +- app/locales/tr.ts | 2 +- app/locales/tw.ts | 2 +- 10 files changed, 12 insertions(+), 10 deletions(-) diff --git a/app/locales/cs.ts b/app/locales/cs.ts index 63d2c237f..b8a3b974c 100644 --- a/app/locales/cs.ts +++ b/app/locales/cs.ts @@ -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`, diff --git a/app/locales/de.ts b/app/locales/de.ts index e8d4dc9c7..59b1fc927 100644 --- a/app/locales/de.ts +++ b/app/locales/de.ts @@ -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`, diff --git a/app/locales/es.ts b/app/locales/es.ts index 5f5ffc75d..6145eccc8 100644 --- a/app/locales/es.ts +++ b/app/locales/es.ts @@ -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`, diff --git a/app/locales/fr.ts b/app/locales/fr.ts index f4cd1490d..a98d4a432 100644 --- a/app/locales/fr.ts +++ b/app/locales/fr.ts @@ -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`, diff --git a/app/locales/it.ts b/app/locales/it.ts index 4b74ff3f0..6a2eabf40 100644 --- a/app/locales/it.ts +++ b/app/locales/it.ts @@ -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`, diff --git a/app/locales/ko.ts b/app/locales/ko.ts index ac5ee5df2..194e44769 100644 --- a/app/locales/ko.ts +++ b/app/locales/ko.ts @@ -5,7 +5,8 @@ import type { PartialLocaleType } from "./index"; const ko: PartialLocaleType = { WIP: "곧 출시 예정...", Error: { - Unauthorized: "권한이 없습니다. 설정 페이지에서 액세스 코드를 입력하세요.", + Unauthorized: + "권한이 없습니다. 설정 페이지에서 액세스 코드를 [입력하세요](/#/auth).", }, ChatItem: { ChatItemCount: (count: number) => `${count}개의 메시지`, diff --git a/app/locales/no.ts b/app/locales/no.ts index e4b834964..43c92916f 100644 --- a/app/locales/no.ts +++ b/app/locales/no.ts @@ -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`, diff --git a/app/locales/ru.ts b/app/locales/ru.ts index 76be21a36..313acf544 100644 --- a/app/locales/ru.ts +++ b/app/locales/ru.ts @@ -5,7 +5,7 @@ const ru: PartialLocaleType = { WIP: "Скоро...", Error: { Unauthorized: - "Несанкционированный доступ. Пожалуйста, введите код доступа на странице настроек.", + "Несанкционированный доступ. Пожалуйста, введите код доступа на [странице](/#/auth) настроек.", }, ChatItem: { ChatItemCount: (count: number) => `${count} сообщений`, diff --git a/app/locales/tr.ts b/app/locales/tr.ts index ad6b66fd4..46fdd6285 100644 --- a/app/locales/tr.ts +++ b/app/locales/tr.ts @@ -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`, diff --git a/app/locales/tw.ts b/app/locales/tw.ts index d64294fa2..45c3caa02 100644 --- a/app/locales/tw.ts +++ b/app/locales/tw.ts @@ -4,7 +4,7 @@ import type { PartialLocaleType } from "./index"; const tw: PartialLocaleType = { WIP: "該功能仍在開發中……", Error: { - Unauthorized: "目前您的狀態是未授權,請前往設定頁面輸入授權碼。", + Unauthorized: "目前您的狀態是未授權,請前往[設定頁面](/#/auth)輸入授權碼。", }, ChatItem: { ChatItemCount: (count: number) => `${count} 條對話`, From cbabb9392c6a2f07235f9765061d7620391ec3ff Mon Sep 17 00:00:00 2001 From: Yidadaa Date: Wed, 2 Aug 2023 22:53:36 +0800 Subject: [PATCH 07/21] feat: improve ChatAction ux --- app/components/chat.module.scss | 5 ++++- app/components/chat.tsx | 1 + app/components/ui-lib.tsx | 17 ++++++++++++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/app/components/chat.module.scss b/app/components/chat.module.scss index a3ab56062..0297a56a5 100644 --- a/app/components/chat.module.scss +++ b/app/components/chat.module.scss @@ -18,6 +18,7 @@ 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); } diff --git a/app/components/chat.tsx b/app/components/chat.tsx index 7f54a7dd5..b4297a7a2 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -504,6 +504,7 @@ export function ChatActions(props: { {showModelSelector && ( ({ title: m, value: m, diff --git a/app/components/ui-lib.tsx b/app/components/ui-lib.tsx index bf83712da..7025daf7e 100644 --- a/app/components/ui-lib.tsx +++ b/app/components/ui-lib.tsx @@ -443,6 +443,7 @@ export function Selector(props: { subTitle?: string; value: T; }>; + defaultSelectedValue?: T; onSelection?: (selection: T[]) => void; onClose?: () => void; multiple?: boolean; @@ -452,6 +453,7 @@ export function Selector(props: {
{props.items.map((item, i) => { + const selected = props.defaultSelectedValue === item.value; return ( (props: { props.onSelection?.([item.value]); props.onClose?.(); }} - > + > + {selected ? ( +
+ ) : ( + <> + )} + ); })}
From b5ef552c253bfc7e1a13b0a44ddea4d5a907deb3 Mon Sep 17 00:00:00 2001 From: Yidadaa Date: Wed, 2 Aug 2023 23:35:51 +0800 Subject: [PATCH 08/21] feat: improve auto scroll ux and edit model title --- app/components/chat.module.scss | 2 +- app/components/chat.tsx | 31 ++++++++++++++++++++----------- app/components/model-config.tsx | 4 ++-- app/locales/cn.ts | 3 ++- app/locales/en.ts | 1 + app/store/config.ts | 2 +- 6 files changed, 27 insertions(+), 16 deletions(-) diff --git a/app/components/chat.module.scss b/app/components/chat.module.scss index 0297a56a5..d407d28e4 100644 --- a/app/components/chat.module.scss +++ b/app/components/chat.module.scss @@ -14,7 +14,7 @@ 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); diff --git a/app/components/chat.tsx b/app/components/chat.tsx index b4297a7a2..edd9fcaf4 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -370,18 +370,27 @@ function ChatAction(props: { function useScrollToBottom() { // for auto-scroll const scrollRef = useRef(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(); + } + }, 100); + return () => clearInterval(intervalId); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); return { scrollRef, @@ -532,7 +541,7 @@ export function EditMessageModal(props: { onClose: () => void }) { return (
[ - state.currentSession(), - state.currentSessionIndex, - ]); + const session = chatStore.currentSession(); const config = useAppConfig(); const fontSize = config.fontSize; @@ -608,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 @@ -1036,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); @@ -1148,7 +1158,7 @@ export function Chat() { }} fontSize={fontSize} parentRef={scrollRef} - defaultShow={i >= messages.length - 10} + defaultShow={i >= messages.length - 6} />
@@ -1193,7 +1203,6 @@ export function Chat() { value={userInput} onKeyDown={onInputKeyDown} onFocus={() => setAutoScroll(true)} - onBlur={() => setAutoScroll(false)} rows={inputRows} autoFocus={autoFocus} style={{ diff --git a/app/components/model-config.tsx b/app/components/model-config.tsx index 76866129b..63950a40d 100644 --- a/app/components/model-config.tsx +++ b/app/components/model-config.tsx @@ -76,7 +76,7 @@ export function ModelConfigList(props: { 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( diff --git a/app/locales/cn.ts b/app/locales/cn.ts index 656cd5fe3..73dc7866e 100644 --- a/app/locales/cn.ts +++ b/app/locales/cn.ts @@ -19,6 +19,7 @@ const cn = { Chat: { SubTitle: (count: number) => `共 ${count} 条对话`, EditMessage: { + Title: "编辑消息记录", Topic: { Title: "聊天主题", SubTitle: "更改当前聊天主题", @@ -274,7 +275,7 @@ const cn = { Context: { Toast: (x: any) => `包含 ${x} 条预设提示词`, Edit: "当前对话设置", - Add: "新增预设对话", + Add: "新增一条对话", Clear: "上下文已清除", Revert: "恢复上下文", }, diff --git a/app/locales/en.ts b/app/locales/en.ts index 2d83de929..5bdd0b501 100644 --- a/app/locales/en.ts +++ b/app/locales/en.ts @@ -21,6 +21,7 @@ const en: LocaleType = { Chat: { SubTitle: (count: number) => `${count} messages`, EditMessage: { + Title: "Edit All Messages", Topic: { Title: "Topic", SubTitle: "Change the current topic", diff --git a/app/store/config.ts b/app/store/config.ts index b1998b930..d963d39dd 100644 --- a/app/store/config.ts +++ b/app/store/config.ts @@ -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); From 75d4eca7223e546d74708e96026a08c7cd46f7f7 Mon Sep 17 00:00:00 2001 From: Yidadaa Date: Wed, 2 Aug 2023 23:51:01 +0800 Subject: [PATCH 09/21] chore: smaller auto scroll interval --- app/components/chat.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/components/chat.tsx b/app/components/chat.tsx index edd9fcaf4..58dc01bd0 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -387,7 +387,7 @@ function useScrollToBottom() { if (autoScroll.current) { scrollToBottom(); } - }, 100); + }, 30); return () => clearInterval(intervalId); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); From 081d84f8489eb4ed1ee6091541946f13e25e57dd Mon Sep 17 00:00:00 2001 From: Yifei Zhang Date: Thu, 3 Aug 2023 10:41:45 +0800 Subject: [PATCH 10/21] Update tauri.conf.json --- src-tauri/tauri.conf.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 2c7398f0d..a8a66642a 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -9,7 +9,7 @@ }, "package": { "productName": "ChatGPT Next Web", - "version": "2.9.1" + "version": "2.9.2" }, "tauri": { "allowlist": { From 203067c936b6f2e3375ee79041c33dafacfc0653 Mon Sep 17 00:00:00 2001 From: Yidadaa Date: Fri, 4 Aug 2023 02:16:44 +0800 Subject: [PATCH 11/21] feat: close #2545 improve lazy load message list --- app/components/chat.tsx | 173 +++++++++++++++++++++++------------- app/components/markdown.tsx | 57 ++---------- app/constant.ts | 3 + 3 files changed, 118 insertions(+), 115 deletions(-) diff --git a/app/components/chat.tsx b/app/components/chat.tsx index 58dc01bd0..4ab963679 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -74,7 +74,13 @@ import { showToast, } from "./ui-lib"; import { useLocation, useNavigate } from "react-router-dom"; -import { LAST_INPUT_KEY, Path, REQUEST_TIMEOUT_MS } from "../constant"; +import { + CHAT_PAGE_SIZE, + LAST_INPUT_KEY, + MAX_RENDER_MSG_COUNT, + Path, + REQUEST_TIMEOUT_MS, +} from "../constant"; import { Avatar } from "./emoji"; import { ContextPrompts, MaskAvatar, MaskConfig } from "./mask"; import { useMaskStore } from "../store/mask"; @@ -370,33 +376,31 @@ function ChatAction(props: { function useScrollToBottom() { // for auto-scroll const scrollRef = useRef(null); - const autoScroll = useRef(true); - const scrollToBottom = useCallback(() => { + const [autoScroll, setAutoScroll] = useState(true); + + function scrollDomToBottom() { const dom = scrollRef.current; if (dom) { - requestAnimationFrame(() => dom.scrollTo(0, dom.scrollHeight)); + requestAnimationFrame(() => { + setAutoScroll(true); + dom.scrollTo(0, dom.scrollHeight); + }); } - }, []); - const setAutoScroll = (enable: boolean) => { - autoScroll.current = enable; - }; + } // auto scroll useEffect(() => { - const intervalId = setInterval(() => { - if (autoScroll.current) { - scrollToBottom(); - } - }, 30); - return () => clearInterval(intervalId); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + console.log("auto scroll", autoScroll); + if (autoScroll) { + scrollDomToBottom(); + } + }); return { scrollRef, autoScroll, setAutoScroll, - scrollToBottom, + scrollDomToBottom, }; } @@ -595,7 +599,7 @@ export function EditMessageModal(props: { onClose: () => void }) { ); } -export function Chat() { +function _Chat() { type RenderMessage = ChatMessage & { preview?: boolean }; const chatStore = useChatStore(); @@ -609,21 +613,11 @@ export function Chat() { const [userInput, setUserInput] = useState(""); const [isLoading, setIsLoading] = useState(false); const { submitKey, shouldSubmit } = useSubmitHandler(); - const { scrollRef, setAutoScroll, scrollToBottom } = useScrollToBottom(); + const { scrollRef, setAutoScroll, scrollDomToBottom } = useScrollToBottom(); const [hitBottom, setHitBottom] = useState(true); 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 const promptStore = usePromptStore(); const [promptHints, setPromptHints] = useState([]); @@ -865,10 +859,9 @@ export function Chat() { }); }; - const context: RenderMessage[] = session.mask.hideContext - ? [] - : session.mask.context.slice(); - + const context: RenderMessage[] = useMemo(() => { + return session.mask.hideContext ? [] : session.mask.context.slice(); + }, [session.mask.context, session.mask.hideContext]); const accessStore = useAccessStore(); if ( @@ -889,34 +882,80 @@ export function Chat() { : -1; // preview messages - const messages = context - .concat(session.messages as RenderMessage[]) - .concat( - isLoading - ? [ - { - ...createMessage({ - role: "assistant", - content: "……", - }), - preview: true, - }, - ] - : [], - ) - .concat( - userInput.length > 0 && config.sendPreviewBubble - ? [ - { - ...createMessage({ - role: "user", - content: userInput, - }), - preview: true, - }, - ] - : [], + const renderMessages = useMemo(() => { + return context + .concat(session.messages as RenderMessage[]) + .concat( + isLoading + ? [ + { + ...createMessage({ + role: "assistant", + content: "……", + }), + preview: true, + }, + ] + : [], + ) + .concat( + userInput.length > 0 && config.sendPreviewBubble + ? [ + { + ...createMessage({ + role: "user", + content: userInput, + }), + preview: true, + }, + ] + : [], + ); + }, [ + config.sendPreviewBubble, + context, + isLoading, + session.messages, + userInput, + ]); + + const [msgRenderIndex, setMsgRenderIndex] = useState( + renderMessages.length - CHAT_PAGE_SIZE, + ); + const messages = useMemo(() => { + const endRenderIndex = Math.min( + msgRenderIndex + 3 * CHAT_PAGE_SIZE, + renderMessages.length, ); + return renderMessages.slice(msgRenderIndex, endRenderIndex); + }, [msgRenderIndex, renderMessages]); + + const onChatBodyScroll = (e: HTMLElement) => { + const EDGE_THRESHOLD = 100; + const bottomHeight = e.scrollTop + e.clientHeight; + const isTouchTopEdge = e.scrollTop <= EDGE_THRESHOLD; + const isTouchBottomEdge = bottomHeight >= e.scrollHeight - EDGE_THRESHOLD; + const isHitBottom = bottomHeight >= e.scrollHeight - 10; + + if (isTouchTopEdge) { + setMsgRenderIndex(Math.max(0, msgRenderIndex - CHAT_PAGE_SIZE)); + } else if (isTouchBottomEdge) { + setMsgRenderIndex( + Math.min( + msgRenderIndex + CHAT_PAGE_SIZE, + renderMessages.length - CHAT_PAGE_SIZE, + ), + ); + } + + setHitBottom(isHitBottom); + setAutoScroll(isHitBottom); + }; + + function scrollToBottom() { + setMsgRenderIndex(renderMessages.length - CHAT_PAGE_SIZE); + scrollDomToBottom(); + } const [showPromptModal, setShowPromptModal] = useState(false); @@ -1064,7 +1103,7 @@ export function Chat() { const shouldShowClearContextDivider = i === clearContextIndex - 1; return ( - +
onRightClick(e, message)} @@ -1202,7 +1242,8 @@ export function Chat() { onInput={(e) => onInput(e.currentTarget.value)} value={userInput} onKeyDown={onInputKeyDown} - onFocus={() => setAutoScroll(true)} + onFocus={scrollToBottom} + onClick={scrollToBottom} rows={inputRows} autoFocus={autoFocus} style={{ @@ -1233,3 +1274,9 @@ export function Chat() {
); } + +export function Chat() { + const chatStore = useChatStore(); + const sessionIndex = chatStore.currentSessionIndex; + return <_Chat key={sessionIndex}>; +} diff --git a/app/components/markdown.tsx b/app/components/markdown.tsx index 3168641c7..0c6a2d437 100644 --- a/app/components/markdown.tsx +++ b/app/components/markdown.tsx @@ -146,70 +146,23 @@ export function Markdown( } & React.DOMAttributes, ) { const mdRef = useRef(null); - const renderedHeight = useRef(0); - const renderedWidth = useRef(0); - const inView = useRef(!!props.defaultShow); - const [_, triggerRender] = useState(0); - const checkInView = useThrottledCallback( - () => { - const parent = props.parentRef?.current; - const md = mdRef.current; - if (parent && md && !props.defaultShow) { - const parentBounds = parent.getBoundingClientRect(); - const twoScreenHeight = Math.max(500, parentBounds.height * 2); - const mdBounds = md.getBoundingClientRect(); - const parentTop = parentBounds.top - twoScreenHeight; - const parentBottom = parentBounds.bottom + twoScreenHeight; - const isOverlap = - Math.max(parentTop, mdBounds.top) <= - Math.min(parentBottom, mdBounds.bottom); - inView.current = isOverlap; - triggerRender(Date.now()); - } - - if (inView.current && md) { - const rect = md.getBoundingClientRect(); - renderedHeight.current = Math.max(renderedHeight.current, rect.height); - renderedWidth.current = Math.max(renderedWidth.current, rect.width); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, - 300, - { - leading: true, - trailing: true, - }, - ); - - useEffect(() => { - props.parentRef?.current?.addEventListener("scroll", checkInView); - checkInView(); - return () => - props.parentRef?.current?.removeEventListener("scroll", checkInView); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - const getSize = (x: number) => (!inView.current && x > 0 ? x : "auto"); return (
- {inView.current && - (props.loading ? ( - - ) : ( - - ))} + {props.loading ? ( + + ) : ( + + )}
); } diff --git a/app/constant.ts b/app/constant.ts index 250bd1359..b4bb7b0fa 100644 --- a/app/constant.ts +++ b/app/constant.ts @@ -109,3 +109,6 @@ export const DEFAULT_MODELS = [ available: true, }, ] as const; + +export const CHAT_PAGE_SIZE = 10; +export const MAX_RENDER_MSG_COUNT = 20; From bc5ddc4541a54fe2796e6fe6c9a1a8439a68416b Mon Sep 17 00:00:00 2001 From: Yidadaa Date: Fri, 4 Aug 2023 02:39:32 +0800 Subject: [PATCH 12/21] fixup: improve auto scroll algo --- app/components/chat.tsx | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/app/components/chat.tsx b/app/components/chat.tsx index 4ab963679..1ed878481 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -390,7 +390,6 @@ function useScrollToBottom() { // auto scroll useEffect(() => { - console.log("auto scroll", autoScroll); if (autoScroll) { scrollDomToBottom(); } @@ -919,9 +918,15 @@ function _Chat() { userInput, ]); - const [msgRenderIndex, setMsgRenderIndex] = useState( - renderMessages.length - CHAT_PAGE_SIZE, + const [msgRenderIndex, _setMsgRenderIndex] = useState( + Math.max(0, renderMessages.length - CHAT_PAGE_SIZE), ); + function setMsgRenderIndex(newIndex: number) { + newIndex = Math.min(renderMessages.length - CHAT_PAGE_SIZE, newIndex); + newIndex = Math.max(0, newIndex); + _setMsgRenderIndex(newIndex); + } + const messages = useMemo(() => { const endRenderIndex = Math.min( msgRenderIndex + 3 * CHAT_PAGE_SIZE, @@ -931,21 +936,20 @@ function _Chat() { }, [msgRenderIndex, renderMessages]); const onChatBodyScroll = (e: HTMLElement) => { - const EDGE_THRESHOLD = 100; const bottomHeight = e.scrollTop + e.clientHeight; - const isTouchTopEdge = e.scrollTop <= EDGE_THRESHOLD; - const isTouchBottomEdge = bottomHeight >= e.scrollHeight - EDGE_THRESHOLD; + const edgeThreshold = e.clientHeight; + + const isTouchTopEdge = e.scrollTop <= edgeThreshold; + const isTouchBottomEdge = bottomHeight >= e.scrollHeight - edgeThreshold; const isHitBottom = bottomHeight >= e.scrollHeight - 10; + const prevPageMsgIndex = msgRenderIndex - CHAT_PAGE_SIZE; + const nextPageMsgIndex = msgRenderIndex + CHAT_PAGE_SIZE; + if (isTouchTopEdge) { - setMsgRenderIndex(Math.max(0, msgRenderIndex - CHAT_PAGE_SIZE)); + setMsgRenderIndex(prevPageMsgIndex); } else if (isTouchBottomEdge) { - setMsgRenderIndex( - Math.min( - msgRenderIndex + CHAT_PAGE_SIZE, - renderMessages.length - CHAT_PAGE_SIZE, - ), - ); + setMsgRenderIndex(nextPageMsgIndex); } setHitBottom(isHitBottom); From 3e63f6ba345a2598e0d1e3ccf4feec9c4679ff18 Mon Sep 17 00:00:00 2001 From: Yidadaa Date: Fri, 4 Aug 2023 02:43:55 +0800 Subject: [PATCH 13/21] feat: disable auto focus on mobile screen --- app/components/chat.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/components/chat.tsx b/app/components/chat.tsx index 1ed878481..c7a8e9ba1 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -965,10 +965,7 @@ function _Chat() { const clientConfig = useMemo(() => getClientConfig(), []); - const location = useLocation(); - const isChat = location.pathname === Path.Chat; - - const autoFocus = !isMobileScreen || isChat; // only focus in chat page + const autoFocus = !isMobileScreen; // wont auto focus on mobile screen const showMaxIcon = !isMobileScreen && !clientConfig?.isApp; useCommand({ From 523d553daca12455f6d90ac075dacb5daffb9b96 Mon Sep 17 00:00:00 2001 From: Yidadaa Date: Fri, 4 Aug 2023 02:58:02 +0800 Subject: [PATCH 14/21] fix: clear btn should display in correct place --- app/components/chat.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/components/chat.tsx b/app/components/chat.tsx index c7a8e9ba1..a99f72f15 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -874,12 +874,6 @@ function _Chat() { context.push(copiedHello); } - // clear context index = context length + index in messages - const clearContextIndex = - (session.clearContextIndex ?? -1) >= 0 - ? session.clearContextIndex! + context.length - : -1; - // preview messages const renderMessages = useMemo(() => { return context @@ -961,6 +955,12 @@ function _Chat() { scrollDomToBottom(); } + // clear context index = context length + index in messages + const clearContextIndex = + (session.clearContextIndex ?? -1) >= 0 + ? session.clearContextIndex! + context.length - msgRenderIndex + : -1; + const [showPromptModal, setShowPromptModal] = useState(false); const clientConfig = useMemo(() => getClientConfig(), []); From 7da83987e4093134b3612c3d5f061783fa9f92e8 Mon Sep 17 00:00:00 2001 From: Yifei Zhang Date: Fri, 4 Aug 2023 15:45:16 +0800 Subject: [PATCH 15/21] chore: use bigger page size and render msg count --- app/constant.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/constant.ts b/app/constant.ts index b4bb7b0fa..7ff22c043 100644 --- a/app/constant.ts +++ b/app/constant.ts @@ -110,5 +110,5 @@ export const DEFAULT_MODELS = [ }, ] as const; -export const CHAT_PAGE_SIZE = 10; -export const MAX_RENDER_MSG_COUNT = 20; +export const CHAT_PAGE_SIZE = 30; +export const MAX_RENDER_MSG_COUNT = 60; From 543989151f406398532a96096085feccf7062949 Mon Sep 17 00:00:00 2001 From: Yifei Zhang Date: Fri, 4 Aug 2023 19:24:10 +0800 Subject: [PATCH 16/21] Update constant.ts --- app/constant.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/constant.ts b/app/constant.ts index 7ff22c043..0a94eed4e 100644 --- a/app/constant.ts +++ b/app/constant.ts @@ -110,5 +110,5 @@ export const DEFAULT_MODELS = [ }, ] as const; -export const CHAT_PAGE_SIZE = 30; -export const MAX_RENDER_MSG_COUNT = 60; +export const CHAT_PAGE_SIZE = 15; +export const MAX_RENDER_MSG_COUNT = 45; From d1096582a50887363554ad7f60821209326b6bbb Mon Sep 17 00:00:00 2001 From: 7lsu Date: Mon, 7 Aug 2023 17:44:32 +0800 Subject: [PATCH 17/21] font family display enhance --- app/components/home.tsx | 3 +-- app/styles/globals.scss | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/components/home.tsx b/app/components/home.tsx index b3cec893e..c6829c2dc 100644 --- a/app/components/home.tsx +++ b/app/components/home.tsx @@ -104,8 +104,7 @@ const loadAsyncGoogleFont = () => { getClientConfig()?.buildMode === "export" ? remoteFontUrl : proxyFontUrl; linkEl.rel = "stylesheet"; linkEl.href = - googleFontUrl + - "/css2?family=Noto+Sans+SC:wght@300;400;700;900&display=swap"; + googleFontUrl + "/css2?family=Noto+Sans:wght@300;400;700;900&display=swap"; document.head.appendChild(linkEl); }; diff --git a/app/styles/globals.scss b/app/styles/globals.scss index 0417087e9..6542ca6ec 100644 --- a/app/styles/globals.scss +++ b/app/styles/globals.scss @@ -89,7 +89,7 @@ html { height: var(--full-height); - font-family: "Noto Sans SC", "SF Pro SC", "SF Pro Text", "SF Pro Icons", + font-family: "Noto Sans", "SF Pro SC", "SF Pro Text", "SF Pro Icons", "PingFang SC", "Helvetica Neue", "Helvetica", "Arial", sans-serif; } From 769c2f9f49b1fd0d0e8e30b3bf579805c6259b7b Mon Sep 17 00:00:00 2001 From: Yidadaa Date: Tue, 8 Aug 2023 21:22:41 +0800 Subject: [PATCH 18/21] feat: close #2583 do not summarize with gpt-4 --- app/store/chat.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/store/chat.ts b/app/store/chat.ts index f06c59481..ef68f7d9e 100644 --- a/app/store/chat.ts +++ b/app/store/chat.ts @@ -553,7 +553,7 @@ export const useChatStore = create()( date: "", }), ), - config: { ...modelConfig, stream: true }, + config: { ...modelConfig, stream: true, model: "gpt-3.5-turbo" }, onUpdate(message) { session.memoryPrompt = message; }, From 4ab9141429ba170308443284bd06c84dac027788 Mon Sep 17 00:00:00 2001 From: Yidadaa Date: Tue, 8 Aug 2023 21:24:45 +0800 Subject: [PATCH 19/21] fix: #2564 should not clear message when error --- app/store/chat.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/store/chat.ts b/app/store/chat.ts index ef68f7d9e..a61765899 100644 --- a/app/store/chat.ts +++ b/app/store/chat.ts @@ -332,7 +332,7 @@ export const useChatStore = create()( }, onError(error) { const isAborted = error.message.includes("aborted"); - botMessage.content = + botMessage.content += "\n\n" + prettyObject({ error: true, From b14c5cd89c760ac81b555c0b4eb061c34cae6978 Mon Sep 17 00:00:00 2001 From: Yidadaa Date: Tue, 8 Aug 2023 21:36:37 +0800 Subject: [PATCH 20/21] fix: #2485 one-time-use body --- app/api/common.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/api/common.ts b/app/api/common.ts index 3146b6bd9..e5afb4d89 100644 --- a/app/api/common.ts +++ b/app/api/common.ts @@ -43,6 +43,8 @@ export async function requestOpenai(req: NextRequest) { }, method: req.method, body: req.body, + // to fix #2485: https://stackoverflow.com/questions/55920957/cloudflare-worker-typeerror-one-time-use-body + redirect: "manual", // @ts-ignore duplex: "half", signal: controller.signal, From 153e7ac7e4fc2ceb6ec14137812f6f26e862fd9a Mon Sep 17 00:00:00 2001 From: Ikko Eltociear Ashimine Date: Wed, 9 Aug 2023 01:22:48 +0900 Subject: [PATCH 21/21] Fix typo in README.md notifictions -> notifications --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f0f298fb9..55e88d90e 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,7 @@ After forking the project, due to the limitations imposed by GitHub, you need to If you want to update instantly, you can check out the [GitHub documentation](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork) to learn how to synchronize a forked project with upstream code. -You can star or watch this project or follow author to get release notifictions in time. +You can star or watch this project or follow author to get release notifications in time. ## Access Password