diff --git a/desktop/app.vue b/desktop/app.vue
index fb5f882e..f81c4321 100644
--- a/desktop/app.vue
+++ b/desktop/app.vue
@@ -6,7 +6,7 @@
diff --git a/desktop/src-tauri/src/downloads/download_manager.rs b/desktop/src-tauri/src/downloads/download_manager.rs
index 86c006a0..f6604303 100644
--- a/desktop/src-tauri/src/downloads/download_manager.rs
+++ b/desktop/src-tauri/src/downloads/download_manager.rs
@@ -41,7 +41,8 @@ pub enum DownloadManagerSignal {
/// Any error which occurs in the agent
Error(GameDownloadError),
/// Pushes UI update
- Update,
+ UpdateUIQueue,
+ UpdateUIStats(usize, usize), //kb/s and seconds
/// Uninstall game
/// Takes game ID
Uninstall(String),
@@ -156,7 +157,7 @@ impl DownloadManager {
let to_move = queue.remove(current_index).unwrap();
queue.insert(new_index, to_move);
self.command_sender
- .send(DownloadManagerSignal::Update)
+ .send(DownloadManagerSignal::UpdateUIQueue)
.unwrap();
}
pub fn cancel(&self, game_id: String) {
@@ -188,7 +189,7 @@ impl DownloadManager {
self.command_sender.send(DownloadManagerSignal::Go).unwrap();
}
self.command_sender
- .send(DownloadManagerSignal::Update)
+ .send(DownloadManagerSignal::UpdateUIQueue)
.unwrap();
}
pub fn pause_downloads(&self) {
diff --git a/desktop/src-tauri/src/downloads/download_manager_builder.rs b/desktop/src-tauri/src/downloads/download_manager_builder.rs
index 6719b3fe..3d813fdc 100644
--- a/desktop/src-tauri/src/downloads/download_manager_builder.rs
+++ b/desktop/src-tauri/src/downloads/download_manager_builder.rs
@@ -16,7 +16,7 @@ use crate::{
db::{Database, GameStatus, GameTransientStatus},
library::{
on_game_complete, push_game_update, GameUpdateEvent, QueueUpdateEvent,
- QueueUpdateEventQueueData,
+ QueueUpdateEventQueueData, StatsUpdateEvent,
},
state::{GameStatusManager, GameStatusWithTransient},
DB,
@@ -128,7 +128,13 @@ impl DownloadManagerBuilder {
push_game_update(&self.app_handle, id, status);
}
- fn push_manager_update(&self) {
+ fn push_ui_stats_update(&self, kbs: usize, time: usize) {
+ let event_data = StatsUpdateEvent { speed: kbs, time };
+
+ self.app_handle.emit("update_stats", event_data).unwrap();
+ }
+
+ fn push_ui_queue_update(&self) {
let queue = self.download_queue.read();
let queue_objs: Vec = queue
.iter()
@@ -208,8 +214,11 @@ impl DownloadManagerBuilder {
DownloadManagerSignal::Cancel => {
self.manage_cancel_signal();
}
- DownloadManagerSignal::Update => {
- self.push_manager_update();
+ DownloadManagerSignal::UpdateUIQueue => {
+ self.push_ui_queue_update();
+ }
+ DownloadManagerSignal::UpdateUIStats(kbs, time) => {
+ self.push_ui_stats_update(kbs, time);
}
DownloadManagerSignal::Finish => {
self.stop_and_wait_current_download();
@@ -315,7 +324,7 @@ impl DownloadManagerBuilder {
self.manage_go_signal();
}
- self.push_manager_update();
+ self.push_ui_queue_update();
}
fn manage_stop_signal(&mut self) {
@@ -356,7 +365,9 @@ impl DownloadManagerBuilder {
}
}
}
- self.sender.send(DownloadManagerSignal::Update).unwrap();
+ self.sender
+ .send(DownloadManagerSignal::UpdateUIQueue)
+ .unwrap();
self.sender.send(DownloadManagerSignal::Go).unwrap();
}
@@ -406,7 +417,9 @@ impl DownloadManagerBuilder {
GameTransientStatus::Downloading { version_name },
);
});
- self.sender.send(DownloadManagerSignal::Update).unwrap();
+ self.sender
+ .send(DownloadManagerSignal::UpdateUIQueue)
+ .unwrap();
}
fn manage_go_signal(&mut self) {
@@ -483,7 +496,9 @@ impl DownloadManagerBuilder {
);
});
- self.sender.send(DownloadManagerSignal::Update).unwrap();
+ self.sender
+ .send(DownloadManagerSignal::UpdateUIQueue)
+ .unwrap();
}
fn manage_error_signal(&mut self, error: GameDownloadError) {
let current_status = self.current_download_agent.clone().unwrap();
@@ -504,7 +519,9 @@ impl DownloadManagerBuilder {
db_handle.games.transient_statuses.remove(id);
});
- self.sender.send(DownloadManagerSignal::Update).unwrap();
+ self.sender
+ .send(DownloadManagerSignal::UpdateUIQueue)
+ .unwrap();
}
fn manage_cancel_signal(&mut self) {
self.stop_and_wait_current_download();
diff --git a/desktop/src-tauri/src/downloads/progress_object.rs b/desktop/src-tauri/src/downloads/progress_object.rs
index 22077027..2e0a1943 100644
--- a/desktop/src-tauri/src/downloads/progress_object.rs
+++ b/desktop/src-tauri/src/downloads/progress_object.rs
@@ -2,9 +2,9 @@ use std::{
sync::{
atomic::{AtomicUsize, Ordering},
mpsc::Sender,
- Arc, Mutex,
+ Arc, Mutex, RwLock,
},
- time::Instant,
+ time::{Duration, Instant},
};
use log::info;
@@ -20,6 +20,8 @@ pub struct ProgressObject {
points_towards_update: Arc,
points_to_push_update: Arc,
+ last_update: Arc>,
+ amount_last_update: Arc,
}
pub struct ProgressHandle {
@@ -59,6 +61,8 @@ impl ProgressObject {
points_towards_update: Arc::new(AtomicUsize::new(0)),
points_to_push_update: Arc::new(AtomicUsize::new(points_to_push_update)),
+ last_update: Arc::new(RwLock::new(Instant::now())),
+ amount_last_update: Arc::new(AtomicUsize::new(0)),
}
}
@@ -69,12 +73,42 @@ impl ProgressObject {
let to_update = self.points_to_push_update.fetch_add(0, Ordering::Relaxed);
- if current_amount < to_update {
- return;
+ if current_amount >= to_update {
+ self.points_towards_update
+ .fetch_sub(to_update, Ordering::Relaxed);
+ self.sender
+ .send(DownloadManagerSignal::UpdateUIQueue)
+ .unwrap();
+ }
+
+ let last_update = self.last_update.read().unwrap();
+ let last_update_difference = Instant::now().duration_since(*last_update).as_millis();
+ if last_update_difference > 1000 {
+ // push update
+ drop(last_update);
+ let mut last_update = self.last_update.write().unwrap();
+ *last_update = Instant::now();
+ drop(last_update);
+
+ let current_amount = self.sum();
+ let max = self.get_max();
+ let amount_at_last_update = self.amount_last_update.fetch_add(0, Ordering::Relaxed);
+ self.amount_last_update
+ .store(current_amount, Ordering::Relaxed);
+
+ let amount_since_last_update = current_amount - amount_at_last_update;
+
+ let kilobytes_per_second = amount_since_last_update / (last_update_difference as usize).max(1);
+
+ let remaining = max - current_amount; // bytes
+ let time_remaining = (remaining / 1000) / kilobytes_per_second.max(1);
+ self.sender
+ .send(DownloadManagerSignal::UpdateUIStats(
+ kilobytes_per_second,
+ time_remaining,
+ ))
+ .unwrap();
}
- self.points_towards_update
- .fetch_sub(to_update, Ordering::Relaxed);
- self.sender.send(DownloadManagerSignal::Update).unwrap();
}
pub fn set_time_now(&self) {
diff --git a/desktop/src-tauri/src/library.rs b/desktop/src-tauri/src/library.rs
index a4c6e442..01b63f91 100644
--- a/desktop/src-tauri/src/library.rs
+++ b/desktop/src-tauri/src/library.rs
@@ -53,6 +53,12 @@ pub struct QueueUpdateEvent {
pub status: DownloadManagerStatus,
}
+#[derive(serde::Serialize, Clone)]
+pub struct StatsUpdateEvent {
+ pub speed: usize,
+ pub time: usize,
+}
+
// Game version with some fields missing and size information
#[derive(serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
diff --git a/desktop/yarn.lock b/desktop/yarn.lock
index 539954ce..2c770d17 100644
--- a/desktop/yarn.lock
+++ b/desktop/yarn.lock
@@ -3935,11 +3935,6 @@ mlly@^1.3.0, mlly@^1.4.2, mlly@^1.6.1, mlly@^1.7.1:
pkg-types "^1.2.0"
ufo "^1.5.4"
-moment@^2.30.1:
- version "2.30.1"
- resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae"
- integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==
-
mri@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b"