forked from XiaoMo/ChatGPT-Next-Web
feat: close #2190 improve app auto updater
This commit is contained in:
parent
3937dad6a6
commit
be4834688d
@ -40,7 +40,7 @@ import Locale, {
|
|||||||
} from "../locales";
|
} from "../locales";
|
||||||
import { copyToClipboard } from "../utils";
|
import { copyToClipboard } from "../utils";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { Path, UPDATE_URL } from "../constant";
|
import { Path, RELEASE_URL, UPDATE_URL } from "../constant";
|
||||||
import { Prompt, SearchService, usePromptStore } from "../store/prompt";
|
import { Prompt, SearchService, usePromptStore } from "../store/prompt";
|
||||||
import { ErrorBoundary } from "./error";
|
import { ErrorBoundary } from "./error";
|
||||||
import { InputRange } from "./input-range";
|
import { InputRange } from "./input-range";
|
||||||
@ -310,19 +310,6 @@ function SyncItems() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatVersionDate(t: string) {
|
|
||||||
const d = new Date(+t);
|
|
||||||
const year = d.getUTCFullYear();
|
|
||||||
const month = d.getUTCMonth() + 1;
|
|
||||||
const day = d.getUTCDate();
|
|
||||||
|
|
||||||
return [
|
|
||||||
year.toString(),
|
|
||||||
month.toString().padStart(2, "0"),
|
|
||||||
day.toString().padStart(2, "0"),
|
|
||||||
].join("");
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Settings() {
|
export function Settings() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [showEmojiPicker, setShowEmojiPicker] = useState(false);
|
const [showEmojiPicker, setShowEmojiPicker] = useState(false);
|
||||||
@ -332,9 +319,10 @@ export function Settings() {
|
|||||||
|
|
||||||
const updateStore = useUpdateStore();
|
const updateStore = useUpdateStore();
|
||||||
const [checkingUpdate, setCheckingUpdate] = useState(false);
|
const [checkingUpdate, setCheckingUpdate] = useState(false);
|
||||||
const currentVersion = formatVersionDate(updateStore.version);
|
const currentVersion = updateStore.formatVersion(updateStore.version);
|
||||||
const remoteId = formatVersionDate(updateStore.remoteVersion);
|
const remoteId = updateStore.formatVersion(updateStore.remoteVersion);
|
||||||
const hasNewVersion = currentVersion !== remoteId;
|
const hasNewVersion = currentVersion !== remoteId;
|
||||||
|
const updateUrl = getClientConfig()?.isApp ? RELEASE_URL : UPDATE_URL;
|
||||||
|
|
||||||
function checkUpdate(force = false) {
|
function checkUpdate(force = false) {
|
||||||
setCheckingUpdate(true);
|
setCheckingUpdate(true);
|
||||||
@ -342,14 +330,8 @@ export function Settings() {
|
|||||||
setCheckingUpdate(false);
|
setCheckingUpdate(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(
|
console.log("[Update] local version ", updateStore.version);
|
||||||
"[Update] local version ",
|
console.log("[Update] remote version ", updateStore.remoteVersion);
|
||||||
new Date(+updateStore.version).toLocaleString(),
|
|
||||||
);
|
|
||||||
console.log(
|
|
||||||
"[Update] remote version ",
|
|
||||||
new Date(+updateStore.remoteVersion).toLocaleString(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const usage = {
|
const usage = {
|
||||||
@ -460,7 +442,7 @@ export function Settings() {
|
|||||||
{checkingUpdate ? (
|
{checkingUpdate ? (
|
||||||
<LoadingIcon />
|
<LoadingIcon />
|
||||||
) : hasNewVersion ? (
|
) : hasNewVersion ? (
|
||||||
<Link href={UPDATE_URL} target="_blank" className="link">
|
<Link href={updateUrl} target="_blank" className="link">
|
||||||
{Locale.Settings.Update.GoToUpdate}
|
{Locale.Settings.Update.GoToUpdate}
|
||||||
</Link>
|
</Link>
|
||||||
) : (
|
) : (
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import tauriConfig from "../../src-tauri/tauri.conf.json";
|
||||||
|
|
||||||
export const getBuildConfig = () => {
|
export const getBuildConfig = () => {
|
||||||
if (typeof process === "undefined") {
|
if (typeof process === "undefined") {
|
||||||
throw Error(
|
throw Error(
|
||||||
@ -5,23 +7,37 @@ export const getBuildConfig = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const COMMIT_ID: string = (() => {
|
const buildMode = process.env.BUILD_MODE ?? "standalone";
|
||||||
|
const isApp = !!process.env.BUILD_APP;
|
||||||
|
const version = tauriConfig.package.version;
|
||||||
|
|
||||||
|
const commitInfo = (() => {
|
||||||
try {
|
try {
|
||||||
const childProcess = require("child_process");
|
const childProcess = require("child_process");
|
||||||
return childProcess
|
const commitDate: string = childProcess
|
||||||
.execSync('git log -1 --format="%at000" --date=unix')
|
.execSync('git log -1 --format="%at000" --date=unix')
|
||||||
.toString()
|
.toString()
|
||||||
.trim();
|
.trim();
|
||||||
|
const commitHash: string = childProcess
|
||||||
|
.execSync('git log --pretty=format:"%H" -n 1')
|
||||||
|
.toString()
|
||||||
|
.trim();
|
||||||
|
|
||||||
|
return { commitDate, commitHash };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("[Build Config] No git or not from git repo.");
|
console.error("[Build Config] No git or not from git repo.");
|
||||||
return "unknown";
|
return {
|
||||||
|
commitDate: "unknown",
|
||||||
|
commitHash: "unknown",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
commitId: COMMIT_ID,
|
version,
|
||||||
buildMode: process.env.BUILD_MODE ?? "standalone",
|
...commitInfo,
|
||||||
isApp: !!process.env.BUILD_APP,
|
buildMode,
|
||||||
|
isApp,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ export const REPO = "ChatGPT-Next-Web";
|
|||||||
export const REPO_URL = `https://github.com/${OWNER}/${REPO}`;
|
export const REPO_URL = `https://github.com/${OWNER}/${REPO}`;
|
||||||
export const ISSUE_URL = `https://github.com/${OWNER}/${REPO}/issues`;
|
export const ISSUE_URL = `https://github.com/${OWNER}/${REPO}/issues`;
|
||||||
export const UPDATE_URL = `${REPO_URL}#keep-updated`;
|
export const UPDATE_URL = `${REPO_URL}#keep-updated`;
|
||||||
|
export const RELEASE_URL = `${REPO_URL}/releases`;
|
||||||
export const FETCH_COMMIT_URL = `https://api.github.com/repos/${OWNER}/${REPO}/commits?per_page=1`;
|
export const FETCH_COMMIT_URL = `https://api.github.com/repos/${OWNER}/${REPO}/commits?per_page=1`;
|
||||||
export const FETCH_TAG_URL = `https://api.github.com/repos/${OWNER}/${REPO}/tags?per_page=1`;
|
export const FETCH_TAG_URL = `https://api.github.com/repos/${OWNER}/${REPO}/tags?per_page=1`;
|
||||||
export const RUNTIME_CONFIG_DOM = "danger-runtime-config";
|
export const RUNTIME_CONFIG_DOM = "danger-runtime-config";
|
||||||
|
@ -1,48 +1,96 @@
|
|||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
import { persist } from "zustand/middleware";
|
import { persist } from "zustand/middleware";
|
||||||
import { FETCH_COMMIT_URL, StoreKey } from "../constant";
|
import { FETCH_COMMIT_URL, FETCH_TAG_URL, StoreKey } from "../constant";
|
||||||
import { api } from "../client/api";
|
import { api } from "../client/api";
|
||||||
import { getClientConfig } from "../config/client";
|
import { getClientConfig } from "../config/client";
|
||||||
|
|
||||||
export interface UpdateStore {
|
export interface UpdateStore {
|
||||||
|
versionType: "date" | "tag";
|
||||||
lastUpdate: number;
|
lastUpdate: number;
|
||||||
|
version: string;
|
||||||
remoteVersion: string;
|
remoteVersion: string;
|
||||||
|
|
||||||
used?: number;
|
used?: number;
|
||||||
subscription?: number;
|
subscription?: number;
|
||||||
lastUpdateUsage: number;
|
lastUpdateUsage: number;
|
||||||
|
|
||||||
version: string;
|
|
||||||
getLatestVersion: (force?: boolean) => Promise<void>;
|
getLatestVersion: (force?: boolean) => Promise<void>;
|
||||||
updateUsage: (force?: boolean) => Promise<void>;
|
updateUsage: (force?: boolean) => Promise<void>;
|
||||||
|
|
||||||
|
formatVersion: (version: string) => string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ONE_MINUTE = 60 * 1000;
|
const ONE_MINUTE = 60 * 1000;
|
||||||
|
|
||||||
|
function formatVersionDate(t: string) {
|
||||||
|
const d = new Date(+t);
|
||||||
|
const year = d.getUTCFullYear();
|
||||||
|
const month = d.getUTCMonth() + 1;
|
||||||
|
const day = d.getUTCDate();
|
||||||
|
|
||||||
|
return [
|
||||||
|
year.toString(),
|
||||||
|
month.toString().padStart(2, "0"),
|
||||||
|
day.toString().padStart(2, "0"),
|
||||||
|
].join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getVersion(type: "date" | "tag") {
|
||||||
|
if (type === "date") {
|
||||||
|
const data = (await (await fetch(FETCH_COMMIT_URL)).json()) as {
|
||||||
|
commit: {
|
||||||
|
author: { name: string; date: string };
|
||||||
|
};
|
||||||
|
sha: string;
|
||||||
|
}[];
|
||||||
|
const remoteCommitTime = data[0].commit.author.date;
|
||||||
|
const remoteId = new Date(remoteCommitTime).getTime().toString();
|
||||||
|
return remoteId;
|
||||||
|
} else if (type === "tag") {
|
||||||
|
const data = (await (await fetch(FETCH_TAG_URL)).json()) as {
|
||||||
|
commit: { sha: string; url: string };
|
||||||
|
name: string;
|
||||||
|
}[];
|
||||||
|
return data.at(0)?.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const useUpdateStore = create<UpdateStore>()(
|
export const useUpdateStore = create<UpdateStore>()(
|
||||||
persist(
|
persist(
|
||||||
(set, get) => ({
|
(set, get) => ({
|
||||||
|
versionType: "tag",
|
||||||
lastUpdate: 0,
|
lastUpdate: 0,
|
||||||
|
version: "unknown",
|
||||||
remoteVersion: "",
|
remoteVersion: "",
|
||||||
|
|
||||||
lastUpdateUsage: 0,
|
lastUpdateUsage: 0,
|
||||||
|
|
||||||
version: "unknown",
|
formatVersion(version: string) {
|
||||||
|
if (get().versionType === "date") {
|
||||||
|
version = formatVersionDate(version);
|
||||||
|
}
|
||||||
|
return version;
|
||||||
|
},
|
||||||
|
|
||||||
async getLatestVersion(force = false) {
|
async getLatestVersion(force = false) {
|
||||||
set(() => ({ version: getClientConfig()?.commitId ?? "unknown" }));
|
const versionType = get().versionType;
|
||||||
|
let version =
|
||||||
|
versionType === "date"
|
||||||
|
? getClientConfig()?.commitDate
|
||||||
|
: getClientConfig()?.version;
|
||||||
|
|
||||||
const overTenMins = Date.now() - get().lastUpdate > 10 * ONE_MINUTE;
|
set(() => ({ version }));
|
||||||
if (!force && !overTenMins) return;
|
|
||||||
|
const shouldCheck =
|
||||||
|
Date.now() - get().lastUpdate > 24 * 60 * ONE_MINUTE;
|
||||||
|
if (!force && !shouldCheck) return;
|
||||||
|
|
||||||
set(() => ({
|
set(() => ({
|
||||||
lastUpdate: Date.now(),
|
lastUpdate: Date.now(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const data = await (await fetch(FETCH_COMMIT_URL)).json();
|
const remoteId = await getVersion(versionType);
|
||||||
const remoteCommitTime = data[0].commit.committer.date;
|
|
||||||
const remoteId = new Date(remoteCommitTime).getTime().toString();
|
|
||||||
set(() => ({
|
set(() => ({
|
||||||
remoteVersion: remoteId,
|
remoteVersion: remoteId,
|
||||||
}));
|
}));
|
||||||
|
Loading…
Reference in New Issue
Block a user