Contact and settings updates.

This commit is contained in:
Burak Kaan Köse
2026-03-06 12:31:37 +01:00
parent 51f64466c2
commit e1be644631
14 changed files with 119 additions and 54 deletions
+10
View File
@@ -0,0 +1,10 @@
namespace Wino.Core.Domain;
public static class AppUrls
{
public const string Website = "https://www.winomail.app";
public const string Discord = "https://discord.gg/windows-apps-hub-714581497222398064";
public const string GitHub = "https://github.com/bkaankose/Wino-Mail/";
public const string PrivacyPolicy = "https://www.winomail.app/support/privacy";
public const string Paypal = "https://paypal.me/bkaankose?country.x=PL&locale.x=en_US";
}
@@ -763,6 +763,8 @@
"SettingsPrefer24HourClock_Title": "Display Clock Format in 24 Hours", "SettingsPrefer24HourClock_Title": "Display Clock Format in 24 Hours",
"SettingsPrivacyPolicy_Description": "Review privacy policy.", "SettingsPrivacyPolicy_Description": "Review privacy policy.",
"SettingsPrivacyPolicy_Title": "Privacy Policy", "SettingsPrivacyPolicy_Title": "Privacy Policy",
"SettingsWebsite_Description": "Open the Wino Mail website.",
"SettingsWebsite_Title": "Website",
"SettingsReadComposePane_Description": "Fonts, external content.", "SettingsReadComposePane_Description": "Fonts, external content.",
"SettingsReadComposePane_Title": "Reader & Composer", "SettingsReadComposePane_Title": "Reader & Composer",
"SettingsReader_Title": "Reader", "SettingsReader_Title": "Reader",
@@ -864,6 +866,7 @@
"SystemFolderConfigSetupSuccess_Message": "System folders are successfully configured.", "SystemFolderConfigSetupSuccess_Message": "System folders are successfully configured.",
"SystemFolderConfigSetupSuccess_Title": "System Folders Setup", "SystemFolderConfigSetupSuccess_Title": "System Folders Setup",
"SystemTrayMenu_ShowWino": "Open Wino Mail", "SystemTrayMenu_ShowWino": "Open Wino Mail",
"SystemTrayMenu_ShowWinoCalendar": "Open Wino Calendar",
"SystemTrayMenu_ExitWino": "Exit", "SystemTrayMenu_ExitWino": "Exit",
"TestingImapConnectionMessage": "Testing server connection...", "TestingImapConnectionMessage": "Testing server connection...",
"TitleBarServerDisconnectedButton_Description": "Wino is disconnected from the network. Click reconnect to restore connection.", "TitleBarServerDisconnectedButton_Description": "Wino is disconnected from the network. Click reconnect to restore connection.",
+5 -4
View File
@@ -21,10 +21,11 @@ public partial class AboutPageViewModel : CoreBaseViewModel
private readonly IWinoLogger _logInitializer; private readonly IWinoLogger _logInitializer;
public string VersionName => _nativeAppService.GetFullAppVersion(); public string VersionName => _nativeAppService.GetFullAppVersion();
public string DiscordChannelUrl => "https://discord.gg/windows-apps-hub-714581497222398064"; public string WebsiteUrl => AppUrls.Website;
public string GitHubUrl => "https://github.com/bkaankose/Wino-Mail/"; public string DiscordChannelUrl => AppUrls.Discord;
public string PrivacyPolicyUrl => "https://www.winomail.app/support/privacy"; public string GitHubUrl => AppUrls.GitHub;
public string PaypalUrl => "https://paypal.me/bkaankose?country.x=PL&locale.x=en_US"; public string PrivacyPolicyUrl => AppUrls.PrivacyPolicy;
public string PaypalUrl => AppUrls.Paypal;
public IPreferencesService PreferencesService { get; } public IPreferencesService PreferencesService { get; }
@@ -16,6 +16,9 @@ public partial class SettingOptionsPageViewModel : CoreBaseViewModel
private readonly INativeAppService _nativeAppService; private readonly INativeAppService _nativeAppService;
private readonly IAccountService _accountService; private readonly IAccountService _accountService;
public string WebsiteUrl => AppUrls.Website;
public string PaypalUrl => AppUrls.Paypal;
[ObservableProperty] [ObservableProperty]
public partial string VersionText { get; set; } = string.Empty; public partial string VersionText { get; set; } = string.Empty;
+13 -8
View File
@@ -12,6 +12,7 @@ using Wino.Core.Domain.Entities.Shared;
using Wino.Core.Domain.Enums; using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Navigation; using Wino.Core.Domain.Models.Navigation;
using Wino.Mail.ViewModels.Data;
namespace Wino.Mail.ViewModels; namespace Wino.Mail.ViewModels;
@@ -56,8 +57,8 @@ public partial class ContactsPageViewModel : MailBaseViewModel
public bool CanLoadMoreContacts => HasMoreContacts && !IsLoading && !IsLoadingMore; public bool CanLoadMoreContacts => HasMoreContacts && !IsLoading && !IsLoadingMore;
public bool CanDeleteSelectedContacts => SelectedContactsCount > 0; public bool CanDeleteSelectedContacts => SelectedContactsCount > 0;
public ObservableCollection<AccountContact> Contacts { get; } = new(); public ObservableCollection<AccountContactViewModel> Contacts { get; } = new();
public ObservableCollection<AccountContact> SelectedContacts { get; } = new(); public ObservableCollection<AccountContactViewModel> SelectedContacts { get; } = new();
public ContactsPageViewModel(IContactService contactService, IMailDialogService dialogService) public ContactsPageViewModel(IContactService contactService, IMailDialogService dialogService)
{ {
@@ -150,7 +151,7 @@ public partial class ContactsPageViewModel : MailBaseViewModel
foreach (var contact in page.Contacts) foreach (var contact in page.Contacts)
{ {
Contacts.Add(contact); Contacts.Add(new AccountContactViewModel(contact));
} }
TotalContactsCount = page.TotalCount; TotalContactsCount = page.TotalCount;
@@ -217,8 +218,9 @@ public partial class ContactsPageViewModel : MailBaseViewModel
} }
[RelayCommand] [RelayCommand]
private async Task EditContactAsync(AccountContact contact) private async Task EditContactAsync(AccountContactViewModel contactViewModel)
{ {
var contact = contactViewModel?.SourceContact;
if (contact == null) return; if (contact == null) return;
var result = await _dialogService.ShowEditContactDialogAsync(contact); var result = await _dialogService.ShowEditContactDialogAsync(contact);
@@ -249,8 +251,9 @@ public partial class ContactsPageViewModel : MailBaseViewModel
} }
[RelayCommand] [RelayCommand]
private async Task DeleteContactAsync(AccountContact contact) private async Task DeleteContactAsync(AccountContactViewModel contactViewModel)
{ {
var contact = contactViewModel?.SourceContact;
if (contact == null || contact.IsRootContact) if (contact == null || contact.IsRootContact)
{ {
_dialogService.InfoBarMessage( _dialogService.InfoBarMessage(
@@ -277,6 +280,7 @@ public partial class ContactsPageViewModel : MailBaseViewModel
if (SelectedContacts.Count == 0) return; if (SelectedContacts.Count == 0) return;
var deletableContacts = SelectedContacts var deletableContacts = SelectedContacts
.Select(c => c?.SourceContact)
.Where(c => c != null && !c.IsRootContact) .Where(c => c != null && !c.IsRootContact)
.GroupBy(c => c.Address, StringComparer.OrdinalIgnoreCase) .GroupBy(c => c.Address, StringComparer.OrdinalIgnoreCase)
.Select(g => g.First()) .Select(g => g.First())
@@ -366,8 +370,9 @@ public partial class ContactsPageViewModel : MailBaseViewModel
} }
[RelayCommand] [RelayCommand]
private async Task PickContactPhotoAsync(AccountContact contact) private async Task PickContactPhotoAsync(AccountContactViewModel contactViewModel)
{ {
var contact = contactViewModel?.SourceContact;
if (contact == null) return; if (contact == null) return;
try try
@@ -410,7 +415,7 @@ public partial class ContactsPageViewModel : MailBaseViewModel
}); });
} }
private static void ReplaceContactByAddress(ObservableCollection<AccountContact> source, AccountContact updatedContact) private static void ReplaceContactByAddress(ObservableCollection<AccountContactViewModel> source, AccountContact updatedContact)
{ {
var index = source var index = source
.Select((item, i) => new { item, i }) .Select((item, i) => new { item, i })
@@ -419,7 +424,7 @@ public partial class ContactsPageViewModel : MailBaseViewModel
if (index < 0) return; if (index < 0) return;
source[index] = CloneContact(updatedContact); source[index] = new AccountContactViewModel(CloneContact(updatedContact));
} }
private static AccountContact CloneContact(AccountContact contact) private static AccountContact CloneContact(AccountContact contact)
@@ -8,17 +8,23 @@ namespace Wino.Mail.ViewModels.Data;
public partial class AccountContactViewModel : ObservableObject, IMailItemDisplayInformation public partial class AccountContactViewModel : ObservableObject, IMailItemDisplayInformation
{ {
public AccountContact SourceContact { get; }
public string Address { get; set; } public string Address { get; set; }
public string Name { get; set; } public string Name { get; set; }
public Guid? ContactPictureFileId { get; set; }
public string Base64ContactPicture { get; set; } public string Base64ContactPicture { get; set; }
public bool IsRootContact { get; set; } public bool IsRootContact { get; set; }
public bool IsOverridden { get; set; }
public AccountContactViewModel(AccountContact contact) public AccountContactViewModel(AccountContact contact)
{ {
SourceContact = contact;
Address = contact.Address; Address = contact.Address;
Name = contact.Name; Name = contact.Name;
ContactPictureFileId = contact.ContactPictureFileId;
Base64ContactPicture = contact.Base64ContactPicture; Base64ContactPicture = contact.Base64ContactPicture;
IsRootContact = contact.IsRootContact; IsRootContact = contact.IsRootContact;
IsOverridden = contact.IsOverridden;
} }
/// <summary> /// <summary>
@@ -68,7 +74,9 @@ public partial class AccountContactViewModel : ObservableObject, IMailItemDispla
{ {
Address = Address, Address = Address,
Name = Name, Name = Name,
ContactPictureFileId = ContactPictureFileId,
Base64ContactPicture = Base64ContactPicture, Base64ContactPicture = Base64ContactPicture,
IsRootContact = IsRootContact IsRootContact = IsRootContact,
IsOverridden = IsOverridden
}; };
} }
@@ -73,7 +73,6 @@ public sealed partial class ImagePreviewControl : PersonPicture
RequestRefresh(); RequestRefresh();
} }
private void OnLoaded(object sender, RoutedEventArgs e) private void OnLoaded(object sender, RoutedEventArgs e)
{ {
RequestRefresh(); RequestRefresh();
@@ -306,7 +305,6 @@ public sealed partial class ImagePreviewControl : PersonPicture
return string.Empty; return string.Empty;
} }
private async Task ApplyInitialVisualStateAsync(string displayName, long refreshVersion, CancellationToken cancellationToken) private async Task ApplyInitialVisualStateAsync(string displayName, long refreshVersion, CancellationToken cancellationToken)
{ {
await ExecuteOnUiThreadAsync(() => await ExecuteOnUiThreadAsync(() =>
+1 -3
View File
@@ -107,9 +107,6 @@
</controls:Segmented> </controls:Segmented>
</StackPanel> </StackPanel>
</TitleBar.RightHeader> </TitleBar.RightHeader>
<TitleBar.IconSource>
<ImageIconSource ImageSource="/Assets/Wino_Icon.ico" />
</TitleBar.IconSource>
</TitleBar> </TitleBar>
<Frame <Frame
@@ -127,6 +124,7 @@
<notifyicon:TaskbarIcon.ContextFlyout> <notifyicon:TaskbarIcon.ContextFlyout>
<MenuFlyout AreOpenCloseAnimationsEnabled="False"> <MenuFlyout AreOpenCloseAnimationsEnabled="False">
<MenuFlyoutItem Command="{x:Bind ShowWinoCommand}" Text="{x:Bind domain:Translator.SystemTrayMenu_ShowWino}" /> <MenuFlyoutItem Command="{x:Bind ShowWinoCommand}" Text="{x:Bind domain:Translator.SystemTrayMenu_ShowWino}" />
<MenuFlyoutItem Command="{x:Bind ShowWinoCalendarCommand}" Text="{x:Bind domain:Translator.SystemTrayMenu_ShowWinoCalendar}" />
<MenuFlyoutSeparator /> <MenuFlyoutSeparator />
<MenuFlyoutItem Command="{x:Bind ExitWinoCommand}" Text="{x:Bind domain:Translator.SystemTrayMenu_ExitWino}" /> <MenuFlyoutItem Command="{x:Bind ExitWinoCommand}" Text="{x:Bind domain:Translator.SystemTrayMenu_ExitWino}" />
</MenuFlyout> </MenuFlyout>
+15 -1
View File
@@ -34,6 +34,7 @@ public sealed partial class ShellWindow : WindowEx, IWinoShellWindow,
public INavigationService NavigationService { get; } = WinoApplication.Current.Services.GetService<INavigationService>() ?? throw new Exception("NavigationService not registered in DI container."); public INavigationService NavigationService { get; } = WinoApplication.Current.Services.GetService<INavigationService>() ?? throw new Exception("NavigationService not registered in DI container.");
public ICommand ShowWinoCommand { get; set; } public ICommand ShowWinoCommand { get; set; }
public ICommand ShowWinoCalendarCommand { get; set; }
public ICommand ExitWinoCommand { get; set; } public ICommand ExitWinoCommand { get; set; }
public ObservableCollection<SynchronizationActionItem> SyncActionItems { get; } = new(); public ObservableCollection<SynchronizationActionItem> SyncActionItems { get; } = new();
@@ -60,7 +61,8 @@ public sealed partial class ShellWindow : WindowEx, IWinoShellWindow,
// Register global mouse button listener for back button // Register global mouse button listener for back button
RegisterMouseBackButtonListener(); RegisterMouseBackButtonListener();
ShowWinoCommand = new RelayCommand(RestoreFromTray); ShowWinoCommand = new RelayCommand(() => RestoreAndSwitchMode(WinoApplicationMode.Mail));
ShowWinoCalendarCommand = new RelayCommand(() => RestoreAndSwitchMode(WinoApplicationMode.Calendar));
ExitWinoCommand = new RelayCommand(ForceClose); ExitWinoCommand = new RelayCommand(ForceClose);
this.SetIcon("Assets/Wino_Icon.ico"); this.SetIcon("Assets/Wino_Icon.ico");
@@ -281,6 +283,18 @@ public sealed partial class ShellWindow : WindowEx, IWinoShellWindow,
BringToFront(); BringToFront();
} }
private void RestoreAndSwitchMode(WinoApplicationMode mode)
{
_currentMode = mode;
_isApplyingActivationMode = true;
AppModeSegmentedControl.SelectedIndex = mode == WinoApplicationMode.Mail ? 0 : 1;
_isApplyingActivationMode = false;
NavigationService.ChangeApplicationMode(mode);
RestoreFromTray();
}
public void ForceClose() public void ForceClose()
{ {
// Unsubscribe from the closing event to avoid infinite loop // Unsubscribe from the closing event to avoid infinite loop
@@ -49,8 +49,6 @@ public sealed partial class AccountDetailsPage : AccountDetailsPageAbstract
{ {
base.OnNavigatedTo(e); base.OnNavigatedTo(e);
if (e.NavigationMode == NavigationMode.New)
{
var targetTabIndex = ViewModel.SelectedTabIndex; var targetTabIndex = ViewModel.SelectedTabIndex;
if (targetTabIndex < 0 || targetTabIndex >= TabSelector.Items.Count) if (targetTabIndex < 0 || targetTabIndex >= TabSelector.Items.Count)
{ {
@@ -60,4 +58,3 @@ public sealed partial class AccountDetailsPage : AccountDetailsPageAbstract
TabSelector.SelectedItem = TabSelector.Items[targetTabIndex]; TabSelector.SelectedItem = TabSelector.Items[targetTabIndex];
} }
} }
}
+16 -12
View File
@@ -33,19 +33,12 @@
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<!-- App Icon --> <Image
<Border Width="96"
Width="72" Height="96"
Height="72"
Background="{ThemeResource AccentFillColorDefaultBrush}"
CornerRadius="16">
<FontIcon
HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center"
FontSize="32" Source="ms-appx:///Assets/AppEntries/MailAssets/Square150x150Logo.scale-100.png"
Foreground="{ThemeResource TextOnAccentFillColorPrimaryBrush}" Stretch="Uniform" />
Glyph="&#xE715;" />
</Border>
<!-- App Info --> <!-- App Info -->
<StackPanel <StackPanel
@@ -65,6 +58,17 @@
Foreground="{ThemeResource TextFillColorTertiaryBrush}" Foreground="{ThemeResource TextFillColorTertiaryBrush}"
Style="{StaticResource CaptionTextBlockStyle}" Style="{StaticResource CaptionTextBlockStyle}"
Text="{x:Bind ViewModel.VersionText, Mode=OneWay}" /> Text="{x:Bind ViewModel.VersionText, Mode=OneWay}" />
<StackPanel
Margin="0,8,0,0"
Orientation="Horizontal"
Spacing="8">
<HyperlinkButton
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>
</Grid> </Grid>
+27 -4
View File
@@ -17,9 +17,12 @@
</TransitionCollection> </TransitionCollection>
</StackPanel.ChildrenTransitions> </StackPanel.ChildrenTransitions>
<Image <Image
Width="50" Width="128"
Height="50" Height="128"
Source="ms-appx:///Images/StoreLogo.png" /> Margin="0,0,0,12"
HorizontalAlignment="Center"
Source="ms-appx:///Assets/AppEntries/MailAssets/Square150x150Logo.scale-100.png"
Stretch="Uniform" />
<TextBlock <TextBlock
Margin="0,6,0,4" Margin="0,6,0,4"
HorizontalAlignment="Center" HorizontalAlignment="Center"
@@ -32,6 +35,26 @@
Style="{StaticResource BodyTextBlockStyle}" Style="{StaticResource BodyTextBlockStyle}"
Text="{x:Bind domain:Translator.SettingsAboutWinoDescription}" /> Text="{x:Bind domain:Translator.SettingsAboutWinoDescription}" />
<controls:SettingsCard
Command="{x:Bind ViewModel.NavigateCommand}"
CommandParameter="{x:Bind ViewModel.WebsiteUrl}"
Description="{x:Bind domain:Translator.SettingsWebsite_Description}"
Header="{x:Bind domain:Translator.SettingsWebsite_Title}"
IsClickEnabled="True">
<controls:SettingsCard.HeaderIcon>
<FontIcon
HorizontalAlignment="Center"
VerticalAlignment="Center"
Glyph="&#xE774;" />
</controls:SettingsCard.HeaderIcon>
<controls:SettingsCard.ActionIcon>
<PathIcon
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="{StaticResource OpenInNewWindowPathIcon}" />
</controls:SettingsCard.ActionIcon>
</controls:SettingsCard>
<controls:SettingsCard <controls:SettingsCard
Command="{x:Bind ViewModel.NavigateCommand}" Command="{x:Bind ViewModel.NavigateCommand}"
CommandParameter="{x:Bind ViewModel.GitHubUrl}" CommandParameter="{x:Bind ViewModel.GitHubUrl}"
@@ -174,7 +197,7 @@
<controls:SettingsCard Header="Wino Mail"> <controls:SettingsCard Header="Wino Mail">
<controls:SettingsCard.HeaderIcon> <controls:SettingsCard.HeaderIcon>
<BitmapIcon ShowAsMonochrome="False" UriSource="ms-appx:///Images/StoreLogo.png" /> <BitmapIcon ShowAsMonochrome="False" UriSource="ms-appx:///Assets/AppEntries/MailAssets/Square150x150Logo.scale-100.png" />
</controls:SettingsCard.HeaderIcon> </controls:SettingsCard.HeaderIcon>
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" IsTextSelectionEnabled="True"> <TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" IsTextSelectionEnabled="True">
<Run Text="{x:Bind domain:Translator.SettingsAboutVersion}" /><Run Text="{x:Bind ViewModel.VersionName}" /> <Run Text="{x:Bind domain:Translator.SettingsAboutVersion}" /><Run Text="{x:Bind ViewModel.VersionName}" />
@@ -3,18 +3,20 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:abstract="using:Wino.Views.Abstract" xmlns:abstract="using:Wino.Views.Abstract"
xmlns:controls="using:Wino.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:domain="using:Wino.Core.Domain" xmlns:domain="using:Wino.Core.Domain"
xmlns:entities="using:Wino.Core.Domain.Entities.Shared" xmlns:entities="using:Wino.Core.Domain.Entities.Shared"
xmlns:helpers="using:Wino.Helpers" xmlns:helpers="using:Wino.Helpers"
xmlns:listview="using:Wino.Mail.WinUI.Controls.ListView" xmlns:listview="using:Wino.Mail.WinUI.Controls.ListView"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="using:Wino.Mail.ViewModels.Data"
xmlns:toolkitExt="using:CommunityToolkit.WinUI" xmlns:toolkitExt="using:CommunityToolkit.WinUI"
x:Name="root" x:Name="root"
mc:Ignorable="d"> mc:Ignorable="d">
<Page.Resources> <Page.Resources>
<DataTemplate x:Key="ContactTemplate" x:DataType="entities:AccountContact"> <DataTemplate x:Key="ContactTemplate" x:DataType="viewModels:AccountContactViewModel">
<Grid Margin="0,0,0,8" Padding="0,4"> <Grid Margin="0,0,0,8" Padding="0,4">
<Border <Border
Background="{ThemeResource CardBackgroundFillColorSecondaryBrush}" Background="{ThemeResource CardBackgroundFillColorSecondaryBrush}"
@@ -29,12 +31,11 @@
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<PersonPicture <controls:ImagePreviewControl
Grid.Column="0" Grid.Column="0"
Width="40" Width="40"
Height="40" Height="40"
DisplayName="{x:Bind Name, Mode=OneTime, TargetNullValue=''}" MailItemInformation="{x:Bind Mode=OneWay}" />
ProfilePicture="{x:Bind helpers:XamlHelpers.Base64ToBitmapImage(Base64ContactPicture), Mode=OneWay}" />
<StackPanel <StackPanel
Grid.Column="1" Grid.Column="1"
@@ -2,8 +2,8 @@ using System;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls;
using Wino.Core.Domain.Entities.Shared;
using Wino.Mail.ViewModels; using Wino.Mail.ViewModels;
using Wino.Mail.ViewModels.Data;
using Wino.Views.Abstract; using Wino.Views.Abstract;
namespace Wino.Views.Settings; namespace Wino.Views.Settings;
@@ -20,7 +20,7 @@ public sealed partial class ContactsPage : ContactsPageAbstract
private void EditContact_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) private void EditContact_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{ {
if (sender is Button button && button.CommandParameter is AccountContact contact) if (sender is Button button && button.CommandParameter is AccountContactViewModel contact)
{ {
ViewModel.EditContactCommand.Execute(contact); ViewModel.EditContactCommand.Execute(contact);
} }
@@ -28,7 +28,7 @@ public sealed partial class ContactsPage : ContactsPageAbstract
private void PickContactPhoto_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) private void PickContactPhoto_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{ {
if (sender is Button button && button.CommandParameter is AccountContact contact) if (sender is Button button && button.CommandParameter is AccountContactViewModel contact)
{ {
ViewModel.PickContactPhotoCommand.Execute(contact); ViewModel.PickContactPhotoCommand.Execute(contact);
} }
@@ -36,7 +36,7 @@ public sealed partial class ContactsPage : ContactsPageAbstract
private void DeleteContact_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) private void DeleteContact_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{ {
if (sender is Button button && button.CommandParameter is AccountContact contact) if (sender is Button button && button.CommandParameter is AccountContactViewModel contact)
{ {
ViewModel.DeleteContactCommand.Execute(contact); ViewModel.DeleteContactCommand.Execute(contact);
} }
@@ -53,7 +53,7 @@ public sealed partial class ContactsPage : ContactsPageAbstract
return; return;
} }
foreach (var removedItem in e.RemovedItems.OfType<AccountContact>()) foreach (var removedItem in e.RemovedItems.OfType<AccountContactViewModel>())
{ {
var selectedContact = ViewModel.SelectedContacts.FirstOrDefault(c => var selectedContact = ViewModel.SelectedContacts.FirstOrDefault(c =>
string.Equals(c.Address, removedItem.Address, StringComparison.OrdinalIgnoreCase)); string.Equals(c.Address, removedItem.Address, StringComparison.OrdinalIgnoreCase));
@@ -64,7 +64,7 @@ public sealed partial class ContactsPage : ContactsPageAbstract
} }
} }
foreach (var addedItem in e.AddedItems.OfType<AccountContact>()) foreach (var addedItem in e.AddedItems.OfType<AccountContactViewModel>())
{ {
var alreadySelected = ViewModel.SelectedContacts.Any(c => var alreadySelected = ViewModel.SelectedContacts.Any(c =>
string.Equals(c.Address, addedItem.Address, StringComparison.OrdinalIgnoreCase)); string.Equals(c.Address, addedItem.Address, StringComparison.OrdinalIgnoreCase));