167 lines
4.7 KiB
TypeScript
167 lines
4.7 KiB
TypeScript
import { ClientApi } from '../client/api';
|
|
import { getClientConfig } from '../config/client';
|
|
import {
|
|
FETCH_COMMIT_URL,
|
|
FETCH_TAG_URL,
|
|
ModelProvider,
|
|
StoreKey,
|
|
} from '../constant';
|
|
import ChatGptIcon from '../icons/chatgpt.png';
|
|
import Locale from '../locales';
|
|
import { clientUpdate } from '../utils';
|
|
import { createPersistStore } from '../utils/store';
|
|
|
|
const ONE_MINUTE = 60 * 1000;
|
|
const isApp = !!getClientConfig()?.isApp;
|
|
|
|
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('');
|
|
}
|
|
|
|
type VersionType = 'date' | 'tag';
|
|
|
|
async function getVersion(type: VersionType) {
|
|
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 = createPersistStore(
|
|
{
|
|
versionType: 'tag' as VersionType,
|
|
lastUpdate: 0,
|
|
version: 'unknown',
|
|
remoteVersion: '',
|
|
used: 0,
|
|
subscription: 0,
|
|
|
|
lastUpdateUsage: 0,
|
|
},
|
|
(set, get) => ({
|
|
formatVersion(version: string) {
|
|
if (get().versionType === 'date') {
|
|
version = formatVersionDate(version);
|
|
}
|
|
return version;
|
|
},
|
|
|
|
async getLatestVersion(force = false) {
|
|
const versionType = get().versionType;
|
|
const version
|
|
= versionType === 'date'
|
|
? getClientConfig()?.commitDate
|
|
: getClientConfig()?.version;
|
|
|
|
set(() => ({ version }));
|
|
|
|
const shouldCheck = Date.now() - get().lastUpdate > 2 * 60 * ONE_MINUTE;
|
|
if (!force && !shouldCheck)
|
|
{ return; }
|
|
|
|
set(() => ({
|
|
lastUpdate: Date.now(),
|
|
}));
|
|
|
|
try {
|
|
const remoteId = await getVersion(versionType);
|
|
set(() => ({
|
|
remoteVersion: remoteId,
|
|
}));
|
|
if (window.__TAURI__?.notification && isApp) {
|
|
// Check if notification permission is granted
|
|
await window.__TAURI__?.notification
|
|
.isPermissionGranted()
|
|
.then((granted: any) => {
|
|
if (!granted) {
|
|
|
|
} else {
|
|
// Request permission to show notifications
|
|
window.__TAURI__?.notification
|
|
.requestPermission()
|
|
.then((permission: any) => {
|
|
if (permission === 'granted') {
|
|
if (version === remoteId) {
|
|
// Show a notification using Tauri
|
|
window.__TAURI__?.notification.sendNotification({
|
|
title: 'NextChat',
|
|
body: `${Locale.Settings.Update.IsLatest}`,
|
|
icon: `${ChatGptIcon.src}`,
|
|
sound: 'Default',
|
|
});
|
|
} else {
|
|
const updateMessage
|
|
= Locale.Settings.Update.FoundUpdate(`${remoteId}`);
|
|
// Show a notification for the new version using Tauri
|
|
window.__TAURI__?.notification.sendNotification({
|
|
title: 'NextChat',
|
|
body: updateMessage,
|
|
icon: `${ChatGptIcon.src}`,
|
|
sound: 'Default',
|
|
});
|
|
clientUpdate();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
console.log('[Got Upstream] ', remoteId);
|
|
} catch (error) {
|
|
console.error('[Fetch Upstream Commit Id]', error);
|
|
}
|
|
},
|
|
|
|
async updateUsage(force = false) {
|
|
// only support openai for now
|
|
const overOneMinute = Date.now() - get().lastUpdateUsage >= ONE_MINUTE;
|
|
if (!overOneMinute && !force)
|
|
{ return; }
|
|
|
|
set(() => ({
|
|
lastUpdateUsage: Date.now(),
|
|
}));
|
|
|
|
try {
|
|
const api = new ClientApi(ModelProvider.GPT);
|
|
const usage = await api.llm.usage();
|
|
|
|
if (usage) {
|
|
set(() => ({
|
|
used: usage.used,
|
|
subscription: usage.total,
|
|
}));
|
|
}
|
|
} catch (e) {
|
|
console.error((e as Error).message);
|
|
}
|
|
},
|
|
}),
|
|
{
|
|
name: StoreKey.Update,
|
|
version: 1,
|
|
},
|
|
);
|