Compare commits
3 Commits
6b9e4bff63
...
3534a797fc
| Author | SHA1 | Date | |
|---|---|---|---|
| 3534a797fc | |||
| a5cad3b746 | |||
| 998084160f |
@ -30,7 +30,7 @@ const About = () => {
|
||||
const { token } = useContext(AuthContext)
|
||||
const { fetchApiServerVersion, fetchWsServerVersion } =
|
||||
useContext(ApiServerContext)
|
||||
const { isElectron, getElectronVersion } = useContext(ElectronContext)
|
||||
const { isElectron, getAppEngine } = useContext(ElectronContext)
|
||||
const { checkForUpdates } = useContext(AppUpdateContext)
|
||||
const isMobile = useMediaQuery({ maxWidth: 768 })
|
||||
|
||||
@ -74,18 +74,18 @@ const About = () => {
|
||||
useEffect(() => {
|
||||
if (!isElectron) return
|
||||
|
||||
getElectronVersion()
|
||||
.then((version) => {
|
||||
setElectronVersion(version || 'unknown')
|
||||
getAppEngine()
|
||||
.then((engine) => {
|
||||
setAppEngine(engine === 'chromium' ? 'Chromium' : 'Native')
|
||||
})
|
||||
.catch(() => {
|
||||
setElectronVersion('unknown')
|
||||
setAppEngine('Unknown')
|
||||
})
|
||||
}, [getElectronVersion, isElectron])
|
||||
}, [getAppEngine, isElectron])
|
||||
|
||||
const [apiServerVersion, setApiServerVersion] = useState(null)
|
||||
const [wsServerVersion, setWsServerVersion] = useState(null)
|
||||
const [electronVersion, setElectronVersion] = useState(null)
|
||||
const [appEngine, setAppEngine] = useState(null)
|
||||
|
||||
const apiServerVersionText = apiServerVersion ? (
|
||||
<Text>
|
||||
@ -99,8 +99,8 @@ const About = () => {
|
||||
) : (
|
||||
<Skeleton.Input active size='small' className='text-skeleton' />
|
||||
)
|
||||
const electronVersionText = electronVersion ? (
|
||||
<Text>{`v${electronVersion}`}</Text>
|
||||
const appEngineText = appEngine ? (
|
||||
<Text>{appEngine}</Text>
|
||||
) : (
|
||||
<Skeleton.Input active size='small' className='text-skeleton' />
|
||||
)
|
||||
@ -153,9 +153,7 @@ const About = () => {
|
||||
</Text>
|
||||
</Text>
|
||||
{isElectron && (
|
||||
<Text type='secondary'>
|
||||
Electron: {electronVersionText}
|
||||
</Text>
|
||||
<Text type='secondary'>Engine: {appEngineText}</Text>
|
||||
)}
|
||||
|
||||
<Text type='secondary'>REST API: {apiServerVersionText}</Text>
|
||||
|
||||
@ -88,6 +88,16 @@ const NewAppUpdate = ({ update, onCancel, onUpdate }) => {
|
||||
<Text style={{ margin: 0 }} type='secondary'>
|
||||
Branch: <Text>{update?.branch || 'Unknown'}</Text>
|
||||
</Text>
|
||||
<Text style={{ margin: 0 }} type='secondary'>
|
||||
Engine:{' '}
|
||||
<Text>
|
||||
{update?.engine === 'chromium'
|
||||
? 'Chromium'
|
||||
: update?.engine === 'native'
|
||||
? 'Native'
|
||||
: 'Unknown'}
|
||||
</Text>
|
||||
</Text>
|
||||
</Flex>
|
||||
<Dropdown menu={actionsMenu}>
|
||||
<Button size='small' type='text'>
|
||||
|
||||
@ -5,6 +5,10 @@ import { useThemeContext } from '../context/ThemeContext'
|
||||
import { ApiServerContext } from '../context/ApiServerContext'
|
||||
import { ElectronContext } from '../context/ElectronContext'
|
||||
import { AuthContext } from '../context/AuthContext'
|
||||
import {
|
||||
normalizeAppUpdateEngine,
|
||||
useAppUpdateContext
|
||||
} from '../context/AppUpdateContext'
|
||||
import { useMessageContext } from '../context/MessageContext'
|
||||
import useCollapseState from '../hooks/useCollapseState'
|
||||
import InfoCollapse from '../common/InfoCollapse'
|
||||
@ -14,13 +18,22 @@ import EditButtons from '../common/EditButtons'
|
||||
const { Text } = Typography
|
||||
const { Option } = Select
|
||||
const DEFAULT_UPDATE_BRANCH = 'main'
|
||||
const DEFAULT_UPDATE_ENGINE = 'native'
|
||||
|
||||
const engineLabel = (engine) => {
|
||||
const normalized = normalizeAppUpdateEngine(engine)
|
||||
if (normalized === 'chromium') return 'Chromium'
|
||||
if (normalized === 'native') return 'Native'
|
||||
return 'Not configured'
|
||||
}
|
||||
|
||||
const Settings = () => {
|
||||
const { isDarkMode, isCompact, isSystem, setThemeMode, setDensityMode } =
|
||||
useThemeContext()
|
||||
const { fetchAppUpdateBranches } = useContext(ApiServerContext)
|
||||
const { isElectron, getAppSettings, setAppSettings } =
|
||||
const { isElectron, getAppSettings, setAppSettings, getAppEngine } =
|
||||
useContext(ElectronContext)
|
||||
const { recheckForUpdates } = useAppUpdateContext()
|
||||
const { userProfile, setUserProfile } = useContext(AuthContext)
|
||||
const { showSuccess, showError } = useMessageContext()
|
||||
const [collapseState, updateCollapseState] = useCollapseState('Settings', {
|
||||
@ -34,20 +47,31 @@ const Settings = () => {
|
||||
const [draftSettings, setDraftSettings] = useState({})
|
||||
const [branches, setBranches] = useState([])
|
||||
const [branchLoading, setBranchLoading] = useState(false)
|
||||
const [runningEngine, setRunningEngine] = useState(DEFAULT_UPDATE_ENGINE)
|
||||
|
||||
useEffect(() => {
|
||||
const loadSettings = async () => {
|
||||
setSettingsLoading(true)
|
||||
const storedSettings = isElectron
|
||||
? await getAppSettings()
|
||||
: userProfile?.settings || {}
|
||||
setAppSettingsState(storedSettings || {})
|
||||
setDraftSettings(storedSettings || {})
|
||||
const [storedSettings, detectedEngine] = await Promise.all([
|
||||
isElectron ? getAppSettings() : Promise.resolve(userProfile?.settings || {}),
|
||||
isElectron ? getAppEngine() : Promise.resolve(DEFAULT_UPDATE_ENGINE)
|
||||
])
|
||||
const nextEngine =
|
||||
normalizeAppUpdateEngine(detectedEngine) || DEFAULT_UPDATE_ENGINE
|
||||
setRunningEngine(nextEngine)
|
||||
|
||||
const nextSettings = { ...(storedSettings || {}) }
|
||||
if (isElectron && !normalizeAppUpdateEngine(nextSettings.appUpdateEngine)) {
|
||||
nextSettings.appUpdateEngine = nextEngine
|
||||
}
|
||||
|
||||
setAppSettingsState(nextSettings)
|
||||
setDraftSettings(nextSettings)
|
||||
setSettingsLoading(false)
|
||||
}
|
||||
|
||||
loadSettings()
|
||||
}, [getAppSettings, isElectron, userProfile?.settings])
|
||||
}, [getAppEngine, getAppSettings, isElectron, userProfile?.settings])
|
||||
|
||||
useEffect(() => {
|
||||
if (settingsLoading || isEditing) return
|
||||
@ -118,12 +142,17 @@ const Settings = () => {
|
||||
(branches.includes(DEFAULT_UPDATE_BRANCH) ? DEFAULT_UPDATE_BRANCH : null) ||
|
||||
branches[0] ||
|
||||
'Not configured'
|
||||
const currentEngine =
|
||||
normalizeAppUpdateEngine(appSettings.appUpdateEngine) ||
|
||||
normalizeAppUpdateEngine(runningEngine) ||
|
||||
DEFAULT_UPDATE_ENGINE
|
||||
|
||||
const startEditing = () => {
|
||||
setDraftSettings({
|
||||
...appSettings,
|
||||
appUpdateBranch:
|
||||
currentBranch === 'Not configured' ? undefined : currentBranch,
|
||||
appUpdateEngine: currentEngine,
|
||||
theme: currentThemeValue,
|
||||
density: currentDensityValue
|
||||
})
|
||||
@ -139,12 +168,18 @@ const Settings = () => {
|
||||
setSaving(true)
|
||||
|
||||
try {
|
||||
const nextEngine =
|
||||
normalizeAppUpdateEngine(draftSettings.appUpdateEngine) ||
|
||||
currentEngine
|
||||
const nextSettings = {
|
||||
...appSettings,
|
||||
theme: draftSettings.theme,
|
||||
density: draftSettings.density,
|
||||
...(isElectron
|
||||
? { appUpdateBranch: draftSettings.appUpdateBranch }
|
||||
? {
|
||||
appUpdateBranch: draftSettings.appUpdateBranch,
|
||||
appUpdateEngine: nextEngine
|
||||
}
|
||||
: {})
|
||||
}
|
||||
const saved = isElectron
|
||||
@ -173,6 +208,16 @@ const Settings = () => {
|
||||
setDraftSettings(nextSettings)
|
||||
setIsEditing(false)
|
||||
showSuccess('Settings saved.')
|
||||
|
||||
const appUpdateSettingsChanged =
|
||||
isElectron &&
|
||||
(nextSettings.appUpdateBranch !== appSettings.appUpdateBranch ||
|
||||
nextSettings.appUpdateEngine !==
|
||||
normalizeAppUpdateEngine(appSettings.appUpdateEngine))
|
||||
|
||||
if (appUpdateSettingsChanged) {
|
||||
void recheckForUpdates()
|
||||
}
|
||||
} finally {
|
||||
setSaving(false)
|
||||
}
|
||||
@ -196,7 +241,9 @@ const Settings = () => {
|
||||
startEditing={startEditing}
|
||||
formValid={
|
||||
Boolean(draftSettings.theme && draftSettings.density) &&
|
||||
(!isElectron || Boolean(draftSettings.appUpdateBranch))
|
||||
(!isElectron ||
|
||||
(Boolean(draftSettings.appUpdateBranch) &&
|
||||
Boolean(normalizeAppUpdateEngine(draftSettings.appUpdateEngine))))
|
||||
}
|
||||
disabled={settingsLoading || (!isElectron && !userProfile)}
|
||||
loading={saving}
|
||||
@ -297,6 +344,29 @@ const Settings = () => {
|
||||
<Text>{currentBranch}</Text>
|
||||
)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label='Engine'>
|
||||
{isEditing ? (
|
||||
<Select
|
||||
value={
|
||||
normalizeAppUpdateEngine(draftSettings.appUpdateEngine) ||
|
||||
currentEngine
|
||||
}
|
||||
onChange={(value) =>
|
||||
setDraftSettings((previous) => ({
|
||||
...previous,
|
||||
appUpdateEngine: value
|
||||
}))
|
||||
}
|
||||
style={{ width: '100%' }}
|
||||
placeholder='Select an engine'
|
||||
>
|
||||
<Option value='native'>Native</Option>
|
||||
<Option value='chromium'>Chromium</Option>
|
||||
</Select>
|
||||
) : (
|
||||
<Text>{engineLabel(currentEngine)}</Text>
|
||||
)}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</InfoCollapse>
|
||||
)}
|
||||
|
||||
@ -20,10 +20,22 @@ import SoftwareUpdateIcon from '../../Icons/SoftwareUpdateIcon'
|
||||
const { Text } = Typography
|
||||
|
||||
const UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1000
|
||||
const DEFAULT_MODEL_WIDTH = 710
|
||||
const DEFAULT_UPDATE_BRANCH = 'main'
|
||||
const DEFAULT_UPDATE_ENGINE = 'native'
|
||||
const CURRENT_BUILD_NUMBER = import.meta.env.VITE_BUILD_NUMBER
|
||||
const APP_UPDATE_DISMISSED_KEY = 'appUpdateDismissed'
|
||||
|
||||
export const normalizeAppUpdateEngine = (engine) => {
|
||||
const value = String(engine || '')
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
|
||||
if (value === 'chromium' || value === 'cef') return 'chromium'
|
||||
if (value === 'native') return 'native'
|
||||
return null
|
||||
}
|
||||
|
||||
const getDismissedUpdate = () => {
|
||||
try {
|
||||
const stored = sessionStorage.getItem(APP_UPDATE_DISMISSED_KEY)
|
||||
@ -42,7 +54,9 @@ const isUpdateDismissed = (update) => {
|
||||
return (
|
||||
dismissed.version === update.version &&
|
||||
dismissed.buildNumber === update.buildNumber &&
|
||||
dismissed.branch === update.branch
|
||||
dismissed.branch === update.branch &&
|
||||
normalizeAppUpdateEngine(dismissed.engine) ===
|
||||
normalizeAppUpdateEngine(update.engine)
|
||||
)
|
||||
}
|
||||
|
||||
@ -54,7 +68,8 @@ const saveDismissedUpdate = (update) => {
|
||||
JSON.stringify({
|
||||
version: update.version,
|
||||
buildNumber: update.buildNumber,
|
||||
branch: update.branch
|
||||
branch: update.branch,
|
||||
engine: normalizeAppUpdateEngine(update.engine) || DEFAULT_UPDATE_ENGINE
|
||||
})
|
||||
)
|
||||
}
|
||||
@ -109,8 +124,14 @@ export const AppUpdateProvider = ({ children }) => {
|
||||
const { fetchAppUpdateBranches, fetchAppUpdateCurrent } =
|
||||
useContext(ApiServerContext)
|
||||
const { token } = useContext(AuthContext)
|
||||
const { isElectron, getAppSettings, startAppUpdate, onAppUpdateProgress } =
|
||||
useContext(ElectronContext)
|
||||
const {
|
||||
isElectron,
|
||||
getAppSettings,
|
||||
setAppSettings,
|
||||
getAppEngine,
|
||||
startAppUpdate,
|
||||
onAppUpdateProgress
|
||||
} = useContext(ElectronContext)
|
||||
const [checking, setChecking] = useState(false)
|
||||
const [noUpdateOpen, setNoUpdateOpen] = useState(false)
|
||||
const [availableUpdate, setAvailableUpdate] = useState(null)
|
||||
@ -120,12 +141,14 @@ export const AppUpdateProvider = ({ children }) => {
|
||||
const runningCheckRef = useRef(null)
|
||||
const updateCheckDependenciesRef = useRef({})
|
||||
|
||||
const [modelWidth, setModelWidth] = useState(650)
|
||||
const [modelWidth, setModelWidth] = useState(DEFAULT_MODEL_WIDTH)
|
||||
|
||||
updateCheckDependenciesRef.current = {
|
||||
fetchAppUpdateBranches,
|
||||
fetchAppUpdateCurrent,
|
||||
getAppSettings,
|
||||
setAppSettings,
|
||||
getAppEngine,
|
||||
isElectron,
|
||||
token
|
||||
}
|
||||
@ -135,6 +158,8 @@ export const AppUpdateProvider = ({ children }) => {
|
||||
fetchAppUpdateBranches,
|
||||
fetchAppUpdateCurrent,
|
||||
getAppSettings,
|
||||
setAppSettings,
|
||||
getAppEngine,
|
||||
isElectron,
|
||||
token
|
||||
} = updateCheckDependenciesRef.current
|
||||
@ -143,9 +168,10 @@ export const AppUpdateProvider = ({ children }) => {
|
||||
if (runningCheckRef.current) return runningCheckRef.current
|
||||
|
||||
const checkPromise = (async () => {
|
||||
const [branches, appSettings] = await Promise.all([
|
||||
const [branches, appSettings, runningEngine] = await Promise.all([
|
||||
fetchAppUpdateBranches(),
|
||||
getAppSettings()
|
||||
getAppSettings(),
|
||||
getAppEngine()
|
||||
])
|
||||
const configuredBranch = appSettings?.appUpdateBranch
|
||||
const defaultBranch = branches.includes(DEFAULT_UPDATE_BRANCH)
|
||||
@ -157,11 +183,52 @@ export const AppUpdateProvider = ({ children }) => {
|
||||
|
||||
if (!selectedBranch) return null
|
||||
|
||||
const update = await fetchAppUpdateCurrent(selectedBranch)
|
||||
const selectedEngine =
|
||||
normalizeAppUpdateEngine(appSettings?.appUpdateEngine) ||
|
||||
normalizeAppUpdateEngine(runningEngine) ||
|
||||
DEFAULT_UPDATE_ENGINE
|
||||
const currentRunningEngine =
|
||||
normalizeAppUpdateEngine(runningEngine) || DEFAULT_UPDATE_ENGINE
|
||||
|
||||
return isAppUpdateAvailable(update, appVersion, CURRENT_BUILD_NUMBER)
|
||||
? update
|
||||
: null
|
||||
const settingsUpdates = {}
|
||||
if (!appSettings?.appUpdateRunningBranch) {
|
||||
settingsUpdates.appUpdateRunningBranch = selectedBranch
|
||||
}
|
||||
if (!normalizeAppUpdateEngine(appSettings?.appUpdateEngine)) {
|
||||
settingsUpdates.appUpdateEngine = selectedEngine
|
||||
}
|
||||
if (Object.keys(settingsUpdates).length > 0) {
|
||||
await setAppSettings({
|
||||
...appSettings,
|
||||
...settingsUpdates
|
||||
})
|
||||
}
|
||||
|
||||
const runningBranch =
|
||||
appSettings?.appUpdateRunningBranch ||
|
||||
settingsUpdates.appUpdateRunningBranch ||
|
||||
selectedBranch
|
||||
|
||||
const update = await fetchAppUpdateCurrent(selectedBranch)
|
||||
if (!update) return null
|
||||
|
||||
const newerVersionAvailable = isAppUpdateAvailable(
|
||||
update,
|
||||
appVersion,
|
||||
CURRENT_BUILD_NUMBER
|
||||
)
|
||||
const engineMismatch = selectedEngine !== currentRunningEngine
|
||||
const branchMismatch = selectedBranch !== runningBranch
|
||||
|
||||
if (!newerVersionAvailable && !engineMismatch && !branchMismatch) {
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
...update,
|
||||
branch: update.branch || selectedBranch,
|
||||
engine: selectedEngine
|
||||
}
|
||||
})()
|
||||
|
||||
runningCheckRef.current = checkPromise
|
||||
@ -181,6 +248,7 @@ export const AppUpdateProvider = ({ children }) => {
|
||||
setNoUpdateOpen(false)
|
||||
setAvailableUpdate(update)
|
||||
if (forcePrompt || !isUpdateDismissed(update)) {
|
||||
setModelWidth(DEFAULT_MODEL_WIDTH)
|
||||
setUpdatePromptOpen(true)
|
||||
}
|
||||
}
|
||||
@ -205,6 +273,11 @@ export const AppUpdateProvider = ({ children }) => {
|
||||
}
|
||||
}, [isElectron, showUpdateIfAvailable])
|
||||
|
||||
const recheckForUpdates = useCallback(async () => {
|
||||
if (!isElectron) return null
|
||||
return showUpdateIfAvailable({ forcePrompt: true })
|
||||
}, [isElectron, showUpdateIfAvailable])
|
||||
|
||||
useEffect(() => {
|
||||
if (!isElectron) return undefined
|
||||
|
||||
@ -252,7 +325,15 @@ export const AppUpdateProvider = ({ children }) => {
|
||||
})
|
||||
|
||||
try {
|
||||
const result = await startAppUpdate(update)
|
||||
const appSettings = await getAppSettings()
|
||||
const engine =
|
||||
normalizeAppUpdateEngine(update?.engine) ||
|
||||
normalizeAppUpdateEngine(appSettings?.appUpdateEngine) ||
|
||||
DEFAULT_UPDATE_ENGINE
|
||||
const result = await startAppUpdate({
|
||||
...update,
|
||||
engine
|
||||
})
|
||||
|
||||
if (!result) {
|
||||
throw new Error(
|
||||
@ -273,7 +354,9 @@ export const AppUpdateProvider = ({ children }) => {
|
||||
Boolean(installingUpdate) && updateProgress?.phase !== 'error'
|
||||
|
||||
return (
|
||||
<AppUpdateContext.Provider value={{ availableUpdate, checkForUpdates }}>
|
||||
<AppUpdateContext.Provider
|
||||
value={{ availableUpdate, checkForUpdates, recheckForUpdates }}
|
||||
>
|
||||
{children}
|
||||
<Modal
|
||||
open={checking}
|
||||
|
||||
@ -369,6 +369,15 @@ const ElectronProvider = ({ children }) => {
|
||||
return await ipcRenderer.invoke('electron-version')
|
||||
}, [electronAvailable, useElectrobun])
|
||||
|
||||
const getAppEngine = useCallback(async () => {
|
||||
if (!electronAvailable) return 'native'
|
||||
if (useElectrobun) {
|
||||
const engine = await desktopBridge.getAppEngine()
|
||||
return engine === 'chromium' ? 'chromium' : 'native'
|
||||
}
|
||||
return 'native'
|
||||
}, [electronAvailable, useElectrobun])
|
||||
|
||||
return (
|
||||
<ElectronContext.Provider
|
||||
value={{
|
||||
@ -390,7 +399,8 @@ const ElectronProvider = ({ children }) => {
|
||||
setToken,
|
||||
resizeSpotlightWindow,
|
||||
setSidebarViewMenu,
|
||||
getElectronVersion
|
||||
getElectronVersion,
|
||||
getAppEngine
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
||||
@ -13,6 +13,7 @@ import { ApiServerContext } from './ApiServerContext'
|
||||
import NotificationCenter from '../common/NotificationCenter'
|
||||
import Notification from '../common/Notification'
|
||||
import { useMediaQuery } from 'react-responsive'
|
||||
import { ElectronContext } from './ElectronContext'
|
||||
|
||||
const NotificationContext = createContext()
|
||||
|
||||
@ -35,6 +36,8 @@ const NotificationProvider = ({ children }) => {
|
||||
const [notifications, setNotifications] = useState([])
|
||||
const [notificationsLoading, setNotificationsLoading] = useState(false)
|
||||
|
||||
const { isElectron } = useContext(ElectronContext)
|
||||
|
||||
const isMobile = useMediaQuery({ maxWidth: 768 })
|
||||
|
||||
const fetchNotifications = useCallback(async () => {
|
||||
@ -180,6 +183,7 @@ const NotificationProvider = ({ children }) => {
|
||||
title='Notifications'
|
||||
placement='right'
|
||||
width={isMobile ? '100%' : 460}
|
||||
style={{ marginTop: isElectron ? '40px' : '0px' }}
|
||||
onClose={() => setNotificationCenterVisible(false)}
|
||||
open={notificationCenterVisible}
|
||||
>
|
||||
|
||||
@ -8,6 +8,7 @@ import { Utils } from "electrobun/bun";
|
||||
import { launchMacInstaller } from "./macappupdate.js";
|
||||
import { launchWindowsInstaller } from "./winappupdate.js";
|
||||
import { scheduleAppRestart } from "./updater-runner.js";
|
||||
import { getAppSettings, setAppSettings } from "./store.js";
|
||||
|
||||
const SUPPORTED_TARGETS = {
|
||||
darwin: {
|
||||
@ -20,6 +21,8 @@ const SUPPORTED_TARGETS = {
|
||||
},
|
||||
};
|
||||
|
||||
const DEFAULT_UPDATE_ENGINE = "native";
|
||||
|
||||
let runningUpdate = null;
|
||||
|
||||
const getArtifactName = (artifact) =>
|
||||
@ -31,6 +34,33 @@ const normalizeArch = (arch) => {
|
||||
return arch;
|
||||
};
|
||||
|
||||
const normalizeEngine = (engine) => {
|
||||
const value = String(engine || "")
|
||||
.trim()
|
||||
.toLowerCase();
|
||||
|
||||
if (value === "chromium" || value === "cef") return "chromium";
|
||||
if (value === "native") return "native";
|
||||
return null;
|
||||
};
|
||||
|
||||
const artifactIsChromium = (artifact) => {
|
||||
const explicit = String(
|
||||
artifact?.engine || artifact?.renderer || "",
|
||||
).toLowerCase();
|
||||
|
||||
if (explicit === "cef" || explicit === "chromium") return true;
|
||||
if (explicit === "native") return false;
|
||||
|
||||
const name = getArtifactName(artifact).toLowerCase();
|
||||
return /[-_.]cef(?:[-_.]|$)/.test(name);
|
||||
};
|
||||
|
||||
const artifactMatchesEngine = (artifact, engine) => {
|
||||
const wantsChromium = normalizeEngine(engine) === "chromium";
|
||||
return artifactIsChromium(artifact) === wantsChromium;
|
||||
};
|
||||
|
||||
const artifactMatchesPlatform = (artifact, target, platform, arch) => {
|
||||
const name = getArtifactName(artifact).toLowerCase();
|
||||
const normalizedArch = normalizeArch(arch);
|
||||
@ -69,22 +99,23 @@ const selectUpdateArtifact = (
|
||||
throw new Error(`App updates are not supported on ${platform}.`);
|
||||
}
|
||||
|
||||
const engine =
|
||||
normalizeEngine(update?.engine) || DEFAULT_UPDATE_ENGINE;
|
||||
const artifacts = Array.isArray(update?.artifacts) ? update.artifacts : [];
|
||||
const matchingArtifact = artifacts.find((artifact) =>
|
||||
artifactMatchesPlatform(artifact, target, platform, arch),
|
||||
const matchingArtifact = artifacts.find(
|
||||
(artifact) =>
|
||||
artifactMatchesPlatform(artifact, target, platform, arch) &&
|
||||
artifactMatchesEngine(artifact, engine),
|
||||
);
|
||||
const fallbackArtifact = artifacts.find((artifact) => {
|
||||
const name = getArtifactName(artifact).toLowerCase();
|
||||
return artifact?.url && name.endsWith(target.extension);
|
||||
});
|
||||
|
||||
if (!matchingArtifact && !fallbackArtifact) {
|
||||
if (!matchingArtifact) {
|
||||
const engineLabel = engine === "chromium" ? "Chromium (cef)" : "Native";
|
||||
throw new Error(
|
||||
`No ${target.extension} update artifact found for ${platform}/${arch}.`,
|
||||
`No ${target.extension} ${engineLabel} update artifact found for ${platform}/${arch}.`,
|
||||
);
|
||||
}
|
||||
|
||||
return matchingArtifact || fallbackArtifact;
|
||||
return matchingArtifact;
|
||||
};
|
||||
|
||||
const getInstallErrorMessage = (error, output = "") => {
|
||||
@ -181,10 +212,34 @@ const downloadArtifact = async (artifact, destinationPath, sendProgress) => {
|
||||
});
|
||||
};
|
||||
|
||||
const persistInstalledUpdateSettings = async (update) => {
|
||||
try {
|
||||
const settings = await getAppSettings();
|
||||
const engine =
|
||||
normalizeEngine(update?.engine) ||
|
||||
normalizeEngine(settings?.appUpdateEngine) ||
|
||||
DEFAULT_UPDATE_ENGINE;
|
||||
|
||||
await setAppSettings({
|
||||
...settings,
|
||||
appUpdateEngine: engine,
|
||||
...(update?.branch
|
||||
? { appUpdateRunningBranch: update.branch }
|
||||
: {}),
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
"[app-update] Failed to persist installed update settings.",
|
||||
error,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const launchInstallerAndRestart = async (
|
||||
mainWindow,
|
||||
installerPath,
|
||||
sendProgress,
|
||||
update,
|
||||
) => {
|
||||
const installerHelpers = { sendProgress, getInstallErrorMessage };
|
||||
|
||||
@ -206,6 +261,8 @@ const launchInstallerAndRestart = async (
|
||||
throw new Error(`App updates are not supported on ${process.platform}.`);
|
||||
}
|
||||
|
||||
await persistInstalledUpdateSettings(update);
|
||||
|
||||
if (process.platform === "darwin") {
|
||||
scheduleAppRestart();
|
||||
}
|
||||
@ -241,7 +298,12 @@ const runAppUpdate = async (mainWindow, update, sendProgress) => {
|
||||
message: "Update downloaded",
|
||||
});
|
||||
|
||||
await launchInstallerAndRestart(mainWindow, installerPath, sendProgress);
|
||||
await launchInstallerAndRestart(
|
||||
mainWindow,
|
||||
installerPath,
|
||||
sendProgress,
|
||||
update,
|
||||
);
|
||||
};
|
||||
|
||||
export function startAppUpdate(mainWindow, update, sendProgress) {
|
||||
|
||||
@ -72,7 +72,12 @@ export function createAppRpc() {
|
||||
setSidebarViewMenu: async ({ sections }) => ({
|
||||
ok: setSidebarViewMenu(sections)
|
||||
}),
|
||||
getAppVersion: async () => process.env.ELECTROBUN_VERSION || 'desktop'
|
||||
getAppVersion: async () => process.env.ELECTROBUN_VERSION || 'desktop',
|
||||
getAppEngine: async () => {
|
||||
const mainWindow = getMainWindow()
|
||||
const renderer = mainWindow?.renderer || 'native'
|
||||
return renderer === 'cef' ? 'chromium' : 'native'
|
||||
}
|
||||
},
|
||||
messages: {}
|
||||
}
|
||||
|
||||
@ -185,7 +185,8 @@ const electronAPI = {
|
||||
invokeRequest('resizeSpotlightWindow', { height }),
|
||||
setSidebarViewMenu: (sections) =>
|
||||
invokeRequest('setSidebarViewMenu', { sections }),
|
||||
getAppVersion: () => invokeRequest('getAppVersion')
|
||||
getAppVersion: () => invokeRequest('getAppVersion'),
|
||||
getAppEngine: () => invokeRequest('getAppEngine')
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user