Skip to content

feat(update): add download progress dialog for in-app updates - #408

Merged
KnifeLemon merged 6 commits into
KnifeLemon:mainfrom
gtxPrime:feature/in-app-update
Oct 23, 2026
Merged

KnifeLemon merged 6 commits into
KnifeLemon:mainfrom
gtxPrime:feature/in-app-update

Conversation

@gtxPrime

@gtxPrime gtxPrime commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

What does this change?

Adds a dedicated progress dialog with a progress bar and status text while downloading in-app updates on Windows (UpdateProgressWindow.axaml).

How was it tested?

  • dotnet format --verify-no-changes (passed with 0 warnings/changes)
  • dotnet test (all 25 UpdateServiceTests passed, including UpdateProgressWindow_tracks_download_percentage_and_status and Release_files_picks_windows_installer_and_exact_checksums_even_when_linux_and_mac_are_present)

@github-actions github-actions Bot added the feature New features label Oct 22, 2026
@KnifeLemon KnifeLemon self-assigned this Oct 22, 2026

@KnifeLemon KnifeLemon left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @gtxPrime for taking this on. A progress bar while the update downloads is nice to have. As it stands, though, this changes the Windows update that works today, and a few parts can lose files, so it can't go in yet:

  1. Windows updates would always fail. The real releases list the checksum files as Filee-2.0.0-linux-arm64-SHA256SUMS.txt, …, Filee-2.0.0-SHA256SUMS.txt, Filee-2.0.0-win-Portable.zip, Filee-2.0.0-win-Setup.exe. On Windows no checksum file starts with Filee-2.0.0-win-Setup, so the EndsWith("-SHA256SUMS.txt") fallback picks the first one, the Linux arm64 file. It has no line for Setup.exe, so DownloadInstallerAsync throws and Filee opens the download page instead. The tests only use releases with one platform's files, so they don't see it. Please pick exactly Filee-<version>-SHA256SUMS.txt on Windows and <package name>-SHA256SUMS.txt elsewhere, without the loose fallbacks ("mac" in the name, .sha256, the first file of any kind, Setup.exe on macOS/Linux).
  2. Every copy now installs itself. InstallsItself defaults to true, so a portable Windows copy downloads and runs Setup (which installs a second copy, while the portable one stays old), and so does a copy run from source. On macOS and Linux a copy unpacked anywhere, or a build in bin/, gets overwritten, and a copy running outside a .app deletes and replaces ~/Applications/Filee.app. Please keep InstallsItself = IsInstalled, and keep "Download" and the portable text in UpdateTexts for copies that don't install themselves.
  3. Windows portable zip. Copying a new zip over the running folder with a hidden cmd script is what main deliberately leaves to the user ("unpack it over this folder"). Please drop that branch.
  4. Linux is covered by #360, which is in review: install.sh --upgrade with a marker check, staging, rollback and quit-first. A second updater that cp -Rs the tarball over the install, with no rollback, leaving removed files behind and copying install.sh/INSTALL.txt into the app folder, would conflict with it. Please leave Linux to #360.
  5. macOS removes the app (rm -rf) before copying the new one, with no backup, so a failed copy leaves no Filee at all. Replacing an ad-hoc-signed bundle also resets the Accessibility and Automation grants (#316), so every update would ask for them again. How macOS should install and update is still open (#379), so please take macOS out of this PR for now.
  6. The helper scripts put paths straight into the script text. A folder name with ", $ or a backtick breaks the script or runs as a command. If a script stays, pass the paths as arguments ($1, $2) via ArgumentList.
  7. ExitApplication calls Environment.Exit(0) one second after App.Quit() no matter what, which cuts off running conversions and settings writes. On Windows, Setup already closes Filee itself.
  8. The progress window opens on its own for every download, also when the update was started from the notice, and in Idle it stays open but empty (for example when Filee is already up to date).

Could you narrow this PR to the Windows flow as it is on main plus the progress dialog, with point 1 not needed any more once FindFiles is back to main's Windows logic? Thanks again!

@gtxPrime gtxPrime changed the title feat(update): add cross-platform in-app download and update restart for Windows, macOS, and Linux feat(update): add download progress dialog for in-app updates Oct 22, 2026

@KnifeLemon KnifeLemon left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @gtxPrime, this is much closer. I checked eb51d6e against the eight points from last time:

  • 1 to 6 are resolved. UpdateService is back to main's Windows flow (InstallsItself = IsInstalled, no portable, macOS or Linux branches, no helper scripts), and FindFiles skips the -linux-/-osx- checksum files, with a test that uses the real release layout.
  • 7: Environment.Exit is gone.
  • 8: the window no longer opens by itself and closes again on Idle.

One thing is left, and it's the point of the PR: the progress window never opens when an update starts. DownloadUpdate (sidebar and About) and the tray item only call ShowUpdateProgress when an update is already running (IsBusy). The first press just calls UpdateAsync(), as on main. So the dialog only shows up if you press the sidebar button or the tray item a second time during the download, and never from About, whose button is hidden while busy. The description says it shows when the update is started from the sidebar, About or the tray.

Could you open it when the update starts from those three places? UpdateAsync() sets Step = Downloading before its first await, so this works:

var update = updates.UpdateAsync();
windows.ShowUpdateProgress(updates);
await update;

In a portable copy Step stays Idle, so ShowUpdateProgress does nothing, and when Filee turns out to be up to date the window closes on Idle. The update notice already has its own progress bar, so it can stay as it is. It would be nice to have this in one place (for example WindowService.StartUpdateAsync(UpdateService)) instead of three copies.

Smaller things, not blocking:

  • When the update fails, ShowUpdateFailedAsync closes the notice. Please close the progress window there too, so it doesn't stay open behind the alert.
  • The status line repeats the percentage that's already on the right ("Downloading… 45%" next to "45%").

Thanks again!

gtxPrime and others added 2 commits October 23, 2026 12:35
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@KnifeLemon
KnifeLemon merged commit 47bd60f into KnifeLemon:main Oct 23, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants