Fix udate update notes.

This commit is contained in:
Burak Kaan Köse
2026-03-08 18:40:43 +01:00
parent d9da326f0a
commit 8548257878
8 changed files with 26 additions and 116 deletions
@@ -271,12 +271,22 @@ public partial class CalendarPageViewModel : CalendarBaseViewModel,
{ {
RefreshSettings(); RefreshSettings();
if (mode == NavigationMode.Back) return; if (mode == NavigationMode.Back)
{
_ = RefreshVisibleRangesAsync();
return;
}
// Automatically select the first primary calendar for quick event dialog. // Automatically select the first primary calendar for quick event dialog.
SelectedQuickEventAccountCalendar = AccountCalendarStateService.ActiveCalendars.FirstOrDefault(a => a.IsPrimary); 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] [RelayCommand]
private void NavigateSeries() private void NavigateSeries()
{ {
@@ -23,11 +23,4 @@ public interface IContactPictureFileService
/// Deletes the picture file for the given file ID if it exists. /// Deletes the picture file for the given file ID if it exists.
/// </summary> /// </summary>
Task DeleteContactPictureAsync(Guid fileId); Task DeleteContactPictureAsync(Guid fileId);
/// <summary>
/// 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.
/// </summary>
Task MigrateBase64PicturesAsync();
} }
@@ -1,7 +1,9 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace Wino.Core.Domain.Models.Updates; namespace Wino.Core.Domain.Models.Updates;
public class UpdateNotes public class UpdateNotes
{ {
[JsonPropertyName("sections")]
public List<UpdateNoteSection> Sections { get; set; } = []; public List<UpdateNoteSection> Sections { get; set; } = [];
} }
@@ -126,7 +126,6 @@
"CalendarAttendeeStatus_Tentative": "Tentative", "CalendarAttendeeStatus_Tentative": "Tentative",
"CalendarEventDetails_Attachments": "Attachments", "CalendarEventDetails_Attachments": "Attachments",
"CalendarEventCompose_AddAttachment": "Add attachment", "CalendarEventCompose_AddAttachment": "Add attachment",
"CalendarEventCompose_AttachmentsNotSupportedForCalDav": "Attachments are not supported for CalDAV calendars.",
"CalendarEventCompose_AllDay": "All Day", "CalendarEventCompose_AllDay": "All Day",
"CalendarEventCompose_EndDate": "End date", "CalendarEventCompose_EndDate": "End date",
"CalendarEventCompose_EndTime": "End time", "CalendarEventCompose_EndTime": "End time",
@@ -254,8 +253,6 @@
"DialogMessage_DeleteAccountConfirmationTitle": "All data associated with this account will be deleted from disk permanently.", "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_DeleteRecurringSeriesMessage": "This will delete all events in the series. Do you want to continue?",
"DialogMessage_DeleteRecurringSeriesTitle": "Delete Recurring Series", "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_DiscardDraftConfirmationMessage": "This draft will be discarded. Do you want to continue?",
"DialogMessage_DiscardDraftConfirmationTitle": "Discard Draft", "DialogMessage_DiscardDraftConfirmationTitle": "Discard Draft",
"DialogMessage_EmptySubjectConfirmation": "Missing Subject", "DialogMessage_EmptySubjectConfirmation": "Missing Subject",
@@ -364,29 +361,19 @@
"KeyboardShortcuts_FailedToReset": "Failed to reset keyboard shortcuts.", "KeyboardShortcuts_FailedToReset": "Failed to reset keyboard shortcuts.",
"KeyboardShortcuts_FailedToUpdate": "Failed to update keyboard shortcuts", "KeyboardShortcuts_FailedToUpdate": "Failed to update keyboard shortcuts",
"KeyboardShortcuts_MailoperationAction": "Action", "KeyboardShortcuts_MailoperationAction": "Action",
"KeyboardShortcuts_Action": "Action",
"KeyboardShortcuts_FailedToLoad": "Failed to load keyboard shortcuts.", "KeyboardShortcuts_FailedToLoad": "Failed to load keyboard shortcuts.",
"KeyboardShortcuts_EnterKeyForShortcut": "Please enter a key for the shortcut.", "KeyboardShortcuts_EnterKeyForShortcut": "Please enter a key for the shortcut.",
"KeyboardShortcuts_SelectOperationForShortcut": "Please an action to perform 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_ShortcutInUse": "This shortcut is already in use by another s hortcut.",
"KeyboardShortcuts_FailedToSave": "Failed to save the shortcut.", "KeyboardShortcuts_FailedToSave": "Failed to save the shortcut.",
"KeyboardShortcuts_FailedToDelete": "Failed to delete 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_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_Add": "Add shortcut",
"KeyboardShortcuts_EditTitle": "Edit Keyboard Shortcut",
"KeyboardShortcuts_ResetToDefaults": "Reset to Defaults", "KeyboardShortcuts_ResetToDefaults": "Reset to Defaults",
"KeyboardShortcuts_PressKeysHere": "Press keys here...", "KeyboardShortcuts_PressKeysHere": "Press keys here...",
"KeyboardShortcuts_KeyCombination": "Key Combination", "KeyboardShortcuts_KeyCombination": "Key Combination",
"KeyboardShortcuts_FocusArea": "Focus the field above and press the desired key combination", "KeyboardShortcuts_FocusArea": "Focus the field above and press the desired key combination",
"KeyboardShortcuts_Modifiers": "Modifier Keys", "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.", "ImageRenderingDisabled": "Image rendering is disabled for this message.",
"ImapAdvancedSetupDialog_AuthenticationMethod": "Authentication method", "ImapAdvancedSetupDialog_AuthenticationMethod": "Authentication method",
"ImapAdvancedSetupDialog_ConnectionSecurity": "Connection security", "ImapAdvancedSetupDialog_ConnectionSecurity": "Connection security",
@@ -611,7 +598,6 @@
"MenuNewMail": "New Mail", "MenuNewMail": "New Mail",
"MenuRate": "Rate Wino", "MenuRate": "Rate Wino",
"MenuSettings": "Settings", "MenuSettings": "Settings",
"MenuUpdateAvailable": "Update Available",
"MergedAccountCommonFolderArchive": "Archive", "MergedAccountCommonFolderArchive": "Archive",
"MergedAccountCommonFolderDraft": "Draft", "MergedAccountCommonFolderDraft": "Draft",
"MergedAccountCommonFolderInbox": "Inbox", "MergedAccountCommonFolderInbox": "Inbox",
@@ -635,8 +621,6 @@
"Notifications_MultipleNotificationsTitle": "New Mail", "Notifications_MultipleNotificationsTitle": "New Mail",
"Notifications_WinoUpdatedMessage": "Checkout new version {0}", "Notifications_WinoUpdatedMessage": "Checkout new version {0}",
"Notifications_WinoUpdatedTitle": "Wino Mail has been updated.", "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.", "OnlineSearchFailed_Message": "Failed to perform search\n{0}\n\nListing offline mails.",
"OnlineSearchTry_Line1": "Can't find what you are looking for?", "OnlineSearchTry_Line1": "Can't find what you are looking for?",
"OnlineSearchTry_Line2": "Try online search.", "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_FatalError": "Fatal error occurred while changing the startup mode for Wino Mail.",
"SettingsAppPreferences_StartupBehavior_Title": "Start minimized on Windows startup", "SettingsAppPreferences_StartupBehavior_Title": "Start minimized on Windows startup",
"SettingsAppPreferences_Title": "App Preferences", "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_Description": "Select the next item after you delete or move a mail.",
"SettingsAutoSelectNextItem_Title": "Auto select next item", "SettingsAutoSelectNextItem_Title": "Auto select next item",
"SettingsAvailableThemes_Description": "Select a theme from Wino's own collection for your taste or apply your own themes.", "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", "SettingsShowSenderPictures_Title": "Show Sender Avatars",
"SettingsEnableGravatarAvatars_Title": "Gravatar", "SettingsEnableGravatarAvatars_Title": "Gravatar",
"SettingsEnableGravatarAvatars_Description": "Use gravatar (if available) as sender picture", "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_Title": "Domain icons (Favicons)",
"SettingsEnableFavicons_Description": "Use domain favicons (if available) as sender picture", "SettingsEnableFavicons_Description": "Use domain favicons (if available) as sender picture",
"SettingsMailList_ClearAvatarsCache_Button": "Clear cached avatars", "SettingsMailList_ClearAvatarsCache_Button": "Clear cached avatars",
@@ -1021,7 +990,6 @@
"Composer_CertificateExpires": "Expires on: ", "Composer_CertificateExpires": "Expires on: ",
"Composer_SmimeSignature": "S/MIME Signature", "Composer_SmimeSignature": "S/MIME Signature",
"Composer_SmimeEncryption": "S/MIME Encryption", "Composer_SmimeEncryption": "S/MIME Encryption",
"Composer_EmailTemplatesPlaceholder": "E-mail templates",
"SettingsAppPreferences_EmailSyncInterval_Title": "Email sync interval", "SettingsAppPreferences_EmailSyncInterval_Title": "Email sync interval",
"SettingsAppPreferences_EmailSyncInterval_Description": "Automatic email synchronization interval (minutes). This setting will be applied only after restarting Wino Mail.", "SettingsAppPreferences_EmailSyncInterval_Description": "Automatic email synchronization interval (minutes). This setting will be applied only after restarting Wino Mail.",
"ContactsPage_Title": "Contacts", "ContactsPage_Title": "Contacts",
@@ -1148,5 +1116,3 @@
"AccountSetup_TryAgainButton": "Try Again", "AccountSetup_TryAgainButton": "Try Again",
"ImapCalDavSettings_AutoDiscoveryFailed": "Auto-discovery failed. Please enter settings manually in the Advanced tab." "ImapCalDavSettings_AutoDiscoveryFailed": "Auto-discovery failed. Please enter settings manually in the Advanced tab."
} }
@@ -76,7 +76,6 @@ public partial class SettingOptionsPageViewModel : CoreBaseViewModel
WinoPage.ReadComposePanePage => Translator.SettingsReadComposePane_Title, WinoPage.ReadComposePanePage => Translator.SettingsReadComposePane_Title,
WinoPage.LanguageTimePage => Translator.SettingsLanguageTime_Title, WinoPage.LanguageTimePage => Translator.SettingsLanguageTime_Title,
WinoPage.AppPreferencesPage => Translator.SettingsAppPreferences_Title, WinoPage.AppPreferencesPage => Translator.SettingsAppPreferences_Title,
WinoPage.EmailTemplatesPage => Translator.SettingsEmailTemplates_Title,
WinoPage.CalendarSettingsPage => Translator.SettingsCalendarSettings_Title, WinoPage.CalendarSettingsPage => Translator.SettingsCalendarSettings_Title,
WinoPage.SignatureAndEncryptionPage => Translator.SettingsSignatureAndEncryption_Title, WinoPage.SignatureAndEncryptionPage => Translator.SettingsSignatureAndEncryption_Title,
WinoPage.KeyboardShortcutsPage => Translator.Settings_KeyboardShortcuts_Title, WinoPage.KeyboardShortcutsPage => Translator.Settings_KeyboardShortcuts_Title,
+1 -3
View File
@@ -209,12 +209,10 @@ public partial class App : WinoApplication,
// Note: Theme service is initialized separately after window creation. // Note: Theme service is initialized separately after window creation.
await InitializeServicesAsync(); await InitializeServicesAsync();
// Migrate existing base64 contact pictures to file system (one-time, no-op on subsequent starts).
await Services.GetRequiredService<IContactPictureFileService>().MigrateBase64PicturesAsync();
_synchronizationManager = Services.GetRequiredService<ISynchronizationManager>(); _synchronizationManager = Services.GetRequiredService<ISynchronizationManager>();
_preferencesService = Services.GetRequiredService<IPreferencesService>(); _preferencesService = Services.GetRequiredService<IPreferencesService>();
_accountService = Services.GetRequiredService<IAccountService>(); _accountService = Services.GetRequiredService<IAccountService>();
EnsureWindowManagerConfigured(); EnsureWindowManagerConfigured();
var hasAnyAccount = (await _accountService.GetAccountsAsync()).Any(); var hasAnyAccount = (await _accountService.GetAccountsAsync()).Any();
+12 -31
View File
@@ -14,14 +14,11 @@
<ScrollViewer Padding="0,0,16,0" VerticalScrollBarVisibility="Auto"> <ScrollViewer Padding="0,0,16,0" VerticalScrollBarVisibility="Auto">
<StackPanel Margin="0,8,0,24" Spacing="4"> <StackPanel Margin="0,8,0,24" Spacing="4">
<!--<StackPanel.ChildrenTransitions> <StackPanel.ChildrenTransitions>
<TransitionCollection> <TransitionCollection>
<PopupThemeTransition /> <EntranceThemeTransition FromVerticalOffset="50" IsStaggeringEnabled="True" />
-->
<!--<EntranceThemeTransition FromVerticalOffset="50" IsStaggeringEnabled="True" />-->
<!--
</TransitionCollection> </TransitionCollection>
</StackPanel.ChildrenTransitions>--> </StackPanel.ChildrenTransitions>
<!-- Hero Banner - Windows 11 style --> <!-- Hero Banner - Windows 11 style -->
<Grid <Grid
@@ -49,7 +46,9 @@
Margin="20,0,0,0" Margin="20,0,0,0"
VerticalAlignment="Center" VerticalAlignment="Center"
Spacing="4"> Spacing="4">
<TextBlock Style="{StaticResource TitleTextBlockStyle}" Text="Wino Mail" /> <TextBlock
Style="{StaticResource TitleTextBlockStyle}"
Text="Wino Mail" />
<TextBlock <TextBlock
Foreground="{ThemeResource TextFillColorSecondaryBrush}" Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Style="{StaticResource BodyTextBlockStyle}" Style="{StaticResource BodyTextBlockStyle}"
@@ -63,8 +62,12 @@
Margin="0,8,0,0" Margin="0,8,0,0"
Orientation="Horizontal" Orientation="Horizontal"
Spacing="8"> Spacing="8">
<HyperlinkButton Content="{x:Bind ViewModel.WebsiteUrl, Mode=OneWay}" NavigateUri="{x:Bind ViewModel.WebsiteUrl, Mode=OneWay}" /> <HyperlinkButton
<HyperlinkButton Content="{x:Bind domain:Translator.SettingsPaypal_Title}" NavigateUri="{x:Bind ViewModel.PaypalUrl, Mode=OneWay}" /> Content="{x:Bind ViewModel.WebsiteUrl, Mode=OneWay}"
NavigateUri="{x:Bind ViewModel.WebsiteUrl, Mode=OneWay}" />
<HyperlinkButton
Content="{x:Bind domain:Translator.SettingsPaypal_Title}"
NavigateUri="{x:Bind ViewModel.PaypalUrl, Mode=OneWay}" />
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>
</Grid> </Grid>
@@ -191,17 +194,6 @@
</controls:SettingsCard.HeaderIcon> </controls:SettingsCard.HeaderIcon>
</controls:SettingsCard> </controls:SettingsCard>
<controls:SettingsCard
Click="SettingOptionClicked"
Description="{x:Bind domain:Translator.SettingsEmailTemplates_Description}"
Header="{x:Bind domain:Translator.SettingsEmailTemplates_Title}"
IsClickEnabled="True"
Tag="{x:Bind enums:WinoPage.EmailTemplatesPage}">
<controls:SettingsCard.HeaderIcon>
<FontIcon Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" Glyph="&#xE70F;" />
</controls:SettingsCard.HeaderIcon>
</controls:SettingsCard>
<controls:SettingsCard <controls:SettingsCard
Click="SettingOptionClicked" Click="SettingOptionClicked"
Description="{x:Bind domain:Translator.SettingsStorage_Description}" Description="{x:Bind domain:Translator.SettingsStorage_Description}"
@@ -229,17 +221,6 @@
<FontIcon Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" Glyph="&#xE787;" /> <FontIcon Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" Glyph="&#xE787;" />
</controls:SettingsCard.HeaderIcon> </controls:SettingsCard.HeaderIcon>
</controls:SettingsCard> </controls:SettingsCard>
<controls:SettingsCard
Click="SettingOptionClicked"
Description="{x:Bind domain:Translator.Settings_KeyboardShortcuts_Description}"
Header="{x:Bind domain:Translator.Settings_KeyboardShortcuts_Title}"
IsClickEnabled="True"
Tag="{x:Bind enums:WinoPage.KeyboardShortcutsPage}">
<controls:SettingsCard.HeaderIcon>
<FontIcon Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" Glyph="&#xE765;" />
</controls:SettingsCard.HeaderIcon>
</controls:SettingsCard>
</StackPanel> </StackPanel>
</ScrollViewer> </ScrollViewer>
</abstract:SettingOptionsPageAbstract> </abstract:SettingOptionsPageAbstract>
@@ -2,7 +2,6 @@ using System;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using Serilog; using Serilog;
using Wino.Core.Domain.Entities.Shared;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
namespace Wino.Services; namespace Wino.Services;
@@ -52,43 +51,5 @@ public class ContactPictureFileService : BaseDatabaseService, IContactPictureFil
File.Delete(filePath); File.Delete(filePath);
return Task.CompletedTask; return Task.CompletedTask;
} }
public async Task MigrateBase64PicturesAsync()
{
try
{
var contacts = await Connection
.QueryAsync<LegacyAccountContactPictureRow>(
"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"); private string BuildFilePath(Guid fileId) => Path.Combine(_contactPicturesFolder, $"{fileId}.jpg");
} }