Line data Source code
1 : import * as React from 'react';
2 :
3 : import { ReleaseManifest, WebVersionCheck } from './web_version_check.js';
4 : import { Result } from '../../utils/result.js';
5 : import { AppHost, getAppHost } from '../native_globals.js';
6 : import { ElectronVersionCheck } from './electron_version_check.js';
7 :
8 1 : export enum VersionCheckStatusCode {
9 1 : Unknown = 0,
10 1 : Disabled = 1,
11 1 : UpToDate = 2,
12 1 : UpdateAvailable = 3,
13 1 : UpdateInstalling = 4,
14 1 : RestartPending = 5,
15 1 : UpdateFailed = 6,
16 1 : }
17 :
18 1 : export enum InstallationStatusCode {
19 1 : Started,
20 1 : InProgress,
21 1 : RestartPending,
22 1 : Failed
23 1 : }
24 :
25 : export interface InstallationState {
26 : update: InstallableUpdate;
27 : statusCode: InstallationStatusCode;
28 : totalBytes: number | null;
29 : loadedBytes: number;
30 : inProgressBytes: number;
31 : error: Error | null;
32 : }
33 :
34 : export type InstallationStatusSetter = React.SetStateAction<InstallationState | null>;
35 :
36 : export interface InstallableUpdate {
37 : download(): Promise<void>
38 : }
39 :
40 1 : export const VERSION_CHECK_CTX = React.createContext<VersionCheckStatusCode>(VersionCheckStatusCode.Unknown);
41 1 : export const INSTALLATION_STATUS_CTX = React.createContext<InstallationState | null>(null);
42 1 : export const STABLE_RELEASE_MANIFEST_CTX = React.createContext<Result<ReleaseManifest> | null>(null);
43 1 : export const STABLE_UPDATE_MANIFEST_CTX = React.createContext<Result<InstallableUpdate | null> | null>(null);
44 1 : export const LATEST_RELEASE_MANIFEST_CTX = React.createContext<Result<ReleaseManifest> | null>(null);
45 1 : export const LATEST_UPDATE_MANIFEST_CTX = React.createContext<Result<InstallableUpdate | null> | null>(null);
46 : export interface VersionCheckRefresh {
47 : refresh: () => void;
48 : isRefreshing: boolean;
49 : }
50 :
51 : /// Re-run the version check for all channels. Null when no check is available (unknown platform).
52 1 : export const VERSION_CHECK_REFRESH_CTX = React.createContext<VersionCheckRefresh | null>(null);
53 :
54 1 : export function useVersionCheckRefreshState(check: () => Promise<void>): VersionCheckRefresh {
55 1 : const pendingChecks = React.useRef(0);
56 1 : const [isRefreshing, setIsRefreshing] = React.useState(false);
57 :
58 1 : const refresh = React.useCallback(() => {
59 1 : pendingChecks.current += 1;
60 1 : setIsRefreshing(true);
61 1 : void check().finally(() => {
62 1 : pendingChecks.current -= 1;
63 1 : if (pendingChecks.current === 0) {
64 1 : setIsRefreshing(false);
65 : }
66 1 : });
67 1 : }, [check]);
68 :
69 1 : React.useEffect(() => {
70 1 : refresh();
71 1 : }, [refresh]);
72 :
73 1 : return {refresh, isRefreshing};
74 1 : }
75 :
76 1 : export const useVersionCheck = () => React.useContext(VERSION_CHECK_CTX)!;
77 1 : export const useInstallationStatus = () => React.useContext(INSTALLATION_STATUS_CTX);
78 1 : export const useStableReleaseManifest = () => React.useContext(STABLE_RELEASE_MANIFEST_CTX);
79 1 : export const useStableUpdateManifest = () => React.useContext(STABLE_UPDATE_MANIFEST_CTX);
80 1 : export const useLatestReleaseManifest = () => React.useContext(LATEST_RELEASE_MANIFEST_CTX);
81 1 : export const useLatestUpdateManifest = () => React.useContext(LATEST_UPDATE_MANIFEST_CTX);
82 1 : export const useVersionCheckRefresh = () => React.useContext(VERSION_CHECK_REFRESH_CTX);
83 :
84 : interface VersionCheckProps {
85 : children: React.ReactElement;
86 : }
87 :
88 1 : export const VersionCheck: React.FC<VersionCheckProps> = (props: VersionCheckProps) => {
89 1 : return getAppHost() === AppHost.ELECTRON
90 1 : ? <ElectronVersionCheck>{props.children}</ElectronVersionCheck>
91 1 : : <WebVersionCheck>{props.children}</WebVersionCheck>;
92 1 : };
|