mirror of
				https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
				synced 2025-11-04 08:13:43 +08:00 
			
		
		
		
	refactor: #6 check update over one hour and debound scroll
This commit is contained in:
		@@ -1,6 +1,6 @@
 | 
			
		||||
"use client";
 | 
			
		||||
 | 
			
		||||
import { useState, useRef, useEffect } from "react";
 | 
			
		||||
import { useState, useRef, useEffect, useLayoutEffect } from "react";
 | 
			
		||||
 | 
			
		||||
import { IconButton } from "./button";
 | 
			
		||||
import styles from "./home.module.scss";
 | 
			
		||||
@@ -192,7 +192,8 @@ export function Chat(props: { showSideBar?: () => void }) {
 | 
			
		||||
        : []
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
  useLayoutEffect(() => {
 | 
			
		||||
    setTimeout(() => {
 | 
			
		||||
      const dom = latestMessageRef.current;
 | 
			
		||||
      if (dom && !isIOS()) {
 | 
			
		||||
        dom.scrollIntoView({
 | 
			
		||||
@@ -200,6 +201,7 @@ export function Chat(props: { showSideBar?: () => void }) {
 | 
			
		||||
          block: "end",
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
    }, 500);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
@@ -296,9 +298,9 @@ export function Chat(props: { showSideBar?: () => void }) {
 | 
			
		||||
            </div>
 | 
			
		||||
          );
 | 
			
		||||
        })}
 | 
			
		||||
        <span ref={latestMessageRef} style={{ opacity: 0 }}>
 | 
			
		||||
        <div ref={latestMessageRef} style={{ opacity: 0, height: "2em" }}>
 | 
			
		||||
          -
 | 
			
		||||
        </span>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div className={styles["chat-input-panel"]}>
 | 
			
		||||
 
 | 
			
		||||
@@ -11,11 +11,17 @@ import ClearIcon from "../icons/clear.svg";
 | 
			
		||||
import { List, ListItem, Popover } from "./ui-lib";
 | 
			
		||||
 | 
			
		||||
import { IconButton } from "./button";
 | 
			
		||||
import { SubmitKey, useChatStore, Theme, ALL_MODELS } from "../store";
 | 
			
		||||
import {
 | 
			
		||||
  SubmitKey,
 | 
			
		||||
  useChatStore,
 | 
			
		||||
  Theme,
 | 
			
		||||
  ALL_MODELS,
 | 
			
		||||
  useUpdateStore,
 | 
			
		||||
} from "../store";
 | 
			
		||||
import { Avatar } from "./home";
 | 
			
		||||
 | 
			
		||||
import Locale, { changeLang, getLang } from "../locales";
 | 
			
		||||
import { checkUpstreamLatestCommitId, getCurrentCommitId } from "../utils";
 | 
			
		||||
import { getCurrentCommitId } from "../utils";
 | 
			
		||||
import Link from "next/link";
 | 
			
		||||
import { UPDATE_URL } from "../constant";
 | 
			
		||||
 | 
			
		||||
@@ -48,15 +54,15 @@ export function Settings(props: { closeSettings: () => void }) {
 | 
			
		||||
    ]
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const currentId = getCurrentCommitId();
 | 
			
		||||
  const updateStore = useUpdateStore();
 | 
			
		||||
  const [checkingUpdate, setCheckingUpdate] = useState(false);
 | 
			
		||||
  const [remoteId, setRemoteId] = useState<string>();
 | 
			
		||||
  const currentId = getCurrentCommitId();
 | 
			
		||||
  const remoteId = updateStore.remoteId;
 | 
			
		||||
  const hasNewVersion = currentId !== remoteId;
 | 
			
		||||
 | 
			
		||||
  function checkUpdate(force = false) {
 | 
			
		||||
    setCheckingUpdate(true);
 | 
			
		||||
    checkUpstreamLatestCommitId(force).then((id) => {
 | 
			
		||||
      setRemoteId(id);
 | 
			
		||||
    updateStore.getLatestCommitId(force).then(() => {
 | 
			
		||||
      setCheckingUpdate(false);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,5 @@
 | 
			
		||||
export const REPO_URL = "https://github.com/Yidadaa/ChatGPT-Next-Web";
 | 
			
		||||
export const UPDATE_URL =
 | 
			
		||||
  "https://github.com/Yidadaa/ChatGPT-Next-Web#%E4%BF%9D%E6%8C%81%E6%9B%B4%E6%96%B0-keep-updated";
 | 
			
		||||
export const OWNER = "Yidadaa";
 | 
			
		||||
export const REPO = "ChatGPT-Next-Web";
 | 
			
		||||
export const REPO_URL = `https://github.com/${OWNER}/${REPO}`;
 | 
			
		||||
export const UPDATE_URL = `${REPO_URL}#%E4%BF%9D%E6%8C%81%E6%9B%B4%E6%96%B0-keep-updated`;
 | 
			
		||||
export const FETCH_COMMIT_URL = `https://api.github.com/repos/${OWNER}/${REPO}/commits?per_page=1`;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
import type { ChatRequest, ChatReponse } from "./api/chat/typing";
 | 
			
		||||
import { filterConfig, isValidModel, Message, ModelConfig } from "./store";
 | 
			
		||||
import { filterConfig, Message, ModelConfig } from "./store";
 | 
			
		||||
 | 
			
		||||
const TIME_OUT_MS = 30000;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,10 +2,10 @@ import { create } from "zustand";
 | 
			
		||||
import { persist } from "zustand/middleware";
 | 
			
		||||
 | 
			
		||||
import { type ChatCompletionResponseMessage } from "openai";
 | 
			
		||||
import { requestChatStream, requestWithPrompt } from "./requests";
 | 
			
		||||
import { trimTopic } from "./utils";
 | 
			
		||||
import { requestChatStream, requestWithPrompt } from "../requests";
 | 
			
		||||
import { trimTopic } from "../utils";
 | 
			
		||||
 | 
			
		||||
import Locale from "./locales";
 | 
			
		||||
import Locale from "../locales";
 | 
			
		||||
 | 
			
		||||
export type Message = ChatCompletionResponseMessage & {
 | 
			
		||||
  date: string;
 | 
			
		||||
							
								
								
									
										2
									
								
								app/store/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								app/store/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
export * from "./app";
 | 
			
		||||
export * from "./update";
 | 
			
		||||
							
								
								
									
										49
									
								
								app/store/update.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								app/store/update.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
import { create } from "zustand";
 | 
			
		||||
import { persist } from "zustand/middleware";
 | 
			
		||||
import { FETCH_COMMIT_URL } from "../constant";
 | 
			
		||||
import { getCurrentCommitId } from "../utils";
 | 
			
		||||
 | 
			
		||||
export interface UpdateStore {
 | 
			
		||||
  lastUpdate: number;
 | 
			
		||||
  remoteId: string;
 | 
			
		||||
 | 
			
		||||
  getLatestCommitId: (force: boolean) => Promise<string>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const UPDATE_KEY = "chat-update";
 | 
			
		||||
 | 
			
		||||
export const useUpdateStore = create<UpdateStore>()(
 | 
			
		||||
  persist(
 | 
			
		||||
    (set, get) => ({
 | 
			
		||||
      lastUpdate: 0,
 | 
			
		||||
      remoteId: "",
 | 
			
		||||
 | 
			
		||||
      async getLatestCommitId(force = false) {
 | 
			
		||||
        const overOneHour = Date.now() - get().lastUpdate > 3600 * 1000;
 | 
			
		||||
        const shouldFetch = force || overOneHour;
 | 
			
		||||
        if (!shouldFetch) {
 | 
			
		||||
          return getCurrentCommitId();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
          const data = await (await fetch(FETCH_COMMIT_URL)).json();
 | 
			
		||||
          const sha = data[0].sha as string;
 | 
			
		||||
          const remoteId = sha.substring(0, 7);
 | 
			
		||||
          set(() => ({
 | 
			
		||||
            lastUpdate: Date.now(),
 | 
			
		||||
            remoteId,
 | 
			
		||||
          }));
 | 
			
		||||
          console.log("[Got Upstream] ", remoteId);
 | 
			
		||||
          return remoteId;
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
          console.error("[Fetch Upstream Commit Id]", error);
 | 
			
		||||
          return getCurrentCommitId();
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
    }),
 | 
			
		||||
    {
 | 
			
		||||
      name: UPDATE_KEY,
 | 
			
		||||
      version: 1,
 | 
			
		||||
    }
 | 
			
		||||
  )
 | 
			
		||||
);
 | 
			
		||||
@@ -199,7 +199,6 @@ div.math {
 | 
			
		||||
  font-size: 12px;
 | 
			
		||||
  color: var(--primary);
 | 
			
		||||
  text-decoration: none;
 | 
			
		||||
  padding: 5px 10px;
 | 
			
		||||
 | 
			
		||||
  &:hover {
 | 
			
		||||
    text-decoration: underline;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								app/utils.ts
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								app/utils.ts
									
									
									
									
									
								
							@@ -74,24 +74,3 @@ export function getCurrentCommitId() {
 | 
			
		||||
 | 
			
		||||
  return currentId;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let remoteId: string;
 | 
			
		||||
export async function checkUpstreamLatestCommitId(force = false) {
 | 
			
		||||
  if (!force && remoteId) {
 | 
			
		||||
    return remoteId;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const owner = "Yidadaa";
 | 
			
		||||
  const repo = "ChatGPT-Next-Web";
 | 
			
		||||
  const url = `https://api.github.com/repos/${owner}/${repo}/commits?per_page=1`;
 | 
			
		||||
 | 
			
		||||
  try {
 | 
			
		||||
    const data = await (await fetch(url)).json();
 | 
			
		||||
    const sha = data[0].sha as string;
 | 
			
		||||
    remoteId = sha.substring(0, 7);
 | 
			
		||||
    return remoteId;
 | 
			
		||||
  } catch (error) {
 | 
			
		||||
    console.error("[Fetch Upstream Commit Id]", error);
 | 
			
		||||
    return getCurrentCommitId();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user