Reminders.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
@@ -35,13 +36,22 @@ public partial class CalendarSettingsPageViewModel : CalendarBaseViewModel
|
||||
|
||||
[ObservableProperty]
|
||||
public partial int WorkingDayEndIndex { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial List<string> ReminderOptions { get; set; } = [];
|
||||
|
||||
[ObservableProperty]
|
||||
public partial int SelectedDefaultReminderIndex { get; set; }
|
||||
|
||||
public IPreferencesService PreferencesService { get; }
|
||||
private readonly ICalendarService _calendarService;
|
||||
|
||||
private readonly bool _isLoaded = false;
|
||||
|
||||
public CalendarSettingsPageViewModel(IPreferencesService preferencesService)
|
||||
public CalendarSettingsPageViewModel(IPreferencesService preferencesService, ICalendarService calendarService)
|
||||
{
|
||||
PreferencesService = preferencesService;
|
||||
_calendarService = calendarService;
|
||||
|
||||
var currentLanguageLanguageCode = WinoTranslationDictionary.GetLanguageFileNameRelativePath(preferencesService.CurrentLanguage);
|
||||
|
||||
@@ -62,6 +72,31 @@ public partial class CalendarSettingsPageViewModel : CalendarBaseViewModel
|
||||
WorkingDayStartIndex = DayNames.IndexOf(cultureInfo.DateTimeFormat.GetDayName(preferencesService.WorkingDayStart));
|
||||
WorkingDayEndIndex = DayNames.IndexOf(cultureInfo.DateTimeFormat.GetDayName(preferencesService.WorkingDayEnd));
|
||||
|
||||
// Initialize reminder options
|
||||
var predefinedMinutes = _calendarService.GetPredefinedReminderMinutes();
|
||||
ReminderOptions.Add("None");
|
||||
foreach (var minutes in predefinedMinutes)
|
||||
{
|
||||
var displayText = minutes switch
|
||||
{
|
||||
>= 60 => $"{minutes / 60} Hour{(minutes / 60 > 1 ? "s" : "")}",
|
||||
_ => $"{minutes} Minute{(minutes > 1 ? "s" : "")}"
|
||||
};
|
||||
ReminderOptions.Add(displayText);
|
||||
}
|
||||
|
||||
// Set selected index based on current default reminder setting
|
||||
if (preferencesService.DefaultReminderDurationInSeconds == 0)
|
||||
{
|
||||
SelectedDefaultReminderIndex = 0; // None
|
||||
}
|
||||
else
|
||||
{
|
||||
var minutes = (int)(preferencesService.DefaultReminderDurationInSeconds / 60);
|
||||
var index = Array.IndexOf(predefinedMinutes, minutes);
|
||||
SelectedDefaultReminderIndex = index >= 0 ? index + 1 : 0;
|
||||
}
|
||||
|
||||
_isLoaded = true;
|
||||
}
|
||||
|
||||
@@ -72,6 +107,7 @@ public partial class CalendarSettingsPageViewModel : CalendarBaseViewModel
|
||||
partial void OnWorkingHourEndChanged(TimeSpan value) => SaveSettings();
|
||||
partial void OnWorkingDayStartIndexChanged(int value) => SaveSettings();
|
||||
partial void OnWorkingDayEndIndexChanged(int value) => SaveSettings();
|
||||
partial void OnSelectedDefaultReminderIndexChanged(int value) => SaveSettings();
|
||||
|
||||
public void SaveSettings()
|
||||
{
|
||||
@@ -118,6 +154,18 @@ public partial class CalendarSettingsPageViewModel : CalendarBaseViewModel
|
||||
PreferencesService.WorkingHourEnd = WorkingHourEnd;
|
||||
PreferencesService.HourHeight = CellHourHeight;
|
||||
|
||||
// Save default reminder setting
|
||||
if (SelectedDefaultReminderIndex == 0)
|
||||
{
|
||||
PreferencesService.DefaultReminderDurationInSeconds = 0; // None
|
||||
}
|
||||
else
|
||||
{
|
||||
var predefinedMinutes = _calendarService.GetPredefinedReminderMinutes();
|
||||
var minutes = predefinedMinutes[SelectedDefaultReminderIndex - 1];
|
||||
PreferencesService.DefaultReminderDurationInSeconds = minutes * 60;
|
||||
}
|
||||
|
||||
Messenger.Send(new CalendarSettingsUpdatedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Wino.Calendar.ViewModels.Data;
|
||||
using Wino.Core.Domain;
|
||||
using Wino.Core.Domain.Entities.Calendar;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Calendar;
|
||||
@@ -32,10 +35,14 @@ public partial class EventDetailsPageViewModel : CalendarBaseViewModel
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(CanViewSeries))]
|
||||
[NotifyPropertyChangedFor(nameof(CanEditSeries))]
|
||||
private CalendarItemViewModel _currentEvent;
|
||||
|
||||
[NotifyPropertyChangedFor(nameof(IsCurrentUserOrganizer))]
|
||||
public partial CalendarItemViewModel CurrentEvent { get; set; }
|
||||
[ObservableProperty]
|
||||
private CalendarItemViewModel _seriesParent;
|
||||
public partial CalendarItemViewModel SeriesParent { get; set; }
|
||||
[ObservableProperty]
|
||||
public partial List<Reminder> Reminders { get; set; }
|
||||
|
||||
public ObservableCollection<ReminderOption> ReminderOptions { get; } = new ObservableCollection<ReminderOption>();
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the event is part of a recurring series (as a child occurrence).
|
||||
@@ -49,6 +56,12 @@ public partial class EventDetailsPageViewModel : CalendarBaseViewModel
|
||||
/// </summary>
|
||||
public bool CanEditSeries => CurrentEvent?.IsRecurringChild ?? false;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the current user is the organizer of the event.
|
||||
/// Used to determine if the user can invite attendees or modify the event.
|
||||
/// </summary>
|
||||
public bool IsCurrentUserOrganizer => CurrentEvent?.Attendees?.Any(a => a.IsOrganizer) ?? true;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Show As Options
|
||||
@@ -113,6 +126,10 @@ public partial class EventDetailsPageViewModel : CalendarBaseViewModel
|
||||
{
|
||||
CurrentEvent.Attendees.Add(item);
|
||||
}
|
||||
|
||||
// Load reminders for this calendar item
|
||||
Reminders = await _calendarService.GetRemindersAsync(currentEventItem.EventTrackingId);
|
||||
InitializeReminderOptions();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -120,17 +137,88 @@ public partial class EventDetailsPageViewModel : CalendarBaseViewModel
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnNavigatedFrom(NavigationMode mode, object parameters)
|
||||
private void InitializeReminderOptions()
|
||||
{
|
||||
base.OnNavigatedFrom(mode, parameters);
|
||||
ReminderOptions.Clear();
|
||||
|
||||
Messenger.Send(new DetailsPageStateChangedMessage(false));
|
||||
// Add predefined options from service
|
||||
var predefinedMinutes = _calendarService.GetPredefinedReminderMinutes();
|
||||
var predefinedOptions = predefinedMinutes.Select(m => new ReminderOption(m)).ToList();
|
||||
|
||||
// Add custom reminders from synced data
|
||||
if (Reminders != null)
|
||||
{
|
||||
foreach (var reminder in Reminders)
|
||||
{
|
||||
// Convert seconds to minutes
|
||||
var minutesDiff = (int)(reminder.DurationInSeconds / 60);
|
||||
|
||||
// Check if this is a custom value not in predefined list
|
||||
if (!predefinedMinutes.Contains(minutesDiff))
|
||||
{
|
||||
predefinedOptions.Add(new ReminderOption(minutesDiff, isCustom: true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by minutes descending and add to collection
|
||||
foreach (var option in predefinedOptions.OrderByDescending(o => o.Minutes))
|
||||
{
|
||||
ReminderOptions.Add(option);
|
||||
}
|
||||
|
||||
// Set selected state based on current reminders
|
||||
if (Reminders != null)
|
||||
{
|
||||
foreach (var reminder in Reminders)
|
||||
{
|
||||
// Convert seconds to minutes
|
||||
var minutesDiff = (int)(reminder.DurationInSeconds / 60);
|
||||
|
||||
var matchingOption = ReminderOptions.FirstOrDefault(o => o.Minutes == minutesDiff);
|
||||
matchingOption?.IsSelected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[RelayCommand]
|
||||
private async Task SaveAsync()
|
||||
{
|
||||
// TODO: Implement saving
|
||||
if (CurrentEvent == null) return;
|
||||
|
||||
try
|
||||
{
|
||||
// Get selected reminder options
|
||||
var selectedOptions = ReminderOptions.Where(o => o.IsSelected).ToList();
|
||||
|
||||
// Create separate Reminder entities for each selected option
|
||||
var newReminders = new List<Reminder>();
|
||||
|
||||
foreach (var option in selectedOptions)
|
||||
{
|
||||
var durationInSeconds = option.Minutes * 60; // Convert minutes to seconds
|
||||
|
||||
newReminders.Add(new Reminder
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
CalendarItemId = CurrentEvent.Id,
|
||||
DurationInSeconds = durationInSeconds,
|
||||
ReminderType = CalendarItemReminderType.Popup
|
||||
});
|
||||
}
|
||||
|
||||
// Save reminders to database
|
||||
await _calendarService.SaveRemindersAsync(CurrentEvent.CalendarItem.EventTrackingId, newReminders);
|
||||
Reminders = newReminders;
|
||||
|
||||
_navigationService.GoBack();
|
||||
// TODO: Implement saving other event details
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"Error saving event: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
@@ -183,4 +271,55 @@ public partial class EventDetailsPageViewModel : CalendarBaseViewModel
|
||||
|
||||
// TODO: Implement response
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task ViewSeriesAsync()
|
||||
{
|
||||
if (CurrentEvent == null || !CurrentEvent.IsRecurringChild) return;
|
||||
|
||||
try
|
||||
{
|
||||
// Get the master event from the recurring series
|
||||
var masterEventId = CurrentEvent.CalendarItem.RecurringCalendarItemId.Value;
|
||||
var masterEvent = await _calendarService.GetCalendarItemAsync(masterEventId);
|
||||
|
||||
if (masterEvent == null) return;
|
||||
|
||||
// Load the master event without navigation
|
||||
var target = new CalendarItemTarget(masterEvent, CalendarEventTargetType.Series);
|
||||
await LoadCalendarItemTargetAsync(target);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"Error loading series: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public partial class ReminderOption : ObservableObject
|
||||
{
|
||||
public int Minutes { get; }
|
||||
public bool IsCustom { get; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial bool IsSelected { get; set; }
|
||||
|
||||
public string DisplayText
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Minutes >= 60)
|
||||
{
|
||||
var hours = Minutes / 60;
|
||||
return hours == 1 ? "1 Hour" : $"{hours} Hours";
|
||||
}
|
||||
return Minutes == 1 ? "1 Minute" : $"{Minutes} Minutes";
|
||||
}
|
||||
}
|
||||
|
||||
public ReminderOption(int minutes, bool isCustom = false)
|
||||
{
|
||||
Minutes = minutes;
|
||||
IsCustom = isCustom;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user