feat(preferences): Add email sync interval setting (#710)

* 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 <bkaankose@outlook.com>
This commit is contained in:
Maicol Battistini
2025-07-24 09:45:35 +02:00
committed by GitHub
parent 8cd7f68c30
commit c2bb07ff3d
7 changed files with 66 additions and 5 deletions

View File

@@ -51,6 +51,12 @@ public interface IPreferencesService: INotifyPropertyChanged
/// Local search will still offer online search at the end of local search results.
/// </summary>
SearchMode DefaultSearchMode { get; set; }
/// <summary>
/// Setting: Interval in minutes for background email synchronization.
/// </summary>
int EmailSyncIntervalMinutes { get; set; }
#endregion
#region Mail

View File

@@ -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."
}

View File

@@ -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."
}

View File

@@ -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);

View File

@@ -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]

View File

@@ -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">
<ScrollViewer>
@@ -35,6 +36,17 @@
<PathIcon Data="F1 M 18.75 18.125 C 18.75 18.294271 18.68815 18.440756 18.564453 18.564453 C 18.440754 18.68815 18.29427 18.75 18.125 18.75 C 17.955729 18.75 17.809244 18.68815 17.685547 18.564453 L 12.519531 13.398438 C 11.907552 13.912761 11.22233 14.308269 10.463867 14.584961 C 9.705403 14.861654 8.925781 15 8.125 15 C 7.493489 15 6.884765 14.91862 6.298828 14.755859 C 5.712891 14.5931 5.166016 14.361979 4.658203 14.0625 C 4.150391 13.763021 3.686523 13.40332 3.266602 12.983398 C 2.84668 12.563477 2.486979 12.099609 2.1875 11.591797 C 1.888021 11.083984 1.656901 10.537109 1.494141 9.951172 C 1.33138 9.365234 1.25 8.756511 1.25 8.125 C 1.25 7.49349 1.33138 6.884766 1.494141 6.298828 C 1.656901 5.712891 1.888021 5.166016 2.1875 4.658203 C 2.486979 4.150391 2.84668 3.686523 3.266602 3.266602 C 3.686523 2.84668 4.150391 2.48698 4.658203 2.1875 C 5.166016 1.888021 5.712891 1.656902 6.298828 1.494141 C 6.884765 1.331381 7.493489 1.25 8.125 1.25 C 8.75651 1.25 9.365234 1.331381 9.951172 1.494141 C 10.537109 1.656902 11.083984 1.888021 11.591797 2.1875 C 12.099609 2.48698 12.563477 2.84668 12.983398 3.266602 C 13.40332 3.686523 13.763021 4.150391 14.0625 4.658203 C 14.361979 5.166016 14.593099 5.712891 14.755859 6.298828 C 14.918619 6.884766 14.999999 7.49349 15 8.125 C 14.999999 8.925781 14.861652 9.705404 14.584961 10.463867 C 14.308268 11.222331 13.91276 11.907553 13.398438 12.519531 L 18.564453 17.685547 C 18.68815 17.809244 18.75 17.955729 18.75 18.125 Z M 13.75 8.125 C 13.75 7.610678 13.683268 7.114258 13.549805 6.635742 C 13.416341 6.157227 13.227539 5.709636 12.983398 5.292969 C 12.739258 4.876303 12.444661 4.495443 12.099609 4.150391 C 11.754557 3.80534 11.373697 3.510742 10.957031 3.266602 C 10.540364 3.022461 10.092773 2.83366 9.614258 2.700195 C 9.135742 2.566732 8.639322 2.5 8.125 2.5 C 7.35026 2.5 6.621094 2.648113 5.9375 2.944336 C 5.253906 3.240561 4.658203 3.642578 4.150391 4.150391 C 3.642578 4.658204 3.24056 5.253907 2.944336 5.9375 C 2.648112 6.621095 2.5 7.350262 2.5 8.125 C 2.5 8.90625 2.646484 9.638672 2.939453 10.322266 C 3.232422 11.005859 3.632812 11.601562 4.140625 12.109375 C 4.648438 12.617188 5.244141 13.017578 5.927734 13.310547 C 6.611328 13.603516 7.34375 13.75 8.125 13.75 C 8.899739 13.75 9.628906 13.601889 10.3125 13.305664 C 10.996094 13.00944 11.591797 12.607422 12.099609 12.099609 C 12.607421 11.591797 13.009439 10.996094 13.305664 10.3125 C 13.601888 9.628906 13.75 8.89974 13.75 8.125 Z " />
</controls:SettingsCard.HeaderIcon>
</controls:SettingsCard>
<controls:SettingsCard Description="{x:Bind domain:Translator.SettingsAppPreferences_EmailSyncInterval_Description}" Header="{x:Bind domain:Translator.SettingsAppPreferences_EmailSyncInterval_Title}">
<muxc:NumberBox
Minimum="1"
PlaceholderText="3"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.EmailSyncIntervalMinutes, Mode=TwoWay}" />
<controls:SettingsCard.HeaderIcon>
<PathIcon Data="F1 M 0 9.375 C 0 8.509115 0.110677 7.677409 0.332031 6.879883 C 0.553385 6.082357 0.867513 5.335287 1.274414 4.638672 C 1.681315 3.942059 2.169596 3.30892 2.739258 2.739258 C 3.308919 2.169598 3.942057 1.681316 4.638672 1.274414 C 5.335286 0.867514 6.082356 0.553387 6.879883 0.332031 C 7.677409 0.110678 8.509114 0 9.375 0 C 10.234375 0 11.062825 0.112305 11.860352 0.336914 C 12.657877 0.561523 13.404947 0.877279 14.101562 1.28418 C 14.798176 1.691082 15.431314 2.179363 16.000977 2.749023 C 16.570637 3.318686 17.058918 3.951824 17.46582 4.648438 C 17.872721 5.345053 18.188477 6.092123 18.413086 6.889648 C 18.637695 7.687175 18.75 8.515625 18.75 9.375 C 18.75 10.240886 18.637695 11.072592 18.413086 11.870117 C 18.188477 12.667644 17.872721 13.413086 17.46582 14.106445 C 17.058918 14.799805 16.570637 15.431315 16.000977 16.000977 C 15.431314 16.570639 14.799804 17.05892 14.106445 17.46582 C 13.413085 17.872721 12.666015 18.188477 11.865234 18.413086 C 11.064453 18.637695 10.234375 18.75 9.375 18.75 C 8.509114 18.75 7.675781 18.639322 6.875 18.417969 C 6.074219 18.196615 5.327148 17.882486 4.633789 17.475586 C 3.94043 17.068686 3.308919 16.580404 2.739258 16.010742 C 2.169596 15.441081 1.681315 14.80957 1.274414 14.116211 C 0.867513 13.422852 0.553385 12.675781 0.332031 11.875 C 0.110677 11.074219 0 10.240886 0 9.375 Z M 17.5 9.375 C 17.5 8.626303 17.403971 7.905273 17.211914 7.211914 C 17.019855 6.518556 16.746418 5.87077 16.391602 5.268555 C 16.036783 4.666342 15.613606 4.119467 15.12207 3.62793 C 14.630533 3.136395 14.083658 2.713217 13.481445 2.358398 C 12.879231 2.003582 12.231445 1.730145 11.538086 1.538086 C 10.844727 1.346029 10.123697 1.25 9.375 1.25 C 8.626302 1.25 7.905273 1.346029 7.211914 1.538086 C 6.518555 1.730145 5.870768 2.003582 5.268555 2.358398 C 4.666341 2.713217 4.119466 3.136395 3.62793 3.62793 C 3.136393 4.119467 2.713216 4.666342 2.358398 5.268555 C 2.003581 5.87077 1.730143 6.518556 1.538086 7.211914 C 1.346029 7.905273 1.25 8.626303 1.25 9.375 C 1.25 10.123698 1.346029 10.844727 1.538086 11.538086 C 1.730143 12.231445 2.001953 12.879232 2.353516 13.481445 C 2.705078 14.083659 3.128255 14.632162 3.623047 15.126953 C 4.117838 15.621745 4.666341 16.044922 5.268555 16.396484 C 5.870768 16.748047 6.518555 17.019857 7.211914 17.211914 C 7.905273 17.403971 8.626302 17.5 9.375 17.5 C 10.123697 17.5 10.844727 17.403971 11.538086 17.211914 C 12.231445 17.019857 12.879231 16.748047 13.481445 16.396484 C 14.083658 16.044922 14.63216 15.621745 15.126953 15.126953 C 15.621744 14.632162 16.044922 14.083659 16.396484 13.481445 C 16.748047 12.879232 17.019855 12.231445 17.211914 11.538086 C 17.403971 10.844727 17.5 10.123698 17.5 9.375 Z M 9.375 10 C 9.205729 10 9.059244 9.938151 8.935547 9.814453 C 8.811849 9.690756 8.75 9.544271 8.75 9.375 L 8.75 4.375 C 8.75 4.20573 8.811849 4.059246 8.935547 3.935547 C 9.059244 3.81185 9.205729 3.75 9.375 3.75 C 9.544271 3.75 9.690755 3.81185 9.814453 3.935547 C 9.93815 4.059246 10 4.20573 10 4.375 L 10 8.75 L 13.125 8.75 C 13.294271 8.75 13.440755 8.81185 13.564453 8.935547 C 13.68815 9.059245 13.75 9.205729 13.75 9.375 C 13.75 9.544271 13.68815 9.690756 13.564453 9.814453 C 13.440755 9.938151 13.294271 10 13.125 10 Z " />
</controls:SettingsCard.HeaderIcon>
</controls:SettingsCard>
</StackPanel>
<VisualStateManager.VisualStateGroups>

View File

@@ -47,6 +47,8 @@ public class ServerContext :
IRecipient<OnlineSearchRequested>,
IRecipient<AccountCacheResetMessage>
{
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();
}