From c2bb07ff3d72c4753cdcccb833d75df4a87b6328 Mon Sep 17 00:00:00 2001 From: Maicol Battistini Date: Thu, 24 Jul 2025 09:45:35 +0200 Subject: [PATCH] =?UTF-8?q?feat(preferences):=20=E2=9C=A8=20Add=20email=20?= =?UTF-8?q?sync=20interval=20setting=20(#710)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(preferences): ✨ Add email sync interval setting Introduced a new property `EmailSyncIntervalMinutes` in the `IPreferencesService` interface to allow users to configure the email synchronization interval in minutes. This feature enhances user control over email sync behavior. • Updated `resources.json` to include translations for the new setting. • Implemented the logic for the new property in `PreferencesService.cs`, with a default value of 3 minutes. • Added binding and UI support in `AppPreferencesPageViewModel.cs` and `AppPreferencesPage.xaml` to allow users to modify the sync interval. • Integrated the new setting into `ServerContext.cs` to dynamically adjust the synchronization timer based on user preferences. This change improves the user experience by providing customizable email synchronization settings. * Minimum interval and added an icon. * Proper SetProperty usage. * Making sure the minimum sync interval is 1 in the ServerContext. * Making sure the minimum is applied to first trigger of the sync timer. --------- Co-authored-by: Burak Kaan Köse --- .../Interfaces/IPreferencesService.cs | 6 +++++ .../Translations/en_US/resources.json | 4 ++- .../Translations/it_IT/resources.json | 4 ++- Wino.Core.UWP/Services/PreferencesService.cs | 6 +++++ .../AppPreferencesPageViewModel.cs | 13 ++++++++++ .../Views/Settings/AppPreferencesPage.xaml | 12 +++++++++ Wino.Server/ServerContext.cs | 26 ++++++++++++++++--- 7 files changed, 66 insertions(+), 5 deletions(-) diff --git a/Wino.Core.Domain/Interfaces/IPreferencesService.cs b/Wino.Core.Domain/Interfaces/IPreferencesService.cs index 345eccb1..51e7eb22 100644 --- a/Wino.Core.Domain/Interfaces/IPreferencesService.cs +++ b/Wino.Core.Domain/Interfaces/IPreferencesService.cs @@ -51,6 +51,12 @@ public interface IPreferencesService: INotifyPropertyChanged /// Local search will still offer online search at the end of local search results. /// SearchMode DefaultSearchMode { get; set; } + + /// + /// Setting: Interval in minutes for background email synchronization. + /// + int EmailSyncIntervalMinutes { get; set; } + #endregion #region Mail diff --git a/Wino.Core.Domain/Translations/en_US/resources.json b/Wino.Core.Domain/Translations/en_US/resources.json index 227a28f9..8eccf7fa 100644 --- a/Wino.Core.Domain/Translations/en_US/resources.json +++ b/Wino.Core.Domain/Translations/en_US/resources.json @@ -698,7 +698,9 @@ "WinoUpgradeDescription": "Wino offers 3 accounts to start with for free. If you need more than 3 accounts, please upgrade", "WinoUpgradeMessage": "Upgrade to Unlimited Accounts", "WinoUpgradeRemainingAccountsMessage": "{0} out of {1} free accounts used.", - "Yesterday": "Yesterday" + "Yesterday": "Yesterday", + "SettingsAppPreferences_EmailSyncInterval_Title": "Email sync interval", + "SettingsAppPreferences_EmailSyncInterval_Description": "Automatic email synchronization interval (minutes). This setting will be applied only after restarting Wino Mail." } diff --git a/Wino.Core.Domain/Translations/it_IT/resources.json b/Wino.Core.Domain/Translations/it_IT/resources.json index 18267504..e5723d8c 100644 --- a/Wino.Core.Domain/Translations/it_IT/resources.json +++ b/Wino.Core.Domain/Translations/it_IT/resources.json @@ -689,7 +689,9 @@ "WinoUpgradeDescription": "Wino offre 3 account per iniziare gratuitamente. Se hai bisogno di più di 3 account, per favore aggiorna", "WinoUpgradeMessage": "Aggiorna ad account illimitati", "WinoUpgradeRemainingAccountsMessage": "{0} di {1} account gratuiti usati.", - "Yesterday": "Ieri" + "Yesterday": "Ieri", + "SettingsAppPreferences_EmailSyncInterval_Title": "Intervallo sincronizzazione email", + "SettingsAppPreferences_EmailSyncInterval_Description": "Intervallo di sincronizzazione automatica delle email (minuti). Questa impostazione verrà applicata solo dopo il riavvio di Wino Mail." } diff --git a/Wino.Core.UWP/Services/PreferencesService.cs b/Wino.Core.UWP/Services/PreferencesService.cs index ea88910e..153cf504 100644 --- a/Wino.Core.UWP/Services/PreferencesService.cs +++ b/Wino.Core.UWP/Services/PreferencesService.cs @@ -290,6 +290,12 @@ public class PreferencesService(IConfigurationService configurationService) : Ob set => SaveProperty(propertyName: nameof(WorkingDayEnd), value); } + public int EmailSyncIntervalMinutes + { + get => _configurationService.Get(nameof(EmailSyncIntervalMinutes), 3); + set => SetPropertyAndSave(nameof(EmailSyncIntervalMinutes), value); + } + public CalendarSettings GetCurrentCalendarSettings() { var workingDays = GetDaysBetween(WorkingDayStart, WorkingDayEnd); diff --git a/Wino.Mail.ViewModels/AppPreferencesPageViewModel.cs b/Wino.Mail.ViewModels/AppPreferencesPageViewModel.cs index 41dcd0e4..3a7489d0 100644 --- a/Wino.Mail.ViewModels/AppPreferencesPageViewModel.cs +++ b/Wino.Mail.ViewModels/AppPreferencesPageViewModel.cs @@ -26,6 +26,18 @@ public partial class AppPreferencesPageViewModel : MailBaseViewModel [NotifyPropertyChangedFor(nameof(IsStartupBehaviorEnabled))] private StartupBehaviorResult startupBehaviorResult; + private int _emailSyncIntervalMinutes; + public int EmailSyncIntervalMinutes + { + get => _emailSyncIntervalMinutes; + set + { + SetProperty(ref _emailSyncIntervalMinutes, value); + + PreferencesService.EmailSyncIntervalMinutes = value; + } + } + public bool IsStartupBehaviorDisabled => !IsStartupBehaviorEnabled; public bool IsStartupBehaviorEnabled => StartupBehaviorResult == StartupBehaviorResult.Enabled; @@ -84,6 +96,7 @@ public partial class AppPreferencesPageViewModel : MailBaseViewModel SelectedAppTerminationBehavior = _appTerminationBehavior[(int)PreferencesService.ServerTerminationBehavior]; SelectedDefaultSearchMode = SearchModes[(int)PreferencesService.DefaultSearchMode]; + EmailSyncIntervalMinutes = PreferencesService.EmailSyncIntervalMinutes; } [RelayCommand] diff --git a/Wino.Mail/Views/Settings/AppPreferencesPage.xaml b/Wino.Mail/Views/Settings/AppPreferencesPage.xaml index 0499a2d6..d9cb3fc2 100644 --- a/Wino.Mail/Views/Settings/AppPreferencesPage.xaml +++ b/Wino.Mail/Views/Settings/AppPreferencesPage.xaml @@ -7,6 +7,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:domain="using:Wino.Core.Domain" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:muxc="using:Microsoft.UI.Xaml.Controls" mc:Ignorable="d"> @@ -35,6 +36,17 @@ + + + + + + + diff --git a/Wino.Server/ServerContext.cs b/Wino.Server/ServerContext.cs index 526429d3..20f5ebd7 100644 --- a/Wino.Server/ServerContext.cs +++ b/Wino.Server/ServerContext.cs @@ -47,6 +47,8 @@ public class ServerContext : IRecipient, IRecipient { + private const double MinimumSynchronizationIntervalMinutes = 1; + private readonly System.Timers.Timer _timer; private static object connectionLock = new object(); @@ -57,6 +59,7 @@ public class ServerContext : private readonly ISynchronizerFactory _synchronizerFactory; private readonly IServerMessageHandlerFactory _serverMessageHandlerFactory; private readonly IAccountService _accountService; + private readonly IPreferencesService _preferencesService; private readonly JsonSerializerOptions _jsonSerializerOptions = new JsonSerializerOptions { TypeInfoResolver = new ServerRequestTypeInfoResolver() @@ -66,12 +69,13 @@ public class ServerContext : IApplicationConfiguration applicationFolderConfiguration, ISynchronizerFactory synchronizerFactory, IServerMessageHandlerFactory serverMessageHandlerFactory, - IAccountService accountService) + IAccountService accountService, + IPreferencesService preferencesService) { - // Setup timer for synchronization. + _preferencesService = preferencesService; - _timer = new System.Timers.Timer(1000 * 60 * 3); // 1 minute _timer.Elapsed += SynchronizationTimerTriggered; + _preferencesService.PropertyChanged += PreferencesUpdated; _databaseService = databaseService; _applicationFolderConfiguration = applicationFolderConfiguration; @@ -81,6 +85,22 @@ public class ServerContext : WeakReferenceMessenger.Default.RegisterAll(this); + // Setup timer for synchronization. + RestartSynchronizationTimer(); + } + + private void PreferencesUpdated(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + if (e.PropertyName == nameof(IPreferencesService.EmailSyncIntervalMinutes)) + RestartSynchronizationTimer(); + } + + private void RestartSynchronizationTimer() + { + _timer.Stop(); + + // Ensure that the interval is at least 1 minute. + _timer.Interval = 1000 * 60 * Math.Max(MinimumSynchronizationIntervalMinutes, _preferencesService.EmailSyncIntervalMinutes); _timer.Start(); }