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