diff --git a/Wino.Calendar.ViewModels/CalendarPageViewModel.cs b/Wino.Calendar.ViewModels/CalendarPageViewModel.cs index 5b9d7c59..10545017 100644 --- a/Wino.Calendar.ViewModels/CalendarPageViewModel.cs +++ b/Wino.Calendar.ViewModels/CalendarPageViewModel.cs @@ -271,12 +271,22 @@ public partial class CalendarPageViewModel : CalendarBaseViewModel, { RefreshSettings(); - if (mode == NavigationMode.Back) return; + if (mode == NavigationMode.Back) + { + _ = RefreshVisibleRangesAsync(); + return; + } // Automatically select the first primary calendar for quick event dialog. SelectedQuickEventAccountCalendar = AccountCalendarStateService.ActiveCalendars.FirstOrDefault(a => a.IsPrimary); } + public override void OnNavigatedFrom(NavigationMode mode, object parameters) + { + // CalendarPage is cached and should continue processing calendar item messages + // while details/compose pages are active on top of it. + } + [RelayCommand] private void NavigateSeries() { diff --git a/Wino.Core.Domain/Interfaces/IContactPictureFileService.cs b/Wino.Core.Domain/Interfaces/IContactPictureFileService.cs index f3b59df1..ea654a17 100644 --- a/Wino.Core.Domain/Interfaces/IContactPictureFileService.cs +++ b/Wino.Core.Domain/Interfaces/IContactPictureFileService.cs @@ -23,11 +23,4 @@ public interface IContactPictureFileService /// Deletes the picture file for the given file ID if it exists. /// Task DeleteContactPictureAsync(Guid fileId); - - /// - /// One-time startup migration: reads AccountContact rows where Base64ContactPicture is set - /// but ContactPictureFileId is null, writes the picture bytes to disk, updates the DB row, - /// and clears the Base64ContactPicture column. - /// - Task MigrateBase64PicturesAsync(); } diff --git a/Wino.Core.Domain/Models/Updates/UpdateNotes.cs b/Wino.Core.Domain/Models/Updates/UpdateNotes.cs index 354f6f6c..fad7d80f 100644 --- a/Wino.Core.Domain/Models/Updates/UpdateNotes.cs +++ b/Wino.Core.Domain/Models/Updates/UpdateNotes.cs @@ -1,7 +1,9 @@ using System.Collections.Generic; +using System.Text.Json.Serialization; namespace Wino.Core.Domain.Models.Updates; public class UpdateNotes { + [JsonPropertyName("sections")] public List Sections { get; set; } = []; } diff --git a/Wino.Core.Domain/Translations/en_US/resources.json b/Wino.Core.Domain/Translations/en_US/resources.json index 2fea340e..450d873a 100644 --- a/Wino.Core.Domain/Translations/en_US/resources.json +++ b/Wino.Core.Domain/Translations/en_US/resources.json @@ -126,7 +126,6 @@ "CalendarAttendeeStatus_Tentative": "Tentative", "CalendarEventDetails_Attachments": "Attachments", "CalendarEventCompose_AddAttachment": "Add attachment", - "CalendarEventCompose_AttachmentsNotSupportedForCalDav": "Attachments are not supported for CalDAV calendars.", "CalendarEventCompose_AllDay": "All Day", "CalendarEventCompose_EndDate": "End date", "CalendarEventCompose_EndTime": "End time", @@ -254,8 +253,6 @@ "DialogMessage_DeleteAccountConfirmationTitle": "All data associated with this account will be deleted from disk permanently.", "DialogMessage_DeleteRecurringSeriesMessage": "This will delete all events in the series. Do you want to continue?", "DialogMessage_DeleteRecurringSeriesTitle": "Delete Recurring Series", - "DialogMessage_DeleteEmailTemplateConfirmationMessage": "Delete template \"{0}\"?", - "DialogMessage_DeleteEmailTemplateConfirmationTitle": "Delete Email Template", "DialogMessage_DiscardDraftConfirmationMessage": "This draft will be discarded. Do you want to continue?", "DialogMessage_DiscardDraftConfirmationTitle": "Discard Draft", "DialogMessage_EmptySubjectConfirmation": "Missing Subject", @@ -364,29 +361,19 @@ "KeyboardShortcuts_FailedToReset": "Failed to reset keyboard shortcuts.", "KeyboardShortcuts_FailedToUpdate": "Failed to update keyboard shortcuts", "KeyboardShortcuts_MailoperationAction": "Action", - "KeyboardShortcuts_Action": "Action", "KeyboardShortcuts_FailedToLoad": "Failed to load keyboard shortcuts.", "KeyboardShortcuts_EnterKeyForShortcut": "Please enter a key for the shortcut.", "KeyboardShortcuts_SelectOperationForShortcut": "Please an action to perform for the shortcut.", - "KeyboardShortcuts_EnterKey": "Please enter a key for the shortcut.", - "KeyboardShortcuts_SelectOperation": "Please select an action for the shortcut.", "KeyboardShortcuts_ShortcutInUse": "This shortcut is already in use by another s hortcut.", "KeyboardShortcuts_FailedToSave": "Failed to save the shortcut.", "KeyboardShortcuts_FailedToDelete": "Failed to delete the shortcut.", "KeyboardShortcuts_PageDescription": "Set up keyboard shortcuts for quick mail operations. Press keys while focused on the key input field to capture shortcuts.", "KeyboardShortcuts_Add": "Add shortcut", - "KeyboardShortcuts_EditTitle": "Edit Keyboard Shortcut", "KeyboardShortcuts_ResetToDefaults": "Reset to Defaults", "KeyboardShortcuts_PressKeysHere": "Press keys here...", "KeyboardShortcuts_KeyCombination": "Key Combination", "KeyboardShortcuts_FocusArea": "Focus the field above and press the desired key combination", "KeyboardShortcuts_Modifiers": "Modifier Keys", - "KeyboardShortcuts_Mode": "App Mode", - "KeyboardShortcuts_ModeMail": "Mail", - "KeyboardShortcuts_ModeCalendar": "Calendar", - "KeyboardShortcuts_ActionToggleReadUnread": "Toggle read/unread", - "KeyboardShortcuts_ActionToggleFlag": "Toggle flag", - "KeyboardShortcuts_ActionToggleArchive": "Toggle archive/unarchive", "ImageRenderingDisabled": "Image rendering is disabled for this message.", "ImapAdvancedSetupDialog_AuthenticationMethod": "Authentication method", "ImapAdvancedSetupDialog_ConnectionSecurity": "Connection security", @@ -611,7 +598,6 @@ "MenuNewMail": "New Mail", "MenuRate": "Rate Wino", "MenuSettings": "Settings", - "MenuUpdateAvailable": "Update Available", "MergedAccountCommonFolderArchive": "Archive", "MergedAccountCommonFolderDraft": "Draft", "MergedAccountCommonFolderInbox": "Inbox", @@ -635,8 +621,6 @@ "Notifications_MultipleNotificationsTitle": "New Mail", "Notifications_WinoUpdatedMessage": "Checkout new version {0}", "Notifications_WinoUpdatedTitle": "Wino Mail has been updated.", - "Notifications_StoreUpdateAvailableTitle": "Update available", - "Notifications_StoreUpdateAvailableMessage": "A newer version of Wino Mail is ready to install from Microsoft Store.", "OnlineSearchFailed_Message": "Failed to perform search\n{0}\n\nListing offline mails.", "OnlineSearchTry_Line1": "Can't find what you are looking for?", "OnlineSearchTry_Line2": "Try online search.", @@ -715,8 +699,6 @@ "SettingsAppPreferences_StartupBehavior_FatalError": "Fatal error occurred while changing the startup mode for Wino Mail.", "SettingsAppPreferences_StartupBehavior_Title": "Start minimized on Windows startup", "SettingsAppPreferences_Title": "App Preferences", - "SettingsAppPreferences_StoreUpdateNotifications_Title": "Store update notifications", - "SettingsAppPreferences_StoreUpdateNotifications_Description": "Show notifications and footer actions when a Microsoft Store update is available.", "SettingsAutoSelectNextItem_Description": "Select the next item after you delete or move a mail.", "SettingsAutoSelectNextItem_Title": "Auto select next item", "SettingsAvailableThemes_Description": "Select a theme from Wino's own collection for your taste or apply your own themes.", @@ -851,19 +833,6 @@ "SettingsShowSenderPictures_Title": "Show Sender Avatars", "SettingsEnableGravatarAvatars_Title": "Gravatar", "SettingsEnableGravatarAvatars_Description": "Use gravatar (if available) as sender picture", - "SettingsEmailTemplates_Title": "Email Templates", - "SettingsEmailTemplates_Description": "Manage e-mail templates", - "SettingsEmailTemplates_CreatePageTitle": "New template", - "SettingsEmailTemplates_EditPageTitle": "Edit template", - "SettingsEmailTemplates_NewTemplateTitle": "New template", - "SettingsEmailTemplates_NewTemplateDescription": "Create a new e-mail template", - "SettingsEmailTemplates_NameTitle": "Name", - "SettingsEmailTemplates_NamePlaceholder": "Template name", - "SettingsEmailTemplates_DescriptionTitle": "Description", - "SettingsEmailTemplates_DescriptionPlaceholder": "Optional description", - "SettingsEmailTemplates_ContentTitle": "Template content", - "SettingsEmailTemplates_ContentDescription": "Edit the HTML content for this template.", - "SettingsEmailTemplates_NameRequired": "Template name is required.", "SettingsEnableFavicons_Title": "Domain icons (Favicons)", "SettingsEnableFavicons_Description": "Use domain favicons (if available) as sender picture", "SettingsMailList_ClearAvatarsCache_Button": "Clear cached avatars", @@ -1021,7 +990,6 @@ "Composer_CertificateExpires": "Expires on: ", "Composer_SmimeSignature": "S/MIME Signature", "Composer_SmimeEncryption": "S/MIME Encryption", - "Composer_EmailTemplatesPlaceholder": "E-mail templates", "SettingsAppPreferences_EmailSyncInterval_Title": "Email sync interval", "SettingsAppPreferences_EmailSyncInterval_Description": "Automatic email synchronization interval (minutes). This setting will be applied only after restarting Wino Mail.", "ContactsPage_Title": "Contacts", @@ -1148,5 +1116,3 @@ "AccountSetup_TryAgainButton": "Try Again", "ImapCalDavSettings_AutoDiscoveryFailed": "Auto-discovery failed. Please enter settings manually in the Advanced tab." } - - diff --git a/Wino.Core.ViewModels/SettingOptionsPageViewModel.cs b/Wino.Core.ViewModels/SettingOptionsPageViewModel.cs index 1eff7136..9f55c8b2 100644 --- a/Wino.Core.ViewModels/SettingOptionsPageViewModel.cs +++ b/Wino.Core.ViewModels/SettingOptionsPageViewModel.cs @@ -76,7 +76,6 @@ public partial class SettingOptionsPageViewModel : CoreBaseViewModel WinoPage.ReadComposePanePage => Translator.SettingsReadComposePane_Title, WinoPage.LanguageTimePage => Translator.SettingsLanguageTime_Title, WinoPage.AppPreferencesPage => Translator.SettingsAppPreferences_Title, - WinoPage.EmailTemplatesPage => Translator.SettingsEmailTemplates_Title, WinoPage.CalendarSettingsPage => Translator.SettingsCalendarSettings_Title, WinoPage.SignatureAndEncryptionPage => Translator.SettingsSignatureAndEncryption_Title, WinoPage.KeyboardShortcutsPage => Translator.Settings_KeyboardShortcuts_Title, diff --git a/Wino.Mail.WinUI/App.xaml.cs b/Wino.Mail.WinUI/App.xaml.cs index a28c0073..24547a48 100644 --- a/Wino.Mail.WinUI/App.xaml.cs +++ b/Wino.Mail.WinUI/App.xaml.cs @@ -209,12 +209,10 @@ public partial class App : WinoApplication, // Note: Theme service is initialized separately after window creation. await InitializeServicesAsync(); - // Migrate existing base64 contact pictures to file system (one-time, no-op on subsequent starts). - await Services.GetRequiredService().MigrateBase64PicturesAsync(); - _synchronizationManager = Services.GetRequiredService(); _preferencesService = Services.GetRequiredService(); _accountService = Services.GetRequiredService(); + EnsureWindowManagerConfigured(); var hasAnyAccount = (await _accountService.GetAccountsAsync()).Any(); diff --git a/Wino.Mail.WinUI/Views/SettingOptionsPage.xaml b/Wino.Mail.WinUI/Views/SettingOptionsPage.xaml index 0c170833..17bb7d32 100644 --- a/Wino.Mail.WinUI/Views/SettingOptionsPage.xaml +++ b/Wino.Mail.WinUI/Views/SettingOptionsPage.xaml @@ -14,14 +14,11 @@ - - - + - + - - + + @@ -191,17 +194,6 @@ - - - - - - - - - - - - diff --git a/Wino.Services/ContactPictureFileService.cs b/Wino.Services/ContactPictureFileService.cs index 2e6e5703..f0581ebe 100644 --- a/Wino.Services/ContactPictureFileService.cs +++ b/Wino.Services/ContactPictureFileService.cs @@ -2,7 +2,6 @@ using System; using System.IO; using System.Threading.Tasks; using Serilog; -using Wino.Core.Domain.Entities.Shared; using Wino.Core.Domain.Interfaces; namespace Wino.Services; @@ -52,43 +51,5 @@ public class ContactPictureFileService : BaseDatabaseService, IContactPictureFil File.Delete(filePath); return Task.CompletedTask; } - - public async Task MigrateBase64PicturesAsync() - { - try - { - var contacts = await Connection - .QueryAsync( - "SELECT Address, Base64ContactPicture FROM AccountContact WHERE Base64ContactPicture IS NOT NULL AND ContactPictureFileId IS NULL") - .ConfigureAwait(false); - - foreach (var contact in contacts) - { - try - { - var base64 = contact.Base64ContactPicture; - if (string.IsNullOrEmpty(base64)) - continue; - - var bytes = Convert.FromBase64String(base64); - var fileId = await SaveContactPictureAsync(bytes).ConfigureAwait(false); - - await Connection.ExecuteAsync( - "UPDATE AccountContact SET ContactPictureFileId = ?, Base64ContactPicture = NULL WHERE Address = ?", - fileId, - contact.Address).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.Error(ex, "Failed to migrate Base64ContactPicture for contact {Address}.", contact.Address); - } - } - } - catch (Exception ex) - { - _logger.Error(ex, "Failed to migrate contact pictures from base64 to file system."); - } - } - private string BuildFilePath(Guid fileId) => Path.Combine(_contactPicturesFolder, $"{fileId}.jpg"); }