fix: update check for desktop app
This commit is contained in:
@@ -39,6 +39,23 @@ interface UpdateStore extends UpdateState {
|
|||||||
|
|
||||||
type ClientRuntime = 'desktop' | 'web' | 'vscode' | 'mobile';
|
type ClientRuntime = 'desktop' | 'web' | 'vscode' | 'mobile';
|
||||||
|
|
||||||
|
const CLIENT_INSTALL_ID_KEY = 'openchamber.update-install-id';
|
||||||
|
|
||||||
|
function getClientInstallId(): string | undefined {
|
||||||
|
if (typeof window === 'undefined' || typeof crypto.randomUUID !== 'function') return undefined;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const existing = window.localStorage.getItem(CLIENT_INSTALL_ID_KEY)?.trim();
|
||||||
|
if (existing) return existing;
|
||||||
|
|
||||||
|
const installId = crypto.randomUUID();
|
||||||
|
window.localStorage.setItem(CLIENT_INSTALL_ID_KEY, installId);
|
||||||
|
return installId;
|
||||||
|
} catch {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function detectDeviceClass(): 'mobile' | 'tablet' | 'desktop' | 'unknown' {
|
function detectDeviceClass(): 'mobile' | 'tablet' | 'desktop' | 'unknown' {
|
||||||
if (typeof window === 'undefined') return 'unknown';
|
if (typeof window === 'undefined') return 'unknown';
|
||||||
try {
|
try {
|
||||||
@@ -86,6 +103,10 @@ function mapRuntimeParams(runtime: ClientRuntime): URLSearchParams {
|
|||||||
params.set('deviceClass', detectDeviceClass());
|
params.set('deviceClass', detectDeviceClass());
|
||||||
params.set('arch', detectArch());
|
params.set('arch', detectArch());
|
||||||
params.set('platform', detectPlatform());
|
params.set('platform', detectPlatform());
|
||||||
|
if (shouldReportUsage && (runtime === 'desktop' || runtime === 'mobile')) {
|
||||||
|
const installId = getClientInstallId();
|
||||||
|
if (installId) params.set('installId', installId);
|
||||||
|
}
|
||||||
if (runtime === 'desktop') {
|
if (runtime === 'desktop') {
|
||||||
params.set('appType', 'desktop-electron');
|
params.set('appType', 'desktop-electron');
|
||||||
params.set('instanceMode', isDesktopLocalOriginActive() ? 'local' : 'remote');
|
params.set('instanceMode', isDesktopLocalOriginActive() ? 'local' : 'remote');
|
||||||
@@ -186,13 +207,21 @@ export const useUpdateStore = create<UpdateStore>()((set, get) => ({
|
|||||||
let suggestedSec: number | null = null;
|
let suggestedSec: number | null = null;
|
||||||
|
|
||||||
if (runtime === 'desktop') {
|
if (runtime === 'desktop') {
|
||||||
const desktopInfo = await checkForDesktopUpdates();
|
const appVersion = typeof __APP_VERSION__ !== 'undefined' ? __APP_VERSION__ : undefined;
|
||||||
|
const [desktopResult, apiResult] = await Promise.allSettled([
|
||||||
|
checkForDesktopUpdates(),
|
||||||
|
checkForWebUpdates('desktop', appVersion),
|
||||||
|
]);
|
||||||
|
const desktopInfo = desktopResult.status === 'fulfilled' ? desktopResult.value : null;
|
||||||
|
suggestedSec = apiResult.status === 'fulfilled'
|
||||||
|
? (apiResult.value?.nextSuggestedCheckInSec ?? null)
|
||||||
|
: null;
|
||||||
set({
|
set({
|
||||||
checking: false,
|
checking: false,
|
||||||
available: desktopInfo?.available ?? false,
|
available: desktopInfo?.available ?? false,
|
||||||
info: desktopInfo,
|
info: desktopInfo,
|
||||||
lastChecked: Date.now(),
|
lastChecked: Date.now(),
|
||||||
nextCheckInSec: null,
|
nextCheckInSec: suggestedSec,
|
||||||
});
|
});
|
||||||
|
|
||||||
return suggestedSec;
|
return suggestedSec;
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ export const registerOpenChamberRoutes = (app, dependencies) => {
|
|||||||
arch: parseString(req.query.arch),
|
arch: parseString(req.query.arch),
|
||||||
instanceMode: parseString(req.query.instanceMode),
|
instanceMode: parseString(req.query.instanceMode),
|
||||||
currentVersion: parseString(req.query.currentVersion),
|
currentVersion: parseString(req.query.currentVersion),
|
||||||
|
installId: parseString(req.query.installId),
|
||||||
reportUsage: parseReportUsage(parseString(req.query.reportUsage)),
|
reportUsage: parseReportUsage(parseString(req.query.reportUsage)),
|
||||||
});
|
});
|
||||||
res.json(updateInfo);
|
res.json(updateInfo);
|
||||||
|
|||||||
@@ -125,9 +125,10 @@ async function checkForUpdatesFromApi(currentVersion, options = {}) {
|
|||||||
const appType = normalizeAppType(options.appType);
|
const appType = normalizeAppType(options.appType);
|
||||||
const hostPlatform = mapPlatform(process.platform);
|
const hostPlatform = mapPlatform(process.platform);
|
||||||
const hostArch = mapArch(process.arch);
|
const hostArch = mapArch(process.arch);
|
||||||
const shouldTrustClientPlatform = appType === 'vscode' || appType === 'mobile-capacitor';
|
const shouldTrustClientPlatform = appType === 'desktop-electron' || appType === 'vscode' || appType === 'mobile-capacitor';
|
||||||
const platform = shouldTrustClientPlatform ? normalizePlatform(options.platform) : hostPlatform;
|
const platform = shouldTrustClientPlatform ? normalizePlatform(options.platform) : hostPlatform;
|
||||||
const arch = shouldTrustClientPlatform ? normalizeArch(options.arch) : hostArch;
|
const arch = shouldTrustClientPlatform ? normalizeArch(options.arch) : hostArch;
|
||||||
|
const reportUsage = options.reportUsage !== false;
|
||||||
const payload = {
|
const payload = {
|
||||||
appType,
|
appType,
|
||||||
deviceClass: normalizeDeviceClass(options.deviceClass),
|
deviceClass: normalizeDeviceClass(options.deviceClass),
|
||||||
@@ -135,9 +136,9 @@ async function checkForUpdatesFromApi(currentVersion, options = {}) {
|
|||||||
arch,
|
arch,
|
||||||
channel: 'stable',
|
channel: 'stable',
|
||||||
currentVersion,
|
currentVersion,
|
||||||
installId: getOrCreateInstallId(appType),
|
installId: reportUsage ? (options.installId || getOrCreateInstallId(appType)) : undefined,
|
||||||
instanceMode: options.instanceMode || 'unknown',
|
instanceMode: options.instanceMode || 'unknown',
|
||||||
reportUsage: options.reportUsage !== false,
|
reportUsage,
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await fetch(UPDATE_CHECK_URL, {
|
const response = await fetch(UPDATE_CHECK_URL, {
|
||||||
|
|||||||
@@ -134,11 +134,19 @@ describe('checkForUpdates', () => {
|
|||||||
const result = await checkForUpdates({
|
const result = await checkForUpdates({
|
||||||
appType: 'desktop-electron',
|
appType: 'desktop-electron',
|
||||||
currentVersion: '1.9.10',
|
currentVersion: '1.9.10',
|
||||||
|
installId: '4f4dfead-9688-4c4f-97d7-4607fbbfc3ab',
|
||||||
|
platform: 'windows',
|
||||||
|
arch: 'arm64',
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result.available).toBe(true);
|
expect(result.available).toBe(true);
|
||||||
expect(result.version).toBe('1.10.0');
|
expect(result.version).toBe('1.10.0');
|
||||||
expect(fetchMock).toHaveBeenCalledTimes(1);
|
expect(fetchMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(JSON.parse(fetchMock.mock.calls[0][1].body)).toMatchObject({
|
||||||
|
installId: '4f4dfead-9688-4c4f-97d7-4607fbbfc3ab',
|
||||||
|
platform: 'windows',
|
||||||
|
arch: 'arm64',
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('resolves an Android APK asset when the update API returns an AAB', async () => {
|
it('resolves an Android APK asset when the update API returns an AAB', async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user