UI visuals for mail calendar items, calendar reminders.
This commit is contained in:
@@ -13,6 +13,9 @@ public static class Constants
|
||||
public const string ToastMailUniqueIdKey = nameof(ToastMailUniqueIdKey);
|
||||
public const string ToastActionKey = nameof(ToastActionKey);
|
||||
public const string ToastMailAccountIdKey = nameof(ToastMailAccountIdKey);
|
||||
public const string ToastCalendarItemIdKey = nameof(ToastCalendarItemIdKey);
|
||||
public const string ToastCalendarActionKey = nameof(ToastCalendarActionKey);
|
||||
public const string ToastCalendarNavigateAction = nameof(ToastCalendarNavigateAction);
|
||||
|
||||
public const string ClientLogFile = "Client_.log";
|
||||
public const string ServerLogFile = "Server_.log";
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Diagnostics;
|
||||
using Itenso.TimePeriod;
|
||||
using SQLite;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Extensions;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Calendar;
|
||||
|
||||
@@ -168,28 +169,7 @@ public class CalendarItem : ICalendarItem
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(StartTimeZone))
|
||||
{
|
||||
// No timezone info, return as-is
|
||||
return StartDate;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var sourceTimeZone = TimeZoneInfo.FindSystemTimeZoneById(StartTimeZone);
|
||||
var localTimeZone = TimeZoneInfo.Local;
|
||||
|
||||
// Ensure DateTime is Unspecified kind before conversion
|
||||
var unspecifiedDateTime = DateTime.SpecifyKind(StartDate, DateTimeKind.Unspecified);
|
||||
|
||||
// Convert from source timezone to local timezone
|
||||
return TimeZoneInfo.ConvertTime(unspecifiedDateTime, sourceTimeZone, localTimeZone);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// If timezone lookup fails, return as-is
|
||||
return StartDate;
|
||||
}
|
||||
return this.GetLocalStartDate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,28 +182,7 @@ public class CalendarItem : ICalendarItem
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(EndTimeZone))
|
||||
{
|
||||
// No timezone info, return as-is
|
||||
return EndDate;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var sourceTimeZone = TimeZoneInfo.FindSystemTimeZoneById(EndTimeZone);
|
||||
var localTimeZone = TimeZoneInfo.Local;
|
||||
|
||||
// Ensure DateTime is Unspecified kind before conversion
|
||||
var unspecifiedDateTime = DateTime.SpecifyKind(EndDate, DateTimeKind.Unspecified);
|
||||
|
||||
// Convert from source timezone to local timezone
|
||||
return TimeZoneInfo.ConvertTime(unspecifiedDateTime, sourceTimeZone, localTimeZone);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// If timezone lookup fails, return as-is
|
||||
return EndDate;
|
||||
}
|
||||
return this.GetLocalEndDate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System;
|
||||
using Wino.Core.Domain.Entities.Calendar;
|
||||
using Wino.Core.Domain.Models.Calendar;
|
||||
|
||||
namespace Wino.Core.Domain.Extensions;
|
||||
@@ -29,4 +30,56 @@ public static class DateTimeExtensions
|
||||
// Start loading from this date instead of visible date.
|
||||
return date.AddDays(-diff).Date;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a datetime from source timezone into local timezone.
|
||||
/// If timezone lookup fails, returns original value.
|
||||
/// </summary>
|
||||
public static DateTime ToLocalTimeFromTimeZone(this DateTime dateTime, string sourceTimeZoneId)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(sourceTimeZoneId))
|
||||
return dateTime;
|
||||
|
||||
try
|
||||
{
|
||||
var sourceTimeZone = TimeZoneInfo.FindSystemTimeZoneById(sourceTimeZoneId);
|
||||
var localTimeZone = TimeZoneInfo.Local;
|
||||
var unspecifiedDateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Unspecified);
|
||||
|
||||
return TimeZoneInfo.ConvertTime(unspecifiedDateTime, sourceTimeZone, localTimeZone);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return dateTime;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts local datetime into target timezone.
|
||||
/// If timezone lookup fails, returns original value.
|
||||
/// </summary>
|
||||
public static DateTime ToTimeZoneFromLocal(this DateTime localDateTime, string targetTimeZoneId)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(targetTimeZoneId))
|
||||
return localDateTime;
|
||||
|
||||
try
|
||||
{
|
||||
var sourceTimeZone = TimeZoneInfo.Local;
|
||||
var targetTimeZone = TimeZoneInfo.FindSystemTimeZoneById(targetTimeZoneId);
|
||||
var unspecifiedDateTime = DateTime.SpecifyKind(localDateTime, DateTimeKind.Unspecified);
|
||||
|
||||
return TimeZoneInfo.ConvertTime(unspecifiedDateTime, sourceTimeZone, targetTimeZone);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return localDateTime;
|
||||
}
|
||||
}
|
||||
|
||||
public static DateTime GetLocalStartDate(this CalendarItem calendarItem)
|
||||
=> calendarItem.StartDate.ToLocalTimeFromTimeZone(calendarItem.StartTimeZone);
|
||||
|
||||
public static DateTime GetLocalEndDate(this CalendarItem calendarItem)
|
||||
=> calendarItem.EndDate.ToLocalTimeFromTimeZone(calendarItem.EndTimeZone);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Itenso.TimePeriod;
|
||||
using Wino.Core.Domain.Entities.Calendar;
|
||||
@@ -18,7 +19,7 @@ public interface ICalendarService
|
||||
Task InsertAccountCalendarAsync(AccountCalendar accountCalendar);
|
||||
Task UpdateAccountCalendarAsync(AccountCalendar accountCalendar);
|
||||
Task CreateNewCalendarItemAsync(CalendarItem calendarItem, List<CalendarEventAttendee> attendees);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves calendar events for a given calendar within the specified time period.
|
||||
/// </summary>
|
||||
@@ -26,7 +27,7 @@ public interface ICalendarService
|
||||
/// <param name="period">The time period to query events for.</param>
|
||||
/// <returns>List of calendar items that fall within the requested period.</returns>
|
||||
Task<List<CalendarItem>> GetCalendarEventsAsync(IAccountCalendar calendar, ITimePeriod period);
|
||||
|
||||
|
||||
Task<CalendarItem> GetCalendarItemAsync(Guid accountCalendarId, string remoteEventId);
|
||||
Task UpdateCalendarDeltaSynchronizationToken(Guid calendarId, string deltaToken);
|
||||
|
||||
@@ -42,6 +43,11 @@ public interface ICalendarService
|
||||
Task<List<Reminder>> GetRemindersAsync(Guid calendarItemId);
|
||||
Task SaveRemindersAsync(Guid calendarItemId, List<Reminder> reminders);
|
||||
|
||||
/// <summary>
|
||||
/// Checks due reminder windows and returns reminder notifications that should trigger now.
|
||||
/// </summary>
|
||||
Task<List<CalendarReminderNotificationRequest>> CheckAndNotifyAsync(DateTime lastCheckLocal, DateTime nowLocal, ISet<string> sentReminderKeys, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Gets predefined reminder options in minutes (1 Hour, 30 Min, 15 Min, 5 Min, 1 Min).
|
||||
/// </summary>
|
||||
|
||||
@@ -17,6 +17,7 @@ public interface IMailItemDisplayInformation : INotifyPropertyChanged
|
||||
bool IsRead { get; }
|
||||
bool IsDraft { get; }
|
||||
bool HasAttachments { get; }
|
||||
bool IsCalendarEvent { get; }
|
||||
bool IsFlagged { get; }
|
||||
DateTime CreationDate { get; }
|
||||
string Base64ContactPicture { get; }
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Wino.Core.Domain.Entities.Calendar;
|
||||
using Wino.Core.Domain.Entities.Mail;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
|
||||
@@ -29,4 +30,9 @@ public interface INotificationBuilder
|
||||
/// </summary>
|
||||
/// <param name="account">Account that needs attention.</param>
|
||||
void CreateAttentionRequiredNotification(MailAccount account);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a calendar reminder toast for the specified calendar item.
|
||||
/// </summary>
|
||||
Task CreateCalendarReminderNotificationAsync(CalendarItem calendarItem, long reminderDurationInSeconds);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
using Wino.Core.Domain.Entities.Calendar;
|
||||
|
||||
namespace Wino.Core.Domain.Models.Calendar;
|
||||
|
||||
public sealed class CalendarReminderNotificationRequest
|
||||
{
|
||||
public CalendarItem CalendarItem { get; init; } = null!;
|
||||
public long ReminderDurationInSeconds { get; init; }
|
||||
public string ReminderKey { get; init; } = string.Empty;
|
||||
}
|
||||
Reference in New Issue
Block a user