Skip to content

Commit

Permalink
feat: close ChatGPTNextWeb#2190 improve app auto updater
Browse files Browse the repository at this point in the history
  • Loading branch information
Yidadaa committed Jun 29, 2023
1 parent 3937dad commit be48346
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 40 deletions.
32 changes: 7 additions & 25 deletions app/components/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import Locale, {
} from "../locales";
import { copyToClipboard } from "../utils";
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 { ErrorBoundary } from "./error";
import { InputRange } from "./input-range";
Expand Down Expand Up @@ -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() {
const navigate = useNavigate();
const [showEmojiPicker, setShowEmojiPicker] = useState(false);
Expand All @@ -332,24 +319,19 @@ export function Settings() {

const updateStore = useUpdateStore();
const [checkingUpdate, setCheckingUpdate] = useState(false);
const currentVersion = formatVersionDate(updateStore.version);
const remoteId = formatVersionDate(updateStore.remoteVersion);
const currentVersion = updateStore.formatVersion(updateStore.version);
const remoteId = updateStore.formatVersion(updateStore.remoteVersion);
const hasNewVersion = currentVersion !== remoteId;
const updateUrl = getClientConfig()?.isApp ? RELEASE_URL : UPDATE_URL;

function checkUpdate(force = false) {
setCheckingUpdate(true);
updateStore.getLatestVersion(force).then(() => {
setCheckingUpdate(false);
});

console.log(
"[Update] local version ",
new Date(+updateStore.version).toLocaleString(),
);
console.log(
"[Update] remote version ",
new Date(+updateStore.remoteVersion).toLocaleString(),
);
console.log("[Update] local version ", updateStore.version);
console.log("[Update] remote version ", updateStore.remoteVersion);
}

const usage = {
Expand Down Expand Up @@ -460,7 +442,7 @@ export function Settings() {
{checkingUpdate ? (
<LoadingIcon />
) : hasNewVersion ? (
<Link href={UPDATE_URL} target="_blank" className="link">
<Link href={updateUrl} target="_blank" className="link">
{Locale.Settings.Update.GoToUpdate}
</Link>
) : (
Expand Down
28 changes: 22 additions & 6 deletions app/config/build.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,43 @@
import tauriConfig from "../../src-tauri/tauri.conf.json";

export const getBuildConfig = () => {
if (typeof process === "undefined") {
throw Error(
"[Server Config] you are importing a nodejs-only module outside of nodejs",
);
}

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 {
const childProcess = require("child_process");
return childProcess
const commitDate: string = childProcess
.execSync('git log -1 --format="%at000" --date=unix')
.toString()
.trim();
const commitHash: string = childProcess
.execSync('git log --pretty=format:"%H" -n 1')
.toString()
.trim();

return { commitDate, commitHash };
} catch (e) {
console.error("[Build Config] No git or not from git repo.");
return "unknown";
return {
commitDate: "unknown",
commitHash: "unknown",
};
}
})();

return {
commitId: COMMIT_ID,
buildMode: process.env.BUILD_MODE ?? "standalone",
isApp: !!process.env.BUILD_APP,
version,
...commitInfo,
buildMode,
isApp,
};
};

Expand Down
1 change: 1 addition & 0 deletions app/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export const REPO = "ChatGPT-Next-Web";
export const REPO_URL = `https://github.com/${OWNER}/${REPO}`;
export const ISSUE_URL = `https://github.com/${OWNER}/${REPO}/issues`;
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_TAG_URL = `https://api.github.com/repos/${OWNER}/${REPO}/tags?per_page=1`;
export const RUNTIME_CONFIG_DOM = "danger-runtime-config";
Expand Down
66 changes: 57 additions & 9 deletions app/store/update.ts
Original file line number Diff line number Diff line change
@@ -1,48 +1,96 @@
import { create } from "zustand";
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 { getClientConfig } from "../config/client";

export interface UpdateStore {
versionType: "date" | "tag";
lastUpdate: number;
version: string;
remoteVersion: string;

used?: number;
subscription?: number;
lastUpdateUsage: number;

version: string;
getLatestVersion: (force?: boolean) => Promise<void>;
updateUsage: (force?: boolean) => Promise<void>;

formatVersion: (version: string) => string;
}

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>()(
persist(
(set, get) => ({
versionType: "tag",
lastUpdate: 0,
version: "unknown",
remoteVersion: "",

lastUpdateUsage: 0,

version: "unknown",
formatVersion(version: string) {
if (get().versionType === "date") {
version = formatVersionDate(version);
}
return version;
},

async getLatestVersion(force = false) {
set(() => ({ version: getClientConfig()?.commitId ?? "unknown" }));
const versionType = get().versionType;
let version =
versionType === "date"
? getClientConfig()?.commitDate
: getClientConfig()?.version;

set(() => ({ version }));

const overTenMins = Date.now() - get().lastUpdate > 10 * ONE_MINUTE;
if (!force && !overTenMins) return;
const shouldCheck =
Date.now() - get().lastUpdate > 24 * 60 * ONE_MINUTE;
if (!force && !shouldCheck) return;

set(() => ({
lastUpdate: Date.now(),
}));

try {
const data = await (await fetch(FETCH_COMMIT_URL)).json();
const remoteCommitTime = data[0].commit.committer.date;
const remoteId = new Date(remoteCommitTime).getTime().toString();
const remoteId = await getVersion(versionType);
set(() => ({
remoteVersion: remoteId,
}));
Expand Down

0 comments on commit be48346

Please sign in to comment.