Compare commits
2 Commits
324a4a1e6f
...
3caae592f1
| Author | SHA1 | Date | |
|---|---|---|---|
| 3caae592f1 | |||
| ba5856c248 |
@ -67,7 +67,7 @@ Function .onInit
|
||||
!insertmacro progressPhase "Starting installation"
|
||||
!insertmacro progressStatus "Starting Farm Control installation..."
|
||||
!insertmacro progressCopyTotal "${APP_COPY_TOTAL_BYTES}"
|
||||
!insertmacro progressPercent 0
|
||||
!insertmacro progressStart
|
||||
|
||||
; In-app updates install into Farm Control.new while the running process
|
||||
; keeps using Farm Control; the folders are swapped after exit (/RESTARTFC).
|
||||
@ -78,6 +78,8 @@ Function .onInit
|
||||
StrCpy $FinalInstDir $INSTDIR
|
||||
!insertmacro uninstallPreviousFarmControl
|
||||
${EndIf}
|
||||
|
||||
!insertmacro progressPrepare
|
||||
FunctionEnd
|
||||
|
||||
Function .onInstFailed
|
||||
@ -93,17 +95,17 @@ Section "Farm Control" SecMain
|
||||
|
||||
!insertmacro progressPhase "Copying application files"
|
||||
!insertmacro progressStatus "Copying application files..."
|
||||
!insertmacro progressPercent 0
|
||||
!insertmacro progressCopyStart
|
||||
|
||||
SetOverwrite try
|
||||
!insertmacro copyApplicationFilesWithProgress
|
||||
|
||||
!insertmacro progressPercent 75
|
||||
!insertmacro progressCopyComplete
|
||||
!insertmacro customInstall
|
||||
|
||||
!insertmacro progressFinalizeInstall
|
||||
!insertmacro progressPhase "Finalizing installation"
|
||||
!insertmacro progressStatus "Writing uninstall information..."
|
||||
!insertmacro progressPercent 90
|
||||
!insertmacro progressStatus "Writing installation registry entries..."
|
||||
|
||||
WriteRegStr HKCU "Software\Tom Butcher\Farm Control" "InstallDir" $FinalInstDir
|
||||
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Farm Control" \
|
||||
@ -119,8 +121,14 @@ Section "Farm Control" SecMain
|
||||
WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Farm Control" \
|
||||
"NoRepair" 1
|
||||
|
||||
!insertmacro progressWriteUninstaller
|
||||
!insertmacro progressStatus "Writing uninstall information..."
|
||||
|
||||
WriteUninstaller "$INSTDIR\Uninstall.exe"
|
||||
|
||||
!insertmacro progressFinalize
|
||||
|
||||
|
||||
; For in-app updates (/RESTARTFC) the success signal is emitted from
|
||||
; restartFarmControlAfterUpdate, right before the install directory swap,
|
||||
; so the running app quits while this installer stays alive.
|
||||
|
||||
@ -95,10 +95,56 @@ Var UpdateParentPid
|
||||
${EndIf}
|
||||
!macroend
|
||||
|
||||
!define PROGRESS_START 1
|
||||
!define PREPARE_PROGRESS 3
|
||||
!define COPY_PROGRESS_START 5
|
||||
!define COPY_PROGRESS_END 90
|
||||
!define CONFIGURE_PROGRESS 91
|
||||
!define SHORTCUTS_PROGRESS 93
|
||||
!define FINALIZE_PROGRESS 95
|
||||
!define UNINSTALLER_PROGRESS 97
|
||||
!define COMPLETE_PROGRESS 99
|
||||
|
||||
!macro progressPercent percent
|
||||
!insertmacro progressLog "installer:%${percent}"
|
||||
!macroend
|
||||
|
||||
!macro progressStart
|
||||
!insertmacro progressPercent "${PROGRESS_START}"
|
||||
!macroend
|
||||
|
||||
!macro progressPrepare
|
||||
!insertmacro progressPercent "${PREPARE_PROGRESS}"
|
||||
!macroend
|
||||
|
||||
!macro progressCopyStart
|
||||
!insertmacro progressPercent "${COPY_PROGRESS_START}"
|
||||
!macroend
|
||||
|
||||
!macro progressCopyComplete
|
||||
!insertmacro progressPercent "${COPY_PROGRESS_END}"
|
||||
!macroend
|
||||
|
||||
!macro progressConfigure
|
||||
!insertmacro progressPercent "${CONFIGURE_PROGRESS}"
|
||||
!macroend
|
||||
|
||||
!macro progressShortcuts
|
||||
!insertmacro progressPercent "${SHORTCUTS_PROGRESS}"
|
||||
!macroend
|
||||
|
||||
!macro progressFinalizeInstall
|
||||
!insertmacro progressPercent "${FINALIZE_PROGRESS}"
|
||||
!macroend
|
||||
|
||||
!macro progressWriteUninstaller
|
||||
!insertmacro progressPercent "${UNINSTALLER_PROGRESS}"
|
||||
!macroend
|
||||
|
||||
!macro progressFinalize
|
||||
!insertmacro progressPercent "${COMPLETE_PROGRESS}"
|
||||
!macroend
|
||||
|
||||
!macro progressPhase phase
|
||||
!insertmacro progressLog "installer:PHASE:${phase}"
|
||||
!macroend
|
||||
@ -302,6 +348,7 @@ Var UpdateParentPid
|
||||
!macroend
|
||||
|
||||
!macro customInstall
|
||||
!insertmacro progressConfigure
|
||||
!insertmacro progressPhase "Configuring Farm Control"
|
||||
!insertmacro progressStatus "Registering farmcontrol URI handler..."
|
||||
DetailPrint "Register farmcontrol URI Handler"
|
||||
@ -313,6 +360,7 @@ Var UpdateParentPid
|
||||
WriteRegStr HKCU "Software\Classes\farmcontrol\shell\Open" "" ""
|
||||
WriteRegStr HKCU "Software\Classes\farmcontrol\shell\Open\command" "" '"$FinalInstDir\bin\bun.exe" "$FinalInstDir\bin\deeplink.js" "%1"'
|
||||
|
||||
!insertmacro progressShortcuts
|
||||
!insertmacro progressStatus "Creating shortcuts..."
|
||||
DetailPrint "Creating shortcuts"
|
||||
!insertmacro createDesktopShortcut
|
||||
|
||||
@ -62,6 +62,20 @@ const isUpdateDismissed = (update) => {
|
||||
)
|
||||
}
|
||||
|
||||
const formatFullAppVersion = (version, buildNumber) => {
|
||||
const normalizedVersion = String(version || '')
|
||||
.trim()
|
||||
.replace(/^v/i, '')
|
||||
|
||||
if (!normalizedVersion) return null
|
||||
|
||||
const build = String(buildNumber || '').trim()
|
||||
const buildSuffix =
|
||||
!build || build === 'dev' ? 'dev' : build.startsWith('b') ? build : `b${build}`
|
||||
|
||||
return `v${normalizedVersion}-${buildSuffix}`
|
||||
}
|
||||
|
||||
const saveDismissedUpdate = (update) => {
|
||||
if (!update) return
|
||||
|
||||
@ -543,13 +557,12 @@ export const AppUpdateProvider = ({ children }) => {
|
||||
]}
|
||||
>
|
||||
<Text>
|
||||
Farm Control was successfully updated to version{' '}
|
||||
{completedUpdate?.current?.version || appVersion}
|
||||
{completedUpdate?.previous?.version &&
|
||||
completedUpdate.previous.version !== completedUpdate?.current?.version
|
||||
? ` (previously ${completedUpdate.previous.version})`
|
||||
: ''}
|
||||
.
|
||||
{completedUpdate?.message ||
|
||||
`Farm Control was successfully updated to version ${
|
||||
completedUpdate?.current?.version ||
|
||||
formatFullAppVersion(appVersion, CURRENT_BUILD_NUMBER) ||
|
||||
`v${appVersion}`
|
||||
}.`}
|
||||
</Text>
|
||||
</Modal>
|
||||
<Modal
|
||||
|
||||
@ -263,6 +263,65 @@ const persistCurrentAppState = async (mainWindow) => {
|
||||
const stateValueChanged = (previous, next) =>
|
||||
Boolean(previous) && Boolean(next) && previous !== next
|
||||
|
||||
const formatEngineLabel = (engine) => {
|
||||
const normalized = normalizeEngine(engine)
|
||||
if (normalized === 'chromium') return 'Chromium'
|
||||
if (normalized === 'native') return 'Native'
|
||||
return String(engine || 'Unknown')
|
||||
}
|
||||
|
||||
export const getUpdateInstalledMessage = ({ changes, current } = {}) => {
|
||||
if (!current) return 'Farm Control was successfully updated.'
|
||||
|
||||
const versionChanged = Boolean(changes?.version && current.version)
|
||||
const branchChanged = Boolean(changes?.branch && current.branch)
|
||||
const engineChanged = Boolean(changes?.engine && current.engine)
|
||||
|
||||
if (!versionChanged && !branchChanged && !engineChanged) {
|
||||
const version = current.version || getRunningAppVersion()
|
||||
return version
|
||||
? `Farm Control was successfully updated to version ${version}.`
|
||||
: 'Farm Control was successfully updated.'
|
||||
}
|
||||
|
||||
const segments = []
|
||||
|
||||
if (versionChanged) {
|
||||
segments.push({ type: 'version', text: `version ${current.version}` })
|
||||
}
|
||||
if (branchChanged) {
|
||||
segments.push({ type: 'branch', text: `the ${current.branch} branch` })
|
||||
}
|
||||
if (engineChanged) {
|
||||
segments.push({
|
||||
type: 'engine',
|
||||
text: `the ${formatEngineLabel(current.engine)} engine`
|
||||
})
|
||||
}
|
||||
|
||||
if (segments.length === 1) {
|
||||
const [segment] = segments
|
||||
if (segment.type === 'engine') {
|
||||
return `Farm Control was successfully updated to use ${segment.text}.`
|
||||
}
|
||||
return `Farm Control was successfully updated to ${segment.text}.`
|
||||
}
|
||||
|
||||
let message = `Farm Control was successfully updated to ${segments[0].text}`
|
||||
|
||||
for (const segment of segments.slice(1)) {
|
||||
if (segment.type === 'branch') {
|
||||
message += ` on ${segment.text}`
|
||||
} else if (segment.type === 'engine') {
|
||||
message += ` using ${segment.text}`
|
||||
} else {
|
||||
message += ` and ${segment.text}`
|
||||
}
|
||||
}
|
||||
|
||||
return `${message}.`
|
||||
}
|
||||
|
||||
let completedUpdateResult = null
|
||||
|
||||
export const checkForCompletedUpdate = async (mainWindow) => {
|
||||
@ -280,18 +339,31 @@ export const checkForCompletedUpdate = async (mainWindow) => {
|
||||
|
||||
await setAppSettings({ ...settings, current })
|
||||
|
||||
const changes = {
|
||||
version: stateValueChanged(previous.version, current.version),
|
||||
branch: stateValueChanged(previous.branch, current.branch),
|
||||
engine: stateValueChanged(
|
||||
normalizeEngine(previous.engine),
|
||||
normalizeEngine(current.engine)
|
||||
)
|
||||
}
|
||||
|
||||
const updated =
|
||||
Boolean(previous) &&
|
||||
(stateValueChanged(previous.version, current.version) ||
|
||||
stateValueChanged(previous.branch, current.branch) ||
|
||||
stateValueChanged(
|
||||
normalizeEngine(previous.engine),
|
||||
normalizeEngine(current.engine)
|
||||
))
|
||||
(changes.version || changes.branch || changes.engine)
|
||||
|
||||
const duplicates = checkForDuplicateInstallations()
|
||||
|
||||
completedUpdateResult = { updated, previous, current, duplicates }
|
||||
completedUpdateResult = {
|
||||
updated,
|
||||
previous,
|
||||
current,
|
||||
changes,
|
||||
message: updated
|
||||
? getUpdateInstalledMessage({ changes, current })
|
||||
: null,
|
||||
duplicates
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('[app-update] Failed to check for a completed update.', error)
|
||||
completedUpdateResult = {
|
||||
|
||||
@ -4,7 +4,9 @@ import os from 'os'
|
||||
import path from 'path'
|
||||
|
||||
const PE_MZ_HEADER = Buffer.from([0x4d, 0x5a]) // "MZ"
|
||||
const COPY_PROGRESS_PERCENT = 75
|
||||
const COPY_PROGRESS_START = 5
|
||||
const COPY_PROGRESS_END = 90
|
||||
const COPY_PROGRESS_RANGE = COPY_PROGRESS_END - COPY_PROGRESS_START
|
||||
|
||||
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
|
||||
|
||||
@ -54,8 +56,11 @@ const parseWindowsInstallerProgress = (output) => {
|
||||
copiedBytes += fileBytes
|
||||
if (copyTotalBytes > 0) {
|
||||
percent = Math.min(
|
||||
COPY_PROGRESS_PERCENT,
|
||||
Math.round((copiedBytes / copyTotalBytes) * COPY_PROGRESS_PERCENT)
|
||||
COPY_PROGRESS_END,
|
||||
COPY_PROGRESS_START +
|
||||
Math.round(
|
||||
(copiedBytes / copyTotalBytes) * COPY_PROGRESS_RANGE
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user