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,
|
||||
};
|
||||
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};
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::components::{
|
||||
use crate::components::mobile_warning_modal::is_mobile_device;
|
||||
use crate::components::sidebar::{Style};
|
||||
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 gloo_storage::{LocalStorage, Storage};
|
||||
use gloo_timers::callback::Interval;
|
||||
@@ -151,9 +151,8 @@ pub fn App() -> Html {
|
||||
|
||||
// Alarm system state
|
||||
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_storage_initialized = use_state(|| false);
|
||||
let alarm_system_initialized = use_state(|| false);
|
||||
|
||||
// Calendar view state - load from localStorage if available
|
||||
let current_view = use_state(|| {
|
||||
@@ -201,74 +200,58 @@ pub fn App() -> Html {
|
||||
// Initialize alarm system after user login
|
||||
{
|
||||
let auth_token = auth_token.clone();
|
||||
let alarm_storage = alarm_storage.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();
|
||||
|
||||
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_storage_initialized = alarm_storage_initialized.clone();
|
||||
let alarm_system_initialized = alarm_system_initialized.clone();
|
||||
let alarm_check_interval = alarm_check_interval.clone();
|
||||
|
||||
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
|
||||
let scheduler = (*alarm_scheduler).clone();
|
||||
match scheduler.request_notification_permission().await {
|
||||
Ok(_permission) => {
|
||||
}
|
||||
Err(e) => {
|
||||
web_sys::console::warn_1(
|
||||
&format!("⚠️ Failed to request notification permission: {:?}", e).into()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
alarm_scheduler.set(scheduler);
|
||||
|
||||
// Set up alarm checking interval (every 30 seconds)
|
||||
let interval = {
|
||||
let alarm_scheduler_ref = alarm_scheduler.clone();
|
||||
Interval::new(30_000, move || {
|
||||
// Get a fresh copy of the current scheduler state each time
|
||||
let mut scheduler = (*alarm_scheduler_ref).clone();
|
||||
let triggered_count = scheduler.check_and_trigger_alarms();
|
||||
|
||||
if triggered_count > 0 {
|
||||
web_sys::console::log_1(
|
||||
&format!("🔔 Triggered {} alarm(s)", triggered_count).into()
|
||||
);
|
||||
}
|
||||
|
||||
// Update the scheduler state with any changes (like alarm status updates)
|
||||
alarm_scheduler_ref.set(scheduler);
|
||||
})
|
||||
};
|
||||
|
||||
alarm_check_interval.set(Some(interval));
|
||||
|
||||
// Request notification permission
|
||||
let scheduler = (*alarm_scheduler).clone();
|
||||
match scheduler.request_notification_permission().await {
|
||||
Ok(_permission) => {
|
||||
}
|
||||
Err(e) => {
|
||||
web_sys::console::error_1(
|
||||
&format!("❌ Failed to initialize alarm storage: {:?}", e).into()
|
||||
web_sys::console::warn_1(
|
||||
&format!("⚠️ Failed to request notification permission: {:?}", e).into()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
alarm_scheduler.set(scheduler);
|
||||
alarm_system_initialized.set(true);
|
||||
|
||||
// Set up alarm checking interval (every 30 seconds)
|
||||
let interval = {
|
||||
let alarm_scheduler_ref = alarm_scheduler.clone();
|
||||
Interval::new(30_000, move || {
|
||||
// Get a fresh copy of the current scheduler state each time
|
||||
let mut scheduler = (*alarm_scheduler_ref).clone();
|
||||
let triggered_count = scheduler.check_and_trigger_alarms();
|
||||
|
||||
if triggered_count > 0 {
|
||||
web_sys::console::log_1(
|
||||
&format!("🔔 Triggered {} alarm(s)", triggered_count).into()
|
||||
);
|
||||
}
|
||||
|
||||
// Update the scheduler state with any changes (like alarm status updates)
|
||||
alarm_scheduler_ref.set(scheduler);
|
||||
})
|
||||
};
|
||||
|
||||
alarm_check_interval.set(Some(interval));
|
||||
});
|
||||
} else if token.is_none() {
|
||||
// Clean up alarm system on logout
|
||||
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
|
||||
let reminder_str = if !original_event.alarms.is_empty() {
|
||||
let _reminder_str = if !original_event.alarms.is_empty() {
|
||||
// Convert from VAlarm to minutes before
|
||||
"15".to_string() // TODO: Convert VAlarm trigger to minutes
|
||||
} 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)]
|
||||
pub enum RecurrenceType {
|
||||
|
||||
@@ -30,18 +30,15 @@ pub enum AlarmStatus {
|
||||
pub struct AlarmScheduler {
|
||||
scheduled_alarms: HashMap<String, ScheduledAlarm>,
|
||||
notification_manager: NotificationManager,
|
||||
instance_id: String, // Unique identifier for debugging
|
||||
}
|
||||
|
||||
const ALARMS_STORAGE_KEY: &str = "scheduled_alarms";
|
||||
|
||||
impl AlarmScheduler {
|
||||
pub fn new() -> Self {
|
||||
let instance_id = format!("scheduler_{}", chrono::Local::now().timestamp_nanos_opt().unwrap_or(0));
|
||||
let mut scheduler = Self {
|
||||
scheduled_alarms: HashMap::new(),
|
||||
notification_manager: NotificationManager::new(),
|
||||
instance_id,
|
||||
};
|
||||
|
||||
// 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
|
||||
pub async fn request_notification_permission(&self) -> Result<web_sys::NotificationPermission, wasm_bindgen::JsValue> {
|
||||
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 {
|
||||
|
||||
@@ -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 notification_manager;
|
||||
pub mod alarm_scheduler;
|
||||
pub mod alarm_storage;
|
||||
|
||||
pub use calendar_service::CalendarService;
|
||||
pub use notification_manager::{NotificationManager, AlarmNotification};
|
||||
pub use alarm_scheduler::{AlarmScheduler, ScheduledAlarm, AlarmStatus};
|
||||
pub use alarm_storage::AlarmStorage;
|
||||
pub use alarm_scheduler::AlarmScheduler;
|
||||
|
||||
@@ -114,7 +114,7 @@ impl NotificationManager {
|
||||
}
|
||||
|
||||
// Create notification options
|
||||
let mut options = NotificationOptions::new();
|
||||
let options = NotificationOptions::new();
|
||||
|
||||
// Set notification body with time and 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());
|
||||
|
||||
// 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| {
|
||||
// Focus the window when notification is clicked
|
||||
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
|
||||
pub fn has_notification(&self, event_uid: &str) -> bool {
|
||||
|
||||
Reference in New Issue
Block a user