diff --git a/desktop/angular/src/app/layout/navigation/navigation.html b/desktop/angular/src/app/layout/navigation/navigation.html
index ae961f6c..8d9989dd 100644
--- a/desktop/angular/src/app/layout/navigation/navigation.html
+++ b/desktop/angular/src/app/layout/navigation/navigation.html
@@ -222,8 +222,8 @@
{{ pauseInfo }}
-
- Auto-resume at {{ pauseInfoTillTime }}
+
+ {{ pauseInfoTillTime }}
diff --git a/desktop/angular/src/app/layout/navigation/navigation.ts b/desktop/angular/src/app/layout/navigation/navigation.ts
index 46980ed4..ee99e324 100644
--- a/desktop/angular/src/app/layout/navigation/navigation.ts
+++ b/desktop/angular/src/app/layout/navigation/navigation.ts
@@ -50,8 +50,12 @@ export class NavigationComponent implements OnInit {
return '';
}
get pauseInfoTillTime(): string {
- if (this.isPaused && this.pauseState?.TillTime)
- return new Date(this.pauseState.TillTime).toLocaleTimeString(undefined, { hour12: false });
+ if (this.isPaused && this.pauseState?.TillTime) {
+ const date = new Date(this.pauseState.TillTime);
+ if (isNaN(date.getTime()) || date.getTime() < Date.now())
+ return '';
+ return `Auto-resume at ${date.toLocaleTimeString(undefined, { hour12: false })}`;
+ }
return '';
}
diff --git a/desktop/tauri/src-tauri/src/traymenu.rs b/desktop/tauri/src-tauri/src/traymenu.rs
index 490b55aa..53c06e13 100644
--- a/desktop/tauri/src-tauri/src/traymenu.rs
+++ b/desktop/tauri/src-tauri/src/traymenu.rs
@@ -2,7 +2,7 @@ use std::ops::Deref;
use std::sync::atomic::AtomicBool;
use std::sync::RwLock;
use std::{sync::atomic::Ordering};
-use chrono::{DateTime};
+use chrono::{DateTime, Local};
use log::{debug, error};
use tauri::{
@@ -163,14 +163,22 @@ fn build_tray_menu(
(false, true) => "SPN is paused",
_ => unreachable!(), // We already checked at least one is true
};
- let status_item = MenuItemBuilder::with_id(PAUSE_INFO_KEY, status_text).enabled(false).build(app)?;
+ let status_item = MenuItemBuilder::with_id(PAUSE_INFO_KEY, status_text).enabled(false).build(app).ok();
- let formatted_time = DateTime::parse_from_rfc3339(&pause_info.till_time)
- .map(|dt| dt.with_timezone(&chrono::Local).format("%H:%M:%S").to_string())
- .unwrap_or_else(|_| pause_info.till_time.clone());
- let time_item = MenuItemBuilder::with_id(PAUSE_INFO_TIME_KEY, format!("Auto-resume at {}", formatted_time)).enabled(false).build(app)?;
- let resume_item = MenuItemBuilder::with_id(RESUME_KEY, "Resume now").build(app)?;
- (Some(status_item), Some(time_item), Some(resume_item))
+ let time_item = if let Ok(resume_time) = DateTime::parse_from_rfc3339(&pause_info.till_time) {
+ let resume_time_local = resume_time.with_timezone(&Local);
+ if resume_time_local > Local::now() {
+ let formatted_time = resume_time_local.format("%H:%M:%S").to_string();
+ MenuItemBuilder::with_id(PAUSE_INFO_TIME_KEY, format!("Auto-resume at {}", formatted_time)).enabled(false).build(app).ok()
+ } else {
+ None
+ }
+ } else {
+ None
+ };
+
+ let resume_item = MenuItemBuilder::with_id(RESUME_KEY, "Resume now").build(app).ok();
+ (status_item, time_item, resume_item)
} else {
(None, None, None)
};
diff --git a/service/control/pause.go b/service/control/pause.go
index 7b07e1fc..3d319f98 100644
--- a/service/control/pause.go
+++ b/service/control/pause.go
@@ -89,11 +89,11 @@ func (c *Control) resume() (retErr error) {
defer c.locker.Unlock()
defer func() {
- // update states after resume attempt
- c.updateStatesAndNotify()
- // log error if resume failed
if retErr != nil {
- c.mgr.Error("Failed to resume: " + retErr.Error())
+ c.updateStatesAndNotifyError("Resume operation failed", retErr)
+ c.mgr.Error("Error occurred while resuming: " + retErr.Error())
+ } else {
+ c.updateStatesAndNotify()
}
}()
@@ -228,3 +228,26 @@ func (c *Control) updateStatesAndNotify() {
notifications.Notify(c.pauseNotification)
c.pauseNotification.SyncWithState(c.states)
}
+
+// updateStatesAndNotifyError updates the paused states and sends an error notification.
+// No thread safety, caller must hold c.locker.
+func (c *Control) updateStatesAndNotifyError(errDescription string, err error) {
+ if err == nil {
+ return
+ }
+
+ if errDescription == "" {
+ errDescription = "Error"
+ }
+
+ // Error notification
+ c.pauseNotification = ¬ifications.Notification{
+ EventID: "control:error",
+ Type: notifications.Error,
+ Title: errDescription,
+ Message: err.Error(),
+ EventData: &c.pauseInfo,
+ }
+ notifications.Notify(c.pauseNotification)
+ c.pauseNotification.SyncWithState(c.states)
+}