diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml
index 9c7b7e6f1..38c272e85 100644
--- a/.github/workflows/sync.yml
+++ b/.github/workflows/sync.yml
@@ -1,5 +1,8 @@
name: Upstream Sync
+permissions:
+ contents: write
+
on:
schedule:
- cron: "0 */6 * * *" # every 6 hours
@@ -12,7 +15,7 @@ jobs:
if: ${{ github.event.repository.fork }}
steps:
- # Step 1: run a standard checkout action, provided by github
+ # Step 1: run a standard checkout action
- name: Checkout target repo
uses: actions/checkout@v3
diff --git a/README.md b/README.md
index 815aba1af..40386a005 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ One-Click to deploy your own ChatGPT web UI.
- 在 1 分钟内使用 Vercel **免费一键部署**
- 精心设计的 UI,响应式设计,支持深色模式
-- 极快的首屏加载速度(~85kb)
+- 极快的首屏加载速度(~100kb)
- 海量的内置 prompt 列表,来自[中文](https://github.com/PlexPt/awesome-chatgpt-prompts-zh)和[英文](https://github.com/f/awesome-chatgpt-prompts)
- 自动压缩上下文聊天记录,在节省 Token 的同时支持超长对话
- 一键导出聊天记录,完整的 Markdown 支持
@@ -31,7 +31,7 @@ One-Click to deploy your own ChatGPT web UI.
- **Deploy for free with one-click** on Vercel in under 1 minute
- Responsive design, and dark mode
-- Fast first screen loading speed (~85kb)
+- Fast first screen loading speed (~100kb)
- Awesome prompts powered by [awesome-chatgpt-prompts-zh](https://github.com/PlexPt/awesome-chatgpt-prompts-zh) and [awesome-chatgpt-prompts](https://github.com/f/awesome-chatgpt-prompts)
- Automatically compresses chat history to support long conversations while also saving your tokens
- One-click export all chat history with full Markdown support
@@ -74,7 +74,9 @@ One-Click to deploy your own ChatGPT web UI.
- 前往 vercel 控制台,删除掉原先的 project,然后新建 project,选择你刚刚 fork 出来的项目重新进行部署即可;
- 在重新部署的过程中,请手动添加名为 `OPENAI_API_KEY` 的环境变量,并填入你的 api key 作为值。
-本项目会持续更新,如果你想让代码库总是保持更新,可以查看 [Github 的文档](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork) 了解如何让 fork 的项目与上游代码同步,建议定期进行同步操作以获得新功能。
+本项目会持续更新,当你 Fork 项目之后,默认会每天自动同步上游代码,无需额外操作。
+
+如果你想让手动立即更新,可以查看 [Github 的文档](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork) 了解如何让 fork 的项目与上游代码同步。
你可以 star/watch 本项目或者 follow 作者来及时获得新功能更新通知。
@@ -87,7 +89,9 @@ We recommend that you follow the steps below to re-deploy:
- Go to the Vercel dashboard, delete the original project, then create a new project and select the project you just forked to redeploy;
- Please manually add an environment variable named `OPENAI_API_KEY` and enter your API key as the value during the redeploy process.
-This project will be continuously maintained. If you want to keep the code repository up to date, 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. It is recommended to perform synchronization operations regularly.
+This project will be continuously updated, and after forking the project, the upstream code will be automatically synchronized every day without additional operations.
+
+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.
diff --git a/app/components/chat.tsx b/app/components/chat.tsx
index 94ae484ce..ebd383845 100644
--- a/app/components/chat.tsx
+++ b/app/components/chat.tsx
@@ -12,14 +12,7 @@ import BotIcon from "../icons/bot.svg";
import AddIcon from "../icons/add.svg";
import DeleteIcon from "../icons/delete.svg";
-import {
- Message,
- SubmitKey,
- useChatStore,
- ChatSession,
- BOT_HELLO,
- ROLES,
-} from "../store";
+import { Message, SubmitKey, useChatStore, BOT_HELLO, ROLES } from "../store";
import {
copyToClipboard,
@@ -378,7 +371,8 @@ export function Chat(props: {}) {
chatStore.onUserInput(userInput).then(() => setIsLoading(false));
setUserInput("");
setPromptHints([]);
- inputRef.current?.focus();
+ if (!isMobileScreen()) inputRef.current?.focus();
+ setAutoScroll(true);
};
// stop response
@@ -514,7 +508,10 @@ export function Chat(props: {}) {
bordered
title={Locale.Chat.Actions.Export}
onClick={() => {
- exportMessages(session.messages, session.topic);
+ exportMessages(
+ session.messages.filter((msg) => !msg.isError),
+ session.topic,
+ );
}}
/>
@@ -531,7 +528,11 @@ export function Chat(props: {}) {
className={styles["chat-body"]}
ref={scrollRef}
onScroll={(e) => onChatBodyScroll(e.currentTarget)}
- onTouchStart={() => inputRef.current?.blur()}
+ onWheel={(e) => setAutoScroll(hitBottom && e.deltaY > 0)}
+ onTouchStart={() => {
+ inputRef.current?.blur();
+ setAutoScroll(false);
+ }}
>
{messages.map((message, i) => {
const isUser = message.role === "user";
@@ -592,7 +593,6 @@ export function Chat(props: {}) {
if (!isMobileScreen()) return;
setUserInput(message.content);
}}
- onMouseOver={() => inputRef.current?.blur()}
>
@@ -627,9 +627,6 @@ export function Chat(props: {}) {
setAutoScroll(false);
setTimeout(() => setPromptHints([]), 500);
}}
- onMouseOver={() => {
- inputRef.current?.focus();
- }}
autoFocus={sidebarCollapse}
/>
{
+ constructor(props: any) {
+ super(props);
+ this.state = { hasError: false, error: null, info: null };
+ }
+
+ componentDidCatch(error: Error, info: React.ErrorInfo) {
+ // Update state with error details
+ this.setState({ hasError: true, error, info });
+ }
+
+ render() {
+ if (this.state.hasError) {
+ // Render error message
+ return (
+