Clean up code to resolve all compiler warnings
All checks were successful
Build and Push Docker Image / docker (push) Successful in 3m48s
All checks were successful
Build and Push Docker Image / docker (push) Successful in 3m48s
- Remove unused AlarmStorage module and all references - Remove unused imports (AlarmAction, AlarmTrigger, VAlarm from backend) - Remove unused ReminderType enum from event form types - Remove unused methods from AlarmScheduler and NotificationManager - Fix unnecessary mut on NotificationOptions - Simplify alarm system initialization in app.rs - Remove unused variable assignments 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -16,7 +16,7 @@ use crate::{
|
|||||||
AppState,
|
AppState,
|
||||||
};
|
};
|
||||||
use calendar_models::{
|
use calendar_models::{
|
||||||
AlarmAction, AlarmTrigger, Attendee, CalendarUser, EventClass, EventStatus, VAlarm, VEvent,
|
Attendee, CalendarUser, EventClass, EventStatus, VEvent,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::auth::{extract_bearer_token, extract_password_header};
|
use super::auth::{extract_bearer_token, extract_password_header};
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use crate::components::{
|
|||||||
use crate::components::mobile_warning_modal::is_mobile_device;
|
use crate::components::mobile_warning_modal::is_mobile_device;
|
||||||
use crate::components::sidebar::{Style};
|
use crate::components::sidebar::{Style};
|
||||||
use crate::models::ical::VEvent;
|
use crate::models::ical::VEvent;
|
||||||
use crate::services::{calendar_service::{UserInfo, ExternalCalendar}, CalendarService, AlarmScheduler, AlarmStorage};
|
use crate::services::{calendar_service::{UserInfo, ExternalCalendar}, CalendarService, AlarmScheduler};
|
||||||
use chrono::NaiveDate;
|
use chrono::NaiveDate;
|
||||||
use gloo_storage::{LocalStorage, Storage};
|
use gloo_storage::{LocalStorage, Storage};
|
||||||
use gloo_timers::callback::Interval;
|
use gloo_timers::callback::Interval;
|
||||||
@@ -151,9 +151,8 @@ pub fn App() -> Html {
|
|||||||
|
|
||||||
// Alarm system state
|
// Alarm system state
|
||||||
let alarm_scheduler = use_state(|| AlarmScheduler::new());
|
let alarm_scheduler = use_state(|| AlarmScheduler::new());
|
||||||
let alarm_storage = use_state(|| AlarmStorage::new());
|
|
||||||
let alarm_check_interval = use_state(|| -> Option<Interval> { None });
|
let alarm_check_interval = use_state(|| -> Option<Interval> { None });
|
||||||
let alarm_storage_initialized = use_state(|| false);
|
let alarm_system_initialized = use_state(|| false);
|
||||||
|
|
||||||
// Calendar view state - load from localStorage if available
|
// Calendar view state - load from localStorage if available
|
||||||
let current_view = use_state(|| {
|
let current_view = use_state(|| {
|
||||||
@@ -201,27 +200,18 @@ pub fn App() -> Html {
|
|||||||
// Initialize alarm system after user login
|
// Initialize alarm system after user login
|
||||||
{
|
{
|
||||||
let auth_token = auth_token.clone();
|
let auth_token = auth_token.clone();
|
||||||
let alarm_storage = alarm_storage.clone();
|
|
||||||
let alarm_scheduler = alarm_scheduler.clone();
|
let alarm_scheduler = alarm_scheduler.clone();
|
||||||
let alarm_storage_initialized = alarm_storage_initialized.clone();
|
let alarm_system_initialized = alarm_system_initialized.clone();
|
||||||
let alarm_check_interval = alarm_check_interval.clone();
|
let alarm_check_interval = alarm_check_interval.clone();
|
||||||
|
|
||||||
use_effect_with((*auth_token).clone(), move |token| {
|
use_effect_with((*auth_token).clone(), move |token| {
|
||||||
if token.is_some() && !*alarm_storage_initialized {
|
if token.is_some() && !*alarm_system_initialized {
|
||||||
|
|
||||||
let alarm_storage = alarm_storage.clone();
|
|
||||||
let alarm_scheduler = alarm_scheduler.clone();
|
let alarm_scheduler = alarm_scheduler.clone();
|
||||||
let alarm_storage_initialized = alarm_storage_initialized.clone();
|
let alarm_system_initialized = alarm_system_initialized.clone();
|
||||||
let alarm_check_interval = alarm_check_interval.clone();
|
let alarm_check_interval = alarm_check_interval.clone();
|
||||||
|
|
||||||
wasm_bindgen_futures::spawn_local(async move {
|
wasm_bindgen_futures::spawn_local(async move {
|
||||||
// Initialize IndexedDB storage
|
|
||||||
let mut storage = (*alarm_storage).clone();
|
|
||||||
match storage.init().await {
|
|
||||||
Ok(()) => {
|
|
||||||
alarm_storage.set(storage);
|
|
||||||
alarm_storage_initialized.set(true);
|
|
||||||
|
|
||||||
// Request notification permission
|
// Request notification permission
|
||||||
let scheduler = (*alarm_scheduler).clone();
|
let scheduler = (*alarm_scheduler).clone();
|
||||||
match scheduler.request_notification_permission().await {
|
match scheduler.request_notification_permission().await {
|
||||||
@@ -235,6 +225,7 @@ pub fn App() -> Html {
|
|||||||
}
|
}
|
||||||
|
|
||||||
alarm_scheduler.set(scheduler);
|
alarm_scheduler.set(scheduler);
|
||||||
|
alarm_system_initialized.set(true);
|
||||||
|
|
||||||
// Set up alarm checking interval (every 30 seconds)
|
// Set up alarm checking interval (every 30 seconds)
|
||||||
let interval = {
|
let interval = {
|
||||||
@@ -256,19 +247,11 @@ pub fn App() -> Html {
|
|||||||
};
|
};
|
||||||
|
|
||||||
alarm_check_interval.set(Some(interval));
|
alarm_check_interval.set(Some(interval));
|
||||||
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
web_sys::console::error_1(
|
|
||||||
&format!("❌ Failed to initialize alarm storage: {:?}", e).into()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else if token.is_none() {
|
} else if token.is_none() {
|
||||||
// Clean up alarm system on logout
|
// Clean up alarm system on logout
|
||||||
alarm_check_interval.set(None); // This will drop and cancel the interval
|
alarm_check_interval.set(None); // This will drop and cancel the interval
|
||||||
alarm_storage_initialized.set(false);
|
alarm_system_initialized.set(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|| ()
|
|| ()
|
||||||
@@ -1253,7 +1236,7 @@ pub fn App() -> Html {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Convert reminders to string format
|
// Convert reminders to string format
|
||||||
let reminder_str = if !original_event.alarms.is_empty() {
|
let _reminder_str = if !original_event.alarms.is_empty() {
|
||||||
// Convert from VAlarm to minutes before
|
// Convert from VAlarm to minutes before
|
||||||
"15".to_string() // TODO: Convert VAlarm trigger to minutes
|
"15".to_string() // TODO: Convert VAlarm trigger to minutes
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -29,22 +29,6 @@ impl Default for EventClass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
|
||||||
pub enum ReminderType {
|
|
||||||
None,
|
|
||||||
Minutes15,
|
|
||||||
Minutes30,
|
|
||||||
Hour1,
|
|
||||||
Day1,
|
|
||||||
Days2,
|
|
||||||
Week1,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for ReminderType {
|
|
||||||
fn default() -> Self {
|
|
||||||
ReminderType::None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
pub enum RecurrenceType {
|
pub enum RecurrenceType {
|
||||||
|
|||||||
@@ -30,18 +30,15 @@ pub enum AlarmStatus {
|
|||||||
pub struct AlarmScheduler {
|
pub struct AlarmScheduler {
|
||||||
scheduled_alarms: HashMap<String, ScheduledAlarm>,
|
scheduled_alarms: HashMap<String, ScheduledAlarm>,
|
||||||
notification_manager: NotificationManager,
|
notification_manager: NotificationManager,
|
||||||
instance_id: String, // Unique identifier for debugging
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ALARMS_STORAGE_KEY: &str = "scheduled_alarms";
|
const ALARMS_STORAGE_KEY: &str = "scheduled_alarms";
|
||||||
|
|
||||||
impl AlarmScheduler {
|
impl AlarmScheduler {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let instance_id = format!("scheduler_{}", chrono::Local::now().timestamp_nanos_opt().unwrap_or(0));
|
|
||||||
let mut scheduler = Self {
|
let mut scheduler = Self {
|
||||||
scheduled_alarms: HashMap::new(),
|
scheduled_alarms: HashMap::new(),
|
||||||
notification_manager: NotificationManager::new(),
|
notification_manager: NotificationManager::new(),
|
||||||
instance_id,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Load alarms from localStorage
|
// Load alarms from localStorage
|
||||||
@@ -287,54 +284,12 @@ impl AlarmScheduler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get all pending alarms
|
|
||||||
pub fn get_pending_alarms(&self) -> Vec<&ScheduledAlarm> {
|
|
||||||
self.scheduled_alarms
|
|
||||||
.values()
|
|
||||||
.filter(|alarm| alarm.status == AlarmStatus::Pending)
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get next alarm time
|
|
||||||
pub fn get_next_alarm_time(&self) -> Option<NaiveDateTime> {
|
|
||||||
self.get_pending_alarms()
|
|
||||||
.iter()
|
|
||||||
.map(|alarm| alarm.trigger_time)
|
|
||||||
.min()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get count of pending alarms
|
|
||||||
pub fn pending_count(&self) -> usize {
|
|
||||||
self.get_pending_alarms().len()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Request notification permission
|
/// Request notification permission
|
||||||
pub async fn request_notification_permission(&self) -> Result<web_sys::NotificationPermission, wasm_bindgen::JsValue> {
|
pub async fn request_notification_permission(&self) -> Result<web_sys::NotificationPermission, wasm_bindgen::JsValue> {
|
||||||
NotificationManager::request_permission().await
|
NotificationManager::request_permission().await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if notifications are supported and permitted
|
|
||||||
pub fn can_show_notifications(&self) -> bool {
|
|
||||||
NotificationManager::is_supported() &&
|
|
||||||
NotificationManager::get_permission() == web_sys::NotificationPermission::Granted
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get notification permission status
|
|
||||||
pub fn get_notification_permission(&self) -> web_sys::NotificationPermission {
|
|
||||||
NotificationManager::get_permission()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Dismiss alarm for an event (close notification)
|
|
||||||
pub fn dismiss_alarm(&mut self, event_uid: &str) {
|
|
||||||
self.notification_manager.close_notification(event_uid);
|
|
||||||
|
|
||||||
// Mark alarms as dismissed
|
|
||||||
for alarm in self.scheduled_alarms.values_mut() {
|
|
||||||
if alarm.event_uid == event_uid && alarm.status == AlarmStatus::Triggered {
|
|
||||||
alarm.status = AlarmStatus::Dismissed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for AlarmScheduler {
|
impl Default for AlarmScheduler {
|
||||||
|
|||||||
@@ -1,116 +0,0 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use chrono::NaiveDateTime;
|
|
||||||
use crate::services::{ScheduledAlarm, AlarmStatus};
|
|
||||||
use gloo_storage::{LocalStorage, Storage};
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
const STORAGE_KEY: &str = "calendar_alarms";
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct AlarmStorage;
|
|
||||||
|
|
||||||
impl AlarmStorage {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Initialize the storage (no-op for localStorage)
|
|
||||||
pub async fn init(&mut self) -> Result<(), wasm_bindgen::JsValue> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Load all alarms from localStorage
|
|
||||||
fn load_all_alarms() -> HashMap<String, ScheduledAlarm> {
|
|
||||||
LocalStorage::get::<HashMap<String, ScheduledAlarm>>(STORAGE_KEY)
|
|
||||||
.unwrap_or_default()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Save all alarms to localStorage
|
|
||||||
fn save_all_alarms(alarms: &HashMap<String, ScheduledAlarm>) {
|
|
||||||
let _ = LocalStorage::set(STORAGE_KEY, alarms);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Store a scheduled alarm
|
|
||||||
pub async fn store_alarm(&self, alarm: &ScheduledAlarm) -> Result<(), wasm_bindgen::JsValue> {
|
|
||||||
let mut all_alarms = Self::load_all_alarms();
|
|
||||||
all_alarms.insert(alarm.id.clone(), alarm.clone());
|
|
||||||
Self::save_all_alarms(&all_alarms);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Store multiple alarms
|
|
||||||
pub async fn store_alarms(&self, alarms: &[ScheduledAlarm]) -> Result<(), wasm_bindgen::JsValue> {
|
|
||||||
let mut all_alarms = Self::load_all_alarms();
|
|
||||||
for alarm in alarms {
|
|
||||||
all_alarms.insert(alarm.id.clone(), alarm.clone());
|
|
||||||
}
|
|
||||||
Self::save_all_alarms(&all_alarms);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Load all alarms
|
|
||||||
pub async fn load_alarms(&self) -> Result<Vec<ScheduledAlarm>, wasm_bindgen::JsValue> {
|
|
||||||
let all_alarms = Self::load_all_alarms();
|
|
||||||
Ok(all_alarms.values().cloned().collect())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Load alarms for a specific event
|
|
||||||
pub async fn load_event_alarms(&self, event_uid: &str) -> Result<Vec<ScheduledAlarm>, wasm_bindgen::JsValue> {
|
|
||||||
let all_alarms = Self::load_all_alarms();
|
|
||||||
let event_alarms: Vec<ScheduledAlarm> = all_alarms
|
|
||||||
.values()
|
|
||||||
.filter(|alarm| alarm.event_uid == event_uid)
|
|
||||||
.cloned()
|
|
||||||
.collect();
|
|
||||||
Ok(event_alarms)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Load pending alarms that should trigger before a specific time
|
|
||||||
pub async fn load_pending_alarms_before(&self, before_time: NaiveDateTime) -> Result<Vec<ScheduledAlarm>, wasm_bindgen::JsValue> {
|
|
||||||
let all_alarms = Self::load_all_alarms();
|
|
||||||
let pending_alarms: Vec<ScheduledAlarm> = all_alarms
|
|
||||||
.values()
|
|
||||||
.filter(|alarm| {
|
|
||||||
alarm.status == AlarmStatus::Pending && alarm.trigger_time <= before_time
|
|
||||||
})
|
|
||||||
.cloned()
|
|
||||||
.collect();
|
|
||||||
Ok(pending_alarms)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Update alarm status
|
|
||||||
pub async fn update_alarm_status(&self, alarm_id: &str, status: AlarmStatus) -> Result<(), wasm_bindgen::JsValue> {
|
|
||||||
let mut all_alarms = Self::load_all_alarms();
|
|
||||||
if let Some(alarm) = all_alarms.get_mut(alarm_id) {
|
|
||||||
alarm.status = status;
|
|
||||||
}
|
|
||||||
Self::save_all_alarms(&all_alarms);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Delete alarms for an event
|
|
||||||
pub async fn delete_event_alarms(&self, event_uid: &str) -> Result<(), wasm_bindgen::JsValue> {
|
|
||||||
let mut all_alarms = Self::load_all_alarms();
|
|
||||||
all_alarms.retain(|_, alarm| alarm.event_uid != event_uid);
|
|
||||||
Self::save_all_alarms(&all_alarms);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Clean up expired alarms
|
|
||||||
pub async fn cleanup_expired_alarms(&self, cutoff_time: NaiveDateTime) -> Result<usize, wasm_bindgen::JsValue> {
|
|
||||||
let mut all_alarms = Self::load_all_alarms();
|
|
||||||
let initial_count = all_alarms.len();
|
|
||||||
|
|
||||||
all_alarms.retain(|_, alarm| alarm.event_start >= cutoff_time);
|
|
||||||
|
|
||||||
let deleted_count = initial_count - all_alarms.len();
|
|
||||||
Self::save_all_alarms(&all_alarms);
|
|
||||||
Ok(deleted_count)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for AlarmStorage {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,9 +2,7 @@ pub mod calendar_service;
|
|||||||
pub mod preferences;
|
pub mod preferences;
|
||||||
pub mod notification_manager;
|
pub mod notification_manager;
|
||||||
pub mod alarm_scheduler;
|
pub mod alarm_scheduler;
|
||||||
pub mod alarm_storage;
|
|
||||||
|
|
||||||
pub use calendar_service::CalendarService;
|
pub use calendar_service::CalendarService;
|
||||||
pub use notification_manager::{NotificationManager, AlarmNotification};
|
pub use notification_manager::{NotificationManager, AlarmNotification};
|
||||||
pub use alarm_scheduler::{AlarmScheduler, ScheduledAlarm, AlarmStatus};
|
pub use alarm_scheduler::AlarmScheduler;
|
||||||
pub use alarm_storage::AlarmStorage;
|
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ impl NotificationManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create notification options
|
// Create notification options
|
||||||
let mut options = NotificationOptions::new();
|
let options = NotificationOptions::new();
|
||||||
|
|
||||||
// Set notification body with time and location
|
// Set notification body with time and location
|
||||||
let body = if let Some(location) = &alarm.event_location {
|
let body = if let Some(location) = &alarm.event_location {
|
||||||
@@ -143,7 +143,7 @@ impl NotificationManager {
|
|||||||
self.active_notifications.insert(alarm.event_uid.clone(), notification.clone());
|
self.active_notifications.insert(alarm.event_uid.clone(), notification.clone());
|
||||||
|
|
||||||
// Set up click handler to focus the calendar app
|
// Set up click handler to focus the calendar app
|
||||||
let event_uid = alarm.event_uid.clone();
|
let _event_uid = alarm.event_uid.clone();
|
||||||
let onclick_closure = Closure::wrap(Box::new(move |_event: web_sys::Event| {
|
let onclick_closure = Closure::wrap(Box::new(move |_event: web_sys::Event| {
|
||||||
// Focus the window when notification is clicked
|
// Focus the window when notification is clicked
|
||||||
if let Some(window) = window() {
|
if let Some(window) = window() {
|
||||||
@@ -175,17 +175,6 @@ impl NotificationManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Close all active notifications
|
|
||||||
pub fn close_all_notifications(&mut self) {
|
|
||||||
for (_, notification) in self.active_notifications.drain() {
|
|
||||||
notification.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get count of active notifications
|
|
||||||
pub fn active_count(&self) -> usize {
|
|
||||||
self.active_notifications.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check if notification exists for event
|
/// Check if notification exists for event
|
||||||
pub fn has_notification(&self, event_uid: &str) -> bool {
|
pub fn has_notification(&self, event_uid: &str) -> bool {
|
||||||
|
|||||||
Reference in New Issue
Block a user