Jelajahi Sumber

feat(updater): add `Downloaded` status event (#3804)

Lucas Fernandes Nogueira 3 tahun lalu
induk
melakukan
9712ed1a68

+ 5 - 0
.changes/updater-downloaded-event.md

@@ -0,0 +1,5 @@
+---
+"tauri": patch
+---
+
+Add updater `Downloaded` status event.

+ 3 - 0
core/tauri/src/lib.rs

@@ -252,6 +252,8 @@ pub enum UpdaterEvent {
     /// The total
     content_length: Option<u64>,
   },
+  /// The update has been download and is now about to be installed.
+  Downloaded,
   /// The update has been applied and the app is now up to date.
   Updated,
   /// The app is already up to date.
@@ -265,6 +267,7 @@ impl UpdaterEvent {
   pub(crate) fn status_message(self) -> &'static str {
     match self {
       Self::Pending => updater::EVENT_STATUS_PENDING,
+      Self::Downloaded => updater::EVENT_STATUS_DOWNLOADED,
       Self::Updated => updater::EVENT_STATUS_SUCCESS,
       Self::AlreadyUpToDate => updater::EVENT_STATUS_UPTODATE,
       Self::Error(_) => updater::EVENT_STATUS_ERROR,

+ 6 - 3
core/tauri/src/updater/core.rs

@@ -476,10 +476,11 @@ impl<R: Runtime> Clone for Update<R> {
 impl<R: Runtime> Update<R> {
   // Download and install our update
   // @todo(lemarier): Split into download and install (two step) but need to be thread safe
-  pub(crate) async fn download_and_install<F: Fn(usize, Option<u64>)>(
+  pub(crate) async fn download_and_install<C: Fn(usize, Option<u64>), D: FnOnce()>(
     &self,
     pub_key: String,
-    on_chunk: F,
+    on_chunk: C,
+    on_download_finish: D,
   ) -> Result {
     // make sure we can install the update on linux
     // We fail here because later we can add more linux support
@@ -551,6 +552,8 @@ impl<R: Runtime> Update<R> {
       }
     }
 
+    on_download_finish();
+
     // create memory buffer from our archive (Seek + Read)
     let mut archive_buffer = Cursor::new(buffer);
 
@@ -1522,7 +1525,7 @@ mod test {
     assert_eq!(updater.version, "2.0.1");
 
     // download, install and validate signature
-    let install_process = block!(updater.download_and_install(pubkey, |_, _| ()));
+    let install_process = block!(updater.download_and_install(pubkey, |_, _| (), || ()));
     assert!(install_process.is_ok());
 
     // make sure the extraction went well (it should have skipped the main app.app folder)

+ 12 - 1
core/tauri/src/updater/mod.rs

@@ -230,6 +230,8 @@
 //!
 //! **Pending** is emitted when the download is started and **Done** when the install is complete. You can then ask to restart the application.
 //!
+//! **Downloaded** is emitted when the download has finished.
+//!
 //! **UpToDate** is emitted when the app already has the latest version installed and an update is not needed.
 //!
 //! **Error** is emitted when there is an error with the updater. We suggest to listen to this event even if the dialog is enabled.
@@ -249,6 +251,9 @@
 //!       tauri::UpdaterEvent::Pending => {
 //!         println!("update is pending!");
 //!       }
+//!       tauri::UpdaterEvent::Downloaded => {
+//!         println!("update has been downloaded!");
+//!       }
 //!       tauri::UpdaterEvent::Updated => {
 //!         println!("app has been updated");
 //!       }
@@ -465,6 +470,8 @@ pub const EVENT_STATUS_PENDING: &str = "PENDING";
 /// When you got this status, something went wrong
 /// you can find the error message inside the `error` field.
 pub const EVENT_STATUS_ERROR: &str = "ERROR";
+/// The update has been downloaded.
+pub const EVENT_STATUS_DOWNLOADED: &str = "DOWNLOADED";
 /// When you receive this status, you should ask the user to restart
 pub const EVENT_STATUS_SUCCESS: &str = "DONE";
 /// When you receive this status, this is because the application is running last version
@@ -712,6 +719,7 @@ pub(crate) async fn download_and_install<R: Runtime>(update: core::Update<R>) ->
   send_status_update(&update.app, UpdaterEvent::Pending);
 
   let handle = update.app.clone();
+  let handle_ = handle.clone();
 
   // Launch updater download process
   // macOS we display the `Ready to restart dialog` asking to restart
@@ -723,6 +731,9 @@ pub(crate) async fn download_and_install<R: Runtime>(update: core::Update<R>) ->
       move |chunk_length, content_length| {
         send_download_progress_event(&handle, chunk_length, content_length);
       },
+      move || {
+        send_status_update(&handle_, UpdaterEvent::Downloaded);
+      },
     )
     .await;
 
@@ -840,7 +851,7 @@ Release Notes:
     // Windows is closing the current App and launch the downloaded MSI when ready (the process stop here)
     // Linux we replace the AppImage by launching a new install, it start a new AppImage instance, so we're closing the previous. (the process stop here)
     update
-      .download_and_install(pubkey.clone(), |_, _| ())
+      .download_and_install(pubkey.clone(), |_, _| (), || ())
       .await?;
 
     // Ask user if we need to restart the application