From 3ddc1a62291bab1920bf197e5133dd1949fe2363 Mon Sep 17 00:00:00 2001 From: Aleh Khantsevich Date: Sun, 16 Feb 2025 11:54:23 +0100 Subject: [PATCH] file scoped namespaces (#565) --- .editorconfig | 6 +- Wino.Authentication/BaseAuthenticator.cs | 17 +- Wino.Authentication/GmailAuthenticator.cs | 65 +- Wino.Authentication/OutlookAuthenticator.cs | 173 +- .../Services/CalendarAuthenticatorConfig.cs | 49 +- .../Collections/CalendarEventCollection.cs | 269 +- .../Collections/DayRangeCollection.cs | 45 +- .../Collections/ObservableRangeCollection.cs | 297 ++- Wino.Core.Domain/Constants.cs | 33 +- .../Entities/Calendar/AccountCalendar.cs | 37 +- .../Calendar/CalendarEventAttendee.cs | 27 +- .../Entities/Calendar/CalendarItem.cs | 333 ++- .../Entities/Calendar/Reminder.cs | 19 +- .../Entities/Mail/AccountSignature.cs | 17 +- .../Entities/Mail/MailAccountAlias.cs | 105 +- Wino.Core.Domain/Entities/Mail/MailCopy.cs | 243 +- .../Entities/Mail/MailItemFolder.cs | 115 +- Wino.Core.Domain/Entities/Mail/MergedInbox.cs | 15 +- .../Entities/Shared/AccountContact.cs | 123 +- .../Shared/CustomServerInformation.cs | 73 +- .../Entities/Shared/MailAccount.cs | 169 +- .../Entities/Shared/MailAccountPreferences.cs | 81 +- .../Enums/AccountAttentionReason.cs | 13 +- .../Enums/AccountCreationDialogState.cs | 29 +- .../Enums/AccountSynchronizerState.cs | 19 +- Wino.Core.Domain/Enums/AppLanguage.cs | 37 +- Wino.Core.Domain/Enums/AppThemeType.cs | 13 +- .../Enums/ApplicationElementTheme.cs | 13 +- Wino.Core.Domain/Enums/AttendeeStatus.cs | 15 +- .../Enums/BackgroundSynchronizationReason.cs | 11 +- Wino.Core.Domain/Enums/CalendarDisplayType.cs | 17 +- .../Enums/CalendarEventTargetType.cs | 11 +- .../Enums/CalendarInitInitiative.cs | 17 +- .../Enums/CalendarItemRecurrenceFrequency.cs | 15 +- .../Enums/CalendarItemReminderType.cs | 11 +- Wino.Core.Domain/Enums/CalendarItemStatus.cs | 15 +- .../Enums/CalendarItemVisibility.cs | 15 +- .../Enums/CalendarLoadDirection.cs | 19 +- Wino.Core.Domain/Enums/CalendarOrientation.cs | 11 +- .../Enums/CalendarSynchronizationType.cs | 17 +- Wino.Core.Domain/Enums/ChangeRequestType.cs | 43 +- .../Enums/CustomIncomingServerType.cs | 11 +- .../Enums/DayHeaderDisplayType.cs | 11 +- Wino.Core.Domain/Enums/DraftCreationReason.cs | 15 +- Wino.Core.Domain/Enums/FilterOptionType.cs | 17 +- Wino.Core.Domain/Enums/FolderOperation.cs | 41 +- .../Enums/ImapAuthenticationMethod.cs | 21 +- .../Enums/ImapConnectionSecurity.cs | 15 +- .../Enums/InfoBarAnimationType.cs | 11 +- Wino.Core.Domain/Enums/InfoBarMessageType.cs | 15 +- Wino.Core.Domain/Enums/MailAttachmentType.cs | 27 +- Wino.Core.Domain/Enums/MailImportance.cs | 13 +- Wino.Core.Domain/Enums/MailListDisplayMode.cs | 13 +- Wino.Core.Domain/Enums/MailMarkAsOption.cs | 13 +- Wino.Core.Domain/Enums/MailOperation.cs | 111 +- Wino.Core.Domain/Enums/MailProviderType.cs | 13 +- .../Enums/MailSynchronizationType.cs | 23 +- .../Enums/NavigationReferenceFrame.cs | 11 +- Wino.Core.Domain/Enums/PickFolderReason.cs | 19 +- Wino.Core.Domain/Enums/PrintingResult.cs | 15 +- .../Enums/ServerBackgroundMode.cs | 19 +- Wino.Core.Domain/Enums/SortingOptionType.cs | 11 +- Wino.Core.Domain/Enums/SpecialFolderType.cs | 43 +- Wino.Core.Domain/Enums/SpecialImapProvider.cs | 13 +- .../Enums/StartupBehaviorResult.cs | 17 +- Wino.Core.Domain/Enums/StorePurchaseResult.cs | 33 +- .../Enums/SynchronizationCompletedState.cs | 13 +- .../Enums/SynchronizationSource.cs | 19 +- Wino.Core.Domain/Enums/WinoAppType.cs | 13 +- .../Enums/WinoCustomMessageDialogIcon.cs | 15 +- Wino.Core.Domain/Enums/WinoPage.cs | 63 +- .../Enums/WinoServerConnectionStatus.cs | 17 +- .../AccountSetupCanceledException.cs | 9 +- .../AuthenticationAttentionException.cs | 25 +- .../Exceptions/AuthenticationException.cs | 25 +- ...ckgroundTaskRegistrationFailedException.cs | 13 +- .../ComposerMimeNotFoundException.cs | 13 +- .../CustomThemeCreationFailedException.cs | 9 +- .../GoogleAuthenticationException.cs | 9 +- .../Exceptions/ImapClientPoolException.cs | 17 +- .../Exceptions/ImapConnectionFailedPackage.cs | 25 +- .../ImapSynchronizerStrategyException.cs | 13 +- .../ImapTestSSLCertificateException.cs | 25 +- .../Exceptions/InvalidMoveTargetException.cs | 7 +- .../Exceptions/MissingAliasException.cs | 9 +- .../SynchronizerEntityNotFoundException.cs | 9 +- .../Exceptions/SynchronizerException.cs | 19 +- ...stemFolderConfigurationMissingException.cs | 13 +- .../UnavailableSpecialFolderException.cs | 27 +- .../Exceptions/WinoServerException.cs | 15 +- .../Extensions/DateTimeExtensions.cs | 41 +- .../Extensions/ExceptionExtensions.cs | 33 +- Wino.Core.Domain/Extensions/MimeExtensions.cs | 21 +- .../Interfaces/IAccountCalendar.cs | 23 +- .../Interfaces/IAccountCreationDialog.cs | 13 +- .../Interfaces/IAccountMenuItem.cs | 31 +- .../Interfaces/IAccountPickerDialog.cs | 7 +- .../IAccountProviderDetailViewModel.cs | 55 +- .../Interfaces/IAccountProviderDetails.cs | 13 +- .../Interfaces/IAccountService.cs | 257 +- .../Interfaces/IApplicationConfiguration.cs | 49 +- .../Interfaces/IApplicationResourceManager.cs | 19 +- .../Interfaces/IAuthenticationProvider.cs | 9 +- Wino.Core.Domain/Interfaces/IAuthenticator.cs | 53 +- .../Interfaces/IAuthenticatorConfig.cs | 17 +- .../Interfaces/IAuthenticatorTypes.cs | 15 +- .../Interfaces/IAutoDiscoveryService.cs | 21 +- .../Interfaces/IBackgroundTaskService.cs | 27 +- .../Interfaces/IBaseSynchronizer.cs | 45 +- .../Interfaces/ICalendarDialogService.cs | 7 +- Wino.Core.Domain/Interfaces/ICalendarItem.cs | 31 +- .../Interfaces/ICalendarItemViewModel.cs | 15 +- .../Interfaces/ICalendarService.cs | 43 +- Wino.Core.Domain/Interfaces/IClientMessage.cs | 15 +- .../Interfaces/IClipboardService.cs | 9 +- .../Interfaces/IConfigurationService.cs | 17 +- .../Interfaces/IContactService.cs | 15 +- .../Interfaces/IContextMenuItemService.cs | 13 +- .../Interfaces/IContextMenuProvider.cs | 41 +- .../Interfaces/ICreateAccountAliasDialog.cs | 9 +- .../ICustomFolderSynchronizationRequest.cs | 27 +- .../Interfaces/IDialogServiceBase.cs | 47 +- Wino.Core.Domain/Interfaces/IDispatcher.cs | 9 +- Wino.Core.Domain/Interfaces/IFileService.cs | 29 +- .../Interfaces/IFolderMenuItem.cs | 49 +- Wino.Core.Domain/Interfaces/IFolderService.cs | 137 +- Wino.Core.Domain/Interfaces/IFontService.cs | 19 +- .../Interfaces/IGmailThreadingStrategy.cs | 7 +- .../Interfaces/IImapAccountCreationDialog.cs | 35 +- .../IImapSynchronizationStrategyProvider.cs | 15 +- .../Interfaces/IImapSynchronizer.cs | 17 +- .../Interfaces/IImapSynchronizerStrategy.cs | 25 +- .../Interfaces/IImapTestService.cs | 9 +- .../Interfaces/IImapThreadingStrategy.cs | 7 +- .../Interfaces/IInitializeAsync.cs | 15 +- .../Interfaces/IKeyPressService.cs | 11 +- .../Interfaces/ILogInitializer.cs | 13 +- .../Interfaces/IMailDialogService.cs | 71 +- Wino.Core.Domain/Interfaces/IMailService.cs | 189 +- Wino.Core.Domain/Interfaces/IMenuItem.cs | 63 +- Wino.Core.Domain/Interfaces/IMenuOperation.cs | 11 +- .../Interfaces/IMimeFileService.cs | 107 +- .../Interfaces/INativeAppService.cs | 33 +- .../Interfaces/INavigationAware.cs | 11 +- .../Interfaces/INotificationBuilder.cs | 33 +- .../Interfaces/IOutlookThreadingStrategy.cs | 7 +- .../Interfaces/IPreferencesService.cs | 291 ++- Wino.Core.Domain/Interfaces/IPrintService.cs | 9 +- .../Interfaces/IProviderDetail.cs | 19 +- .../Interfaces/IProviderService.cs | 11 +- Wino.Core.Domain/Interfaces/IRequestBundle.cs | 111 +- .../Interfaces/ISettingsBuilderService.cs | 9 +- .../Interfaces/ISignatureService.cs | 69 +- .../ISpecialImapProviderConfigResolver.cs | 9 +- .../Interfaces/IStartupBehaviorService.cs | 29 +- .../Interfaces/IStatePersistenceService.cs | 83 +- .../Interfaces/IStoreManagementService.cs | 25 +- .../Interfaces/IStoreRatingService.cs | 11 +- .../Interfaces/ISynchronizerFactory.cs | 13 +- Wino.Core.Domain/Interfaces/IThemeService.cs | 31 +- .../Interfaces/IThreadingStrategy.cs | 21 +- .../Interfaces/IThreadingStrategyProvider.cs | 17 +- .../Interfaces/ITranslationService.cs | 11 +- Wino.Core.Domain/Interfaces/IUIMessage.cs | 19 +- .../Interfaces/IUnderlyingThemeService.cs | 9 +- .../Interfaces/IUnsubscriptionService.cs | 19 +- .../Interfaces/IWinoNavigationService.cs | 21 +- .../Interfaces/IWinoRequestDelegator.cs | 47 +- .../Interfaces/IWinoRequestProcessor.cs | 37 +- .../IWinoServerConnectionManager.cs | 97 +- .../Interfaces/IWinoSynchronizerBase.cs | 55 +- Wino.Core.Domain/MenuItems/AccountMenuItem.cs | 149 +- .../MenuItems/FixAccountIssuesMenuItem.cs | 17 +- Wino.Core.Domain/MenuItems/FolderMenuItem.cs | 127 +- .../MenuItems/ManageAccountsMenuItem.cs | 7 +- Wino.Core.Domain/MenuItems/MenuItemBase.cs | 91 +- .../MenuItems/MenuItemCollection.cs | 377 ++- .../MenuItems/MergedAccountFolderMenuItem.cs | 175 +- .../MenuItems/MergedAccountMenuItem.cs | 59 +- .../MergedAccountMoreFolderMenuItem.cs | 9 +- Wino.Core.Domain/MenuItems/NewMailMenuItem.cs | 7 +- Wino.Core.Domain/MenuItems/RateMenuItem.cs | 7 +- Wino.Core.Domain/MenuItems/SeperatorItem.cs | 7 +- Wino.Core.Domain/MenuItems/SettingsItem.cs | 7 +- .../Accounts/AccountCreationDialogResult.cs | 7 +- .../Accounts/ImapAuthenticationMethodModel.cs | 11 +- .../Accounts/ImapConnectionSecurityModel.cs | 11 +- .../Models/Accounts/ProfileInformation.cs | 19 +- .../Models/Accounts/ProviderDetail.cs | 111 +- .../Accounts/SpecialImapProviderDetails.cs | 7 +- .../Models/Accounts/UnreadItemCountResult.cs | 15 +- .../Authentication/TokenInformationEx.cs | 21 +- .../GoogleAuthorizationRequest.cs | 101 +- .../GoogleTokenizationRequest.cs | 31 +- .../AutoDiscoveryMinimalSettings.cs | 13 +- .../AutoDiscoveryProviderSetting.cs | 27 +- .../AutoDiscovery/AutoDiscoverySettings.cs | 111 +- .../Models/Calendar/CalendarDayModel.cs | 37 +- .../Models/Calendar/CalendarItemTarget.cs | 7 +- .../Calendar/CalendarPageNavigationArgs.cs | 25 +- .../Models/Calendar/CalendarRenderOptions.cs | 19 +- .../Models/Calendar/CalendarSettings.cs | 69 +- .../BaseCalendarTypeDrawingStrategy.cs | 59 +- .../DayCalendarDrawingStrategy.cs | 53 +- .../MonthCalendarDrawingStrategy.cs | 49 +- .../WeekCalendarDrawingStrategy.cs | 47 +- .../CalendarViewDayClickedEventArgs.cs | 15 +- Wino.Core.Domain/Models/Calendar/DateRange.cs | 53 +- .../Models/Calendar/DayHeaderRenderModel.cs | 21 +- .../Models/Calendar/DayRangeRenderModel.cs | 73 +- Wino.Core.Domain/Models/Common/SharedFile.cs | 19 +- .../Models/Comparers/DateComparer.cs | 33 +- .../Models/Comparers/DateTimeComparer.cs | 17 +- .../Models/Comparers/FolderNameComparer.cs | 11 +- .../Models/Comparers/ListItemComparer.cs | 51 +- .../Models/Comparers/NameComparer.cs | 11 +- .../Connectivity/ImapClientPoolOptions.cs | 35 +- .../ImapConnectivityTestResults.cs | 71 +- .../Models/Folders/AccountFolderTree.cs | 41 +- .../Models/Folders/FolderOperationMenuItem.cs | 15 +- .../FolderOperationPreperationRequest.cs | 17 +- .../Models/Folders/IMailItemFolder.cs | 49 +- .../Folders/SystemFolderConfiguration.cs | 15 +- .../Models/MailItem/HtmlPreviewVisitor.cs | 403 ++- .../Models/MailItem/IMailHashContainer.cs | 19 +- Wino.Core.Domain/Models/MailItem/IMailItem.cs | 57 +- .../Models/MailItem/IMailItemThread.cs | 23 +- .../MailItem/ImapMessageCreationPackage.cs | 27 +- .../Models/MailItem/MailDetailInformation.cs | 25 +- .../Models/MailItem/MailDragPackage.cs | 37 +- .../Models/MailItem/MailFolderPairMetadata.cs | 13 +- .../Models/MailItem/MailInsertPackage.cs | 7 +- .../MailItem/MailListInitializationOptions.cs | 19 +- .../MailOperationPreperationRequest.cs | 59 +- .../Models/MailItem/MimeMessageInformation.cs | 13 +- .../OutlookSpecialFolderIdInformation.cs | 25 +- .../MailItem/SendDraftPreparationRequest.cs | 27 +- .../Models/MailItem/ThreadMailItem.cs | 149 +- .../Models/MailItem/ToggleRequestRule.cs | 21 +- .../Models/Menus/MailOperationMenuItem.cs | 27 +- .../Models/Menus/MenuOperationItemBase.cs | 25 +- .../Navigation/NavigateMailFolderEventArgs.cs | 33 +- .../Models/Navigation/NavigationMode.cs | 15 +- .../Navigation/NavigationTransitionType.cs | 13 +- .../Models/Personalization/AppThemeBase.cs | 41 +- .../Personalization/CustomThemeMetadata.cs | 15 +- .../Personalization/ElementThemeContainer.cs | 21 +- .../Models/Printing/PrintInformation.cs | 21 +- .../Models/Reader/FilterOption.cs | 21 +- .../Models/Reader/MailRenderModel.cs | 49 +- .../Models/Reader/MailRenderingOptions.cs | 31 +- .../Models/Reader/SortingOption.cs | 37 +- .../Models/Reader/WebViewMessage.cs | 23 +- .../Models/Requests/RequestBase.cs | 63 +- .../Models/Requests/ServerRequestPackage.cs | 19 +- .../Models/Server/WinoServerResponse.cs | 59 +- .../Models/Settings/SettingOption.cs | 7 +- .../Models/Store/StoreProductType.cs | 9 +- .../CalendarSynchronizationOptions.cs | 41 +- .../CalendarSynchronizationResult.cs | 61 +- .../MailSynchronizationOptions.cs | 63 +- .../MailSynchronizationResult.cs | 61 +- .../Models/Translations/AppLanguageModel.cs | 7 +- .../Translations/WinoTranslationDictionary.cs | 81 +- Wino.Core.UWP/Activation/ActivationHandler.cs | 55 +- Wino.Core.UWP/BasePage.cs | 111 +- .../AccountCreationDialogControl.xaml.cs | 121 +- Wino.Core.UWP/Controls/ControlConstants.cs | 201 +- Wino.Core.UWP/Controls/EqualGridPanel.cs | 153 +- .../Controls/WinoAppTitleBar.xaml.cs | 393 ++- Wino.Core.UWP/Controls/WinoFontIcon.cs | 243 +- Wino.Core.UWP/Controls/WinoFontIconSource.cs | 45 +- Wino.Core.UWP/Controls/WinoInfoBar.cs | 127 +- .../Controls/WinoNavigationViewItem.cs | 71 +- .../Converters/GridLengthConverter.cs | 35 +- .../Converters/ReverseBooleanConverter.cs | 23 +- .../ReverseBooleanToVisibilityConverter.cs | 23 +- Wino.Core.UWP/CoreGeneric.xaml.cs | 9 +- Wino.Core.UWP/CoreUWPContainerSetup.cs | 67 +- .../Dialogs/AccountCreationDialog.xaml.cs | 113 +- .../Dialogs/AccountEditDialog.xaml.cs | 27 +- .../Dialogs/AccountPickerDialog.xaml.cs | 31 +- ...CustomMessageDialogInformationContainer.cs | 33 +- .../Dialogs/CustomThemeBuilderDialog.xaml.cs | 89 +- .../Dialogs/NewAccountDialog.xaml.cs | 259 +- Wino.Core.UWP/Dialogs/TextInputDialog.xaml.cs | 61 +- Wino.Core.UWP/Dispatcher.cs | 21 +- .../Extensions/AnimationExtensions.cs | 199 +- Wino.Core.UWP/Extensions/CompositionEnums.cs | 129 +- .../CompositionExtensions.Implicit.cs | 349 ++- .../Extensions/CompositionExtensions.Size.cs | 219 +- .../Extensions/ElementThemeExtensions.cs | 43 +- .../Extensions/StartupTaskStateExtensions.cs | 31 +- .../Extensions/StorageFileExtensions.cs | 37 +- Wino.Core.UWP/Extensions/UIExtensions.cs | 23 +- Wino.Core.UWP/Extensions/UtilExtensions.cs | 171 +- Wino.Core.UWP/Helpers/WinoVisualTreeHelper.cs | 73 +- Wino.Core.UWP/Helpers/XamlHelpers.cs | 683 +++--- .../Models/Personalization/CustomAppTheme.cs | 33 +- .../Personalization/PreDefinedAppTheme.cs | 41 +- .../Models/Personalization/SystemAppTheme.cs | 15 +- .../AppThemePreviewTemplateSelector.cs | 31 +- .../CustomWinoMessageDialogIconSelector.cs | 47 +- .../Selectors/FileAttachmentTypeSelector.cs | 79 +- .../NavigationMenuTemplateSelector.cs | 99 +- .../Services/ApplicationResourceManager.cs | 31 +- .../Services/BackgroundTaskService.cs | 91 +- Wino.Core.UWP/Services/ClipboardService.cs | 17 +- .../Services/ConfigurationService.cs | 69 +- Wino.Core.UWP/Services/DialogServiceBase.cs | 475 ++-- Wino.Core.UWP/Services/FileService.cs | 89 +- Wino.Core.UWP/Services/KeyPressService.cs | 17 +- Wino.Core.UWP/Services/NativeAppService.cs | 133 +- .../Services/NavigationServiceBase.cs | 31 +- Wino.Core.UWP/Services/NotificationBuilder.cs | 379 ++- Wino.Core.UWP/Services/PreferencesService.cs | 569 +++-- Wino.Core.UWP/Services/PrintService.cs | 427 ++-- .../Services/StartupBehaviorService.cs | 61 +- .../Services/StatePersistenceService.cs | 253 +- .../Services/StoreManagementService.cs | 101 +- Wino.Core.UWP/Services/StoreRatingService.cs | 199 +- Wino.Core.UWP/Services/ThemeService.cs | 741 +++--- Wino.Core.UWP/Services/ThumbnailService.cs | 95 +- .../Services/UnderlyingThemeService.cs | 41 +- .../Services/WinoServerConnectionManager.cs | 669 +++-- .../Styles/CustomMessageDialogStyles.xaml.cs | 11 +- Wino.Core.UWP/Styles/DataTemplates.xaml.cs | 11 +- .../Abstract/ManageAccountsPageAbstract.cs | 7 +- .../Abstract/SettingOptionsPageAbstract.cs | 7 +- .../Views/Abstract/SettingsPageAbstract.cs | 7 +- .../Views/Abstract/SettingsPageBase.cs | 19 +- .../Views/ManageAccountsPage.xaml.cs | 159 +- .../Views/SettingOptionsPage.xaml.cs | 11 +- Wino.Core.UWP/Views/SettingsPage.xaml.cs | 129 +- Wino.Core.UWP/WinoApplication.cs | 417 ++-- Wino.Core.ViewModels/AboutPageViewModel.cs | 193 +- .../AccountManagementPageViewModelBase.cs | 223 +- Wino.Core.ViewModels/CalendarBaseViewModel.cs | 13 +- Wino.Core.ViewModels/CoreBaseViewModel.cs | 81 +- .../Data/AccountProviderDetailViewModel.cs | 49 +- .../Data/AppColorViewModel.cs | 29 +- .../Data/BreadcrumbNavigationItemViewModel.cs | 31 +- .../MergedAccountProviderDetailViewModel.cs | 47 +- .../NewAccountManagementPageViewModel.cs | 17 +- .../PersonalizationPageViewModel.cs | 535 ++-- .../SettingOptionsPageViewModel.cs | 83 +- Wino.Core.ViewModels/SettingsPageViewModel.cs | 17 +- Wino.Core.ViewModels/SettingsViewModel.cs | 9 +- Wino.Core/CoreContainerSetup.cs | 47 +- .../Extensions/GoogleIntegratorExtensions.cs | 381 ++- Wino.Core/Extensions/ListExtensions.cs | 21 +- Wino.Core/Extensions/LongExtensions.cs | 95 +- Wino.Core/Extensions/MailkitExtensions.cs | 45 +- Wino.Core/Extensions/MimeExtensions.cs | 183 +- .../Extensions/OutlookIntegratorExtensions.cs | 687 +++--- Wino.Core/Extensions/StringExtensions.cs | 29 +- Wino.Core/Http/GmailClientMessageHandler.cs | 35 +- Wino.Core/Http/MicrosoftImmutableIdHandler.cs | 23 +- Wino.Core/Http/MicrosoftTokenProvider.cs | 35 +- Wino.Core/Integration/ImapClientPool.cs | 645 +++-- .../Json/ServerRequestTypeInfoResolver.cs | 81 +- .../Processors/DefaultChangeProcessor.cs | 373 ++- .../Processors/GmailChangeProcessor.cs | 583 +++-- .../Processors/ImapChangeProcessor.cs | 25 +- .../Processors/OutlookChangeProcessor.cs | 229 +- Wino.Core/Integration/WinoImapClient.cs | 83 +- Wino.Core/Misc/ColorHelpers.cs | 67 +- Wino.Core/Misc/OutlookFileAttachment.cs | 31 +- Wino.Core/Requests/Bundles/RequestBundle.cs | 33 +- .../Requests/Bundles/ServerRequestPackage.cs | 33 +- .../Requests/Bundles/TaskRequestBundle.cs | 43 +- .../Requests/Folder/EmptyFolderRequest.cs | 35 +- .../Folder/MarkFolderAsReadRequest.cs | 43 +- .../Requests/Folder/RenameFolderRequest.cs | 27 +- .../Requests/Mail/AlwaysMoveToRequest.cs | 19 +- Wino.Core/Requests/Mail/ArchiveRequest.cs | 75 +- Wino.Core/Requests/Mail/ChangeFlagRequest.cs | 49 +- Wino.Core/Requests/Mail/CreateDraftRequest.cs | 33 +- Wino.Core/Requests/Mail/DeleteRequest.cs | 47 +- Wino.Core/Requests/Mail/MarkReadRequest.cs | 47 +- Wino.Core/Requests/Mail/MoveRequest.cs | 39 +- .../Requests/Mail/MoveToFocusedRequest.cs | 19 +- Wino.Core/Requests/Mail/SendDraftRequest.cs | 53 +- Wino.Core/Services/AuthenticationProvider.cs | 45 +- Wino.Core/Services/AutoDiscoveryService.cs | 77 +- Wino.Core/Services/ImapTestService.cs | 77 +- Wino.Core/Services/SynchronizerFactory.cs | 193 +- .../Services/ThreadingStrategyProvider.cs | 43 +- Wino.Core/Services/UnsubscriptionService.cs | 37 +- Wino.Core/Services/WinoRequestDelegator.cs | 265 +- Wino.Core/Services/WinoRequestProcessor.cs | 451 ++-- Wino.Core/Synchronizers/BaseSynchronizer.cs | 177 +- Wino.Core/Synchronizers/GmailSynchronizer.cs | 2169 ++++++++--------- .../ImapSync/CondstoreSynchronizer.cs | 197 +- .../ImapSynchronizationStrategyBase.cs | 267 +- .../ImapSynchronizationStrategyProvider.cs | 39 +- .../ImapSync/QResyncSynchronizer.cs | 179 +- .../ImapSync/UidBasedSynchronizer.cs | 103 +- Wino.Core/Synchronizers/ImapSynchronizer.cs | 1431 ++++++----- .../Synchronizers/OutlookSynchronizer.cs | 1983 ++++++++------- Wino.Core/Synchronizers/WinoSynchronizer.cs | 771 +++--- .../AccountDetailsPageViewModel.cs | 253 +- .../AccountManagementViewModel.cs | 599 +++-- .../AliasManagementPageViewModel.cs | 223 +- .../AppPreferencesPageViewModel.cs | 247 +- Wino.Mail.ViewModels/AppShellViewModel.cs | 1825 +++++++------- .../Collections/WinoMailCollection.cs | 887 ++++--- Wino.Mail.ViewModels/ComposePageViewModel.cs | 1033 ++++---- .../Data/FolderPivotViewModel.cs | 47 +- .../Data/MailAttachmentViewModel.cs | 161 +- .../Data/MailItemContainer.cs | 25 +- .../Data/MailItemViewModel.cs | 191 +- .../Data/ThreadMailItemViewModel.cs | 219 +- Wino.Mail.ViewModels/IdlePageViewModel.cs | 9 +- .../LanguageTimePageViewModel.cs | 57 +- Wino.Mail.ViewModels/MailBaseViewModel.cs | 61 +- Wino.Mail.ViewModels/MailListPageViewModel.cs | 1853 +++++++------- .../MailRenderingPageViewModel.cs | 1343 +++++----- .../MailViewModelsContainerSetup.cs | 13 +- .../MergedAccountDetailsPageViewModel.cs | 385 ++- .../MessageListPageViewModel.cs | 181 +- .../Messages/ActiveMailFolderChangedEvent.cs | 11 +- .../Messages/ActiveMailItemChangedEvent.cs | 25 +- .../Messages/MailItemSelectedEvent.cs | 27 +- .../Messages/MailItemSelectionRemovedEvent.cs | 23 +- .../NewMailItemRenderingRequestedEvent.cs | 17 +- .../Messages/SelectMailItemContainerEvent.cs | 13 +- .../ReadComposePanePageViewModel.cs | 103 +- .../SignatureManagementPageViewModel.cs | 275 ++- Wino.Mail.ViewModels/WelcomePageViewModel.cs | 43 +- .../Activation/DefaultActivationHandler.cs | 21 +- Wino.Mail/Activation/FileActivationHandler.cs | 85 +- .../Activation/ProtocolActivationHandler.cs | 79 +- .../ToastNotificationActivationHandler.cs | 105 +- Wino.Mail/App.xaml.cs | 527 ++-- Wino.Mail/AppShell.xaml.cs | 503 ++-- .../Behaviors/BindableCommandBarBehavior.cs | 341 ++- .../CreateMailNavigationItemBehavior.cs | 127 +- Wino.Mail/Controls/AccountNavigationItem.cs | 97 +- Wino.Mail/Controls/Advanced/WinoListView.cs | 653 +++-- Wino.Mail/Controls/ImagePreviewControl.cs | 313 ++- .../MailItemDisplayInformationControl.xaml.cs | 375 ++- Wino.Mail/Controls/SettingsMenuItemControl.cs | 127 +- Wino.Mail/Controls/WinoExpander.cs | 229 +- Wino.Mail/Controls/WinoSwipeControlItems.cs | 133 +- .../Dialogs/AccountReorderDialog.xaml.cs | 67 +- .../Dialogs/CreateAccountAliasDialog.xaml.cs | 35 +- Wino.Mail/Dialogs/MessageSourceDialog.xaml.cs | 31 +- Wino.Mail/Dialogs/MoveMailDialog.xaml.cs | 125 +- Wino.Mail/Dialogs/NewImapSetupDialog.xaml.cs | 193 +- .../Dialogs/SignatureEditorDialog.xaml.cs | 645 +++-- .../SystemFolderConfigurationDialog.xaml.cs | 95 +- .../MenuFlyouts/AccountSelectorFlyout.cs | 83 +- Wino.Mail/MenuFlyouts/FilterMenuFlyout.cs | 335 ++- .../MenuFlyouts/FolderOperationFlyout.cs | 25 +- .../FolderOperationMenuFlyoutItem.cs | 9 +- Wino.Mail/MenuFlyouts/MailOperationFlyout.cs | 25 +- .../MailOperationMenuFlyoutItem.cs | 9 +- Wino.Mail/MenuFlyouts/MoveButtonFlyout.cs | 111 +- Wino.Mail/MenuFlyouts/WinoOperationFlyout.cs | 67 +- .../MenuFlyouts/WinoOperationFlyoutItem.cs | 73 +- ...ccountProviderViewModelTemplateSelector.cs | 25 +- .../AccountReorderTemplateSelector.cs | 23 +- .../MailItemContainerStyleSelector.cs | 23 +- ...lItemDisplayModePreviewTemplateSelector.cs | 43 +- .../Selectors/MailItemDisplaySelector.cs | 25 +- Wino.Mail/Services/DialogService.cs | 333 ++- .../MailAuthenticatorConfiguration.cs | 47 +- Wino.Mail/Services/NavigationService.cs | 257 +- Wino.Mail/Services/ProviderService.cs | 45 +- Wino.Mail/Services/SettingsBuilderService.cs | 29 +- Wino.Mail/Styles/WinoExpanderStyle.xaml.cs | 11 +- Wino.Mail/Views/AboutPage.xaml.cs | 11 +- Wino.Mail/Views/Abstract/AboutPageAbstract.cs | 7 +- .../Abstract/AccountDetailsPageAbstract.cs | 7 +- .../Abstract/AccountManagementPageAbstract.cs | 9 +- .../Abstract/AliasManagementPageAbstract.cs | 7 +- .../Abstract/AppPreferencesPageAbstract.cs | 7 +- Wino.Mail/Views/Abstract/AppShellAbstract.cs | 7 +- .../Views/Abstract/ComposePageAbstract.cs | 7 +- Wino.Mail/Views/Abstract/IdlePageAbstract.cs | 7 +- .../Abstract/LanguageTimePageAbstract.cs | 7 +- .../Abstract/MailRenderingPageAbstract.cs | 37 +- .../MergedAccountDetailsPageAbstract.cs | 7 +- .../Views/Abstract/MessageListPageAbstract.cs | 7 +- .../Abstract/PersonalizationPageAbstract.cs | 9 +- .../Abstract/ReadComposePanePageAbstract.cs | 7 +- .../SignatureManagementPageAbstract.cs | 7 +- .../Views/Abstract/WelcomePageAbstract.cs | 9 +- .../Views/Account/AccountDetailsPage.xaml.cs | 31 +- .../Account/AccountManagementPage.xaml.cs | 17 +- .../Account/MergedAccountDetailsPage.xaml.cs | 11 +- Wino.Mail/Views/ComposePage.xaml.cs | 1213 +++++---- Wino.Mail/Views/IdlePage.xaml.cs | 11 +- .../ImapSetup/AdvancedImapSetupPage.xaml.cs | 367 ++- .../ImapConnectionFailedPage.xaml.cs | 69 +- .../PreparingImapFoldersPage.xaml.cs | 17 +- .../TestingImapConnectionPage.xaml.cs | 173 +- .../ImapSetup/WelcomeImapSetupPage.xaml.cs | 141 +- Wino.Mail/Views/MailListPage.xaml.cs | 837 ++++--- Wino.Mail/Views/MailRenderingPage.xaml.cs | 435 ++-- Wino.Mail/Views/PersonalizationPage.xaml.cs | 11 +- .../Settings/AliasManagementPage.xaml.cs | 11 +- .../Views/Settings/AppPreferencesPage.xaml.cs | 11 +- .../Views/Settings/LanguageTimePage.xaml.cs | 21 +- .../Views/Settings/MessageListPage.xaml.cs | 11 +- .../Settings/ReadComposePanePage.xaml.cs | 11 +- .../Settings/SignatureManagementPage.xaml.cs | 11 +- .../Accounts/AccountMenuItemExtended.cs | 21 +- .../Accounts/AccountMenuItemsReordered.cs | 15 +- .../Accounts/AccountsMenuRefreshRequested.cs | 13 +- .../CalendarDisplayTypeChangedMessage.cs | 15 +- .../CalendarEnableStatusChangedMessage.cs | 7 +- .../Client/Calendar/CalendarEventMessages.cs | 13 +- .../Calendar/CalendarItemEventMessages.cs | 11 +- .../CalendarSettingsUpdatedMessage.cs | 13 +- .../DetailsPageStateChangedMessage.cs | 13 +- .../Calendar/GoNextDayRequestedMessage.cs | 13 +- .../Calendar/GoPreviousDayRequestedMessage.cs | 13 +- .../Client/Calendar/LoadCalendarMessage.cs | 21 +- .../Client/Calendar/ScrollToDateMessage.cs | 15 +- .../Client/Calendar/ScrollToHourMessage.cs | 15 +- .../VisibleDateRangeChangedMessage.cs | 17 +- .../WinoServerConnectionEstrablished.cs | 13 +- .../Mails/CancelRenderingContentRequested.cs | 13 +- .../Mails/ClearMailSelectionsRequested.cs | 13 +- .../Mails/CreateNewComposeMailRequested.cs | 15 +- .../Mails/DisposeRenderingFrameRequested.cs | 13 +- .../Client/Mails/HtmlRenderingRequested.cs | 15 +- .../Mails/ImapSetupBackNavigationRequested.cs | 19 +- .../Client/Mails/ImapSetupDismissRequested.cs | 15 +- .../Mails/ImapSetupNavigationRequested.cs | 17 +- .../Mails/MailItemNavigationRequested.cs | 17 +- .../Client/Mails/NavigateMailFolderEvent.cs | 17 +- .../Client/Mails/PrintMailRequested.cs | 17 +- .../Client/Mails/SaveAsPDFRequested.cs | 13 +- .../BackBreadcrumNavigationRequested.cs | 13 +- .../BreadcrumbNavigationRequested.cs | 19 +- .../NavigateAppPreferencesRequested.cs | 13 +- .../NavigateManageAccountsRequested.cs | 13 +- .../Client/Shell/ApplicationThemeChanged.cs | 15 +- ...ateNewMailWithMultipleAccountsRequested.cs | 25 +- .../Client/Shell/InfoBarMessageRequested.cs | 27 +- Wino.Messages/Client/Shell/LanguageChanged.cs | 13 +- .../Shell/MailtoProtocolMessageRequested.cs | 7 +- Wino.Messages/Enums/MessageType.cs | 11 +- Wino.Messages/MessageConstants.cs | 15 +- .../Server/AuthorizationRequested.cs | 13 +- .../Server/DownloadMissingMessageRequested.cs | 19 +- .../Server/ImapConnectivityTestRequested.cs | 7 +- .../KillAccountSynchronizerRequested.cs | 15 +- .../Server/NewSynchronizationRequested.cs | 25 +- .../Server/ServerTerminationModeChanged.cs | 15 +- .../SynchronizationExistenceCheckRequest.cs | 15 +- .../Server/TerminateServerRequested.cs | 13 +- Wino.Messages/UI/AccountCreatedMessage.cs | 7 +- .../UI/AccountFolderConfigurationUpdated.cs | 13 +- Wino.Messages/UI/AccountRemovedMessage.cs | 7 +- .../UI/AccountSynchronizationCompleted.cs | 9 +- ...ntSynchronizationProgressUpdatedMessage.cs | 13 +- .../UI/AccountSynchronizerStateChanged.cs | 17 +- Wino.Messages/UI/AccountUpdatedMessage.cs | 7 +- Wino.Messages/UI/CopyAuthURLRequested.cs | 15 +- Wino.Messages/UI/DraftCreated.cs | 7 +- Wino.Messages/UI/DraftFailed.cs | 7 +- Wino.Messages/UI/DraftMapped.cs | 7 +- Wino.Messages/UI/FolderRenamed.cs | 7 +- .../UI/FolderSynchronizationEnabled.cs | 7 +- Wino.Messages/UI/MailAddedMessage.cs | 7 +- Wino.Messages/UI/MailDownloadedMessage.cs | 7 +- Wino.Messages/UI/MailRemovedMessage.cs | 7 +- Wino.Messages/UI/MailUpdatedMessage.cs | 7 +- Wino.Messages/UI/MergedInboxRenamed.cs | 7 +- .../UI/RefreshUnreadCountsMessage.cs | 7 +- Wino.Messages/UI/UIMessageBase.cs | 7 +- Wino.Server/App.xaml.cs | 427 ++-- Wino.Server/Core/ServerMessageHandlerBase.cs | 107 +- .../Core/ServerMessageHandlerFactory.cs | 63 +- .../IServerMessageHandlerFactory.cs | 13 +- .../MessageHandlers/AuthenticationHandler.cs | 71 +- .../CalendarSynchronizationRequestHandler.cs | 41 +- .../ImapConnectivityTestHandler.cs | 61 +- .../KillAccountSynchronizerHandler.cs | 31 +- .../MailSynchronizationRequestHandler.cs | 169 +- .../ServerTerminationModeHandler.cs | 17 +- .../SingleMimeDownloadHandler.cs | 31 +- .../MessageHandlers/SyncExistenceHandler.cs | 31 +- .../TerminateServerRequestHandler.cs | 23 +- .../UserActionRequestHandler.cs | 49 +- Wino.Server/ServerContext.cs | 677 +++-- Wino.Server/ServerViewModel.cs | 101 +- Wino.Services/AccountService.cs | 1063 ++++---- Wino.Services/ApplicationConfiguration.cs | 17 +- Wino.Services/BaseDatabaseService.cs | 27 +- Wino.Services/CalendarService.cs | 505 ++-- Wino.Services/ContactService.cs | 91 +- Wino.Services/ContextMenuItemService.cs | 309 ++- Wino.Services/DatabaseService.cs | 87 +- .../Extensions/HtmlAgilityPackExtensions.cs | 213 +- .../Extensions/MailkitClientExtensions.cs | 329 ++- Wino.Services/Extensions/SqlKataExtensions.cs | 17 +- Wino.Services/FolderService.cs | 1163 +++++---- Wino.Services/LaunchProtocolService.cs | 11 +- Wino.Services/LogInitializer.cs | 61 +- Wino.Services/MailService.cs | 1763 +++++++------- Wino.Services/MimeFileService.cs | 249 +- Wino.Services/Misc/WinoTelemetryConverter.cs | 45 +- Wino.Services/ServiceConstants.cs | 111 +- Wino.Services/ServicesContainerSetup.cs | 45 +- Wino.Services/SignatureService.cs | 81 +- .../SpecialImapProviderConfigResolver.cs | 111 +- .../Threading/APIThreadingStrategy.cs | 189 +- .../Threading/GmailThreadingStrategy.cs | 9 +- .../Threading/ImapThreadingStrategy.cs | 279 ++- .../Threading/OutlookThreadingStrategy.cs | 17 +- Wino.Services/ThreadingStrategyProvider.cs | 43 +- Wino.Services/TranslationService.cs | 119 +- 617 files changed, 32107 insertions(+), 32721 deletions(-) diff --git a/.editorconfig b/.editorconfig index c686ec1f..b06e6570 100644 --- a/.editorconfig +++ b/.editorconfig @@ -149,7 +149,7 @@ csharp_preferred_modifier_order = public,private,protected,internal,static,exter # Code-block preferences csharp_prefer_braces = true:silent csharp_prefer_simple_using_statement = true:suggestion -csharp_style_namespace_declarations = block_scoped:silent +csharp_style_namespace_declarations = file_scoped:error # Expression-level preferences csharp_prefer_simple_default_expression = true:suggestion @@ -287,4 +287,6 @@ csharp_style_prefer_top_level_statements = true:silent csharp_style_prefer_utf8_string_literals = true:suggestion csharp_style_prefer_readonly_struct = true:suggestion csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true:silent -csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true:silent \ No newline at end of file +csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true:silent +csharp_style_prefer_primary_constructors = true:silent +csharp_prefer_system_threading_lock = true:suggestion \ No newline at end of file diff --git a/Wino.Authentication/BaseAuthenticator.cs b/Wino.Authentication/BaseAuthenticator.cs index 4e3664df..29fbb757 100644 --- a/Wino.Authentication/BaseAuthenticator.cs +++ b/Wino.Authentication/BaseAuthenticator.cs @@ -1,17 +1,16 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; -namespace Wino.Authentication +namespace Wino.Authentication; + +public abstract class BaseAuthenticator { - public abstract class BaseAuthenticator + public abstract MailProviderType ProviderType { get; } + protected IAuthenticatorConfig AuthenticatorConfig { get; } + + protected BaseAuthenticator(IAuthenticatorConfig authenticatorConfig) { - public abstract MailProviderType ProviderType { get; } - protected IAuthenticatorConfig AuthenticatorConfig { get; } - protected BaseAuthenticator(IAuthenticatorConfig authenticatorConfig) - { - - AuthenticatorConfig = authenticatorConfig; - } + AuthenticatorConfig = authenticatorConfig; } } diff --git a/Wino.Authentication/GmailAuthenticator.cs b/Wino.Authentication/GmailAuthenticator.cs index 901df797..506d0448 100644 --- a/Wino.Authentication/GmailAuthenticator.cs +++ b/Wino.Authentication/GmailAuthenticator.cs @@ -7,45 +7,44 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Authentication; -namespace Wino.Authentication +namespace Wino.Authentication; + +public class GmailAuthenticator : BaseAuthenticator, IGmailAuthenticator { - public class GmailAuthenticator : BaseAuthenticator, IGmailAuthenticator + public GmailAuthenticator(IAuthenticatorConfig authConfig) : base(authConfig) { - public GmailAuthenticator(IAuthenticatorConfig authConfig) : base(authConfig) + } + + public string ClientId => AuthenticatorConfig.GmailAuthenticatorClientId; + public bool ProposeCopyAuthURL { get; set; } + + public override MailProviderType ProviderType => MailProviderType.Gmail; + + /// + /// Generates the token information for the given account. + /// For gmail, interactivity is automatically handled when you get the token. + /// + /// Account to get token for. + public Task GenerateTokenInformationAsync(MailAccount account) + => GetTokenInformationAsync(account); + + public async Task GetTokenInformationAsync(MailAccount account) + { + var userCredential = await GetGoogleUserCredentialAsync(account); + + if (userCredential.Token.IsStale) { + await userCredential.RefreshTokenAsync(CancellationToken.None); } - public string ClientId => AuthenticatorConfig.GmailAuthenticatorClientId; - public bool ProposeCopyAuthURL { get; set; } + return new TokenInformationEx(userCredential.Token.AccessToken, account.Address); + } - public override MailProviderType ProviderType => MailProviderType.Gmail; - - /// - /// Generates the token information for the given account. - /// For gmail, interactivity is automatically handled when you get the token. - /// - /// Account to get token for. - public Task GenerateTokenInformationAsync(MailAccount account) - => GetTokenInformationAsync(account); - - public async Task GetTokenInformationAsync(MailAccount account) + private Task GetGoogleUserCredentialAsync(MailAccount account) + { + return GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets() { - var userCredential = await GetGoogleUserCredentialAsync(account); - - if (userCredential.Token.IsStale) - { - await userCredential.RefreshTokenAsync(CancellationToken.None); - } - - return new TokenInformationEx(userCredential.Token.AccessToken, account.Address); - } - - private Task GetGoogleUserCredentialAsync(MailAccount account) - { - return GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets() - { - ClientId = ClientId - }, AuthenticatorConfig.GmailScope, account.Id.ToString(), CancellationToken.None, new FileDataStore(AuthenticatorConfig.GmailTokenStoreIdentifier)); - } + ClientId = ClientId + }, AuthenticatorConfig.GmailScope, account.Id.ToString(), CancellationToken.None, new FileDataStore(AuthenticatorConfig.GmailTokenStoreIdentifier)); } } diff --git a/Wino.Authentication/OutlookAuthenticator.cs b/Wino.Authentication/OutlookAuthenticator.cs index 8bdcfb27..106f9717 100644 --- a/Wino.Authentication/OutlookAuthenticator.cs +++ b/Wino.Authentication/OutlookAuthenticator.cs @@ -11,116 +11,115 @@ using Wino.Core.Domain.Exceptions; using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Authentication; -namespace Wino.Authentication +namespace Wino.Authentication; + +public class OutlookAuthenticator : BaseAuthenticator, IOutlookAuthenticator { - public class OutlookAuthenticator : BaseAuthenticator, IOutlookAuthenticator + private const string TokenCacheFileName = "OutlookCache.bin"; + private bool isTokenCacheAttached = false; + + // Outlook + private const string Authority = "https://login.microsoftonline.com/common"; + + public override MailProviderType ProviderType => MailProviderType.Outlook; + + private readonly IPublicClientApplication _publicClientApplication; + private readonly IApplicationConfiguration _applicationConfiguration; + + public OutlookAuthenticator(INativeAppService nativeAppService, + IApplicationConfiguration applicationConfiguration, + IAuthenticatorConfig authenticatorConfig) : base(authenticatorConfig) { - private const string TokenCacheFileName = "OutlookCache.bin"; - private bool isTokenCacheAttached = false; + _applicationConfiguration = applicationConfiguration; - // Outlook - private const string Authority = "https://login.microsoftonline.com/common"; + var authenticationRedirectUri = nativeAppService.GetWebAuthenticationBrokerUri(); - public override MailProviderType ProviderType => MailProviderType.Outlook; - - private readonly IPublicClientApplication _publicClientApplication; - private readonly IApplicationConfiguration _applicationConfiguration; - - public OutlookAuthenticator(INativeAppService nativeAppService, - IApplicationConfiguration applicationConfiguration, - IAuthenticatorConfig authenticatorConfig) : base(authenticatorConfig) + var options = new BrokerOptions(BrokerOptions.OperatingSystems.Windows) { - _applicationConfiguration = applicationConfiguration; + Title = "Wino Mail", + ListOperatingSystemAccounts = true, + }; - var authenticationRedirectUri = nativeAppService.GetWebAuthenticationBrokerUri(); + var outlookAppBuilder = PublicClientApplicationBuilder.Create(AuthenticatorConfig.OutlookAuthenticatorClientId) + .WithParentActivityOrWindow(nativeAppService.GetCoreWindowHwnd) + .WithBroker(options) + .WithDefaultRedirectUri() + .WithAuthority(Authority); - var options = new BrokerOptions(BrokerOptions.OperatingSystems.Windows) - { - Title = "Wino Mail", - ListOperatingSystemAccounts = true, - }; + _publicClientApplication = outlookAppBuilder.Build(); + } - var outlookAppBuilder = PublicClientApplicationBuilder.Create(AuthenticatorConfig.OutlookAuthenticatorClientId) - .WithParentActivityOrWindow(nativeAppService.GetCoreWindowHwnd) - .WithBroker(options) - .WithDefaultRedirectUri() - .WithAuthority(Authority); + public string[] Scope => AuthenticatorConfig.OutlookScope; - _publicClientApplication = outlookAppBuilder.Build(); - } - - public string[] Scope => AuthenticatorConfig.OutlookScope; - - private async Task EnsureTokenCacheAttachedAsync() + private async Task EnsureTokenCacheAttachedAsync() + { + if (!isTokenCacheAttached) { - if (!isTokenCacheAttached) - { - var storageProperties = new StorageCreationPropertiesBuilder(TokenCacheFileName, _applicationConfiguration.PublisherSharedFolderPath).Build(); - var msalcachehelper = await MsalCacheHelper.CreateAsync(storageProperties); - msalcachehelper.RegisterCache(_publicClientApplication.UserTokenCache); + var storageProperties = new StorageCreationPropertiesBuilder(TokenCacheFileName, _applicationConfiguration.PublisherSharedFolderPath).Build(); + var msalcachehelper = await MsalCacheHelper.CreateAsync(storageProperties); + msalcachehelper.RegisterCache(_publicClientApplication.UserTokenCache); - isTokenCacheAttached = true; - } + isTokenCacheAttached = true; } + } - public async Task GetTokenInformationAsync(MailAccount account) + public async Task GetTokenInformationAsync(MailAccount account) + { + await EnsureTokenCacheAttachedAsync(); + + var storedAccount = (await _publicClientApplication.GetAccountsAsync()).FirstOrDefault(a => a.Username == account.Address); + + if (storedAccount == null) + return await GenerateTokenInformationAsync(account); + + try + { + var authResult = await _publicClientApplication.AcquireTokenSilent(Scope, storedAccount).ExecuteAsync(); + + return new TokenInformationEx(authResult.AccessToken, authResult.Account.Username); + } + catch (MsalUiRequiredException) + { + // Somehow MSAL is not able to refresh the token silently. + // Force interactive login. + + return await GenerateTokenInformationAsync(account); + } + catch (Exception) + { + throw; + } + } + + public async Task GenerateTokenInformationAsync(MailAccount account) + { + try { await EnsureTokenCacheAttachedAsync(); - var storedAccount = (await _publicClientApplication.GetAccountsAsync()).FirstOrDefault(a => a.Username == account.Address); + var authResult = await _publicClientApplication + .AcquireTokenInteractive(Scope) + .ExecuteAsync(); - if (storedAccount == null) - return await GenerateTokenInformationAsync(account); + // If the account is null, it means it's the initial creation of it. + // If not, make sure the authenticated user address matches the username. + // When people refresh their token, accounts must match. - try + if (account?.Address != null && !account.Address.Equals(authResult.Account.Username, StringComparison.OrdinalIgnoreCase)) { - var authResult = await _publicClientApplication.AcquireTokenSilent(Scope, storedAccount).ExecuteAsync(); + throw new AuthenticationException("Authenticated address does not match with your account address."); + } - return new TokenInformationEx(authResult.AccessToken, authResult.Account.Username); - } - catch (MsalUiRequiredException) - { - // Somehow MSAL is not able to refresh the token silently. - // Force interactive login. - - return await GenerateTokenInformationAsync(account); - } - catch (Exception) - { - throw; - } + return new TokenInformationEx(authResult.AccessToken, authResult.Account.Username); } - - public async Task GenerateTokenInformationAsync(MailAccount account) + catch (MsalClientException msalClientException) { - try - { - await EnsureTokenCacheAttachedAsync(); + if (msalClientException.ErrorCode == "authentication_canceled" || msalClientException.ErrorCode == "access_denied") + throw new AccountSetupCanceledException(); - var authResult = await _publicClientApplication - .AcquireTokenInteractive(Scope) - .ExecuteAsync(); - - // If the account is null, it means it's the initial creation of it. - // If not, make sure the authenticated user address matches the username. - // When people refresh their token, accounts must match. - - if (account?.Address != null && !account.Address.Equals(authResult.Account.Username, StringComparison.OrdinalIgnoreCase)) - { - throw new AuthenticationException("Authenticated address does not match with your account address."); - } - - return new TokenInformationEx(authResult.AccessToken, authResult.Account.Username); - } - catch (MsalClientException msalClientException) - { - if (msalClientException.ErrorCode == "authentication_canceled" || msalClientException.ErrorCode == "access_denied") - throw new AccountSetupCanceledException(); - - throw; - } - - throw new AuthenticationException(Translator.Exception_UnknowErrorDuringAuthentication, new Exception(Translator.Exception_TokenGenerationFailed)); + throw; } + + throw new AuthenticationException(Translator.Exception_UnknowErrorDuringAuthentication, new Exception(Translator.Exception_TokenGenerationFailed)); } } diff --git a/Wino.Calendar/Services/CalendarAuthenticatorConfig.cs b/Wino.Calendar/Services/CalendarAuthenticatorConfig.cs index f139ff59..391ff7f2 100644 --- a/Wino.Calendar/Services/CalendarAuthenticatorConfig.cs +++ b/Wino.Calendar/Services/CalendarAuthenticatorConfig.cs @@ -1,33 +1,32 @@ using Wino.Core.Domain.Interfaces; -namespace Wino.Calendar.Services +namespace Wino.Calendar.Services; + +public class CalendarAuthenticatorConfig : IAuthenticatorConfig { - public class CalendarAuthenticatorConfig : IAuthenticatorConfig + public string OutlookAuthenticatorClientId => "b19c2035-d740-49ff-b297-de6ec561b208"; + + public string[] OutlookScope => new string[] { - public string OutlookAuthenticatorClientId => "b19c2035-d740-49ff-b297-de6ec561b208"; + "Calendars.Read", + "Calendars.Read.Shared", + "offline_access", + "Calendars.ReadBasic", + "Calendars.ReadWrite", + "Calendars.ReadWrite.Shared", + "User.Read" + }; - public string[] OutlookScope => new string[] - { - "Calendars.Read", - "Calendars.Read.Shared", - "offline_access", - "Calendars.ReadBasic", - "Calendars.ReadWrite", - "Calendars.ReadWrite.Shared", - "User.Read" - }; + public string GmailAuthenticatorClientId => "973025879644-s7b4ur9p3rlgop6a22u7iuptdc0brnrn.apps.googleusercontent.com"; - public string GmailAuthenticatorClientId => "973025879644-s7b4ur9p3rlgop6a22u7iuptdc0brnrn.apps.googleusercontent.com"; + public string[] GmailScope => new string[] + { + "https://www.googleapis.com/auth/calendar", + "https://www.googleapis.com/auth/calendar.events", + "https://www.googleapis.com/auth/calendar.settings.readonly", + "https://www.googleapis.com/auth/userinfo.profile", + "https://www.googleapis.com/auth/userinfo.email" + }; - public string[] GmailScope => new string[] - { - "https://www.googleapis.com/auth/calendar", - "https://www.googleapis.com/auth/calendar.events", - "https://www.googleapis.com/auth/calendar.settings.readonly", - "https://www.googleapis.com/auth/userinfo.profile", - "https://www.googleapis.com/auth/userinfo.email" - }; - - public string GmailTokenStoreIdentifier => "WinoCalendarGmailTokenStore"; - } + public string GmailTokenStoreIdentifier => "WinoCalendarGmailTokenStore"; } diff --git a/Wino.Core.Domain/Collections/CalendarEventCollection.cs b/Wino.Core.Domain/Collections/CalendarEventCollection.cs index f6eb6c68..94a1eef6 100644 --- a/Wino.Core.Domain/Collections/CalendarEventCollection.cs +++ b/Wino.Core.Domain/Collections/CalendarEventCollection.cs @@ -7,150 +7,149 @@ using Wino.Core.Domain.Entities.Calendar; using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Calendar; -namespace Wino.Core.Domain.Collections +namespace Wino.Core.Domain.Collections; + +public class CalendarEventCollection { - public class CalendarEventCollection + public event EventHandler CalendarItemAdded; + public event EventHandler CalendarItemRemoved; + + public event EventHandler CalendarItemsCleared; + + private ObservableRangeCollection _internalRegularEvents = []; + private ObservableRangeCollection _internalAllDayEvents = []; + + public ReadOnlyObservableCollection RegularEvents { get; } + public ReadOnlyObservableCollection AllDayEvents { get; } // TODO: Rename this to include multi-day events. + public ITimePeriod Period { get; } + public CalendarSettings Settings { get; } + + private readonly List _allItems = new List(); + + public CalendarEventCollection(ITimePeriod period, CalendarSettings settings) { - public event EventHandler CalendarItemAdded; - public event EventHandler CalendarItemRemoved; + Period = period; + Settings = settings; - public event EventHandler CalendarItemsCleared; + RegularEvents = new ReadOnlyObservableCollection(_internalRegularEvents); + AllDayEvents = new ReadOnlyObservableCollection(_internalAllDayEvents); + } - private ObservableRangeCollection _internalRegularEvents = []; - private ObservableRangeCollection _internalAllDayEvents = []; + public bool HasCalendarEvent(AccountCalendar accountCalendar) + => _allItems.Any(x => x.AssignedCalendar.Id == accountCalendar.Id); - public ReadOnlyObservableCollection RegularEvents { get; } - public ReadOnlyObservableCollection AllDayEvents { get; } // TODO: Rename this to include multi-day events. - public ITimePeriod Period { get; } - public CalendarSettings Settings { get; } + public ICalendarItem GetCalendarItem(Guid calendarItemId) + { + return _allItems.FirstOrDefault(x => x.Id == calendarItemId); + } - private readonly List _allItems = new List(); - - public CalendarEventCollection(ITimePeriod period, CalendarSettings settings) + public void ClearSelectionStates() + { + foreach (var item in _allItems) { - Period = period; - Settings = settings; - - RegularEvents = new ReadOnlyObservableCollection(_internalRegularEvents); - AllDayEvents = new ReadOnlyObservableCollection(_internalAllDayEvents); - } - - public bool HasCalendarEvent(AccountCalendar accountCalendar) - => _allItems.Any(x => x.AssignedCalendar.Id == accountCalendar.Id); - - public ICalendarItem GetCalendarItem(Guid calendarItemId) - { - return _allItems.FirstOrDefault(x => x.Id == calendarItemId); - } - - public void ClearSelectionStates() - { - foreach (var item in _allItems) + if (item is ICalendarItemViewModel calendarItemViewModel) { - if (item is ICalendarItemViewModel calendarItemViewModel) - { - calendarItemViewModel.IsSelected = false; - } + calendarItemViewModel.IsSelected = false; } } - - public void FilterByCalendars(IEnumerable visibleCalendarIds) - { - foreach (var item in _allItems) - { - var collections = GetProperCollectionsForCalendarItem(item); - - foreach (var collection in collections) - { - if (!visibleCalendarIds.Contains(item.AssignedCalendar.Id) && collection.Contains(item)) - { - RemoveCalendarItemInternal(collection, item, false); - } - else if (visibleCalendarIds.Contains(item.AssignedCalendar.Id) && !collection.Contains(item)) - { - AddCalendarItemInternal(collection, item, false); - } - } - } - } - - private IEnumerable> GetProperCollectionsForCalendarItem(ICalendarItem calendarItem) - { - // All-day events go to all days. - // Multi-day events go to both. - // Anything else goes to regular. - - if (calendarItem.IsAllDayEvent) - { - return [_internalAllDayEvents]; - } - else if (calendarItem.IsMultiDayEvent) - { - return [_internalRegularEvents, _internalAllDayEvents]; - } - else - { - return [_internalRegularEvents]; - } - } - - public void AddCalendarItem(ICalendarItem calendarItem) - { - var collections = GetProperCollectionsForCalendarItem(calendarItem); - - foreach (var collection in collections) - { - AddCalendarItemInternal(collection, calendarItem); - } - } - - public void RemoveCalendarItem(ICalendarItem calendarItem) - { - var collections = GetProperCollectionsForCalendarItem(calendarItem); - - foreach (var collection in collections) - { - RemoveCalendarItemInternal(collection, calendarItem); - } - } - - private void AddCalendarItemInternal(ObservableRangeCollection collection, ICalendarItem calendarItem, bool create = true) - { - if (calendarItem is not ICalendarItemViewModel) - throw new ArgumentException("CalendarItem must be of type ICalendarItemViewModel", nameof(calendarItem)); - - collection.Add(calendarItem); - - if (create) - { - _allItems.Add(calendarItem); - } - - CalendarItemAdded?.Invoke(this, calendarItem); - } - - private void RemoveCalendarItemInternal(ObservableRangeCollection collection, ICalendarItem calendarItem, bool destroy = true) - { - if (calendarItem is not ICalendarItemViewModel) - throw new ArgumentException("CalendarItem must be of type ICalendarItemViewModel", nameof(calendarItem)); - - collection.Remove(calendarItem); - - if (destroy) - { - _allItems.Remove(calendarItem); - } - - CalendarItemRemoved?.Invoke(this, calendarItem); - } - - public void Clear() - { - _internalAllDayEvents.Clear(); - _internalRegularEvents.Clear(); - _allItems.Clear(); - - CalendarItemsCleared?.Invoke(this, EventArgs.Empty); - } + } + + public void FilterByCalendars(IEnumerable visibleCalendarIds) + { + foreach (var item in _allItems) + { + var collections = GetProperCollectionsForCalendarItem(item); + + foreach (var collection in collections) + { + if (!visibleCalendarIds.Contains(item.AssignedCalendar.Id) && collection.Contains(item)) + { + RemoveCalendarItemInternal(collection, item, false); + } + else if (visibleCalendarIds.Contains(item.AssignedCalendar.Id) && !collection.Contains(item)) + { + AddCalendarItemInternal(collection, item, false); + } + } + } + } + + private IEnumerable> GetProperCollectionsForCalendarItem(ICalendarItem calendarItem) + { + // All-day events go to all days. + // Multi-day events go to both. + // Anything else goes to regular. + + if (calendarItem.IsAllDayEvent) + { + return [_internalAllDayEvents]; + } + else if (calendarItem.IsMultiDayEvent) + { + return [_internalRegularEvents, _internalAllDayEvents]; + } + else + { + return [_internalRegularEvents]; + } + } + + public void AddCalendarItem(ICalendarItem calendarItem) + { + var collections = GetProperCollectionsForCalendarItem(calendarItem); + + foreach (var collection in collections) + { + AddCalendarItemInternal(collection, calendarItem); + } + } + + public void RemoveCalendarItem(ICalendarItem calendarItem) + { + var collections = GetProperCollectionsForCalendarItem(calendarItem); + + foreach (var collection in collections) + { + RemoveCalendarItemInternal(collection, calendarItem); + } + } + + private void AddCalendarItemInternal(ObservableRangeCollection collection, ICalendarItem calendarItem, bool create = true) + { + if (calendarItem is not ICalendarItemViewModel) + throw new ArgumentException("CalendarItem must be of type ICalendarItemViewModel", nameof(calendarItem)); + + collection.Add(calendarItem); + + if (create) + { + _allItems.Add(calendarItem); + } + + CalendarItemAdded?.Invoke(this, calendarItem); + } + + private void RemoveCalendarItemInternal(ObservableRangeCollection collection, ICalendarItem calendarItem, bool destroy = true) + { + if (calendarItem is not ICalendarItemViewModel) + throw new ArgumentException("CalendarItem must be of type ICalendarItemViewModel", nameof(calendarItem)); + + collection.Remove(calendarItem); + + if (destroy) + { + _allItems.Remove(calendarItem); + } + + CalendarItemRemoved?.Invoke(this, calendarItem); + } + + public void Clear() + { + _internalAllDayEvents.Clear(); + _internalRegularEvents.Clear(); + _allItems.Clear(); + + CalendarItemsCleared?.Invoke(this, EventArgs.Empty); } } diff --git a/Wino.Core.Domain/Collections/DayRangeCollection.cs b/Wino.Core.Domain/Collections/DayRangeCollection.cs index ec8dd5db..89afeb68 100644 --- a/Wino.Core.Domain/Collections/DayRangeCollection.cs +++ b/Wino.Core.Domain/Collections/DayRangeCollection.cs @@ -2,41 +2,40 @@ using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Calendar; -namespace Wino.Core.Domain.Collections +namespace Wino.Core.Domain.Collections; + +public class DayRangeCollection : ObservableRangeCollection { - public class DayRangeCollection : ObservableRangeCollection + /// + /// Gets the range of dates that are currently displayed in the collection. + /// + public DateRange DisplayRange { - /// - /// Gets the range of dates that are currently displayed in the collection. - /// - public DateRange DisplayRange + get { - get - { - if (Count == 0) return null; + if (Count == 0) return null; - var minimumLoadedDate = this[0].CalendarRenderOptions.DateRange.StartDate; - var maximumLoadedDate = this[Count - 1].CalendarRenderOptions.DateRange.EndDate; + var minimumLoadedDate = this[0].CalendarRenderOptions.DateRange.StartDate; + var maximumLoadedDate = this[Count - 1].CalendarRenderOptions.DateRange.EndDate; - return new DateRange(minimumLoadedDate, maximumLoadedDate); - } + return new DateRange(minimumLoadedDate, maximumLoadedDate); } + } - public void RemoveCalendarItem(ICalendarItem calendarItem) + public void RemoveCalendarItem(ICalendarItem calendarItem) + { + foreach (var dayRange in this) { - foreach (var dayRange in this) - { - } } + } - public void AddCalendarItem(ICalendarItem calendarItem) + public void AddCalendarItem(ICalendarItem calendarItem) + { + foreach (var dayRange in this) { - foreach (var dayRange in this) - { - var calendarDayModel = dayRange.CalendarDays.FirstOrDefault(x => x.Period.HasInside(calendarItem.Period.Start)); - calendarDayModel?.EventsCollection.AddCalendarItem(calendarItem); - } + var calendarDayModel = dayRange.CalendarDays.FirstOrDefault(x => x.Period.HasInside(calendarItem.Period.Start)); + calendarDayModel?.EventsCollection.AddCalendarItem(calendarItem); } } } diff --git a/Wino.Core.Domain/Collections/ObservableRangeCollection.cs b/Wino.Core.Domain/Collections/ObservableRangeCollection.cs index b3531c95..e1869554 100644 --- a/Wino.Core.Domain/Collections/ObservableRangeCollection.cs +++ b/Wino.Core.Domain/Collections/ObservableRangeCollection.cs @@ -4,171 +4,170 @@ using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; -namespace Wino.Core.Domain.Collections +namespace Wino.Core.Domain.Collections; + +/// +/// Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed. +/// +/// +public class ObservableRangeCollection : ObservableCollection { + /// - /// Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed. + /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class. /// - /// - public class ObservableRangeCollection : ObservableCollection + public ObservableRangeCollection() + : base() { + } - /// - /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class. - /// - public ObservableRangeCollection() - : base() + /// + /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class that contains elements copied from the specified collection. + /// + /// collection: The collection from which the elements are copied. + /// The collection parameter cannot be null. + public ObservableRangeCollection(IEnumerable collection) + : base(collection) + { + } + + /// + /// Adds the elements of the specified collection to the end of the ObservableCollection(Of T). + /// + public void AddRange(IEnumerable collection, NotifyCollectionChangedAction notificationMode = NotifyCollectionChangedAction.Add) + { + if (notificationMode != NotifyCollectionChangedAction.Add && notificationMode != NotifyCollectionChangedAction.Reset) + throw new ArgumentException("Mode must be either Add or Reset for AddRange.", nameof(notificationMode)); + if (collection == null) + throw new ArgumentNullException(nameof(collection)); + + CheckReentrancy(); + + var startIndex = Count; + + var itemsAdded = AddArrangeCore(collection); + + if (!itemsAdded) + return; + + if (notificationMode == NotifyCollectionChangedAction.Reset) { - } - - /// - /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class that contains elements copied from the specified collection. - /// - /// collection: The collection from which the elements are copied. - /// The collection parameter cannot be null. - public ObservableRangeCollection(IEnumerable collection) - : base(collection) - { - } - - /// - /// Adds the elements of the specified collection to the end of the ObservableCollection(Of T). - /// - public void AddRange(IEnumerable collection, NotifyCollectionChangedAction notificationMode = NotifyCollectionChangedAction.Add) - { - if (notificationMode != NotifyCollectionChangedAction.Add && notificationMode != NotifyCollectionChangedAction.Reset) - throw new ArgumentException("Mode must be either Add or Reset for AddRange.", nameof(notificationMode)); - if (collection == null) - throw new ArgumentNullException(nameof(collection)); - - CheckReentrancy(); - - var startIndex = Count; - - var itemsAdded = AddArrangeCore(collection); - - if (!itemsAdded) - return; - - if (notificationMode == NotifyCollectionChangedAction.Reset) - { - RaiseChangeNotificationEvents(action: NotifyCollectionChangedAction.Reset); - - return; - } - - var changedItems = collection is List ? (List)collection : new List(collection); - - RaiseChangeNotificationEvents( - action: NotifyCollectionChangedAction.Add, - changedItems: changedItems, - startingIndex: startIndex); - } - - /// - /// Removes the first occurence of each item in the specified collection from ObservableCollection(Of T). NOTE: with notificationMode = Remove, removed items starting index is not set because items are not guaranteed to be consecutive. - /// - public void RemoveRange(IEnumerable collection, NotifyCollectionChangedAction notificationMode = NotifyCollectionChangedAction.Reset) - { - if (notificationMode != NotifyCollectionChangedAction.Remove && notificationMode != NotifyCollectionChangedAction.Reset) - throw new ArgumentException("Mode must be either Remove or Reset for RemoveRange.", nameof(notificationMode)); - if (collection == null) - throw new ArgumentNullException(nameof(collection)); - - CheckReentrancy(); - - if (notificationMode == NotifyCollectionChangedAction.Reset) - { - var raiseEvents = false; - foreach (var item in collection) - { - Items.Remove(item); - raiseEvents = true; - } - - if (raiseEvents) - RaiseChangeNotificationEvents(action: NotifyCollectionChangedAction.Reset); - - return; - } - - var changedItems = new List(collection); - for (var i = 0; i < changedItems.Count; i++) - { - if (!Items.Remove(changedItems[i])) - { - changedItems.RemoveAt(i); //Can't use a foreach because changedItems is intended to be (carefully) modified - i--; - } - } - - if (changedItems.Count == 0) - return; - - RaiseChangeNotificationEvents( - action: NotifyCollectionChangedAction.Remove, - changedItems: changedItems); - } - - /// - /// Clears the current collection and replaces it with the specified item. - /// - public void Replace(T item) => ReplaceRange(new T[] { item }); - - /// - /// Clears the current collection and replaces it with the specified collection. - /// - public void ReplaceRange(IEnumerable collection) - { - if (collection == null) - throw new ArgumentNullException(nameof(collection)); - - CheckReentrancy(); - - var previouslyEmpty = Items.Count == 0; - - Items.Clear(); - - AddArrangeCore(collection); - - var currentlyEmpty = Items.Count == 0; - - if (previouslyEmpty && currentlyEmpty) - return; - RaiseChangeNotificationEvents(action: NotifyCollectionChangedAction.Reset); + + return; } - public void InsertRange(IEnumerable items) + var changedItems = collection is List ? (List)collection : new List(collection); + + RaiseChangeNotificationEvents( + action: NotifyCollectionChangedAction.Add, + changedItems: changedItems, + startingIndex: startIndex); + } + + /// + /// Removes the first occurence of each item in the specified collection from ObservableCollection(Of T). NOTE: with notificationMode = Remove, removed items starting index is not set because items are not guaranteed to be consecutive. + /// + public void RemoveRange(IEnumerable collection, NotifyCollectionChangedAction notificationMode = NotifyCollectionChangedAction.Reset) + { + if (notificationMode != NotifyCollectionChangedAction.Remove && notificationMode != NotifyCollectionChangedAction.Reset) + throw new ArgumentException("Mode must be either Remove or Reset for RemoveRange.", nameof(notificationMode)); + if (collection == null) + throw new ArgumentNullException(nameof(collection)); + + CheckReentrancy(); + + if (notificationMode == NotifyCollectionChangedAction.Reset) { - CheckReentrancy(); - - foreach (var item in items) - Items.Insert(0, item); - - OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); - } - - private bool AddArrangeCore(IEnumerable collection) - { - var itemAdded = false; + var raiseEvents = false; foreach (var item in collection) { - Items.Add(item); - itemAdded = true; + Items.Remove(item); + raiseEvents = true; } - return itemAdded; + + if (raiseEvents) + RaiseChangeNotificationEvents(action: NotifyCollectionChangedAction.Reset); + + return; } - private void RaiseChangeNotificationEvents(NotifyCollectionChangedAction action, List changedItems = null, int startingIndex = -1) + var changedItems = new List(collection); + for (var i = 0; i < changedItems.Count; i++) { - OnPropertyChanged(new PropertyChangedEventArgs(nameof(Count))); - OnPropertyChanged(new PropertyChangedEventArgs("Item[]")); - - if (changedItems is null) - OnCollectionChanged(new NotifyCollectionChangedEventArgs(action)); - else - OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, changedItems: changedItems, startingIndex: startingIndex)); + if (!Items.Remove(changedItems[i])) + { + changedItems.RemoveAt(i); //Can't use a foreach because changedItems is intended to be (carefully) modified + i--; + } } + + if (changedItems.Count == 0) + return; + + RaiseChangeNotificationEvents( + action: NotifyCollectionChangedAction.Remove, + changedItems: changedItems); + } + + /// + /// Clears the current collection and replaces it with the specified item. + /// + public void Replace(T item) => ReplaceRange(new T[] { item }); + + /// + /// Clears the current collection and replaces it with the specified collection. + /// + public void ReplaceRange(IEnumerable collection) + { + if (collection == null) + throw new ArgumentNullException(nameof(collection)); + + CheckReentrancy(); + + var previouslyEmpty = Items.Count == 0; + + Items.Clear(); + + AddArrangeCore(collection); + + var currentlyEmpty = Items.Count == 0; + + if (previouslyEmpty && currentlyEmpty) + return; + + RaiseChangeNotificationEvents(action: NotifyCollectionChangedAction.Reset); + } + + public void InsertRange(IEnumerable items) + { + CheckReentrancy(); + + foreach (var item in items) + Items.Insert(0, item); + + OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); + } + + private bool AddArrangeCore(IEnumerable collection) + { + var itemAdded = false; + foreach (var item in collection) + { + Items.Add(item); + itemAdded = true; + } + return itemAdded; + } + + private void RaiseChangeNotificationEvents(NotifyCollectionChangedAction action, List changedItems = null, int startingIndex = -1) + { + OnPropertyChanged(new PropertyChangedEventArgs(nameof(Count))); + OnPropertyChanged(new PropertyChangedEventArgs("Item[]")); + + if (changedItems is null) + OnCollectionChanged(new NotifyCollectionChangedEventArgs(action)); + else + OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, changedItems: changedItems, startingIndex: startingIndex)); } } diff --git a/Wino.Core.Domain/Constants.cs b/Wino.Core.Domain/Constants.cs index f0a3d111..0406edcd 100644 --- a/Wino.Core.Domain/Constants.cs +++ b/Wino.Core.Domain/Constants.cs @@ -1,23 +1,22 @@ -namespace Wino.Core.Domain +namespace Wino.Core.Domain; + +public static class Constants { - public static class Constants - { - /// - /// MIME header that exists in all the drafts created from Wino. - /// - public const string WinoLocalDraftHeader = "X-Wino-Draft-Id"; - public const string LocalDraftStartPrefix = "localDraft_"; + /// + /// MIME header that exists in all the drafts created from Wino. + /// + public const string WinoLocalDraftHeader = "X-Wino-Draft-Id"; + public const string LocalDraftStartPrefix = "localDraft_"; - public const string CalendarEventRecurrenceRuleSeperator = "___"; + public const string CalendarEventRecurrenceRuleSeperator = "___"; - public const string ToastMailUniqueIdKey = nameof(ToastMailUniqueIdKey); - public const string ToastActionKey = nameof(ToastActionKey); + public const string ToastMailUniqueIdKey = nameof(ToastMailUniqueIdKey); + public const string ToastActionKey = nameof(ToastActionKey); - public const string ClientLogFile = "Client_.log"; - public const string ServerLogFile = "Server_.log"; - public const string LogArchiveFileName = "WinoLogs.zip"; + public const string ClientLogFile = "Client_.log"; + public const string ServerLogFile = "Server_.log"; + public const string LogArchiveFileName = "WinoLogs.zip"; - public const string WinoMailIdentiifer = nameof(WinoMailIdentiifer); - public const string WinoCalendarIdentifier = nameof(WinoCalendarIdentifier); - } + public const string WinoMailIdentiifer = nameof(WinoMailIdentiifer); + public const string WinoCalendarIdentifier = nameof(WinoCalendarIdentifier); } diff --git a/Wino.Core.Domain/Entities/Calendar/AccountCalendar.cs b/Wino.Core.Domain/Entities/Calendar/AccountCalendar.cs index 8d7f6218..29a200cf 100644 --- a/Wino.Core.Domain/Entities/Calendar/AccountCalendar.cs +++ b/Wino.Core.Domain/Entities/Calendar/AccountCalendar.cs @@ -2,24 +2,23 @@ using SQLite; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.Domain.Entities.Calendar -{ - public class AccountCalendar : IAccountCalendar - { - [PrimaryKey] - public Guid Id { get; set; } - public Guid AccountId { get; set; } - public string RemoteCalendarId { get; set; } - public string SynchronizationDeltaToken { get; set; } - public string Name { get; set; } - public bool IsPrimary { get; set; } - public bool IsExtended { get; set; } = true; +namespace Wino.Core.Domain.Entities.Calendar; - /// - /// Unused for now. - /// - public string TextColorHex { get; set; } - public string BackgroundColorHex { get; set; } - public string TimeZone { get; set; } - } +public class AccountCalendar : IAccountCalendar +{ + [PrimaryKey] + public Guid Id { get; set; } + public Guid AccountId { get; set; } + public string RemoteCalendarId { get; set; } + public string SynchronizationDeltaToken { get; set; } + public string Name { get; set; } + public bool IsPrimary { get; set; } + public bool IsExtended { get; set; } = true; + + /// + /// Unused for now. + /// + public string TextColorHex { get; set; } + public string BackgroundColorHex { get; set; } + public string TimeZone { get; set; } } diff --git a/Wino.Core.Domain/Entities/Calendar/CalendarEventAttendee.cs b/Wino.Core.Domain/Entities/Calendar/CalendarEventAttendee.cs index 5fd07479..e9c47da3 100644 --- a/Wino.Core.Domain/Entities/Calendar/CalendarEventAttendee.cs +++ b/Wino.Core.Domain/Entities/Calendar/CalendarEventAttendee.cs @@ -2,19 +2,18 @@ using SQLite; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Entities.Calendar +namespace Wino.Core.Domain.Entities.Calendar; + +// TODO: Connect to Contact store with Wino People. +public class CalendarEventAttendee { - // TODO: Connect to Contact store with Wino People. - public class CalendarEventAttendee - { - [PrimaryKey] - public Guid Id { get; set; } - public Guid CalendarItemId { get; set; } - public string Name { get; set; } - public string Email { get; set; } - public AttendeeStatus AttendenceStatus { get; set; } - public bool IsOrganizer { get; set; } - public bool IsOptionalAttendee { get; set; } - public string Comment { get; set; } - } + [PrimaryKey] + public Guid Id { get; set; } + public Guid CalendarItemId { get; set; } + public string Name { get; set; } + public string Email { get; set; } + public AttendeeStatus AttendenceStatus { get; set; } + public bool IsOrganizer { get; set; } + public bool IsOptionalAttendee { get; set; } + public string Comment { get; set; } } diff --git a/Wino.Core.Domain/Entities/Calendar/CalendarItem.cs b/Wino.Core.Domain/Entities/Calendar/CalendarItem.cs index 022296f8..de03e74e 100644 --- a/Wino.Core.Domain/Entities/Calendar/CalendarItem.cs +++ b/Wino.Core.Domain/Entities/Calendar/CalendarItem.cs @@ -5,176 +5,175 @@ using SQLite; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.Domain.Entities.Calendar +namespace Wino.Core.Domain.Entities.Calendar; + +[DebuggerDisplay("{Title} ({StartDate} - {EndDate})")] +public class CalendarItem : ICalendarItem { - [DebuggerDisplay("{Title} ({StartDate} - {EndDate})")] - public class CalendarItem : ICalendarItem + [PrimaryKey] + public Guid Id { get; set; } + public string RemoteEventId { get; set; } + public string Title { get; set; } + public string Description { get; set; } + public string Location { get; set; } + + public DateTime StartDate { get; set; } + + public DateTime EndDate { - [PrimaryKey] - public Guid Id { get; set; } - public string RemoteEventId { get; set; } - public string Title { get; set; } - public string Description { get; set; } - public string Location { get; set; } - - public DateTime StartDate { get; set; } - - public DateTime EndDate + get { - get - { - return StartDate.AddSeconds(DurationInSeconds); - } - } - - public TimeSpan StartDateOffset { get; set; } - public TimeSpan EndDateOffset { get; set; } - - private ITimePeriod _period; - public ITimePeriod Period - { - get - { - _period ??= new TimeRange(StartDate, EndDate); - - return _period; - } - } - - /// - /// Events that starts at midnight and ends at midnight are considered all-day events. - /// - public bool IsAllDayEvent - { - get - { - return - StartDate.TimeOfDay == TimeSpan.Zero && - EndDate.TimeOfDay == TimeSpan.Zero; - } - } - - /// - /// Events that are either an exceptional instance of a recurring event or occurrences. - /// IsOccurrence is used to display occurrence instances of parent recurring events. - /// IsOccurrence == false && IsRecurringChild == true => exceptional single instance. - /// - public bool IsRecurringChild - { - get - { - return RecurringCalendarItemId != null; - } - } - - /// - /// Events that are either an exceptional instance of a recurring event or occurrences. - /// - public bool IsRecurringEvent => IsRecurringChild || IsRecurringParent; - - /// - /// Events that are the master event definition of recurrence events. - /// - public bool IsRecurringParent - { - get - { - return !string.IsNullOrEmpty(Recurrence) && RecurringCalendarItemId == null; - } - } - - /// - /// Events that are not all-day events and last more than one day are considered multi-day events. - /// - public bool IsMultiDayEvent - { - get - { - return Period.Duration.TotalDays >= 1 && !IsAllDayEvent; - } - } - - public double DurationInSeconds { get; set; } - public string Recurrence { get; set; } - - public string OrganizerDisplayName { get; set; } - public string OrganizerEmail { get; set; } - - /// - /// The id of the parent calendar item of the recurring event. - /// Exceptional instances are stored as a separate calendar item. - /// This makes the calendar item a child of the recurring event. - /// - public Guid? RecurringCalendarItemId { get; set; } - - /// - /// Indicates read-only events. Default is false. - /// - public bool IsLocked { get; set; } - - /// - /// Hidden events must not be displayed to the user. - /// This usually happens when a child instance of recurring parent is cancelled after creation. - /// - public bool IsHidden { get; set; } - - // TODO - public string CustomEventColorHex { get; set; } - public string HtmlLink { get; set; } - public CalendarItemStatus Status { get; set; } - public CalendarItemVisibility Visibility { get; set; } - public DateTimeOffset CreatedAt { get; set; } - public DateTimeOffset UpdatedAt { get; set; } - public Guid CalendarId { get; set; } - - [Ignore] - public IAccountCalendar AssignedCalendar { get; set; } - - /// - /// Whether this item does not really exist in the database or not. - /// These are used to display occurrence instances of parent recurring events. - /// - [Ignore] - public bool IsOccurrence { get; set; } - - /// - /// Id to load information related to this event. - /// Occurrences tracked by the parent recurring event if they are not exceptional instances. - /// Recurring children here are exceptional instances. They have their own info in the database including Id. - /// - public Guid EventTrackingId => IsOccurrence ? RecurringCalendarItemId.Value : Id; - - public CalendarItem CreateRecurrence(DateTime startDate, double durationInSeconds) - { - // Create a copy with the new start date and duration - - return new CalendarItem - { - Id = Guid.NewGuid(), - Title = Title, - Description = Description, - Location = Location, - StartDate = startDate, - DurationInSeconds = durationInSeconds, - Recurrence = Recurrence, - OrganizerDisplayName = OrganizerDisplayName, - OrganizerEmail = OrganizerEmail, - RecurringCalendarItemId = Id, - AssignedCalendar = AssignedCalendar, - CalendarId = CalendarId, - CreatedAt = CreatedAt, - UpdatedAt = UpdatedAt, - Visibility = Visibility, - Status = Status, - CustomEventColorHex = CustomEventColorHex, - HtmlLink = HtmlLink, - StartDateOffset = StartDateOffset, - EndDateOffset = EndDateOffset, - RemoteEventId = RemoteEventId, - IsHidden = IsHidden, - IsLocked = IsLocked, - IsOccurrence = true - }; + return StartDate.AddSeconds(DurationInSeconds); } } + + public TimeSpan StartDateOffset { get; set; } + public TimeSpan EndDateOffset { get; set; } + + private ITimePeriod _period; + public ITimePeriod Period + { + get + { + _period ??= new TimeRange(StartDate, EndDate); + + return _period; + } + } + + /// + /// Events that starts at midnight and ends at midnight are considered all-day events. + /// + public bool IsAllDayEvent + { + get + { + return + StartDate.TimeOfDay == TimeSpan.Zero && + EndDate.TimeOfDay == TimeSpan.Zero; + } + } + + /// + /// Events that are either an exceptional instance of a recurring event or occurrences. + /// IsOccurrence is used to display occurrence instances of parent recurring events. + /// IsOccurrence == false && IsRecurringChild == true => exceptional single instance. + /// + public bool IsRecurringChild + { + get + { + return RecurringCalendarItemId != null; + } + } + + /// + /// Events that are either an exceptional instance of a recurring event or occurrences. + /// + public bool IsRecurringEvent => IsRecurringChild || IsRecurringParent; + + /// + /// Events that are the master event definition of recurrence events. + /// + public bool IsRecurringParent + { + get + { + return !string.IsNullOrEmpty(Recurrence) && RecurringCalendarItemId == null; + } + } + + /// + /// Events that are not all-day events and last more than one day are considered multi-day events. + /// + public bool IsMultiDayEvent + { + get + { + return Period.Duration.TotalDays >= 1 && !IsAllDayEvent; + } + } + + public double DurationInSeconds { get; set; } + public string Recurrence { get; set; } + + public string OrganizerDisplayName { get; set; } + public string OrganizerEmail { get; set; } + + /// + /// The id of the parent calendar item of the recurring event. + /// Exceptional instances are stored as a separate calendar item. + /// This makes the calendar item a child of the recurring event. + /// + public Guid? RecurringCalendarItemId { get; set; } + + /// + /// Indicates read-only events. Default is false. + /// + public bool IsLocked { get; set; } + + /// + /// Hidden events must not be displayed to the user. + /// This usually happens when a child instance of recurring parent is cancelled after creation. + /// + public bool IsHidden { get; set; } + + // TODO + public string CustomEventColorHex { get; set; } + public string HtmlLink { get; set; } + public CalendarItemStatus Status { get; set; } + public CalendarItemVisibility Visibility { get; set; } + public DateTimeOffset CreatedAt { get; set; } + public DateTimeOffset UpdatedAt { get; set; } + public Guid CalendarId { get; set; } + + [Ignore] + public IAccountCalendar AssignedCalendar { get; set; } + + /// + /// Whether this item does not really exist in the database or not. + /// These are used to display occurrence instances of parent recurring events. + /// + [Ignore] + public bool IsOccurrence { get; set; } + + /// + /// Id to load information related to this event. + /// Occurrences tracked by the parent recurring event if they are not exceptional instances. + /// Recurring children here are exceptional instances. They have their own info in the database including Id. + /// + public Guid EventTrackingId => IsOccurrence ? RecurringCalendarItemId.Value : Id; + + public CalendarItem CreateRecurrence(DateTime startDate, double durationInSeconds) + { + // Create a copy with the new start date and duration + + return new CalendarItem + { + Id = Guid.NewGuid(), + Title = Title, + Description = Description, + Location = Location, + StartDate = startDate, + DurationInSeconds = durationInSeconds, + Recurrence = Recurrence, + OrganizerDisplayName = OrganizerDisplayName, + OrganizerEmail = OrganizerEmail, + RecurringCalendarItemId = Id, + AssignedCalendar = AssignedCalendar, + CalendarId = CalendarId, + CreatedAt = CreatedAt, + UpdatedAt = UpdatedAt, + Visibility = Visibility, + Status = Status, + CustomEventColorHex = CustomEventColorHex, + HtmlLink = HtmlLink, + StartDateOffset = StartDateOffset, + EndDateOffset = EndDateOffset, + RemoteEventId = RemoteEventId, + IsHidden = IsHidden, + IsLocked = IsLocked, + IsOccurrence = true + }; + } } diff --git a/Wino.Core.Domain/Entities/Calendar/Reminder.cs b/Wino.Core.Domain/Entities/Calendar/Reminder.cs index 64c3b65c..3dc64b81 100644 --- a/Wino.Core.Domain/Entities/Calendar/Reminder.cs +++ b/Wino.Core.Domain/Entities/Calendar/Reminder.cs @@ -2,15 +2,14 @@ using SQLite; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Entities.Calendar -{ - public class Reminder - { - [PrimaryKey] - public Guid Id { get; set; } - public Guid CalendarItemId { get; set; } +namespace Wino.Core.Domain.Entities.Calendar; - public DateTimeOffset ReminderTime { get; set; } - public CalendarItemReminderType ReminderType { get; set; } - } +public class Reminder +{ + [PrimaryKey] + public Guid Id { get; set; } + public Guid CalendarItemId { get; set; } + + public DateTimeOffset ReminderTime { get; set; } + public CalendarItemReminderType ReminderType { get; set; } } diff --git a/Wino.Core.Domain/Entities/Mail/AccountSignature.cs b/Wino.Core.Domain/Entities/Mail/AccountSignature.cs index fa867d7e..fb1066b6 100644 --- a/Wino.Core.Domain/Entities/Mail/AccountSignature.cs +++ b/Wino.Core.Domain/Entities/Mail/AccountSignature.cs @@ -1,17 +1,16 @@ using System; using SQLite; -namespace Wino.Core.Domain.Entities.Mail +namespace Wino.Core.Domain.Entities.Mail; + +public class AccountSignature { - public class AccountSignature - { - [PrimaryKey] - public Guid Id { get; set; } + [PrimaryKey] + public Guid Id { get; set; } - public string Name { get; set; } + public string Name { get; set; } - public string HtmlBody { get; set; } + public string HtmlBody { get; set; } - public Guid MailAccountId { get; set; } - } + public Guid MailAccountId { get; set; } } diff --git a/Wino.Core.Domain/Entities/Mail/MailAccountAlias.cs b/Wino.Core.Domain/Entities/Mail/MailAccountAlias.cs index 0860ecf6..f13dd5ef 100644 --- a/Wino.Core.Domain/Entities/Mail/MailAccountAlias.cs +++ b/Wino.Core.Domain/Entities/Mail/MailAccountAlias.cs @@ -1,63 +1,62 @@ using System; using SQLite; -namespace Wino.Core.Domain.Entities.Mail +namespace Wino.Core.Domain.Entities.Mail; + +public class RemoteAccountAlias { - public class RemoteAccountAlias - { - /// - /// Display address of the alias. - /// - public string AliasAddress { get; set; } + /// + /// Display address of the alias. + /// + public string AliasAddress { get; set; } - /// - /// Address to be included in Reply-To header when alias is used for sending messages. - /// - public string ReplyToAddress { get; set; } + /// + /// Address to be included in Reply-To header when alias is used for sending messages. + /// + public string ReplyToAddress { get; set; } - /// - /// Whether this alias is the primary alias for the account. - /// - public bool IsPrimary { get; set; } + /// + /// Whether this alias is the primary alias for the account. + /// + public bool IsPrimary { get; set; } - /// - /// Whether the alias is verified by the server. - /// Only Gmail aliases are verified for now. - /// Non-verified alias messages might be rejected by SMTP server. - /// - public bool IsVerified { get; set; } + /// + /// Whether the alias is verified by the server. + /// Only Gmail aliases are verified for now. + /// Non-verified alias messages might be rejected by SMTP server. + /// + public bool IsVerified { get; set; } - /// - /// Whether this alias is the root alias for the account. - /// Root alias means the first alias that was created for the account. - /// It can't be deleted or changed. - /// - public bool IsRootAlias { get; set; } + /// + /// Whether this alias is the root alias for the account. + /// Root alias means the first alias that was created for the account. + /// It can't be deleted or changed. + /// + public bool IsRootAlias { get; set; } - /// - /// Optional sender name for the alias. - /// Falls back to account's sender name if not set when preparing messages. - /// Used for Gmail only. - /// - public string AliasSenderName { get; set; } - } - - public class MailAccountAlias : RemoteAccountAlias - { - /// - /// Unique Id for the alias. - /// - [PrimaryKey] - public Guid Id { get; set; } - - /// - /// Account id that this alias is attached to. - /// - public Guid AccountId { get; set; } - - /// - /// Root aliases can't be deleted. - /// - public bool CanDelete => !IsRootAlias; - } + /// + /// Optional sender name for the alias. + /// Falls back to account's sender name if not set when preparing messages. + /// Used for Gmail only. + /// + public string AliasSenderName { get; set; } +} + +public class MailAccountAlias : RemoteAccountAlias +{ + /// + /// Unique Id for the alias. + /// + [PrimaryKey] + public Guid Id { get; set; } + + /// + /// Account id that this alias is attached to. + /// + public Guid AccountId { get; set; } + + /// + /// Root aliases can't be deleted. + /// + public bool CanDelete => !IsRootAlias; } diff --git a/Wino.Core.Domain/Entities/Mail/MailCopy.cs b/Wino.Core.Domain/Entities/Mail/MailCopy.cs index b0b9d208..b3c1049d 100644 --- a/Wino.Core.Domain/Entities/Mail/MailCopy.cs +++ b/Wino.Core.Domain/Entities/Mail/MailCopy.cs @@ -5,153 +5,152 @@ using Wino.Core.Domain.Entities.Shared; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.MailItem; -namespace Wino.Core.Domain.Entities.Mail +namespace Wino.Core.Domain.Entities.Mail; + +/// +/// Summary of the parsed MIME messages. +/// Wino will do non-network operations on this table and others from the original MIME. +/// +public class MailCopy : IMailItem { /// - /// Summary of the parsed MIME messages. - /// Wino will do non-network operations on this table and others from the original MIME. + /// Unique Id of the mail. /// - public class MailCopy : IMailItem - { - /// - /// Unique Id of the mail. - /// - [PrimaryKey] - public Guid UniqueId { get; set; } + [PrimaryKey] + public Guid UniqueId { get; set; } - /// - /// Not unique id of the item. Some operations held on this Id, some on the UniqueId. - /// Same message can be in different folder. In that case UniqueId is used. - /// - public string Id { get; set; } + /// + /// Not unique id of the item. Some operations held on this Id, some on the UniqueId. + /// Same message can be in different folder. In that case UniqueId is used. + /// + public string Id { get; set; } - /// - /// Folder that this mail belongs to. - /// - public Guid FolderId { get; set; } + /// + /// Folder that this mail belongs to. + /// + public Guid FolderId { get; set; } - /// - /// Conversation id for the mail. - /// - public string ThreadId { get; set; } + /// + /// Conversation id for the mail. + /// + public string ThreadId { get; set; } - /// - /// MIME MessageId if exists. - /// - public string MessageId { get; set; } + /// + /// MIME MessageId if exists. + /// + public string MessageId { get; set; } - /// - /// References header from MIME - /// - public string References { get; set; } + /// + /// References header from MIME + /// + public string References { get; set; } - /// - /// In-Reply-To header from MIME - /// - public string InReplyTo { get; set; } + /// + /// In-Reply-To header from MIME + /// + public string InReplyTo { get; set; } - /// - /// Name for the sender. - /// - public string FromName { get; set; } + /// + /// Name for the sender. + /// + public string FromName { get; set; } - /// - /// Address of the sender. - /// - public string FromAddress { get; set; } + /// + /// Address of the sender. + /// + public string FromAddress { get; set; } - /// - /// Subject of the mail. - /// - public string Subject { get; set; } + /// + /// Subject of the mail. + /// + public string Subject { get; set; } - /// - /// Short preview of the content. - /// - public string PreviewText { get; set; } + /// + /// Short preview of the content. + /// + public string PreviewText { get; set; } - /// - /// Date that represents this mail has been created in provider servers. - /// Stored always in UTC. - /// - public DateTime CreationDate { get; set; } + /// + /// Date that represents this mail has been created in provider servers. + /// Stored always in UTC. + /// + public DateTime CreationDate { get; set; } - /// - /// Importance of the mail. - /// - public MailImportance Importance { get; set; } + /// + /// Importance of the mail. + /// + public MailImportance Importance { get; set; } - /// - /// Read status for the mail. - /// - public bool IsRead { get; set; } + /// + /// Read status for the mail. + /// + public bool IsRead { get; set; } - /// - /// Flag status. - /// Flagged for Outlook. - /// Important for Gmail. - /// - public bool IsFlagged { get; set; } + /// + /// Flag status. + /// Flagged for Outlook. + /// Important for Gmail. + /// + public bool IsFlagged { get; set; } - /// - /// To support Outlook. - /// Gmail doesn't use it. - /// - public bool IsFocused { get; set; } + /// + /// To support Outlook. + /// Gmail doesn't use it. + /// + public bool IsFocused { get; set; } - /// - /// Whether mail has attachments included or not. - /// - public bool HasAttachments { get; set; } + /// + /// Whether mail has attachments included or not. + /// + public bool HasAttachments { get; set; } - /// - /// Assigned draft id. - /// - public string DraftId { get; set; } + /// + /// Assigned draft id. + /// + public string DraftId { get; set; } - /// - /// Whether this mail is only created locally. - /// - [Ignore] - public bool IsLocalDraft => !string.IsNullOrEmpty(DraftId) && DraftId.StartsWith(Constants.LocalDraftStartPrefix); + /// + /// Whether this mail is only created locally. + /// + [Ignore] + public bool IsLocalDraft => !string.IsNullOrEmpty(DraftId) && DraftId.StartsWith(Constants.LocalDraftStartPrefix); - /// - /// Whether this copy is draft or not. - /// - public bool IsDraft { get; set; } + /// + /// Whether this copy is draft or not. + /// + public bool IsDraft { get; set; } - /// - /// File id that this mail is assigned to. - /// This Id is immutable. It's used to find the file in the file system. - /// Even after mapping local draft to remote draft, it will not change. - /// - public Guid FileId { get; set; } + /// + /// File id that this mail is assigned to. + /// This Id is immutable. It's used to find the file in the file system. + /// Even after mapping local draft to remote draft, it will not change. + /// + public Guid FileId { get; set; } - /// - /// Folder that this mail is assigned to. - /// Warning: This field is not populated by queries. - /// Services or View Models are responsible for populating this field. - /// - [Ignore] - public MailItemFolder AssignedFolder { get; set; } + /// + /// Folder that this mail is assigned to. + /// Warning: This field is not populated by queries. + /// Services or View Models are responsible for populating this field. + /// + [Ignore] + public MailItemFolder AssignedFolder { get; set; } - /// - /// Account that this mail is assigned to. - /// Warning: This field is not populated by queries. - /// Services or View Models are responsible for populating this field. - /// - [Ignore] - public MailAccount AssignedAccount { get; set; } + /// + /// Account that this mail is assigned to. + /// Warning: This field is not populated by queries. + /// Services or View Models are responsible for populating this field. + /// + [Ignore] + public MailAccount AssignedAccount { get; set; } - /// - /// Contact information of the sender if exists. - /// Warning: This field is not populated by queries. - /// Services or View Models are responsible for populating this field. - /// - [Ignore] - public AccountContact SenderContact { get; set; } + /// + /// Contact information of the sender if exists. + /// Warning: This field is not populated by queries. + /// Services or View Models are responsible for populating this field. + /// + [Ignore] + public AccountContact SenderContact { get; set; } - public IEnumerable GetContainingIds() => [UniqueId]; - public override string ToString() => $"{Subject} <-> {Id}"; - } + public IEnumerable GetContainingIds() => [UniqueId]; + public override string ToString() => $"{Subject} <-> {Id}"; } diff --git a/Wino.Core.Domain/Entities/Mail/MailItemFolder.cs b/Wino.Core.Domain/Entities/Mail/MailItemFolder.cs index 62e13796..bb1a2cae 100644 --- a/Wino.Core.Domain/Entities/Mail/MailItemFolder.cs +++ b/Wino.Core.Domain/Entities/Mail/MailItemFolder.cs @@ -5,71 +5,70 @@ using SQLite; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.Folders; -namespace Wino.Core.Domain.Entities.Mail +namespace Wino.Core.Domain.Entities.Mail; + +[DebuggerDisplay("{FolderName} - {SpecialFolderType}")] +public class MailItemFolder : IMailItemFolder { - [DebuggerDisplay("{FolderName} - {SpecialFolderType}")] - public class MailItemFolder : IMailItemFolder + [PrimaryKey] + public Guid Id { get; set; } + + public string RemoteFolderId { get; set; } + public string ParentRemoteFolderId { get; set; } + + public Guid MailAccountId { get; set; } + public string FolderName { get; set; } + public SpecialFolderType SpecialFolderType { get; set; } + public bool IsSystemFolder { get; set; } + public bool IsSticky { get; set; } + public bool IsSynchronizationEnabled { get; set; } + public bool IsHidden { get; set; } + public bool ShowUnreadCount { get; set; } + public DateTime? LastSynchronizedDate { get; set; } + + // For IMAP + public uint UidValidity { get; set; } + public long HighestModeSeq { get; set; } + + /// + /// Outlook shares delta changes per-folder. Gmail is for per-account. + /// This is only used for Outlook provider. + /// + public string DeltaToken { get; set; } + + // For GMail Labels + public string TextColorHex { get; set; } + public string BackgroundColorHex { get; set; } + + [Ignore] + public List ChildFolders { get; set; } = []; + + // Category and Move type folders are not valid move targets. + // These folders are virtual. They don't exist on the server. + public bool IsMoveTarget => !(SpecialFolderType == SpecialFolderType.More || SpecialFolderType == SpecialFolderType.Category); + + public bool ContainsSpecialFolderType(SpecialFolderType type) { - [PrimaryKey] - public Guid Id { get; set; } + if (SpecialFolderType == type) + return true; - public string RemoteFolderId { get; set; } - public string ParentRemoteFolderId { get; set; } - - public Guid MailAccountId { get; set; } - public string FolderName { get; set; } - public SpecialFolderType SpecialFolderType { get; set; } - public bool IsSystemFolder { get; set; } - public bool IsSticky { get; set; } - public bool IsSynchronizationEnabled { get; set; } - public bool IsHidden { get; set; } - public bool ShowUnreadCount { get; set; } - public DateTime? LastSynchronizedDate { get; set; } - - // For IMAP - public uint UidValidity { get; set; } - public long HighestModeSeq { get; set; } - - /// - /// Outlook shares delta changes per-folder. Gmail is for per-account. - /// This is only used for Outlook provider. - /// - public string DeltaToken { get; set; } - - // For GMail Labels - public string TextColorHex { get; set; } - public string BackgroundColorHex { get; set; } - - [Ignore] - public List ChildFolders { get; set; } = []; - - // Category and Move type folders are not valid move targets. - // These folders are virtual. They don't exist on the server. - public bool IsMoveTarget => !(SpecialFolderType == SpecialFolderType.More || SpecialFolderType == SpecialFolderType.Category); - - public bool ContainsSpecialFolderType(SpecialFolderType type) + foreach (var child in ChildFolders) { - if (SpecialFolderType == type) - return true; - - foreach (var child in ChildFolders) + if (child.SpecialFolderType == type) { - if (child.SpecialFolderType == type) - { - return true; - } - else - { - return child.ContainsSpecialFolderType(type); - } + return true; + } + else + { + return child.ContainsSpecialFolderType(type); } - - return false; } - public static MailItemFolder CreateMoreFolder() => new MailItemFolder() { IsSticky = true, SpecialFolderType = SpecialFolderType.More, FolderName = Translator.MoreFolderNameOverride }; - public static MailItemFolder CreateCategoriesFolder() => new MailItemFolder() { IsSticky = true, SpecialFolderType = SpecialFolderType.Category, FolderName = Translator.CategoriesFolderNameOverride }; - - public override string ToString() => FolderName; + return false; } + + public static MailItemFolder CreateMoreFolder() => new MailItemFolder() { IsSticky = true, SpecialFolderType = SpecialFolderType.More, FolderName = Translator.MoreFolderNameOverride }; + public static MailItemFolder CreateCategoriesFolder() => new MailItemFolder() { IsSticky = true, SpecialFolderType = SpecialFolderType.Category, FolderName = Translator.CategoriesFolderNameOverride }; + + public override string ToString() => FolderName; } diff --git a/Wino.Core.Domain/Entities/Mail/MergedInbox.cs b/Wino.Core.Domain/Entities/Mail/MergedInbox.cs index f0811c96..446a6b55 100644 --- a/Wino.Core.Domain/Entities/Mail/MergedInbox.cs +++ b/Wino.Core.Domain/Entities/Mail/MergedInbox.cs @@ -1,13 +1,12 @@ using System; using SQLite; -namespace Wino.Core.Domain.Entities.Mail -{ - public class MergedInbox - { - [PrimaryKey] - public Guid Id { get; set; } +namespace Wino.Core.Domain.Entities.Mail; - public string Name { get; set; } - } +public class MergedInbox +{ + [PrimaryKey] + public Guid Id { get; set; } + + public string Name { get; set; } } diff --git a/Wino.Core.Domain/Entities/Shared/AccountContact.cs b/Wino.Core.Domain/Entities/Shared/AccountContact.cs index 6679ca2f..9b2eae37 100644 --- a/Wino.Core.Domain/Entities/Shared/AccountContact.cs +++ b/Wino.Core.Domain/Entities/Shared/AccountContact.cs @@ -2,76 +2,75 @@ using System.Collections.Generic; using SQLite; -namespace Wino.Core.Domain.Entities.Shared +namespace Wino.Core.Domain.Entities.Shared; + +/// +/// Back storage for simple name-address book. +/// These values will be inserted during MIME fetch. +/// + +// TODO: This can easily evolve to Contact store, just like People app in Windows 10/11. +// Do it. +public class AccountContact : IEquatable { /// - /// Back storage for simple name-address book. - /// These values will be inserted during MIME fetch. + /// E-mail address of the contact. /// + [PrimaryKey] + public string Address { get; set; } - // TODO: This can easily evolve to Contact store, just like People app in Windows 10/11. - // Do it. - public class AccountContact : IEquatable + /// + /// Display name of the contact. + /// + public string Name { get; set; } + + /// + /// Base64 encoded profile image of the contact. + /// + public string Base64ContactPicture { get; set; } + + /// + /// All registered accounts have their contacts registered as root. + /// Root contacts must not be overridden by any configuration. + /// They are created on account creation. + /// + public bool IsRootContact { get; set; } + + /// + /// Short display name of the contact. + /// Eather Name or Address. + /// + public string ShortDisplayName => Address == Name || string.IsNullOrWhiteSpace(Name) ? $"{Address.ToLowerInvariant()};" : $"{Name};"; + + public string DisplayName => Address == Name || string.IsNullOrWhiteSpace(Name) ? Address.ToLowerInvariant() : $"{Name} <{Address.ToLowerInvariant()}>"; + + public override bool Equals(object obj) { - /// - /// E-mail address of the contact. - /// - [PrimaryKey] - public string Address { get; set; } + return Equals(obj as AccountContact); + } - /// - /// Display name of the contact. - /// - public string Name { get; set; } + public bool Equals(AccountContact other) + { + return other is not null && + Address == other.Address && + Name == other.Name; + } - /// - /// Base64 encoded profile image of the contact. - /// - public string Base64ContactPicture { get; set; } + public override int GetHashCode() + { + int hashCode = -1717786383; + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(Address); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(Name); + return hashCode; + } - /// - /// All registered accounts have their contacts registered as root. - /// Root contacts must not be overridden by any configuration. - /// They are created on account creation. - /// - public bool IsRootContact { get; set; } + public static bool operator ==(AccountContact left, AccountContact right) + { + return EqualityComparer.Default.Equals(left, right); + } - /// - /// Short display name of the contact. - /// Eather Name or Address. - /// - public string ShortDisplayName => Address == Name || string.IsNullOrWhiteSpace(Name) ? $"{Address.ToLowerInvariant()};" : $"{Name};"; - - public string DisplayName => Address == Name || string.IsNullOrWhiteSpace(Name) ? Address.ToLowerInvariant() : $"{Name} <{Address.ToLowerInvariant()}>"; - - public override bool Equals(object obj) - { - return Equals(obj as AccountContact); - } - - public bool Equals(AccountContact other) - { - return other is not null && - Address == other.Address && - Name == other.Name; - } - - public override int GetHashCode() - { - int hashCode = -1717786383; - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(Address); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(Name); - return hashCode; - } - - public static bool operator ==(AccountContact left, AccountContact right) - { - return EqualityComparer.Default.Equals(left, right); - } - - public static bool operator !=(AccountContact left, AccountContact right) - { - return !(left == right); - } + public static bool operator !=(AccountContact left, AccountContact right) + { + return !(left == right); } } diff --git a/Wino.Core.Domain/Entities/Shared/CustomServerInformation.cs b/Wino.Core.Domain/Entities/Shared/CustomServerInformation.cs index 630a79c7..164027c7 100644 --- a/Wino.Core.Domain/Entities/Shared/CustomServerInformation.cs +++ b/Wino.Core.Domain/Entities/Shared/CustomServerInformation.cs @@ -2,52 +2,51 @@ using SQLite; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Entities.Shared +namespace Wino.Core.Domain.Entities.Shared; + +public class CustomServerInformation { - public class CustomServerInformation - { - [PrimaryKey] - public Guid Id { get; set; } + [PrimaryKey] + public Guid Id { get; set; } - public Guid AccountId { get; set; } + public Guid AccountId { get; set; } - /// - /// This field is ignored. DisplayName is stored in MailAccount as SenderName from now. - /// - [Ignore] - public string DisplayName { get; set; } - public string Address { get; set; } - public string IncomingServer { get; set; } - public string IncomingServerUsername { get; set; } - public string IncomingServerPassword { get; set; } - public string IncomingServerPort { get; set; } + /// + /// This field is ignored. DisplayName is stored in MailAccount as SenderName from now. + /// + [Ignore] + public string DisplayName { get; set; } + public string Address { get; set; } + public string IncomingServer { get; set; } + public string IncomingServerUsername { get; set; } + public string IncomingServerPassword { get; set; } + public string IncomingServerPort { get; set; } - public CustomIncomingServerType IncomingServerType { get; set; } + public CustomIncomingServerType IncomingServerType { get; set; } - public string OutgoingServer { get; set; } - public string OutgoingServerPort { get; set; } - public string OutgoingServerUsername { get; set; } - public string OutgoingServerPassword { get; set; } + public string OutgoingServer { get; set; } + public string OutgoingServerPort { get; set; } + public string OutgoingServerUsername { get; set; } + public string OutgoingServerPassword { get; set; } - /// - /// useSSL True: SslOnConnect - /// useSSL False: StartTlsWhenAvailable - /// + /// + /// useSSL True: SslOnConnect + /// useSSL False: StartTlsWhenAvailable + /// - public ImapConnectionSecurity IncomingServerSocketOption { get; set; } - public ImapAuthenticationMethod IncomingAuthenticationMethod { get; set; } + public ImapConnectionSecurity IncomingServerSocketOption { get; set; } + public ImapAuthenticationMethod IncomingAuthenticationMethod { get; set; } - public ImapConnectionSecurity OutgoingServerSocketOption { get; set; } - public ImapAuthenticationMethod OutgoingAuthenticationMethod { get; set; } + public ImapConnectionSecurity OutgoingServerSocketOption { get; set; } + public ImapAuthenticationMethod OutgoingAuthenticationMethod { get; set; } - public string ProxyServer { get; set; } - public string ProxyServerPort { get; set; } + public string ProxyServer { get; set; } + public string ProxyServerPort { get; set; } - /// - /// Number of concurrent clients that can connect to the server. - /// Default is 5. - /// - public int MaxConcurrentClients { get; set; } - } + /// + /// Number of concurrent clients that can connect to the server. + /// Default is 5. + /// + public int MaxConcurrentClients { get; set; } } diff --git a/Wino.Core.Domain/Entities/Shared/MailAccount.cs b/Wino.Core.Domain/Entities/Shared/MailAccount.cs index 20c2a304..8f40f70d 100644 --- a/Wino.Core.Domain/Entities/Shared/MailAccount.cs +++ b/Wino.Core.Domain/Entities/Shared/MailAccount.cs @@ -3,109 +3,108 @@ using SQLite; using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Entities.Shared +namespace Wino.Core.Domain.Entities.Shared; + +public class MailAccount { - public class MailAccount - { - [PrimaryKey] - public Guid Id { get; set; } + [PrimaryKey] + public Guid Id { get; set; } - /// - /// Given name of the account in Wino. - /// - public string Name { get; set; } + /// + /// Given name of the account in Wino. + /// + public string Name { get; set; } - /// - /// TODO: Display name of the authenticated user/account. - /// API integrations will query this value from the API. - /// IMAP is populated by user on setup dialog. - /// + /// + /// TODO: Display name of the authenticated user/account. + /// API integrations will query this value from the API. + /// IMAP is populated by user on setup dialog. + /// - public string SenderName { get; set; } + public string SenderName { get; set; } - /// - /// Account e-mail address. - /// - public string Address { get; set; } + /// + /// Account e-mail address. + /// + public string Address { get; set; } - /// - /// Provider type of the account. Outlook,Gmail etc... - /// - public MailProviderType ProviderType { get; set; } + /// + /// Provider type of the account. Outlook,Gmail etc... + /// + public MailProviderType ProviderType { get; set; } - /// - /// For tracking mail change delta. - /// Gmail : historyId - /// Outlook: deltaToken - /// - public string SynchronizationDeltaIdentifier { get; set; } + /// + /// For tracking mail change delta. + /// Gmail : historyId + /// Outlook: deltaToken + /// + public string SynchronizationDeltaIdentifier { get; set; } - /// - /// For tracking calendar change delta. - /// Gmail: It's per-calendar, so unused. - /// Outlook: deltaLink - /// - public string CalendarSynchronizationDeltaIdentifier { get; set; } + /// + /// For tracking calendar change delta. + /// Gmail: It's per-calendar, so unused. + /// Outlook: deltaLink + /// + public string CalendarSynchronizationDeltaIdentifier { get; set; } - /// - /// TODO: Gets or sets the custom account identifier color in hex. - /// - public string AccountColorHex { get; set; } + /// + /// TODO: Gets or sets the custom account identifier color in hex. + /// + public string AccountColorHex { get; set; } - /// - /// Base64 encoded profile picture of the account. - /// - public string Base64ProfilePictureData { get; set; } + /// + /// Base64 encoded profile picture of the account. + /// + public string Base64ProfilePictureData { get; set; } - /// - /// Gets or sets the listing order of the account in the accounts list. - /// - public int Order { get; set; } + /// + /// Gets or sets the listing order of the account in the accounts list. + /// + public int Order { get; set; } - /// - /// Gets or sets whether the account has any reason for an interactive user action to fix continue operating. - /// - public AccountAttentionReason AttentionReason { get; set; } + /// + /// Gets or sets whether the account has any reason for an interactive user action to fix continue operating. + /// + public AccountAttentionReason AttentionReason { get; set; } - /// - /// Gets or sets the id of the merged inbox this account belongs to. - /// - public Guid? MergedInboxId { get; set; } + /// + /// Gets or sets the id of the merged inbox this account belongs to. + /// + public Guid? MergedInboxId { get; set; } - /// - /// Gets or sets the additional IMAP provider assignment for the account. - /// Providers that use IMAP as a synchronizer but have special requirements. - /// - public SpecialImapProvider SpecialImapProvider { get; set; } + /// + /// Gets or sets the additional IMAP provider assignment for the account. + /// Providers that use IMAP as a synchronizer but have special requirements. + /// + public SpecialImapProvider SpecialImapProvider { get; set; } - /// - /// Contains the merged inbox this account belongs to. - /// Ignored for all SQLite operations. - /// - [Ignore] - public MergedInbox MergedInbox { get; set; } + /// + /// Contains the merged inbox this account belongs to. + /// Ignored for all SQLite operations. + /// + [Ignore] + public MergedInbox MergedInbox { get; set; } - /// - /// Populated only when account has custom server information. - /// + /// + /// Populated only when account has custom server information. + /// - [Ignore] - public CustomServerInformation ServerInformation { get; set; } + [Ignore] + public CustomServerInformation ServerInformation { get; set; } - /// - /// Account preferences. - /// - [Ignore] - public MailAccountPreferences Preferences { get; set; } + /// + /// Account preferences. + /// + [Ignore] + public MailAccountPreferences Preferences { get; set; } - /// - /// Gets whether the account can perform ProfileInformation sync type. - /// - public bool IsProfileInfoSyncSupported => ProviderType == MailProviderType.Outlook || ProviderType == MailProviderType.Gmail; + /// + /// Gets whether the account can perform ProfileInformation sync type. + /// + public bool IsProfileInfoSyncSupported => ProviderType == MailProviderType.Outlook || ProviderType == MailProviderType.Gmail; - /// - /// Gets whether the account can perform AliasInformation sync type. - /// - public bool IsAliasSyncSupported => ProviderType == MailProviderType.Gmail; - } + /// + /// Gets whether the account can perform AliasInformation sync type. + /// + public bool IsAliasSyncSupported => ProviderType == MailProviderType.Gmail; } diff --git a/Wino.Core.Domain/Entities/Shared/MailAccountPreferences.cs b/Wino.Core.Domain/Entities/Shared/MailAccountPreferences.cs index 92e97aab..4330db83 100644 --- a/Wino.Core.Domain/Entities/Shared/MailAccountPreferences.cs +++ b/Wino.Core.Domain/Entities/Shared/MailAccountPreferences.cs @@ -1,54 +1,53 @@ using System; using SQLite; -namespace Wino.Core.Domain.Entities.Shared +namespace Wino.Core.Domain.Entities.Shared; + +public class MailAccountPreferences { - public class MailAccountPreferences - { - [PrimaryKey] - public Guid Id { get; set; } + [PrimaryKey] + public Guid Id { get; set; } - /// - /// Id of the account in MailAccount table. - /// - public Guid AccountId { get; set; } + /// + /// Id of the account in MailAccount table. + /// + public Guid AccountId { get; set; } - /// - /// Gets or sets whether sent draft messages should be appended to the sent folder. - /// Some IMAP servers do this automatically, some don't. - /// It's disabled by default. - /// - public bool ShouldAppendMessagesToSentFolder { get; set; } + /// + /// Gets or sets whether sent draft messages should be appended to the sent folder. + /// Some IMAP servers do this automatically, some don't. + /// It's disabled by default. + /// + public bool ShouldAppendMessagesToSentFolder { get; set; } - /// - /// Gets or sets whether the notifications are enabled for the account. - /// - public bool IsNotificationsEnabled { get; set; } + /// + /// Gets or sets whether the notifications are enabled for the account. + /// + public bool IsNotificationsEnabled { get; set; } - /// - /// Gets or sets whether the account has Focused inbox support. - /// Null if the account provider type doesn't support Focused inbox. - /// - public bool? IsFocusedInboxEnabled { get; set; } + /// + /// Gets or sets whether the account has Focused inbox support. + /// Null if the account provider type doesn't support Focused inbox. + /// + public bool? IsFocusedInboxEnabled { get; set; } - /// - /// Gets or sets whether signature should be appended automatically. - /// - public bool IsSignatureEnabled { get; set; } + /// + /// Gets or sets whether signature should be appended automatically. + /// + public bool IsSignatureEnabled { get; set; } - /// - /// Gets or sets whether this account's unread items should be included in taskbar badge. - /// - public bool IsTaskbarBadgeEnabled { get; set; } = true; + /// + /// Gets or sets whether this account's unread items should be included in taskbar badge. + /// + public bool IsTaskbarBadgeEnabled { get; set; } = true; - /// - /// Gets or sets signature for new messages. Null if signature is not needed. - /// - public Guid? SignatureIdForNewMessages { get; set; } + /// + /// Gets or sets signature for new messages. Null if signature is not needed. + /// + public Guid? SignatureIdForNewMessages { get; set; } - /// - /// Gets or sets signature for following messages. Null if signature is not needed. - /// - public Guid? SignatureIdForFollowingMessages { get; set; } - } + /// + /// Gets or sets signature for following messages. Null if signature is not needed. + /// + public Guid? SignatureIdForFollowingMessages { get; set; } } diff --git a/Wino.Core.Domain/Enums/AccountAttentionReason.cs b/Wino.Core.Domain/Enums/AccountAttentionReason.cs index b192e74f..61e157b0 100644 --- a/Wino.Core.Domain/Enums/AccountAttentionReason.cs +++ b/Wino.Core.Domain/Enums/AccountAttentionReason.cs @@ -1,9 +1,8 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum AccountAttentionReason { - public enum AccountAttentionReason - { - None, - InvalidCredentials, - MissingSystemFolderConfiguration - } + None, + InvalidCredentials, + MissingSystemFolderConfiguration } diff --git a/Wino.Core.Domain/Enums/AccountCreationDialogState.cs b/Wino.Core.Domain/Enums/AccountCreationDialogState.cs index 17393e26..0cc10546 100644 --- a/Wino.Core.Domain/Enums/AccountCreationDialogState.cs +++ b/Wino.Core.Domain/Enums/AccountCreationDialogState.cs @@ -1,17 +1,16 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum AccountCreationDialogState { - public enum AccountCreationDialogState - { - Idle, - SigningIn, - PreparingFolders, - Completed, - ManuelSetupWaiting, - TestingConnection, - AutoDiscoverySetup, - AutoDiscoveryInProgress, - FetchingProfileInformation, - Canceled, - FetchingEvents - } + Idle, + SigningIn, + PreparingFolders, + Completed, + ManuelSetupWaiting, + TestingConnection, + AutoDiscoverySetup, + AutoDiscoveryInProgress, + FetchingProfileInformation, + Canceled, + FetchingEvents } diff --git a/Wino.Core.Domain/Enums/AccountSynchronizerState.cs b/Wino.Core.Domain/Enums/AccountSynchronizerState.cs index 9a9e0810..6f3f22e8 100644 --- a/Wino.Core.Domain/Enums/AccountSynchronizerState.cs +++ b/Wino.Core.Domain/Enums/AccountSynchronizerState.cs @@ -1,12 +1,11 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +/// +/// Indicates the state of synchronizer. +/// +public enum AccountSynchronizerState { - /// - /// Indicates the state of synchronizer. - /// - public enum AccountSynchronizerState - { - Idle, - ExecutingRequests, - Synchronizing - } + Idle, + ExecutingRequests, + Synchronizing } diff --git a/Wino.Core.Domain/Enums/AppLanguage.cs b/Wino.Core.Domain/Enums/AppLanguage.cs index 004fad36..9a73afb2 100644 --- a/Wino.Core.Domain/Enums/AppLanguage.cs +++ b/Wino.Core.Domain/Enums/AppLanguage.cs @@ -1,21 +1,20 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum AppLanguage { - public enum AppLanguage - { - None, - English, - Deutsch, - Russian, - Turkish, - Polish, - Czech, - Chinese, - Spanish, - French, - Indonesian, - Greek, - PortugeseBrazil, - Italian, - Romanian - } + None, + English, + Deutsch, + Russian, + Turkish, + Polish, + Czech, + Chinese, + Spanish, + French, + Indonesian, + Greek, + PortugeseBrazil, + Italian, + Romanian } diff --git a/Wino.Core.Domain/Enums/AppThemeType.cs b/Wino.Core.Domain/Enums/AppThemeType.cs index 138f499b..c6e25b79 100644 --- a/Wino.Core.Domain/Enums/AppThemeType.cs +++ b/Wino.Core.Domain/Enums/AppThemeType.cs @@ -1,9 +1,8 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum AppThemeType { - public enum AppThemeType - { - System, - PreDefined, - Custom, - } + System, + PreDefined, + Custom, } diff --git a/Wino.Core.Domain/Enums/ApplicationElementTheme.cs b/Wino.Core.Domain/Enums/ApplicationElementTheme.cs index 6c3e0bca..24da4411 100644 --- a/Wino.Core.Domain/Enums/ApplicationElementTheme.cs +++ b/Wino.Core.Domain/Enums/ApplicationElementTheme.cs @@ -1,9 +1,8 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum ApplicationElementTheme { - public enum ApplicationElementTheme - { - Default, - Light, - Dark - } + Default, + Light, + Dark } diff --git a/Wino.Core.Domain/Enums/AttendeeStatus.cs b/Wino.Core.Domain/Enums/AttendeeStatus.cs index 57203f30..06bd5a02 100644 --- a/Wino.Core.Domain/Enums/AttendeeStatus.cs +++ b/Wino.Core.Domain/Enums/AttendeeStatus.cs @@ -1,10 +1,9 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum AttendeeStatus { - public enum AttendeeStatus - { - NeedsAction, - Accepted, - Tentative, - Declined - } + NeedsAction, + Accepted, + Tentative, + Declined } diff --git a/Wino.Core.Domain/Enums/BackgroundSynchronizationReason.cs b/Wino.Core.Domain/Enums/BackgroundSynchronizationReason.cs index eac0a746..1bd8060c 100644 --- a/Wino.Core.Domain/Enums/BackgroundSynchronizationReason.cs +++ b/Wino.Core.Domain/Enums/BackgroundSynchronizationReason.cs @@ -1,8 +1,7 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum BackgroundSynchronizationReason { - public enum BackgroundSynchronizationReason - { - SessionConnected, - Timer - } + SessionConnected, + Timer } diff --git a/Wino.Core.Domain/Enums/CalendarDisplayType.cs b/Wino.Core.Domain/Enums/CalendarDisplayType.cs index d4b4c2b8..5582899b 100644 --- a/Wino.Core.Domain/Enums/CalendarDisplayType.cs +++ b/Wino.Core.Domain/Enums/CalendarDisplayType.cs @@ -1,11 +1,10 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum CalendarDisplayType { - public enum CalendarDisplayType - { - Day, - Week, - WorkWeek, - Month, - Year - } + Day, + Week, + WorkWeek, + Month, + Year } diff --git a/Wino.Core.Domain/Enums/CalendarEventTargetType.cs b/Wino.Core.Domain/Enums/CalendarEventTargetType.cs index ef42f74f..96d2893e 100644 --- a/Wino.Core.Domain/Enums/CalendarEventTargetType.cs +++ b/Wino.Core.Domain/Enums/CalendarEventTargetType.cs @@ -1,8 +1,7 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum CalendarEventTargetType { - public enum CalendarEventTargetType - { - Single, // Show details for a single event. - Series // Show the series event. Parent of all recurring events. - } + Single, // Show details for a single event. + Series // Show the series event. Parent of all recurring events. } diff --git a/Wino.Core.Domain/Enums/CalendarInitInitiative.cs b/Wino.Core.Domain/Enums/CalendarInitInitiative.cs index d9a0c880..d5e08a76 100644 --- a/Wino.Core.Domain/Enums/CalendarInitInitiative.cs +++ b/Wino.Core.Domain/Enums/CalendarInitInitiative.cs @@ -1,11 +1,10 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +/// +/// Trigger to load more data. +/// +public enum CalendarInitInitiative { - /// - /// Trigger to load more data. - /// - public enum CalendarInitInitiative - { - User, - App - } + User, + App } diff --git a/Wino.Core.Domain/Enums/CalendarItemRecurrenceFrequency.cs b/Wino.Core.Domain/Enums/CalendarItemRecurrenceFrequency.cs index 00c6053b..d4288648 100644 --- a/Wino.Core.Domain/Enums/CalendarItemRecurrenceFrequency.cs +++ b/Wino.Core.Domain/Enums/CalendarItemRecurrenceFrequency.cs @@ -1,10 +1,9 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum CalendarItemRecurrenceFrequency { - public enum CalendarItemRecurrenceFrequency - { - Daily, - Weekly, - Monthly, - Yearly - } + Daily, + Weekly, + Monthly, + Yearly } diff --git a/Wino.Core.Domain/Enums/CalendarItemReminderType.cs b/Wino.Core.Domain/Enums/CalendarItemReminderType.cs index 669a06c6..38bec546 100644 --- a/Wino.Core.Domain/Enums/CalendarItemReminderType.cs +++ b/Wino.Core.Domain/Enums/CalendarItemReminderType.cs @@ -1,8 +1,7 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum CalendarItemReminderType { - public enum CalendarItemReminderType - { - Popup, - Email - } + Popup, + Email } diff --git a/Wino.Core.Domain/Enums/CalendarItemStatus.cs b/Wino.Core.Domain/Enums/CalendarItemStatus.cs index ac4ce6e8..e8605573 100644 --- a/Wino.Core.Domain/Enums/CalendarItemStatus.cs +++ b/Wino.Core.Domain/Enums/CalendarItemStatus.cs @@ -1,10 +1,9 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum CalendarItemStatus { - public enum CalendarItemStatus - { - NotResponded, - Confirmed, - Tentative, - Cancelled, - } + NotResponded, + Confirmed, + Tentative, + Cancelled, } diff --git a/Wino.Core.Domain/Enums/CalendarItemVisibility.cs b/Wino.Core.Domain/Enums/CalendarItemVisibility.cs index 5fc3143e..b6804893 100644 --- a/Wino.Core.Domain/Enums/CalendarItemVisibility.cs +++ b/Wino.Core.Domain/Enums/CalendarItemVisibility.cs @@ -1,10 +1,9 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum CalendarItemVisibility { - public enum CalendarItemVisibility - { - Default, - Public, - Private, - Confidential - } + Default, + Public, + Private, + Confidential } diff --git a/Wino.Core.Domain/Enums/CalendarLoadDirection.cs b/Wino.Core.Domain/Enums/CalendarLoadDirection.cs index b9dbea40..763b25c2 100644 --- a/Wino.Core.Domain/Enums/CalendarLoadDirection.cs +++ b/Wino.Core.Domain/Enums/CalendarLoadDirection.cs @@ -1,12 +1,11 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +/// +/// Which way in time to load more data for calendar. +/// +public enum CalendarLoadDirection { - /// - /// Which way in time to load more data for calendar. - /// - public enum CalendarLoadDirection - { - Replace, - Previous, - Next - } + Replace, + Previous, + Next } diff --git a/Wino.Core.Domain/Enums/CalendarOrientation.cs b/Wino.Core.Domain/Enums/CalendarOrientation.cs index 67bd7b0c..d1f7717f 100644 --- a/Wino.Core.Domain/Enums/CalendarOrientation.cs +++ b/Wino.Core.Domain/Enums/CalendarOrientation.cs @@ -1,8 +1,7 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum CalendarOrientation { - public enum CalendarOrientation - { - Horizontal, - Vertical - } + Horizontal, + Vertical } diff --git a/Wino.Core.Domain/Enums/CalendarSynchronizationType.cs b/Wino.Core.Domain/Enums/CalendarSynchronizationType.cs index 9b19472b..d9f01a19 100644 --- a/Wino.Core.Domain/Enums/CalendarSynchronizationType.cs +++ b/Wino.Core.Domain/Enums/CalendarSynchronizationType.cs @@ -1,11 +1,10 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum CalendarSynchronizationType { - public enum CalendarSynchronizationType - { - ExecuteRequests, // Execute all requests in the queue. - CalendarMetadata, // Sync calendar metadata. - CalendarEvents, // Sync all events for all calendars. - SingleCalendar, // Sync events for only specified calendars. - UpdateProfile // Update profile information only. - } + ExecuteRequests, // Execute all requests in the queue. + CalendarMetadata, // Sync calendar metadata. + CalendarEvents, // Sync all events for all calendars. + SingleCalendar, // Sync events for only specified calendars. + UpdateProfile // Update profile information only. } diff --git a/Wino.Core.Domain/Enums/ChangeRequestType.cs b/Wino.Core.Domain/Enums/ChangeRequestType.cs index d0af1669..99ede7be 100644 --- a/Wino.Core.Domain/Enums/ChangeRequestType.cs +++ b/Wino.Core.Domain/Enums/ChangeRequestType.cs @@ -1,24 +1,23 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum ChangeRequestType { - public enum ChangeRequestType - { - MailMarkAs, - MailChangeFlag, - MailHardDelete, - MailMove, - MailAlwaysMoveTo, - MailChangeFocused, - MailArchive, - MailUnarchive, - FolderMarkAsRead, - FolderDelete, - FolderEmpty, - FolderRename, - CreateNewDraft, - CreateReplyDraft, - CreateForwardDraft, - DiscardDraft, - SendDraft, - FetchSingleItem - } + MailMarkAs, + MailChangeFlag, + MailHardDelete, + MailMove, + MailAlwaysMoveTo, + MailChangeFocused, + MailArchive, + MailUnarchive, + FolderMarkAsRead, + FolderDelete, + FolderEmpty, + FolderRename, + CreateNewDraft, + CreateReplyDraft, + CreateForwardDraft, + DiscardDraft, + SendDraft, + FetchSingleItem } diff --git a/Wino.Core.Domain/Enums/CustomIncomingServerType.cs b/Wino.Core.Domain/Enums/CustomIncomingServerType.cs index 40312e4a..9890751a 100644 --- a/Wino.Core.Domain/Enums/CustomIncomingServerType.cs +++ b/Wino.Core.Domain/Enums/CustomIncomingServerType.cs @@ -1,8 +1,7 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum CustomIncomingServerType { - public enum CustomIncomingServerType - { - POP3, - IMAP4 - } + POP3, + IMAP4 } diff --git a/Wino.Core.Domain/Enums/DayHeaderDisplayType.cs b/Wino.Core.Domain/Enums/DayHeaderDisplayType.cs index 5a3b96fd..e67067f3 100644 --- a/Wino.Core.Domain/Enums/DayHeaderDisplayType.cs +++ b/Wino.Core.Domain/Enums/DayHeaderDisplayType.cs @@ -1,8 +1,7 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum DayHeaderDisplayType { - public enum DayHeaderDisplayType - { - TwelveHour, - TwentyFourHour, - } + TwelveHour, + TwentyFourHour, } diff --git a/Wino.Core.Domain/Enums/DraftCreationReason.cs b/Wino.Core.Domain/Enums/DraftCreationReason.cs index e988c03a..b62e1e2f 100644 --- a/Wino.Core.Domain/Enums/DraftCreationReason.cs +++ b/Wino.Core.Domain/Enums/DraftCreationReason.cs @@ -1,10 +1,9 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum DraftCreationReason { - public enum DraftCreationReason - { - Empty, - Reply, - ReplyAll, - Forward - } + Empty, + Reply, + ReplyAll, + Forward } diff --git a/Wino.Core.Domain/Enums/FilterOptionType.cs b/Wino.Core.Domain/Enums/FilterOptionType.cs index 02bf14ff..6f9fce91 100644 --- a/Wino.Core.Domain/Enums/FilterOptionType.cs +++ b/Wino.Core.Domain/Enums/FilterOptionType.cs @@ -1,11 +1,10 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum FilterOptionType { - public enum FilterOptionType - { - All, - Unread, - Flagged, - Mentions, - Files - } + All, + Unread, + Flagged, + Mentions, + Files } diff --git a/Wino.Core.Domain/Enums/FolderOperation.cs b/Wino.Core.Domain/Enums/FolderOperation.cs index 2d33144f..b863c0dd 100644 --- a/Wino.Core.Domain/Enums/FolderOperation.cs +++ b/Wino.Core.Domain/Enums/FolderOperation.cs @@ -1,23 +1,22 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +/// +/// Defines all possible folder operations that can be done. +/// Available values for each folder is returned by IContextMenuProvider +/// that integrators hold. +/// +public enum FolderOperation { - /// - /// Defines all possible folder operations that can be done. - /// Available values for each folder is returned by IContextMenuProvider - /// that integrators hold. - /// - public enum FolderOperation - { - None, - Pin, - Unpin, - MarkAllAsRead, - DontSync, - Empty, - Rename, - Delete, - Move, - TurnOffNotifications, - CreateSubFolder, - Seperator - } + None, + Pin, + Unpin, + MarkAllAsRead, + DontSync, + Empty, + Rename, + Delete, + Move, + TurnOffNotifications, + CreateSubFolder, + Seperator } diff --git a/Wino.Core.Domain/Enums/ImapAuthenticationMethod.cs b/Wino.Core.Domain/Enums/ImapAuthenticationMethod.cs index 4390f247..b1922640 100644 --- a/Wino.Core.Domain/Enums/ImapAuthenticationMethod.cs +++ b/Wino.Core.Domain/Enums/ImapAuthenticationMethod.cs @@ -1,13 +1,12 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum ImapAuthenticationMethod { - public enum ImapAuthenticationMethod - { - Auto, - None, - NormalPassword, - EncryptedPassword, - Ntlm, - CramMd5, - DigestMd5 - } + Auto, + None, + NormalPassword, + EncryptedPassword, + Ntlm, + CramMd5, + DigestMd5 } diff --git a/Wino.Core.Domain/Enums/ImapConnectionSecurity.cs b/Wino.Core.Domain/Enums/ImapConnectionSecurity.cs index 9a3e6e7b..e624bca1 100644 --- a/Wino.Core.Domain/Enums/ImapConnectionSecurity.cs +++ b/Wino.Core.Domain/Enums/ImapConnectionSecurity.cs @@ -1,10 +1,9 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum ImapConnectionSecurity { - public enum ImapConnectionSecurity - { - Auto, - None, - StartTls, - SslTls - } + Auto, + None, + StartTls, + SslTls } diff --git a/Wino.Core.Domain/Enums/InfoBarAnimationType.cs b/Wino.Core.Domain/Enums/InfoBarAnimationType.cs index 488b667b..6728a194 100644 --- a/Wino.Core.Domain/Enums/InfoBarAnimationType.cs +++ b/Wino.Core.Domain/Enums/InfoBarAnimationType.cs @@ -1,8 +1,7 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum InfoBarAnimationType { - public enum InfoBarAnimationType - { - SlideFromRightToLeft, - SlideFromBottomToTop - } + SlideFromRightToLeft, + SlideFromBottomToTop } diff --git a/Wino.Core.Domain/Enums/InfoBarMessageType.cs b/Wino.Core.Domain/Enums/InfoBarMessageType.cs index 15df6dcf..3bcfed06 100644 --- a/Wino.Core.Domain/Enums/InfoBarMessageType.cs +++ b/Wino.Core.Domain/Enums/InfoBarMessageType.cs @@ -1,10 +1,9 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum InfoBarMessageType { - public enum InfoBarMessageType - { - Information, - Success, - Warning, - Error - } + Information, + Success, + Warning, + Error } diff --git a/Wino.Core.Domain/Enums/MailAttachmentType.cs b/Wino.Core.Domain/Enums/MailAttachmentType.cs index b444b4c5..4459a893 100644 --- a/Wino.Core.Domain/Enums/MailAttachmentType.cs +++ b/Wino.Core.Domain/Enums/MailAttachmentType.cs @@ -1,16 +1,15 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum MailAttachmentType { - public enum MailAttachmentType - { - None, - Executable, - Image, - Audio, - Video, - PDF, - HTML, - RarArchive, - Archive, - Other - } + None, + Executable, + Image, + Audio, + Video, + PDF, + HTML, + RarArchive, + Archive, + Other } diff --git a/Wino.Core.Domain/Enums/MailImportance.cs b/Wino.Core.Domain/Enums/MailImportance.cs index 22f2a6ab..0c4ff9fa 100644 --- a/Wino.Core.Domain/Enums/MailImportance.cs +++ b/Wino.Core.Domain/Enums/MailImportance.cs @@ -1,9 +1,8 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum MailImportance { - public enum MailImportance - { - Low, - Normal, - High - } + Low, + Normal, + High } diff --git a/Wino.Core.Domain/Enums/MailListDisplayMode.cs b/Wino.Core.Domain/Enums/MailListDisplayMode.cs index d27278e7..c1d04584 100644 --- a/Wino.Core.Domain/Enums/MailListDisplayMode.cs +++ b/Wino.Core.Domain/Enums/MailListDisplayMode.cs @@ -1,9 +1,8 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum MailListDisplayMode { - public enum MailListDisplayMode - { - Spacious, - Medium, - Compact, - } + Spacious, + Medium, + Compact, } diff --git a/Wino.Core.Domain/Enums/MailMarkAsOption.cs b/Wino.Core.Domain/Enums/MailMarkAsOption.cs index e08ce803..fe335b5e 100644 --- a/Wino.Core.Domain/Enums/MailMarkAsOption.cs +++ b/Wino.Core.Domain/Enums/MailMarkAsOption.cs @@ -1,9 +1,8 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum MailMarkAsOption { - public enum MailMarkAsOption - { - WhenSelected, - DontMark, - AfterDelay - } + WhenSelected, + DontMark, + AfterDelay } diff --git a/Wino.Core.Domain/Enums/MailOperation.cs b/Wino.Core.Domain/Enums/MailOperation.cs index 445e6e4f..973ff62f 100644 --- a/Wino.Core.Domain/Enums/MailOperation.cs +++ b/Wino.Core.Domain/Enums/MailOperation.cs @@ -1,58 +1,57 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +// Synchronizer requests. +public enum MailSynchronizerOperation { - // Synchronizer requests. - public enum MailSynchronizerOperation - { - MarkRead, - Move, - Delete, // Hard delete. - CreateDraft, - Send, - ChangeFlag, - AlwaysMoveTo, - MoveToFocused, - Archive, - } - - public enum FolderSynchronizerOperation - { - RenameFolder, - EmptyFolder, - MarkFolderRead, - } - - // UI requests - public enum MailOperation - { - None, - Archive, - UnArchive, - SoftDelete, - HardDelete, - Move, - MoveToJunk, - MoveToFocused, - MoveToOther, - AlwaysMoveToOther, - AlwaysMoveToFocused, - SetFlag, - ClearFlag, - MarkAsRead, - MarkAsUnread, - MarkAsNotJunk, - Seperator, - Ignore, - Reply, - ReplyAll, - Zoom, - SaveAs, - Find, - Forward, - DarkEditor, - LightEditor, - Print, - ViewMessageSource, - DiscardLocalDraft, - Navigate // For toast activation - } + MarkRead, + Move, + Delete, // Hard delete. + CreateDraft, + Send, + ChangeFlag, + AlwaysMoveTo, + MoveToFocused, + Archive, +} + +public enum FolderSynchronizerOperation +{ + RenameFolder, + EmptyFolder, + MarkFolderRead, +} + +// UI requests +public enum MailOperation +{ + None, + Archive, + UnArchive, + SoftDelete, + HardDelete, + Move, + MoveToJunk, + MoveToFocused, + MoveToOther, + AlwaysMoveToOther, + AlwaysMoveToFocused, + SetFlag, + ClearFlag, + MarkAsRead, + MarkAsUnread, + MarkAsNotJunk, + Seperator, + Ignore, + Reply, + ReplyAll, + Zoom, + SaveAs, + Find, + Forward, + DarkEditor, + LightEditor, + Print, + ViewMessageSource, + DiscardLocalDraft, + Navigate // For toast activation } diff --git a/Wino.Core.Domain/Enums/MailProviderType.cs b/Wino.Core.Domain/Enums/MailProviderType.cs index 1ff81b96..42b6626d 100644 --- a/Wino.Core.Domain/Enums/MailProviderType.cs +++ b/Wino.Core.Domain/Enums/MailProviderType.cs @@ -1,9 +1,8 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum MailProviderType { - public enum MailProviderType - { - Outlook, - Gmail, - IMAP4 = 4 // 2-3 were removed after release. Don't change for backward compatibility. - } + Outlook, + Gmail, + IMAP4 = 4 // 2-3 were removed after release. Don't change for backward compatibility. } diff --git a/Wino.Core.Domain/Enums/MailSynchronizationType.cs b/Wino.Core.Domain/Enums/MailSynchronizationType.cs index e7dfe826..650c2a59 100644 --- a/Wino.Core.Domain/Enums/MailSynchronizationType.cs +++ b/Wino.Core.Domain/Enums/MailSynchronizationType.cs @@ -1,14 +1,13 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum MailSynchronizationType { - public enum MailSynchronizationType - { - UpdateProfile, // Only update profile information - ExecuteRequests, // Run the queued requests, and then synchronize if needed. - FoldersOnly, // Only synchronize folder metadata. - InboxOnly, // Only Inbox, Sent, Draft and Deleted folders. - CustomFolders, // Only sync folders that are specified in the options. - FullFolders, // Synchronize all folders. This won't update profile or alias information. - Alias, // Only update alias information - IMAPIdle // Idle client triggered synchronization. - } + UpdateProfile, // Only update profile information + ExecuteRequests, // Run the queued requests, and then synchronize if needed. + FoldersOnly, // Only synchronize folder metadata. + InboxOnly, // Only Inbox, Sent, Draft and Deleted folders. + CustomFolders, // Only sync folders that are specified in the options. + FullFolders, // Synchronize all folders. This won't update profile or alias information. + Alias, // Only update alias information + IMAPIdle // Idle client triggered synchronization. } diff --git a/Wino.Core.Domain/Enums/NavigationReferenceFrame.cs b/Wino.Core.Domain/Enums/NavigationReferenceFrame.cs index 1d116fdb..3495a98e 100644 --- a/Wino.Core.Domain/Enums/NavigationReferenceFrame.cs +++ b/Wino.Core.Domain/Enums/NavigationReferenceFrame.cs @@ -1,8 +1,7 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum NavigationReferenceFrame { - public enum NavigationReferenceFrame - { - ShellFrame, - RenderingFrame - } + ShellFrame, + RenderingFrame } diff --git a/Wino.Core.Domain/Enums/PickFolderReason.cs b/Wino.Core.Domain/Enums/PickFolderReason.cs index 99067066..52df0139 100644 --- a/Wino.Core.Domain/Enums/PickFolderReason.cs +++ b/Wino.Core.Domain/Enums/PickFolderReason.cs @@ -1,12 +1,11 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +/// +/// Defines the potential reasons for picking folder in the folder picking dialog. +/// +public enum PickFolderReason { - /// - /// Defines the potential reasons for picking folder in the folder picking dialog. - /// - public enum PickFolderReason - { - Move, - SpecialFolder, - Any - } + Move, + SpecialFolder, + Any } diff --git a/Wino.Core.Domain/Enums/PrintingResult.cs b/Wino.Core.Domain/Enums/PrintingResult.cs index 64ab8564..2967b80f 100644 --- a/Wino.Core.Domain/Enums/PrintingResult.cs +++ b/Wino.Core.Domain/Enums/PrintingResult.cs @@ -1,10 +1,9 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum PrintingResult { - public enum PrintingResult - { - Abandoned, - Canceled, - Failed, - Submitted - } + Abandoned, + Canceled, + Failed, + Submitted } diff --git a/Wino.Core.Domain/Enums/ServerBackgroundMode.cs b/Wino.Core.Domain/Enums/ServerBackgroundMode.cs index 835a4776..d7f9e5df 100644 --- a/Wino.Core.Domain/Enums/ServerBackgroundMode.cs +++ b/Wino.Core.Domain/Enums/ServerBackgroundMode.cs @@ -1,12 +1,11 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +/// +/// What should happen to server app when the client is terminated. +/// +public enum ServerBackgroundMode { - /// - /// What should happen to server app when the client is terminated. - /// - public enum ServerBackgroundMode - { - MinimizedTray, // Still runs, tray icon is visible. - Invisible, // Still runs, tray icon is invisible. - Terminate // Server is terminated as Wino terminates. - } + MinimizedTray, // Still runs, tray icon is visible. + Invisible, // Still runs, tray icon is invisible. + Terminate // Server is terminated as Wino terminates. } diff --git a/Wino.Core.Domain/Enums/SortingOptionType.cs b/Wino.Core.Domain/Enums/SortingOptionType.cs index 4a88d2fd..f259fcf9 100644 --- a/Wino.Core.Domain/Enums/SortingOptionType.cs +++ b/Wino.Core.Domain/Enums/SortingOptionType.cs @@ -1,8 +1,7 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum SortingOptionType { - public enum SortingOptionType - { - ReceiveDate, - Sender - } + ReceiveDate, + Sender } diff --git a/Wino.Core.Domain/Enums/SpecialFolderType.cs b/Wino.Core.Domain/Enums/SpecialFolderType.cs index b26ae4c3..e85463f1 100644 --- a/Wino.Core.Domain/Enums/SpecialFolderType.cs +++ b/Wino.Core.Domain/Enums/SpecialFolderType.cs @@ -1,24 +1,23 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum SpecialFolderType { - public enum SpecialFolderType - { - Inbox, - Starred, - Important, - Sent, - Draft, - Archive, - Deleted, - Junk, - Chat, - Category, - Unread, - Forums, - Updates, - Personal, - Promotions, - Social, - Other, - More - } + Inbox, + Starred, + Important, + Sent, + Draft, + Archive, + Deleted, + Junk, + Chat, + Category, + Unread, + Forums, + Updates, + Personal, + Promotions, + Social, + Other, + More } diff --git a/Wino.Core.Domain/Enums/SpecialImapProvider.cs b/Wino.Core.Domain/Enums/SpecialImapProvider.cs index 27254a86..18d182bf 100644 --- a/Wino.Core.Domain/Enums/SpecialImapProvider.cs +++ b/Wino.Core.Domain/Enums/SpecialImapProvider.cs @@ -1,9 +1,8 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum SpecialImapProvider { - public enum SpecialImapProvider - { - None, - iCloud, - Yahoo - } + None, + iCloud, + Yahoo } diff --git a/Wino.Core.Domain/Enums/StartupBehaviorResult.cs b/Wino.Core.Domain/Enums/StartupBehaviorResult.cs index 912f0ecc..b33a9e1b 100644 --- a/Wino.Core.Domain/Enums/StartupBehaviorResult.cs +++ b/Wino.Core.Domain/Enums/StartupBehaviorResult.cs @@ -1,11 +1,10 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum StartupBehaviorResult { - public enum StartupBehaviorResult - { - Enabled, - Disabled, - DisabledByUser, - DisabledByPolicy, - Fatal - } + Enabled, + Disabled, + DisabledByUser, + DisabledByPolicy, + Fatal } diff --git a/Wino.Core.Domain/Enums/StorePurchaseResult.cs b/Wino.Core.Domain/Enums/StorePurchaseResult.cs index 8364b81a..f86e9a3f 100644 --- a/Wino.Core.Domain/Enums/StorePurchaseResult.cs +++ b/Wino.Core.Domain/Enums/StorePurchaseResult.cs @@ -1,19 +1,18 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +// From the SDK. +public enum StorePurchaseResult { - // From the SDK. - public enum StorePurchaseResult - { - // - // Summary: - // The purchase request succeeded. - Succeeded, - // - // Summary: - // The current user has already purchased the specified app or add-on. - AlreadyPurchased, - // - // Summary: - // The purchase request did not succeed. - NotPurchased, - } + // + // Summary: + // The purchase request succeeded. + Succeeded, + // + // Summary: + // The current user has already purchased the specified app or add-on. + AlreadyPurchased, + // + // Summary: + // The purchase request did not succeed. + NotPurchased, } diff --git a/Wino.Core.Domain/Enums/SynchronizationCompletedState.cs b/Wino.Core.Domain/Enums/SynchronizationCompletedState.cs index b4376afe..6a2edb6c 100644 --- a/Wino.Core.Domain/Enums/SynchronizationCompletedState.cs +++ b/Wino.Core.Domain/Enums/SynchronizationCompletedState.cs @@ -1,9 +1,8 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum SynchronizationCompletedState { - public enum SynchronizationCompletedState - { - Success, // All succeeded. - Canceled, // Canceled by user or HTTP call. - Failed // Exception. - } + Success, // All succeeded. + Canceled, // Canceled by user or HTTP call. + Failed // Exception. } diff --git a/Wino.Core.Domain/Enums/SynchronizationSource.cs b/Wino.Core.Domain/Enums/SynchronizationSource.cs index f64b00e5..d7b3e2d3 100644 --- a/Wino.Core.Domain/Enums/SynchronizationSource.cs +++ b/Wino.Core.Domain/Enums/SynchronizationSource.cs @@ -1,12 +1,11 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +/// +/// Enumeration for the source of synchronization. +/// Right now it can either be from the client or the server. +/// +public enum SynchronizationSource { - /// - /// Enumeration for the source of synchronization. - /// Right now it can either be from the client or the server. - /// - public enum SynchronizationSource - { - Client, - Server - } + Client, + Server } diff --git a/Wino.Core.Domain/Enums/WinoAppType.cs b/Wino.Core.Domain/Enums/WinoAppType.cs index da453cd5..4a35b9c8 100644 --- a/Wino.Core.Domain/Enums/WinoAppType.cs +++ b/Wino.Core.Domain/Enums/WinoAppType.cs @@ -1,9 +1,8 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum WinoAppType { - public enum WinoAppType - { - Unknown, - Mail, - Calendar - } + Unknown, + Mail, + Calendar } diff --git a/Wino.Core.Domain/Enums/WinoCustomMessageDialogIcon.cs b/Wino.Core.Domain/Enums/WinoCustomMessageDialogIcon.cs index c85bb5af..11dbeab7 100644 --- a/Wino.Core.Domain/Enums/WinoCustomMessageDialogIcon.cs +++ b/Wino.Core.Domain/Enums/WinoCustomMessageDialogIcon.cs @@ -1,10 +1,9 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum WinoCustomMessageDialogIcon { - public enum WinoCustomMessageDialogIcon - { - Information, - Warning, - Error, - Question - } + Information, + Warning, + Error, + Question } diff --git a/Wino.Core.Domain/Enums/WinoPage.cs b/Wino.Core.Domain/Enums/WinoPage.cs index 2ad07bcf..2ef77757 100644 --- a/Wino.Core.Domain/Enums/WinoPage.cs +++ b/Wino.Core.Domain/Enums/WinoPage.cs @@ -1,34 +1,33 @@ -namespace Wino.Core.Domain.Enums -{ - /// - /// All registered views. - /// - public enum WinoPage - { - None, - IdlePage, - ComposePage, - SettingsPage, - MailRenderingPage, - WelcomePage, - AccountDetailsPage, - MergedAccountDetailsPage, - ManageAccountsPage, - AccountManagementPage, - SignatureManagementPage, - AboutPage, - PersonalizationPage, - MessageListPage, - MailListPage, - ReadComposePanePage, - LanguageTimePage, - AppPreferencesPage, - SettingOptionsPage, - AliasManagementPage, +namespace Wino.Core.Domain.Enums; - // Calendar - CalendarPage, - CalendarSettingsPage, - EventDetailsPage - } +/// +/// All registered views. +/// +public enum WinoPage +{ + None, + IdlePage, + ComposePage, + SettingsPage, + MailRenderingPage, + WelcomePage, + AccountDetailsPage, + MergedAccountDetailsPage, + ManageAccountsPage, + AccountManagementPage, + SignatureManagementPage, + AboutPage, + PersonalizationPage, + MessageListPage, + MailListPage, + ReadComposePanePage, + LanguageTimePage, + AppPreferencesPage, + SettingOptionsPage, + AliasManagementPage, + + // Calendar + CalendarPage, + CalendarSettingsPage, + EventDetailsPage } diff --git a/Wino.Core.Domain/Enums/WinoServerConnectionStatus.cs b/Wino.Core.Domain/Enums/WinoServerConnectionStatus.cs index e997ce4b..9897b5bd 100644 --- a/Wino.Core.Domain/Enums/WinoServerConnectionStatus.cs +++ b/Wino.Core.Domain/Enums/WinoServerConnectionStatus.cs @@ -1,11 +1,10 @@ -namespace Wino.Core.Domain.Enums +namespace Wino.Core.Domain.Enums; + +public enum WinoServerConnectionStatus { - public enum WinoServerConnectionStatus - { - None, - Connecting, - Connected, - Disconnected, - Failed - } + None, + Connecting, + Connected, + Disconnected, + Failed } diff --git a/Wino.Core.Domain/Exceptions/AccountSetupCanceledException.cs b/Wino.Core.Domain/Exceptions/AccountSetupCanceledException.cs index 03819076..05a8c616 100644 --- a/Wino.Core.Domain/Exceptions/AccountSetupCanceledException.cs +++ b/Wino.Core.Domain/Exceptions/AccountSetupCanceledException.cs @@ -1,7 +1,6 @@ -namespace Wino.Core.Domain.Exceptions -{ - public class AccountSetupCanceledException : System.Exception - { +namespace Wino.Core.Domain.Exceptions; + +public class AccountSetupCanceledException : System.Exception +{ - } } diff --git a/Wino.Core.Domain/Exceptions/AuthenticationAttentionException.cs b/Wino.Core.Domain/Exceptions/AuthenticationAttentionException.cs index 3d775d17..9d19e8dd 100644 --- a/Wino.Core.Domain/Exceptions/AuthenticationAttentionException.cs +++ b/Wino.Core.Domain/Exceptions/AuthenticationAttentionException.cs @@ -1,19 +1,18 @@ using System; using Wino.Core.Domain.Entities.Shared; -namespace Wino.Core.Domain.Exceptions -{ - /// - /// Thrown when IAuthenticator requires user interaction to fix authentication issues. - /// It can be expired and can't restorable token, or some stuff that requires re-authentication. - /// - public class AuthenticationAttentionException : Exception - { - public AuthenticationAttentionException(MailAccount account) - { - Account = account; - } +namespace Wino.Core.Domain.Exceptions; - public MailAccount Account { get; } +/// +/// Thrown when IAuthenticator requires user interaction to fix authentication issues. +/// It can be expired and can't restorable token, or some stuff that requires re-authentication. +/// +public class AuthenticationAttentionException : Exception +{ + public AuthenticationAttentionException(MailAccount account) + { + Account = account; } + + public MailAccount Account { get; } } diff --git a/Wino.Core.Domain/Exceptions/AuthenticationException.cs b/Wino.Core.Domain/Exceptions/AuthenticationException.cs index 87e622df..ae7877ce 100644 --- a/Wino.Core.Domain/Exceptions/AuthenticationException.cs +++ b/Wino.Core.Domain/Exceptions/AuthenticationException.cs @@ -1,18 +1,17 @@ using System; -namespace Wino.Core.Domain.Exceptions -{ - /// - /// All exceptions related to authentication. - /// - public class AuthenticationException : Exception - { - public AuthenticationException(string message) : base(message) - { - } +namespace Wino.Core.Domain.Exceptions; - public AuthenticationException(string message, Exception innerException) : base(message, innerException) - { - } +/// +/// All exceptions related to authentication. +/// +public class AuthenticationException : Exception +{ + public AuthenticationException(string message) : base(message) + { + } + + public AuthenticationException(string message, Exception innerException) : base(message, innerException) + { } } diff --git a/Wino.Core.Domain/Exceptions/BackgroundTaskRegistrationFailedException.cs b/Wino.Core.Domain/Exceptions/BackgroundTaskRegistrationFailedException.cs index 50d3d40d..1a8ac966 100644 --- a/Wino.Core.Domain/Exceptions/BackgroundTaskRegistrationFailedException.cs +++ b/Wino.Core.Domain/Exceptions/BackgroundTaskRegistrationFailedException.cs @@ -1,9 +1,8 @@ using System; -namespace Wino.Core.Domain.Exceptions -{ - /// - /// An exception thrown when the background task registration is failed. - /// - public class BackgroundTaskRegistrationFailedException : Exception { } -} +namespace Wino.Core.Domain.Exceptions; + +/// +/// An exception thrown when the background task registration is failed. +/// +public class BackgroundTaskRegistrationFailedException : Exception { } diff --git a/Wino.Core.Domain/Exceptions/ComposerMimeNotFoundException.cs b/Wino.Core.Domain/Exceptions/ComposerMimeNotFoundException.cs index 2a82d580..8f06bdce 100644 --- a/Wino.Core.Domain/Exceptions/ComposerMimeNotFoundException.cs +++ b/Wino.Core.Domain/Exceptions/ComposerMimeNotFoundException.cs @@ -1,11 +1,10 @@ using System; -namespace Wino.Core.Domain.Exceptions +namespace Wino.Core.Domain.Exceptions; + +/// +/// Thrown when composer cant find the mime to load. +/// +public class ComposerMimeNotFoundException : Exception { - /// - /// Thrown when composer cant find the mime to load. - /// - public class ComposerMimeNotFoundException : Exception - { - } } diff --git a/Wino.Core.Domain/Exceptions/CustomThemeCreationFailedException.cs b/Wino.Core.Domain/Exceptions/CustomThemeCreationFailedException.cs index 8ffd3992..f1f64dd9 100644 --- a/Wino.Core.Domain/Exceptions/CustomThemeCreationFailedException.cs +++ b/Wino.Core.Domain/Exceptions/CustomThemeCreationFailedException.cs @@ -1,11 +1,10 @@ using System; -namespace Wino.Core.Domain.Exceptions +namespace Wino.Core.Domain.Exceptions; + +public class CustomThemeCreationFailedException : Exception { - public class CustomThemeCreationFailedException : Exception + public CustomThemeCreationFailedException(string message) : base(message) { - public CustomThemeCreationFailedException(string message) : base(message) - { - } } } diff --git a/Wino.Core.Domain/Exceptions/GoogleAuthenticationException.cs b/Wino.Core.Domain/Exceptions/GoogleAuthenticationException.cs index 71d244c1..651e0530 100644 --- a/Wino.Core.Domain/Exceptions/GoogleAuthenticationException.cs +++ b/Wino.Core.Domain/Exceptions/GoogleAuthenticationException.cs @@ -1,7 +1,6 @@ -namespace Wino.Core.Domain.Exceptions +namespace Wino.Core.Domain.Exceptions; + +public class GoogleAuthenticationException : System.Exception { - public class GoogleAuthenticationException : System.Exception - { - public GoogleAuthenticationException(string message) : base(message) { } - } + public GoogleAuthenticationException(string message) : base(message) { } } diff --git a/Wino.Core.Domain/Exceptions/ImapClientPoolException.cs b/Wino.Core.Domain/Exceptions/ImapClientPoolException.cs index 41226041..9a185743 100644 --- a/Wino.Core.Domain/Exceptions/ImapClientPoolException.cs +++ b/Wino.Core.Domain/Exceptions/ImapClientPoolException.cs @@ -1,14 +1,13 @@ using System; -namespace Wino.Core.Domain.Exceptions -{ - public class ImapClientPoolException : Exception - { - public ImapClientPoolException(Exception innerException, string protocolLog) : base(Translator.Exception_ImapClientPoolFailed, innerException) - { - ProtocolLog = protocolLog; - } +namespace Wino.Core.Domain.Exceptions; - public string ProtocolLog { get; } +public class ImapClientPoolException : Exception +{ + public ImapClientPoolException(Exception innerException, string protocolLog) : base(Translator.Exception_ImapClientPoolFailed, innerException) + { + ProtocolLog = protocolLog; } + + public string ProtocolLog { get; } } diff --git a/Wino.Core.Domain/Exceptions/ImapConnectionFailedPackage.cs b/Wino.Core.Domain/Exceptions/ImapConnectionFailedPackage.cs index 10b956f8..e431d969 100644 --- a/Wino.Core.Domain/Exceptions/ImapConnectionFailedPackage.cs +++ b/Wino.Core.Domain/Exceptions/ImapConnectionFailedPackage.cs @@ -1,18 +1,17 @@ using Wino.Core.Domain.Models.AutoDiscovery; -namespace Wino.Core.Domain.Exceptions -{ - public class ImapConnectionFailedPackage - { - public ImapConnectionFailedPackage(string errorMessage, string protocolLog, AutoDiscoverySettings settings) - { - ErrorMessage = errorMessage; - ProtocolLog = protocolLog; - Settings = settings; - } +namespace Wino.Core.Domain.Exceptions; - public AutoDiscoverySettings Settings { get; } - public string ErrorMessage { get; set; } - public string ProtocolLog { get; } +public class ImapConnectionFailedPackage +{ + public ImapConnectionFailedPackage(string errorMessage, string protocolLog, AutoDiscoverySettings settings) + { + ErrorMessage = errorMessage; + ProtocolLog = protocolLog; + Settings = settings; } + + public AutoDiscoverySettings Settings { get; } + public string ErrorMessage { get; set; } + public string ProtocolLog { get; } } diff --git a/Wino.Core.Domain/Exceptions/ImapSynchronizerStrategyException.cs b/Wino.Core.Domain/Exceptions/ImapSynchronizerStrategyException.cs index e59927ab..46a87bdf 100644 --- a/Wino.Core.Domain/Exceptions/ImapSynchronizerStrategyException.cs +++ b/Wino.Core.Domain/Exceptions/ImapSynchronizerStrategyException.cs @@ -1,10 +1,9 @@ -namespace Wino.Core.Domain.Exceptions -{ - public class ImapSynchronizerStrategyException : System.Exception - { - public ImapSynchronizerStrategyException(string message) : base(message) - { +namespace Wino.Core.Domain.Exceptions; + +public class ImapSynchronizerStrategyException : System.Exception +{ + public ImapSynchronizerStrategyException(string message) : base(message) + { - } } } diff --git a/Wino.Core.Domain/Exceptions/ImapTestSSLCertificateException.cs b/Wino.Core.Domain/Exceptions/ImapTestSSLCertificateException.cs index 7b15c3cb..6fa96bdf 100644 --- a/Wino.Core.Domain/Exceptions/ImapTestSSLCertificateException.cs +++ b/Wino.Core.Domain/Exceptions/ImapTestSSLCertificateException.cs @@ -1,17 +1,16 @@ -namespace Wino.Core.Domain.Exceptions +namespace Wino.Core.Domain.Exceptions; + +public class ImapTestSSLCertificateException : System.Exception { - public class ImapTestSSLCertificateException : System.Exception + public ImapTestSSLCertificateException(string issuer, string expirationDateString, string validFromDateString) { - public ImapTestSSLCertificateException(string issuer, string expirationDateString, string validFromDateString) - { - Issuer = issuer; - ExpirationDateString = expirationDateString; - ValidFromDateString = validFromDateString; - } - - public string Issuer { get; set; } - public string ExpirationDateString { get; set; } - public string ValidFromDateString { get; set; } - + Issuer = issuer; + ExpirationDateString = expirationDateString; + ValidFromDateString = validFromDateString; } + + public string Issuer { get; set; } + public string ExpirationDateString { get; set; } + public string ValidFromDateString { get; set; } + } diff --git a/Wino.Core.Domain/Exceptions/InvalidMoveTargetException.cs b/Wino.Core.Domain/Exceptions/InvalidMoveTargetException.cs index 05f3e7b4..830a8205 100644 --- a/Wino.Core.Domain/Exceptions/InvalidMoveTargetException.cs +++ b/Wino.Core.Domain/Exceptions/InvalidMoveTargetException.cs @@ -1,6 +1,5 @@ using System; -namespace Wino.Core.Domain.Exceptions -{ - public class InvalidMoveTargetException : Exception { } -} +namespace Wino.Core.Domain.Exceptions; + +public class InvalidMoveTargetException : Exception { } diff --git a/Wino.Core.Domain/Exceptions/MissingAliasException.cs b/Wino.Core.Domain/Exceptions/MissingAliasException.cs index f81cb8c6..adc19e06 100644 --- a/Wino.Core.Domain/Exceptions/MissingAliasException.cs +++ b/Wino.Core.Domain/Exceptions/MissingAliasException.cs @@ -1,7 +1,6 @@ -namespace Wino.Core.Domain.Exceptions +namespace Wino.Core.Domain.Exceptions; + +public class MissingAliasException : System.Exception { - public class MissingAliasException : System.Exception - { - public MissingAliasException() : base(Translator.Exception_MissingAlias) { } - } + public MissingAliasException() : base(Translator.Exception_MissingAlias) { } } diff --git a/Wino.Core.Domain/Exceptions/SynchronizerEntityNotFoundException.cs b/Wino.Core.Domain/Exceptions/SynchronizerEntityNotFoundException.cs index 4d35aad6..eb337480 100644 --- a/Wino.Core.Domain/Exceptions/SynchronizerEntityNotFoundException.cs +++ b/Wino.Core.Domain/Exceptions/SynchronizerEntityNotFoundException.cs @@ -1,11 +1,10 @@ using System; -namespace Wino.Core.Domain.Exceptions +namespace Wino.Core.Domain.Exceptions; + +public class SynchronizerEntityNotFoundException : Exception { - public class SynchronizerEntityNotFoundException : Exception + public SynchronizerEntityNotFoundException(string message) : base(message) { - public SynchronizerEntityNotFoundException(string message) : base(message) - { - } } } diff --git a/Wino.Core.Domain/Exceptions/SynchronizerException.cs b/Wino.Core.Domain/Exceptions/SynchronizerException.cs index cd2960fb..d5b66938 100644 --- a/Wino.Core.Domain/Exceptions/SynchronizerException.cs +++ b/Wino.Core.Domain/Exceptions/SynchronizerException.cs @@ -1,15 +1,14 @@ using System; -namespace Wino.Core.Domain.Exceptions -{ - public class SynchronizerException : Exception - { - public SynchronizerException(string message) : base(message) - { - } +namespace Wino.Core.Domain.Exceptions; - public SynchronizerException(string message, Exception innerException) : base(message, innerException) - { - } +public class SynchronizerException : Exception +{ + public SynchronizerException(string message) : base(message) + { + } + + public SynchronizerException(string message, Exception innerException) : base(message, innerException) + { } } diff --git a/Wino.Core.Domain/Exceptions/SystemFolderConfigurationMissingException.cs b/Wino.Core.Domain/Exceptions/SystemFolderConfigurationMissingException.cs index 918aa253..a49405c4 100644 --- a/Wino.Core.Domain/Exceptions/SystemFolderConfigurationMissingException.cs +++ b/Wino.Core.Domain/Exceptions/SystemFolderConfigurationMissingException.cs @@ -1,7 +1,6 @@ -namespace Wino.Core.Domain.Exceptions -{ - /// - /// When IMAP account's system folder configuration setup is not done yet. - /// - public class SystemFolderConfigurationMissingException : System.Exception { } -} +namespace Wino.Core.Domain.Exceptions; + +/// +/// When IMAP account's system folder configuration setup is not done yet. +/// +public class SystemFolderConfigurationMissingException : System.Exception { } diff --git a/Wino.Core.Domain/Exceptions/UnavailableSpecialFolderException.cs b/Wino.Core.Domain/Exceptions/UnavailableSpecialFolderException.cs index 9153cbaa..81b17b44 100644 --- a/Wino.Core.Domain/Exceptions/UnavailableSpecialFolderException.cs +++ b/Wino.Core.Domain/Exceptions/UnavailableSpecialFolderException.cs @@ -1,20 +1,19 @@ using System; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Exceptions -{ - /// - /// Emitted when special folder is needed for an operation but it couldn't be found. - /// - public class UnavailableSpecialFolderException : Exception - { - public UnavailableSpecialFolderException(SpecialFolderType specialFolderType, Guid accountId) - { - SpecialFolderType = specialFolderType; - AccountId = accountId; - } +namespace Wino.Core.Domain.Exceptions; - public SpecialFolderType SpecialFolderType { get; } - public Guid AccountId { get; set; } +/// +/// Emitted when special folder is needed for an operation but it couldn't be found. +/// +public class UnavailableSpecialFolderException : Exception +{ + public UnavailableSpecialFolderException(SpecialFolderType specialFolderType, Guid accountId) + { + SpecialFolderType = specialFolderType; + AccountId = accountId; } + + public SpecialFolderType SpecialFolderType { get; } + public Guid AccountId { get; set; } } diff --git a/Wino.Core.Domain/Exceptions/WinoServerException.cs b/Wino.Core.Domain/Exceptions/WinoServerException.cs index 8cbf87d4..afa7f132 100644 --- a/Wino.Core.Domain/Exceptions/WinoServerException.cs +++ b/Wino.Core.Domain/Exceptions/WinoServerException.cs @@ -1,12 +1,11 @@ using System; -namespace Wino.Core.Domain.Exceptions +namespace Wino.Core.Domain.Exceptions; + +/// +/// All server crash types. Wino Server ideally should not throw anything else than this Exception type. +/// +public class WinoServerException : Exception { - /// - /// All server crash types. Wino Server ideally should not throw anything else than this Exception type. - /// - public class WinoServerException : Exception - { - public WinoServerException(string message) : base(message) { } - } + public WinoServerException(string message) : base(message) { } } diff --git a/Wino.Core.Domain/Extensions/DateTimeExtensions.cs b/Wino.Core.Domain/Extensions/DateTimeExtensions.cs index 69c1b571..f026c80f 100644 --- a/Wino.Core.Domain/Extensions/DateTimeExtensions.cs +++ b/Wino.Core.Domain/Extensions/DateTimeExtensions.cs @@ -1,33 +1,32 @@ using System; using Wino.Core.Domain.Models.Calendar; -namespace Wino.Core.Domain.Extensions +namespace Wino.Core.Domain.Extensions; + +public static class DateTimeExtensions { - public static class DateTimeExtensions + /// + /// Returns a date range for the month of the given date. + /// + /// Date to get range for. + public static DateRange GetMonthDateRangeStartingWeekday(this DateTime date, DayOfWeek WeekStartDay) { - /// - /// Returns a date range for the month of the given date. - /// - /// Date to get range for. - public static DateRange GetMonthDateRangeStartingWeekday(this DateTime date, DayOfWeek WeekStartDay) - { - DateTime firstDayOfMonth = new DateTime(date.Year, date.Month, 1); + DateTime firstDayOfMonth = new DateTime(date.Year, date.Month, 1); - int daysToSubtract = (7 + (firstDayOfMonth.DayOfWeek - WeekStartDay)) % 7; - DateTime rangeStart = firstDayOfMonth.AddDays(-daysToSubtract); + int daysToSubtract = (7 + (firstDayOfMonth.DayOfWeek - WeekStartDay)) % 7; + DateTime rangeStart = firstDayOfMonth.AddDays(-daysToSubtract); - DateTime rangeEnd = rangeStart.AddDays(34); + DateTime rangeEnd = rangeStart.AddDays(34); - return new DateRange(rangeStart, rangeEnd); - } + return new DateRange(rangeStart, rangeEnd); + } - public static DateTime GetWeekStartDateForDate(this DateTime date, DayOfWeek firstDayOfWeek) - { - // Detect the first day of the week that contains the selected date. - int diff = (7 + (date.DayOfWeek - firstDayOfWeek)) % 7; + public static DateTime GetWeekStartDateForDate(this DateTime date, DayOfWeek firstDayOfWeek) + { + // Detect the first day of the week that contains the selected date. + int diff = (7 + (date.DayOfWeek - firstDayOfWeek)) % 7; - // Start loading from this date instead of visible date. - return date.AddDays(-diff).Date; - } + // Start loading from this date instead of visible date. + return date.AddDays(-diff).Date; } } diff --git a/Wino.Core.Domain/Extensions/ExceptionExtensions.cs b/Wino.Core.Domain/Extensions/ExceptionExtensions.cs index b42a0206..d7d62238 100644 --- a/Wino.Core.Domain/Extensions/ExceptionExtensions.cs +++ b/Wino.Core.Domain/Extensions/ExceptionExtensions.cs @@ -1,24 +1,23 @@ using System; using System.Collections.Generic; -namespace Wino.Core.Domain.Extensions -{ - public static class ExceptionExtensions - { - public static IEnumerable GetInnerExceptions(this Exception ex) - { - if (ex == null) - { - throw new ArgumentNullException("ex"); - } +namespace Wino.Core.Domain.Extensions; - var innerException = ex; - do - { - yield return innerException; - innerException = innerException.InnerException; - } - while (innerException != null); +public static class ExceptionExtensions +{ + public static IEnumerable GetInnerExceptions(this Exception ex) + { + if (ex == null) + { + throw new ArgumentNullException("ex"); } + + var innerException = ex; + do + { + yield return innerException; + innerException = innerException.InnerException; + } + while (innerException != null); } } diff --git a/Wino.Core.Domain/Extensions/MimeExtensions.cs b/Wino.Core.Domain/Extensions/MimeExtensions.cs index 1555e932..98a9b0c9 100644 --- a/Wino.Core.Domain/Extensions/MimeExtensions.cs +++ b/Wino.Core.Domain/Extensions/MimeExtensions.cs @@ -1,20 +1,19 @@ using System; using System.IO; -namespace Wino.Core.Domain.Extensions +namespace Wino.Core.Domain.Extensions; + +public static class MimeExtensions { - public static class MimeExtensions + public static string GetBase64MimeMessage(this MimeKit.MimeMessage message) { - public static string GetBase64MimeMessage(this MimeKit.MimeMessage message) - { - using MemoryStream memoryStream = new(); + using MemoryStream memoryStream = new(); - message.WriteTo(memoryStream); + message.WriteTo(memoryStream); - return Convert.ToBase64String(memoryStream.ToArray()); - } - - public static MimeKit.MimeMessage GetMimeMessageFromBase64(this string base64) - => MimeKit.MimeMessage.Load(new System.IO.MemoryStream(Convert.FromBase64String(base64))); + return Convert.ToBase64String(memoryStream.ToArray()); } + + public static MimeKit.MimeMessage GetMimeMessageFromBase64(this string base64) + => MimeKit.MimeMessage.Load(new System.IO.MemoryStream(Convert.FromBase64String(base64))); } diff --git a/Wino.Core.Domain/Interfaces/IAccountCalendar.cs b/Wino.Core.Domain/Interfaces/IAccountCalendar.cs index 32c908cb..85a340c3 100644 --- a/Wino.Core.Domain/Interfaces/IAccountCalendar.cs +++ b/Wino.Core.Domain/Interfaces/IAccountCalendar.cs @@ -1,16 +1,15 @@ using System; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IAccountCalendar { - public interface IAccountCalendar - { - string Name { get; set; } - string TextColorHex { get; set; } - string BackgroundColorHex { get; set; } - bool IsPrimary { get; set; } - Guid AccountId { get; set; } - string RemoteCalendarId { get; set; } - bool IsExtended { get; set; } - Guid Id { get; set; } - } + string Name { get; set; } + string TextColorHex { get; set; } + string BackgroundColorHex { get; set; } + bool IsPrimary { get; set; } + Guid AccountId { get; set; } + string RemoteCalendarId { get; set; } + bool IsExtended { get; set; } + Guid Id { get; set; } } diff --git a/Wino.Core.Domain/Interfaces/IAccountCreationDialog.cs b/Wino.Core.Domain/Interfaces/IAccountCreationDialog.cs index 8454a4ed..2cf94608 100644 --- a/Wino.Core.Domain/Interfaces/IAccountCreationDialog.cs +++ b/Wino.Core.Domain/Interfaces/IAccountCreationDialog.cs @@ -2,12 +2,11 @@ using System.Threading.Tasks; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IAccountCreationDialog { - public interface IAccountCreationDialog - { - Task ShowDialogAsync(CancellationTokenSource cancellationTokenSource); - void Complete(bool cancel); - AccountCreationDialogState State { get; set; } - } + Task ShowDialogAsync(CancellationTokenSource cancellationTokenSource); + void Complete(bool cancel); + AccountCreationDialogState State { get; set; } } diff --git a/Wino.Core.Domain/Interfaces/IAccountMenuItem.cs b/Wino.Core.Domain/Interfaces/IAccountMenuItem.cs index 3faca7f0..b3a917bd 100644 --- a/Wino.Core.Domain/Interfaces/IAccountMenuItem.cs +++ b/Wino.Core.Domain/Interfaces/IAccountMenuItem.cs @@ -2,21 +2,20 @@ using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Entities.Shared; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IAccountMenuItem : IMenuItem { - public interface IAccountMenuItem : IMenuItem - { - bool IsEnabled { get; set; } - double SynchronizationProgress { get; set; } - int UnreadItemCount { get; set; } - IEnumerable HoldingAccounts { get; } - void UpdateAccount(MailAccount account); - } - - public interface IMergedAccountMenuItem : IAccountMenuItem - { - int MergedAccountCount { get; } - - MergedInbox Parameter { get; } - } + bool IsEnabled { get; set; } + double SynchronizationProgress { get; set; } + int UnreadItemCount { get; set; } + IEnumerable HoldingAccounts { get; } + void UpdateAccount(MailAccount account); +} + +public interface IMergedAccountMenuItem : IAccountMenuItem +{ + int MergedAccountCount { get; } + + MergedInbox Parameter { get; } } diff --git a/Wino.Core.Domain/Interfaces/IAccountPickerDialog.cs b/Wino.Core.Domain/Interfaces/IAccountPickerDialog.cs index a43bbc26..52a0c33a 100644 --- a/Wino.Core.Domain/Interfaces/IAccountPickerDialog.cs +++ b/Wino.Core.Domain/Interfaces/IAccountPickerDialog.cs @@ -1,6 +1,5 @@ -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IAccountPickerDialog { - public interface IAccountPickerDialog - { - } } diff --git a/Wino.Core.Domain/Interfaces/IAccountProviderDetailViewModel.cs b/Wino.Core.Domain/Interfaces/IAccountProviderDetailViewModel.cs index d4a9b279..2272974b 100644 --- a/Wino.Core.Domain/Interfaces/IAccountProviderDetailViewModel.cs +++ b/Wino.Core.Domain/Interfaces/IAccountProviderDetailViewModel.cs @@ -1,38 +1,37 @@ using System; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IAccountProviderDetailViewModel { - public interface IAccountProviderDetailViewModel - { - /// - /// Entity id that will help to identify the startup entity on launch. - /// - Guid StartupEntityId { get; } + /// + /// Entity id that will help to identify the startup entity on launch. + /// + Guid StartupEntityId { get; } - /// - /// Name representation of the view model that will be used to identify the startup entity on launch. - /// - string StartupEntityTitle { get; } + /// + /// Name representation of the view model that will be used to identify the startup entity on launch. + /// + string StartupEntityTitle { get; } - /// - /// E-mail addresses that this account holds. - /// + /// + /// E-mail addresses that this account holds. + /// - string StartupEntityAddresses { get; } + string StartupEntityAddresses { get; } - /// - /// Represents the account order in the accounts list. - /// - int Order { get; } + /// + /// Represents the account order in the accounts list. + /// + int Order { get; } - /// - /// Provider details of the account. - /// - IProviderDetail ProviderDetail { get; set; } + /// + /// Provider details of the account. + /// + IProviderDetail ProviderDetail { get; set; } - /// - /// How many accounts this provider has. - /// - int HoldingAccountCount { get; } - } + /// + /// How many accounts this provider has. + /// + int HoldingAccountCount { get; } } diff --git a/Wino.Core.Domain/Interfaces/IAccountProviderDetails.cs b/Wino.Core.Domain/Interfaces/IAccountProviderDetails.cs index c5b7c5f5..66eb5b10 100644 --- a/Wino.Core.Domain/Interfaces/IAccountProviderDetails.cs +++ b/Wino.Core.Domain/Interfaces/IAccountProviderDetails.cs @@ -1,11 +1,10 @@ using Wino.Core.Domain.Entities.Shared; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IAccountProviderDetails { - public interface IAccountProviderDetails - { - MailAccount Account { get; set; } - bool AutoExtend { get; set; } - IProviderDetail ProviderDetail { get; set; } - } + MailAccount Account { get; set; } + bool AutoExtend { get; set; } + IProviderDetail ProviderDetail { get; set; } } diff --git a/Wino.Core.Domain/Interfaces/IAccountService.cs b/Wino.Core.Domain/Interfaces/IAccountService.cs index 8a226f25..338e4270 100644 --- a/Wino.Core.Domain/Interfaces/IAccountService.cs +++ b/Wino.Core.Domain/Interfaces/IAccountService.cs @@ -5,156 +5,155 @@ using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Entities.Shared; using Wino.Core.Domain.Models.Accounts; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IAccountService { - public interface IAccountService - { - /// - /// Current IAuthenticator that should receive external authentication process to continue with. - /// For example: Google auth will launch a browser authentication. After it completes, this is the IAuthenticator - /// to continue process for token exchange. - /// - IAuthenticator ExternalAuthenticationAuthenticator { get; set; } + /// + /// Current IAuthenticator that should receive external authentication process to continue with. + /// For example: Google auth will launch a browser authentication. After it completes, this is the IAuthenticator + /// to continue process for token exchange. + /// + IAuthenticator ExternalAuthenticationAuthenticator { get; set; } - /// - /// Returns all local accounts. - /// - /// All local accounts - Task> GetAccountsAsync(); + /// + /// Returns all local accounts. + /// + /// All local accounts + Task> GetAccountsAsync(); - /// - /// Returns single MailAccount - /// - /// AccountId. - Task GetAccountAsync(Guid accountId); + /// + /// Returns single MailAccount + /// + /// AccountId. + Task GetAccountAsync(Guid accountId); - /// - /// Deletes all information about the account, including token information. - /// - /// MailAccount to be removed - Task DeleteAccountAsync(MailAccount account); + /// + /// Deletes all information about the account, including token information. + /// + /// MailAccount to be removed + Task DeleteAccountAsync(MailAccount account); - /// - /// Returns the custom server information for the given account id. - /// - Task GetAccountCustomServerInformationAsync(Guid accountId); + /// + /// Returns the custom server information for the given account id. + /// + Task GetAccountCustomServerInformationAsync(Guid accountId); - /// - /// Updates the given account properties. - /// - Task UpdateAccountAsync(MailAccount account); + /// + /// Updates the given account properties. + /// + Task UpdateAccountAsync(MailAccount account); - /// - /// Creates new account with the given server information if any. - /// Also sets the account as Startup account if there are no accounts. - /// - Task CreateAccountAsync(MailAccount account, CustomServerInformation customServerInformation); + /// + /// Creates new account with the given server information if any. + /// Also sets the account as Startup account if there are no accounts. + /// + Task CreateAccountAsync(MailAccount account, CustomServerInformation customServerInformation); - /// - /// Fixed authentication errors for account by forcing interactive login. - /// - Task FixTokenIssuesAsync(Guid accountId); + /// + /// Fixed authentication errors for account by forcing interactive login. + /// + Task FixTokenIssuesAsync(Guid accountId); - /// - /// Removed the attention from an account. - /// - /// Account id to remove from - Task ClearAccountAttentionAsync(Guid accountId); + /// + /// Removed the attention from an account. + /// + /// Account id to remove from + Task ClearAccountAttentionAsync(Guid accountId); - /// - /// Updates the account synchronization identifier. - /// For example: Gmail uses this identifier to keep track of the last synchronization. - /// Update is ignored for Gmail if the new identifier is older than the current one. - /// - /// Identifier to update - /// Current account synchronization modifier. - Task UpdateSynchronizationIdentifierAsync(Guid accountId, string newIdentifier); + /// + /// Updates the account synchronization identifier. + /// For example: Gmail uses this identifier to keep track of the last synchronization. + /// Update is ignored for Gmail if the new identifier is older than the current one. + /// + /// Identifier to update + /// Current account synchronization modifier. + Task UpdateSynchronizationIdentifierAsync(Guid accountId, string newIdentifier); - /// - /// Renames the merged inbox with the given id. - /// - /// Merged Inbox id - /// New name for the merged/linked inbox. - Task RenameMergedAccountAsync(Guid mergedInboxId, string newName); + /// + /// Renames the merged inbox with the given id. + /// + /// Merged Inbox id + /// New name for the merged/linked inbox. + Task RenameMergedAccountAsync(Guid mergedInboxId, string newName); - /// - /// Creates a new merged inbox with the given accounts. - /// - /// Merged inbox properties. - /// List of accounts to merge together. - Task CreateMergeAccountsAsync(MergedInbox mergedInbox, IEnumerable accountsToMerge); + /// + /// Creates a new merged inbox with the given accounts. + /// + /// Merged inbox properties. + /// List of accounts to merge together. + Task CreateMergeAccountsAsync(MergedInbox mergedInbox, IEnumerable accountsToMerge); - /// - /// Updates the merged inbox with the given id with the new linked accounts. - /// - /// Updating merged inbox id. - /// List of linked account ids. - Task UpdateMergedInboxAsync(Guid mergedInboxId, IEnumerable linkedAccountIds); + /// + /// Updates the merged inbox with the given id with the new linked accounts. + /// + /// Updating merged inbox id. + /// List of linked account ids. + Task UpdateMergedInboxAsync(Guid mergedInboxId, IEnumerable linkedAccountIds); - /// - /// Destroys the merged inbox with the given id. - /// - /// Merged inbox id to destroy. - Task UnlinkMergedInboxAsync(Guid mergedInboxId); + /// + /// Destroys the merged inbox with the given id. + /// + /// Merged inbox id to destroy. + Task UnlinkMergedInboxAsync(Guid mergedInboxId); - /// - /// Updates the account listing orders. - /// - /// AccountId-OrderNumber pair for all accounts. - Task UpdateAccountOrdersAsync(Dictionary accountIdOrderPair); + /// + /// Updates the account listing orders. + /// + /// AccountId-OrderNumber pair for all accounts. + Task UpdateAccountOrdersAsync(Dictionary accountIdOrderPair); - /// - /// Returns the account aliases. - /// - /// Account id. - /// A list of MailAccountAlias that has e-mail aliases. - Task> GetAccountAliasesAsync(Guid accountId); + /// + /// Returns the account aliases. + /// + /// Account id. + /// A list of MailAccountAlias that has e-mail aliases. + Task> GetAccountAliasesAsync(Guid accountId); - /// - /// Updated account's aliases. - /// - /// Account id to update aliases for. - /// Full list of updated aliases. - /// - Task UpdateAccountAliasesAsync(Guid accountId, List aliases); + /// + /// Updated account's aliases. + /// + /// Account id to update aliases for. + /// Full list of updated aliases. + /// + Task UpdateAccountAliasesAsync(Guid accountId, List aliases); - /// - /// Delete account alias. - /// - /// Alias to remove. - Task DeleteAccountAliasAsync(Guid aliasId); + /// + /// Delete account alias. + /// + /// Alias to remove. + Task DeleteAccountAliasAsync(Guid aliasId); - /// - /// Updated profile information of the account. - /// - /// Account id to update info for. - /// Info data. - /// - Task UpdateProfileInformationAsync(Guid accountId, ProfileInformation profileInformation); + /// + /// Updated profile information of the account. + /// + /// Account id to update info for. + /// Info data. + /// + Task UpdateProfileInformationAsync(Guid accountId, ProfileInformation profileInformation); - /// - /// Creates a root + primary alias for the account. - /// This is only called when the account is created. - /// - /// Account id. - /// Address to create root primary alias from. - Task CreateRootAliasAsync(Guid accountId, string address); + /// + /// Creates a root + primary alias for the account. + /// This is only called when the account is created. + /// + /// Account id. + /// Address to create root primary alias from. + Task CreateRootAliasAsync(Guid accountId, string address); - /// - /// Will compare local-remote aliases and update the local ones or add/delete new ones. - /// - /// Remotely fetched basic alias info from synchronizer. - /// Account to update remote aliases for.. - Task UpdateRemoteAliasInformationAsync(MailAccount account, List remoteAccountAliases); + /// + /// Will compare local-remote aliases and update the local ones or add/delete new ones. + /// + /// Remotely fetched basic alias info from synchronizer. + /// Account to update remote aliases for.. + Task UpdateRemoteAliasInformationAsync(MailAccount account, List remoteAccountAliases); - /// - /// Gets the primary account alias for the given account id. - /// Used when creating draft messages. - /// - /// Account id. - /// Primary alias for the account. - Task GetPrimaryAccountAliasAsync(Guid accountId); - Task IsAccountFocusedEnabledAsync(Guid accountId); - } + /// + /// Gets the primary account alias for the given account id. + /// Used when creating draft messages. + /// + /// Account id. + /// Primary alias for the account. + Task GetPrimaryAccountAliasAsync(Guid accountId); + Task IsAccountFocusedEnabledAsync(Guid accountId); } diff --git a/Wino.Core.Domain/Interfaces/IApplicationConfiguration.cs b/Wino.Core.Domain/Interfaces/IApplicationConfiguration.cs index b87c0a56..3b1f71eb 100644 --- a/Wino.Core.Domain/Interfaces/IApplicationConfiguration.cs +++ b/Wino.Core.Domain/Interfaces/IApplicationConfiguration.cs @@ -1,32 +1,31 @@ -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +/// +/// Singleton object that holds the application data folder path and the publisher shared folder path. +/// Load the values before calling any service. +/// App data folder is used for storing files. +/// Pubhlisher cache folder is only used for database file so other apps can access it in the same package by same publisher. +/// +public interface IApplicationConfiguration { /// - /// Singleton object that holds the application data folder path and the publisher shared folder path. - /// Load the values before calling any service. - /// App data folder is used for storing files. - /// Pubhlisher cache folder is only used for database file so other apps can access it in the same package by same publisher. + /// Application data folder. /// - public interface IApplicationConfiguration - { - /// - /// Application data folder. - /// - string ApplicationDataFolderPath { get; set; } + string ApplicationDataFolderPath { get; set; } - /// - /// Publisher shared folder path. - /// - string PublisherSharedFolderPath { get; set; } + /// + /// Publisher shared folder path. + /// + string PublisherSharedFolderPath { get; set; } - /// - /// Temp folder path of the application. - /// Files here are short-lived and can be deleted by system. - /// - string ApplicationTempFolderPath { get; set; } + /// + /// Temp folder path of the application. + /// Files here are short-lived and can be deleted by system. + /// + string ApplicationTempFolderPath { get; set; } - /// - /// Application insights instrumentation key. - /// - string ApplicationInsightsInstrumentationKey { get; } - } + /// + /// Application insights instrumentation key. + /// + string ApplicationInsightsInstrumentationKey { get; } } diff --git a/Wino.Core.Domain/Interfaces/IApplicationResourceManager.cs b/Wino.Core.Domain/Interfaces/IApplicationResourceManager.cs index b96edb7c..f0a8f1dc 100644 --- a/Wino.Core.Domain/Interfaces/IApplicationResourceManager.cs +++ b/Wino.Core.Domain/Interfaces/IApplicationResourceManager.cs @@ -1,12 +1,11 @@ -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IApplicationResourceManager { - public interface IApplicationResourceManager - { - void RemoveResource(T resource); - void AddResource(T resource); - bool ContainsResourceKey(string resourceKey); - void ReplaceResource(string resourceKey, object resource); - T GetLastResource(); - TReturnType GetResource(string resourceKey); - } + void RemoveResource(T resource); + void AddResource(T resource); + bool ContainsResourceKey(string resourceKey); + void ReplaceResource(string resourceKey, object resource); + T GetLastResource(); + TReturnType GetResource(string resourceKey); } diff --git a/Wino.Core.Domain/Interfaces/IAuthenticationProvider.cs b/Wino.Core.Domain/Interfaces/IAuthenticationProvider.cs index 49390dcb..652ac62b 100644 --- a/Wino.Core.Domain/Interfaces/IAuthenticationProvider.cs +++ b/Wino.Core.Domain/Interfaces/IAuthenticationProvider.cs @@ -1,9 +1,8 @@ using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IAuthenticationProvider { - public interface IAuthenticationProvider - { - IAuthenticator GetAuthenticator(MailProviderType providerType); - } + IAuthenticator GetAuthenticator(MailProviderType providerType); } diff --git a/Wino.Core.Domain/Interfaces/IAuthenticator.cs b/Wino.Core.Domain/Interfaces/IAuthenticator.cs index 86d2f8b4..837b99f9 100644 --- a/Wino.Core.Domain/Interfaces/IAuthenticator.cs +++ b/Wino.Core.Domain/Interfaces/IAuthenticator.cs @@ -3,37 +3,36 @@ using Wino.Core.Domain.Entities.Shared; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.Authentication; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IAuthenticator { - public interface IAuthenticator - { - /// - /// Type of the provider. - /// - MailProviderType ProviderType { get; } + /// + /// Type of the provider. + /// + MailProviderType ProviderType { get; } - Task GetTokenInformationAsync(MailAccount account); + Task GetTokenInformationAsync(MailAccount account); - Task GenerateTokenInformationAsync(MailAccount account); + Task GenerateTokenInformationAsync(MailAccount account); - ///// - ///// Gets the token for the given account from the cache. - ///// Forces interactive login if the token is not found. - ///// - ///// Account to get access token for. - ///// Access token - //Task GetTokenAsync(MailAccount account); + ///// + ///// Gets the token for the given account from the cache. + ///// Forces interactive login if the token is not found. + ///// + ///// Account to get access token for. + ///// Access token + //Task GetTokenAsync(MailAccount account); - ///// - ///// Forces an interactive login to get the token for the given account. - ///// - ///// Account to get access token for. - ///// Access token - //// Task GenerateTokenAsync(MailAccount account); + ///// + ///// Forces an interactive login to get the token for the given account. + ///// + ///// Account to get access token for. + ///// Access token + //// Task GenerateTokenAsync(MailAccount account); - ///// - ///// ClientId in case of needed for authorization/authentication. - ///// - //string ClientId { get; } - } + ///// + ///// ClientId in case of needed for authorization/authentication. + ///// + //string ClientId { get; } } diff --git a/Wino.Core.Domain/Interfaces/IAuthenticatorConfig.cs b/Wino.Core.Domain/Interfaces/IAuthenticatorConfig.cs index 1f154727..a867fee7 100644 --- a/Wino.Core.Domain/Interfaces/IAuthenticatorConfig.cs +++ b/Wino.Core.Domain/Interfaces/IAuthenticatorConfig.cs @@ -1,11 +1,10 @@ -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IAuthenticatorConfig { - public interface IAuthenticatorConfig - { - string OutlookAuthenticatorClientId { get; } - string[] OutlookScope { get; } - string GmailAuthenticatorClientId { get; } - string[] GmailScope { get; } - string GmailTokenStoreIdentifier { get; } - } + string OutlookAuthenticatorClientId { get; } + string[] OutlookScope { get; } + string GmailAuthenticatorClientId { get; } + string[] GmailScope { get; } + string GmailTokenStoreIdentifier { get; } } diff --git a/Wino.Core.Domain/Interfaces/IAuthenticatorTypes.cs b/Wino.Core.Domain/Interfaces/IAuthenticatorTypes.cs index ef842706..a6d25aff 100644 --- a/Wino.Core.Domain/Interfaces/IAuthenticatorTypes.cs +++ b/Wino.Core.Domain/Interfaces/IAuthenticatorTypes.cs @@ -1,10 +1,9 @@ -namespace Wino.Core.Domain.Interfaces -{ - public interface IOutlookAuthenticator : IAuthenticator { } - public interface IGmailAuthenticator : IAuthenticator - { - bool ProposeCopyAuthURL { get; set; } - } +namespace Wino.Core.Domain.Interfaces; - public interface IImapAuthenticator : IAuthenticator { } +public interface IOutlookAuthenticator : IAuthenticator { } +public interface IGmailAuthenticator : IAuthenticator +{ + bool ProposeCopyAuthURL { get; set; } } + +public interface IImapAuthenticator : IAuthenticator { } diff --git a/Wino.Core.Domain/Interfaces/IAutoDiscoveryService.cs b/Wino.Core.Domain/Interfaces/IAutoDiscoveryService.cs index 6886022d..0ba6642a 100644 --- a/Wino.Core.Domain/Interfaces/IAutoDiscoveryService.cs +++ b/Wino.Core.Domain/Interfaces/IAutoDiscoveryService.cs @@ -1,18 +1,17 @@ using System.Threading.Tasks; using Wino.Core.Domain.Models.AutoDiscovery; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +/// +/// Searches for Auto Discovery settings for custom mail accounts. +/// +public interface IAutoDiscoveryService { /// - /// Searches for Auto Discovery settings for custom mail accounts. + /// Tries to return the best mail server settings using different techniques. /// - public interface IAutoDiscoveryService - { - /// - /// Tries to return the best mail server settings using different techniques. - /// - /// Address to search settings for. - /// CustomServerInformation with only settings applied. - Task GetAutoDiscoverySettings(AutoDiscoveryMinimalSettings autoDiscoveryMinimalSettings); - } + /// Address to search settings for. + /// CustomServerInformation with only settings applied. + Task GetAutoDiscoverySettings(AutoDiscoveryMinimalSettings autoDiscoveryMinimalSettings); } diff --git a/Wino.Core.Domain/Interfaces/IBackgroundTaskService.cs b/Wino.Core.Domain/Interfaces/IBackgroundTaskService.cs index 53fb80b3..651ee659 100644 --- a/Wino.Core.Domain/Interfaces/IBackgroundTaskService.cs +++ b/Wino.Core.Domain/Interfaces/IBackgroundTaskService.cs @@ -1,18 +1,17 @@ using System.Threading.Tasks; -namespace Wino.Core.Domain.Interfaces -{ - public interface IBackgroundTaskService - { - /// - /// Unregisters all background tasks once. - /// This is used to clean up the background tasks when the app is updated. - /// - void UnregisterAllBackgroundTask(); +namespace Wino.Core.Domain.Interfaces; - /// - /// Registers required background tasks. - /// - Task RegisterBackgroundTasksAsync(); - } +public interface IBackgroundTaskService +{ + /// + /// Unregisters all background tasks once. + /// This is used to clean up the background tasks when the app is updated. + /// + void UnregisterAllBackgroundTask(); + + /// + /// Registers required background tasks. + /// + Task RegisterBackgroundTasksAsync(); } diff --git a/Wino.Core.Domain/Interfaces/IBaseSynchronizer.cs b/Wino.Core.Domain/Interfaces/IBaseSynchronizer.cs index 09e2b402..00f2f406 100644 --- a/Wino.Core.Domain/Interfaces/IBaseSynchronizer.cs +++ b/Wino.Core.Domain/Interfaces/IBaseSynchronizer.cs @@ -3,31 +3,30 @@ using Wino.Core.Domain.Entities.Shared; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.Accounts; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IBaseSynchronizer { - public interface IBaseSynchronizer - { - /// - /// Account that is assigned for this synchronizer. - /// - MailAccount Account { get; } + /// + /// Account that is assigned for this synchronizer. + /// + MailAccount Account { get; } - /// - /// Synchronizer state. - /// - AccountSynchronizerState State { get; } + /// + /// Synchronizer state. + /// + AccountSynchronizerState State { get; } - /// - /// Queues a single request to be executed in the next synchronization. - /// - /// Request to queue. - void QueueRequest(IRequestBase request); + /// + /// Queues a single request to be executed in the next synchronization. + /// + /// Request to queue. + void QueueRequest(IRequestBase request); - /// - /// Synchronizes profile information with the server. - /// Sender name and Profile picture are updated. - /// - /// Profile information model that holds the values. - Task GetProfileInformationAsync(); - } + /// + /// Synchronizes profile information with the server. + /// Sender name and Profile picture are updated. + /// + /// Profile information model that holds the values. + Task GetProfileInformationAsync(); } diff --git a/Wino.Core.Domain/Interfaces/ICalendarDialogService.cs b/Wino.Core.Domain/Interfaces/ICalendarDialogService.cs index 023d9eaf..7b48f868 100644 --- a/Wino.Core.Domain/Interfaces/ICalendarDialogService.cs +++ b/Wino.Core.Domain/Interfaces/ICalendarDialogService.cs @@ -1,6 +1,5 @@ -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface ICalendarDialogService : IDialogServiceBase { - public interface ICalendarDialogService : IDialogServiceBase - { - } } diff --git a/Wino.Core.Domain/Interfaces/ICalendarItem.cs b/Wino.Core.Domain/Interfaces/ICalendarItem.cs index 815b4a22..e83827a6 100644 --- a/Wino.Core.Domain/Interfaces/ICalendarItem.cs +++ b/Wino.Core.Domain/Interfaces/ICalendarItem.cs @@ -1,23 +1,22 @@ using System; using Itenso.TimePeriod; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface ICalendarItem { - public interface ICalendarItem - { - string Title { get; } - Guid Id { get; } - IAccountCalendar AssignedCalendar { get; } - DateTime StartDate { get; set; } - DateTime EndDate { get; } - double DurationInSeconds { get; set; } - ITimePeriod Period { get; } + string Title { get; } + Guid Id { get; } + IAccountCalendar AssignedCalendar { get; } + DateTime StartDate { get; set; } + DateTime EndDate { get; } + double DurationInSeconds { get; set; } + ITimePeriod Period { get; } - bool IsAllDayEvent { get; } - bool IsMultiDayEvent { get; } + bool IsAllDayEvent { get; } + bool IsMultiDayEvent { get; } - bool IsRecurringChild { get; } - bool IsRecurringParent { get; } - bool IsRecurringEvent { get; } - } + bool IsRecurringChild { get; } + bool IsRecurringParent { get; } + bool IsRecurringEvent { get; } } diff --git a/Wino.Core.Domain/Interfaces/ICalendarItemViewModel.cs b/Wino.Core.Domain/Interfaces/ICalendarItemViewModel.cs index 6c2a4de6..3eaf1ff7 100644 --- a/Wino.Core.Domain/Interfaces/ICalendarItemViewModel.cs +++ b/Wino.Core.Domain/Interfaces/ICalendarItemViewModel.cs @@ -1,10 +1,9 @@ -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +/// +/// Temporarily to enforce CalendarItemViewModel. Used in CalendarEventCollection. +/// +public interface ICalendarItemViewModel { - /// - /// Temporarily to enforce CalendarItemViewModel. Used in CalendarEventCollection. - /// - public interface ICalendarItemViewModel - { - bool IsSelected { get; set; } - } + bool IsSelected { get; set; } } diff --git a/Wino.Core.Domain/Interfaces/ICalendarService.cs b/Wino.Core.Domain/Interfaces/ICalendarService.cs index 6c4a93f3..f0e18b4a 100644 --- a/Wino.Core.Domain/Interfaces/ICalendarService.cs +++ b/Wino.Core.Domain/Interfaces/ICalendarService.cs @@ -4,29 +4,28 @@ using System.Threading.Tasks; using Wino.Core.Domain.Entities.Calendar; using Wino.Core.Domain.Models.Calendar; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface ICalendarService { - public interface ICalendarService - { - Task> GetAccountCalendarsAsync(Guid accountId); - Task GetAccountCalendarAsync(Guid accountCalendarId); - Task DeleteCalendarItemAsync(Guid calendarItemId); + Task> GetAccountCalendarsAsync(Guid accountId); + Task GetAccountCalendarAsync(Guid accountCalendarId); + Task DeleteCalendarItemAsync(Guid calendarItemId); - Task DeleteAccountCalendarAsync(AccountCalendar accountCalendar); - Task InsertAccountCalendarAsync(AccountCalendar accountCalendar); - Task UpdateAccountCalendarAsync(AccountCalendar accountCalendar); - Task CreateNewCalendarItemAsync(CalendarItem calendarItem, List attendees); - Task> GetCalendarEventsAsync(IAccountCalendar calendar, DayRangeRenderModel dayRangeRenderModel); - Task GetCalendarItemAsync(Guid accountCalendarId, string remoteEventId); - Task UpdateCalendarDeltaSynchronizationToken(Guid calendarId, string deltaToken); + Task DeleteAccountCalendarAsync(AccountCalendar accountCalendar); + Task InsertAccountCalendarAsync(AccountCalendar accountCalendar); + Task UpdateAccountCalendarAsync(AccountCalendar accountCalendar); + Task CreateNewCalendarItemAsync(CalendarItem calendarItem, List attendees); + Task> GetCalendarEventsAsync(IAccountCalendar calendar, DayRangeRenderModel dayRangeRenderModel); + Task GetCalendarItemAsync(Guid accountCalendarId, string remoteEventId); + Task UpdateCalendarDeltaSynchronizationToken(Guid calendarId, string deltaToken); - /// - /// Returns the correct calendar item based on the target details. - /// - /// Target details. - Task GetCalendarItemTargetAsync(CalendarItemTarget targetDetails); - Task GetCalendarItemAsync(Guid id); - Task> GetAttendeesAsync(Guid calendarEventTrackingId); - Task> ManageEventAttendeesAsync(Guid calendarItemId, List allAttendees); - } + /// + /// Returns the correct calendar item based on the target details. + /// + /// Target details. + Task GetCalendarItemTargetAsync(CalendarItemTarget targetDetails); + Task GetCalendarItemAsync(Guid id); + Task> GetAttendeesAsync(Guid calendarEventTrackingId); + Task> ManageEventAttendeesAsync(Guid calendarItemId, List allAttendees); } diff --git a/Wino.Core.Domain/Interfaces/IClientMessage.cs b/Wino.Core.Domain/Interfaces/IClientMessage.cs index 5244059e..9dd64bca 100644 --- a/Wino.Core.Domain/Interfaces/IClientMessage.cs +++ b/Wino.Core.Domain/Interfaces/IClientMessage.cs @@ -1,8 +1,7 @@ -namespace Wino.Core.Domain.Interfaces -{ - /// - /// All messages that Client sends to Server and awaits a response in return. - /// For example; triggering a new synchronization request. - /// - public interface IClientMessage; -} +namespace Wino.Core.Domain.Interfaces; + +/// +/// All messages that Client sends to Server and awaits a response in return. +/// For example; triggering a new synchronization request. +/// +public interface IClientMessage; diff --git a/Wino.Core.Domain/Interfaces/IClipboardService.cs b/Wino.Core.Domain/Interfaces/IClipboardService.cs index f5bb4782..ef2ab61a 100644 --- a/Wino.Core.Domain/Interfaces/IClipboardService.cs +++ b/Wino.Core.Domain/Interfaces/IClipboardService.cs @@ -1,9 +1,8 @@ using System.Threading.Tasks; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IClipboardService { - public interface IClipboardService - { - Task CopyClipboardAsync(string text); - } + Task CopyClipboardAsync(string text); } diff --git a/Wino.Core.Domain/Interfaces/IConfigurationService.cs b/Wino.Core.Domain/Interfaces/IConfigurationService.cs index c08c463c..a32410d6 100644 --- a/Wino.Core.Domain/Interfaces/IConfigurationService.cs +++ b/Wino.Core.Domain/Interfaces/IConfigurationService.cs @@ -1,11 +1,10 @@ -namespace Wino.Core.Domain.Interfaces -{ - public interface IConfigurationService - { - void Set(string key, object value); - T Get(string key, T defaultValue = default); +namespace Wino.Core.Domain.Interfaces; - void SetRoaming(string key, object value); - T GetRoaming(string key, T defaultValue = default); - } +public interface IConfigurationService +{ + void Set(string key, object value); + T Get(string key, T defaultValue = default); + + void SetRoaming(string key, object value); + T GetRoaming(string key, T defaultValue = default); } diff --git a/Wino.Core.Domain/Interfaces/IContactService.cs b/Wino.Core.Domain/Interfaces/IContactService.cs index e9e1df7d..e721ec2a 100644 --- a/Wino.Core.Domain/Interfaces/IContactService.cs +++ b/Wino.Core.Domain/Interfaces/IContactService.cs @@ -3,13 +3,12 @@ using System.Threading.Tasks; using MimeKit; using Wino.Core.Domain.Entities.Shared; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IContactService { - public interface IContactService - { - Task> GetAddressInformationAsync(string queryText); - Task GetAddressInformationByAddressAsync(string address); - Task SaveAddressInformationAsync(MimeMessage message); - Task CreateNewContactAsync(string address, string displayName); - } + Task> GetAddressInformationAsync(string queryText); + Task GetAddressInformationByAddressAsync(string address); + Task SaveAddressInformationAsync(MimeMessage message); + Task CreateNewContactAsync(string address, string displayName); } diff --git a/Wino.Core.Domain/Interfaces/IContextMenuItemService.cs b/Wino.Core.Domain/Interfaces/IContextMenuItemService.cs index 06d91240..c3b1c54d 100644 --- a/Wino.Core.Domain/Interfaces/IContextMenuItemService.cs +++ b/Wino.Core.Domain/Interfaces/IContextMenuItemService.cs @@ -3,12 +3,11 @@ using Wino.Core.Domain.Models.Folders; using Wino.Core.Domain.Models.MailItem; using Wino.Core.Domain.Models.Menus; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IContextMenuItemService { - public interface IContextMenuItemService - { - IEnumerable GetFolderContextMenuActions(IBaseFolderMenuItem folderInformation); - IEnumerable GetMailItemContextMenuActions(IEnumerable selectedMailItems); - IEnumerable GetMailItemRenderMenuActions(IMailItem mailItem, bool isDarkEditor); - } + IEnumerable GetFolderContextMenuActions(IBaseFolderMenuItem folderInformation); + IEnumerable GetMailItemContextMenuActions(IEnumerable selectedMailItems); + IEnumerable GetMailItemRenderMenuActions(IMailItem mailItem, bool isDarkEditor); } diff --git a/Wino.Core.Domain/Interfaces/IContextMenuProvider.cs b/Wino.Core.Domain/Interfaces/IContextMenuProvider.cs index 968b2c2c..7e7ef089 100644 --- a/Wino.Core.Domain/Interfaces/IContextMenuProvider.cs +++ b/Wino.Core.Domain/Interfaces/IContextMenuProvider.cs @@ -3,28 +3,27 @@ using Wino.Core.Domain.Models.Folders; using Wino.Core.Domain.Models.MailItem; using Wino.Core.Domain.Models.Menus; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IContextMenuProvider { - public interface IContextMenuProvider - { - /// - /// Calculates and returns available folder operations for the given folder. - /// - /// Folder to get actions for. - IEnumerable GetFolderContextMenuActions(IMailItemFolder folderInformation); + /// + /// Calculates and returns available folder operations for the given folder. + /// + /// Folder to get actions for. + IEnumerable GetFolderContextMenuActions(IMailItemFolder folderInformation); - /// - /// Calculates and returns available context menu items for selected mail items. - /// - /// Current folder that asks for the menu items. - /// Selected menu items in the given folder. - IEnumerable GetMailItemContextMenuActions(IMailItemFolder folderInformation, IEnumerable selectedMailItems); + /// + /// Calculates and returns available context menu items for selected mail items. + /// + /// Current folder that asks for the menu items. + /// Selected menu items in the given folder. + IEnumerable GetMailItemContextMenuActions(IMailItemFolder folderInformation, IEnumerable selectedMailItems); - /// - /// Calculates and returns available mail operations for mail rendering CommandBar. - /// - /// Rendered mail item. - /// Folder that mail item belongs to. - IEnumerable GetMailItemRenderMenuActions(IMailItem mailItem, IMailItemFolder activeFolder, bool isDarkEditor); - } + /// + /// Calculates and returns available mail operations for mail rendering CommandBar. + /// + /// Rendered mail item. + /// Folder that mail item belongs to. + IEnumerable GetMailItemRenderMenuActions(IMailItem mailItem, IMailItemFolder activeFolder, bool isDarkEditor); } diff --git a/Wino.Core.Domain/Interfaces/ICreateAccountAliasDialog.cs b/Wino.Core.Domain/Interfaces/ICreateAccountAliasDialog.cs index 35341304..d787fe3d 100644 --- a/Wino.Core.Domain/Interfaces/ICreateAccountAliasDialog.cs +++ b/Wino.Core.Domain/Interfaces/ICreateAccountAliasDialog.cs @@ -1,9 +1,8 @@ using Wino.Core.Domain.Entities.Mail; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface ICreateAccountAliasDialog { - public interface ICreateAccountAliasDialog - { - public MailAccountAlias CreatedAccountAlias { get; set; } - } + public MailAccountAlias CreatedAccountAlias { get; set; } } diff --git a/Wino.Core.Domain/Interfaces/ICustomFolderSynchronizationRequest.cs b/Wino.Core.Domain/Interfaces/ICustomFolderSynchronizationRequest.cs index 36c90040..ae756a92 100644 --- a/Wino.Core.Domain/Interfaces/ICustomFolderSynchronizationRequest.cs +++ b/Wino.Core.Domain/Interfaces/ICustomFolderSynchronizationRequest.cs @@ -1,22 +1,21 @@ using System; using System.Collections.Generic; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +/// +/// An interface that should force synchronizer to do synchronization for only given folder ids +/// after the execution is completed. +/// +public interface ICustomFolderSynchronizationRequest { /// - /// An interface that should force synchronizer to do synchronization for only given folder ids - /// after the execution is completed. + /// Which folders to sync after this operation? /// - public interface ICustomFolderSynchronizationRequest - { - /// - /// Which folders to sync after this operation? - /// - List SynchronizationFolderIds { get; } + List SynchronizationFolderIds { get; } - /// - /// If true, additional folders like Sent, Drafts and Deleted will not be synchronized - /// - bool ExcludeMustHaveFolders { get; } - } + /// + /// If true, additional folders like Sent, Drafts and Deleted will not be synchronized + /// + bool ExcludeMustHaveFolders { get; } } diff --git a/Wino.Core.Domain/Interfaces/IDialogServiceBase.cs b/Wino.Core.Domain/Interfaces/IDialogServiceBase.cs index 42789f42..ba2cbf0b 100644 --- a/Wino.Core.Domain/Interfaces/IDialogServiceBase.cs +++ b/Wino.Core.Domain/Interfaces/IDialogServiceBase.cs @@ -6,29 +6,28 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.Accounts; using Wino.Core.Domain.Models.Common; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IDialogServiceBase { - public interface IDialogServiceBase - { - Task PickWindowsFolderAsync(); - Task PickWindowsFileContentAsync(params object[] typeFilters); - Task ShowConfirmationDialogAsync(string question, string title, string confirmationButtonTitle); - Task ShowMessageAsync(string message, string title, WinoCustomMessageDialogIcon icon); - void InfoBarMessage(string title, string message, InfoBarMessageType messageType); - void InfoBarMessage(string title, string message, InfoBarMessageType messageType, string actionButtonText, Action action); - void ShowNotSupportedMessage(); - Task ShowEditAccountDialogAsync(MailAccount account); - Task ShowTextInputDialogAsync(string currentInput, string dialogTitle, string dialogDescription, string primaryButtonText); - Task ShowWinoCustomMessageDialogAsync(string title, - string description, - string approveButtonText, - WinoCustomMessageDialogIcon? icon, - string cancelButtonText = "", - string dontAskAgainConfigurationKey = ""); - Task ShowCustomThemeBuilderDialogAsync(); - Task ShowAccountProviderSelectionDialogAsync(List availableProviders); - IAccountCreationDialog GetAccountCreationDialog(AccountCreationDialogResult accountCreationDialogResult); - Task> PickFilesAsync(params object[] typeFilters); - Task PickFilePathAsync(string saveFileName); - } + Task PickWindowsFolderAsync(); + Task PickWindowsFileContentAsync(params object[] typeFilters); + Task ShowConfirmationDialogAsync(string question, string title, string confirmationButtonTitle); + Task ShowMessageAsync(string message, string title, WinoCustomMessageDialogIcon icon); + void InfoBarMessage(string title, string message, InfoBarMessageType messageType); + void InfoBarMessage(string title, string message, InfoBarMessageType messageType, string actionButtonText, Action action); + void ShowNotSupportedMessage(); + Task ShowEditAccountDialogAsync(MailAccount account); + Task ShowTextInputDialogAsync(string currentInput, string dialogTitle, string dialogDescription, string primaryButtonText); + Task ShowWinoCustomMessageDialogAsync(string title, + string description, + string approveButtonText, + WinoCustomMessageDialogIcon? icon, + string cancelButtonText = "", + string dontAskAgainConfigurationKey = ""); + Task ShowCustomThemeBuilderDialogAsync(); + Task ShowAccountProviderSelectionDialogAsync(List availableProviders); + IAccountCreationDialog GetAccountCreationDialog(AccountCreationDialogResult accountCreationDialogResult); + Task> PickFilesAsync(params object[] typeFilters); + Task PickFilePathAsync(string saveFileName); } diff --git a/Wino.Core.Domain/Interfaces/IDispatcher.cs b/Wino.Core.Domain/Interfaces/IDispatcher.cs index 0eb9f08b..b6fb1dd3 100644 --- a/Wino.Core.Domain/Interfaces/IDispatcher.cs +++ b/Wino.Core.Domain/Interfaces/IDispatcher.cs @@ -1,10 +1,9 @@ using System; using System.Threading.Tasks; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IDispatcher { - public interface IDispatcher - { - Task ExecuteOnUIThread(Action action); - } + Task ExecuteOnUIThread(Action action); } diff --git a/Wino.Core.Domain/Interfaces/IFileService.cs b/Wino.Core.Domain/Interfaces/IFileService.cs index 6fbe5d96..6b47a99c 100644 --- a/Wino.Core.Domain/Interfaces/IFileService.cs +++ b/Wino.Core.Domain/Interfaces/IFileService.cs @@ -1,20 +1,19 @@ using System.IO; using System.Threading.Tasks; -namespace Wino.Core.Domain.Interfaces -{ - public interface IFileService - { - Task CopyFileAsync(string sourceFilePath, string destinationFolderPath); - Task GetFileStreamAsync(string folderPath, string fileName); - Task GetFileContentByApplicationUriAsync(string resourcePath); +namespace Wino.Core.Domain.Interfaces; - /// - /// Zips all existing logs and saves to picked destination folder. - /// - /// Folder path where logs are stored. - /// Target path to save the archive file. - /// True if zip is created with at least one item, false if logs are not found. - Task SaveLogsToFolderAsync(string logsFolder, string destinationFolder); - } +public interface IFileService +{ + Task CopyFileAsync(string sourceFilePath, string destinationFolderPath); + Task GetFileStreamAsync(string folderPath, string fileName); + Task GetFileContentByApplicationUriAsync(string resourcePath); + + /// + /// Zips all existing logs and saves to picked destination folder. + /// + /// Folder path where logs are stored. + /// Target path to save the archive file. + /// True if zip is created with at least one item, false if logs are not found. + Task SaveLogsToFolderAsync(string logsFolder, string destinationFolder); } diff --git a/Wino.Core.Domain/Interfaces/IFolderMenuItem.cs b/Wino.Core.Domain/Interfaces/IFolderMenuItem.cs index 6c1fdf33..7deff38d 100644 --- a/Wino.Core.Domain/Interfaces/IFolderMenuItem.cs +++ b/Wino.Core.Domain/Interfaces/IFolderMenuItem.cs @@ -3,30 +3,29 @@ using Wino.Core.Domain.Entities.Shared; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.Folders; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IFolderMenuItem : IBaseFolderMenuItem { - public interface IFolderMenuItem : IBaseFolderMenuItem - { - MailAccount ParentAccount { get; } - void UpdateParentAccounnt(MailAccount account); - } - - public interface IMergedAccountFolderMenuItem : IBaseFolderMenuItem { } - - public interface IBaseFolderMenuItem : IMenuItem - { - string FolderName { get; } - bool IsSynchronizationEnabled { get; } - int UnreadItemCount { get; set; } - SpecialFolderType SpecialFolderType { get; } - IEnumerable HandlingFolders { get; } - IEnumerable SubMenuItems { get; } - bool IsMoveTarget { get; } - bool IsSticky { get; } - bool IsSystemFolder { get; } - bool ShowUnreadCount { get; } - string AssignedAccountName { get; } - - void UpdateFolder(IMailItemFolder folder); - } + MailAccount ParentAccount { get; } + void UpdateParentAccounnt(MailAccount account); +} + +public interface IMergedAccountFolderMenuItem : IBaseFolderMenuItem { } + +public interface IBaseFolderMenuItem : IMenuItem +{ + string FolderName { get; } + bool IsSynchronizationEnabled { get; } + int UnreadItemCount { get; set; } + SpecialFolderType SpecialFolderType { get; } + IEnumerable HandlingFolders { get; } + IEnumerable SubMenuItems { get; } + bool IsMoveTarget { get; } + bool IsSticky { get; } + bool IsSystemFolder { get; } + bool ShowUnreadCount { get; } + string AssignedAccountName { get; } + + void UpdateFolder(IMailItemFolder folder); } diff --git a/Wino.Core.Domain/Interfaces/IFolderService.cs b/Wino.Core.Domain/Interfaces/IFolderService.cs index c7a27a87..33cf1f35 100644 --- a/Wino.Core.Domain/Interfaces/IFolderService.cs +++ b/Wino.Core.Domain/Interfaces/IFolderService.cs @@ -9,87 +9,86 @@ using Wino.Core.Domain.Models.Folders; using Wino.Core.Domain.Models.MailItem; using Wino.Core.Domain.Models.Synchronization; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IFolderService { - public interface IFolderService - { - Task GetFolderStructureForAccountAsync(Guid accountId, bool includeHiddenFolders); - Task GetFolderAsync(Guid folderId); - Task GetFolderAsync(Guid accountId, string remoteFolderId); - Task> GetFoldersAsync(Guid accountId); - Task GetSpecialFolderByAccountIdAsync(Guid accountId, SpecialFolderType type); - Task GetCurrentItemCountForFolder(Guid folderId); - Task GetFolderNotificationBadgeAsync(Guid folderId); - Task ChangeStickyStatusAsync(Guid folderId, bool isSticky); + Task GetFolderStructureForAccountAsync(Guid accountId, bool includeHiddenFolders); + Task GetFolderAsync(Guid folderId); + Task GetFolderAsync(Guid accountId, string remoteFolderId); + Task> GetFoldersAsync(Guid accountId); + Task GetSpecialFolderByAccountIdAsync(Guid accountId, SpecialFolderType type); + Task GetCurrentItemCountForFolder(Guid folderId); + Task GetFolderNotificationBadgeAsync(Guid folderId); + Task ChangeStickyStatusAsync(Guid folderId, bool isSticky); - Task UpdateSystemFolderConfigurationAsync(Guid accountId, SystemFolderConfiguration configuration); - Task ChangeFolderSynchronizationStateAsync(Guid folderId, bool isSynchronizationEnabled); - Task ChangeFolderShowUnreadCountStateAsync(Guid folderId, bool showUnreadCount); + Task UpdateSystemFolderConfigurationAsync(Guid accountId, SystemFolderConfiguration configuration); + Task ChangeFolderSynchronizationStateAsync(Guid folderId, bool isSynchronizationEnabled); + Task ChangeFolderShowUnreadCountStateAsync(Guid folderId, bool showUnreadCount); - Task> GetSynchronizationFoldersAsync(MailSynchronizationOptions options); + Task> GetSynchronizationFoldersAsync(MailSynchronizationOptions options); - /// - /// Returns the folder - mail mapping for the given mail copy ids. - /// - Task> GetMailFolderPairMetadatasAsync(IEnumerable mailCopyIds); + /// + /// Returns the folder - mail mapping for the given mail copy ids. + /// + Task> GetMailFolderPairMetadatasAsync(IEnumerable mailCopyIds); - /// - /// Returns the folder - mail mapping for the given mail copy id. - /// - Task> GetMailFolderPairMetadatasAsync(string mailCopyId); + /// + /// Returns the folder - mail mapping for the given mail copy id. + /// + Task> GetMailFolderPairMetadatasAsync(string mailCopyId); - /// - /// Deletes the folder for the given account by remote folder id. - /// - /// Account to remove from. - /// Remote folder id. - /// - Task DeleteFolderAsync(Guid accountId, string remoteFolderId); + /// + /// Deletes the folder for the given account by remote folder id. + /// + /// Account to remove from. + /// Remote folder id. + /// + Task DeleteFolderAsync(Guid accountId, string remoteFolderId); - /// - /// Adds a new folder. - /// - /// Folder to add. - Task InsertFolderAsync(MailItemFolder folder); + /// + /// Adds a new folder. + /// + /// Folder to add. + Task InsertFolderAsync(MailItemFolder folder); - /// - /// Returns the known uids for the given folder. - /// Only used for IMAP - /// - /// Folder to get uIds for - Task> GetKnownUidsForFolderAsync(Guid folderId); + /// + /// Returns the known uids for the given folder. + /// Only used for IMAP + /// + /// Folder to get uIds for + Task> GetKnownUidsForFolderAsync(Guid folderId); - /// - /// Checks if Inbox special folder exists for an account. - /// - /// Account id to check for. - /// True if Inbox exists, False if not. - Task IsInboxAvailableForAccountAsync(Guid accountId); + /// + /// Checks if Inbox special folder exists for an account. + /// + /// Account id to check for. + /// True if Inbox exists, False if not. + Task IsInboxAvailableForAccountAsync(Guid accountId); - /// - /// Updates folder's LastSynchronizedDate to now. - /// - /// Folder to update. - Task UpdateFolderLastSyncDateAsync(Guid folderId); + /// + /// Updates folder's LastSynchronizedDate to now. + /// + /// Folder to update. + Task UpdateFolderLastSyncDateAsync(Guid folderId); - /// - /// Updates the given folder. - /// - /// Folder to update. - Task UpdateFolderAsync(MailItemFolder folder); + /// + /// Updates the given folder. + /// + /// Folder to update. + Task UpdateFolderAsync(MailItemFolder folder); - /// - /// Returns the active folder menu items for the given account for UI. - /// - /// Account to get folder menu items for. - Task> GetAccountFoldersForDisplayAsync(IAccountMenuItem accountMenuItem); + /// + /// Returns the active folder menu items for the given account for UI. + /// + /// Account to get folder menu items for. + Task> GetAccountFoldersForDisplayAsync(IAccountMenuItem accountMenuItem); - /// - /// Returns a list of unread item counts for the given account ids. - /// Every folder that is marked as show unread badge is included. - /// - /// Account ids to get unread folder counts for. - Task> GetUnreadItemCountResultsAsync(IEnumerable accountIds); - } + /// + /// Returns a list of unread item counts for the given account ids. + /// Every folder that is marked as show unread badge is included. + /// + /// Account ids to get unread folder counts for. + Task> GetUnreadItemCountResultsAsync(IEnumerable accountIds); } diff --git a/Wino.Core.Domain/Interfaces/IFontService.cs b/Wino.Core.Domain/Interfaces/IFontService.cs index ac938bd9..ac2d3249 100644 --- a/Wino.Core.Domain/Interfaces/IFontService.cs +++ b/Wino.Core.Domain/Interfaces/IFontService.cs @@ -1,16 +1,15 @@ using System.Collections.Generic; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +/// +/// Service to access available fonts. +/// +public interface IFontService { /// - /// Service to access available fonts. + /// Get available fonts. Default + installed system fonts. + /// Fonts initialized only once. To refresh fonts, restart the application. /// - public interface IFontService - { - /// - /// Get available fonts. Default + installed system fonts. - /// Fonts initialized only once. To refresh fonts, restart the application. - /// - List GetFonts(); - } + List GetFonts(); } diff --git a/Wino.Core.Domain/Interfaces/IGmailThreadingStrategy.cs b/Wino.Core.Domain/Interfaces/IGmailThreadingStrategy.cs index 2348d8b2..17ec3b74 100644 --- a/Wino.Core.Domain/Interfaces/IGmailThreadingStrategy.cs +++ b/Wino.Core.Domain/Interfaces/IGmailThreadingStrategy.cs @@ -1,4 +1,3 @@ -namespace Wino.Core.Domain.Interfaces -{ - public interface IGmailThreadingStrategy : IThreadingStrategy { } -} +namespace Wino.Core.Domain.Interfaces; + +public interface IGmailThreadingStrategy : IThreadingStrategy { } diff --git a/Wino.Core.Domain/Interfaces/IImapAccountCreationDialog.cs b/Wino.Core.Domain/Interfaces/IImapAccountCreationDialog.cs index 9230aec0..21d9fb47 100644 --- a/Wino.Core.Domain/Interfaces/IImapAccountCreationDialog.cs +++ b/Wino.Core.Domain/Interfaces/IImapAccountCreationDialog.cs @@ -1,25 +1,24 @@ using System.Threading.Tasks; using Wino.Core.Domain.Entities.Shared; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IImapAccountCreationDialog : IAccountCreationDialog { - public interface IImapAccountCreationDialog : IAccountCreationDialog - { - /// - /// Returns the custom server information from the dialog.. - /// - /// Null if canceled. - Task GetCustomServerInformationAsync(); + /// + /// Returns the custom server information from the dialog.. + /// + /// Null if canceled. + Task GetCustomServerInformationAsync(); - /// - /// Displays preparing folders page. - /// - void ShowPreparingFolders(); + /// + /// Displays preparing folders page. + /// + void ShowPreparingFolders(); - /// - /// Updates account properties for the welcome imap setup dialog and starts the setup. - /// - /// Account properties. - void StartImapConnectionSetup(MailAccount account); - } + /// + /// Updates account properties for the welcome imap setup dialog and starts the setup. + /// + /// Account properties. + void StartImapConnectionSetup(MailAccount account); } diff --git a/Wino.Core.Domain/Interfaces/IImapSynchronizationStrategyProvider.cs b/Wino.Core.Domain/Interfaces/IImapSynchronizationStrategyProvider.cs index 6292285f..3fafc48e 100644 --- a/Wino.Core.Domain/Interfaces/IImapSynchronizationStrategyProvider.cs +++ b/Wino.Core.Domain/Interfaces/IImapSynchronizationStrategyProvider.cs @@ -1,12 +1,11 @@ using MailKit.Net.Imap; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +/// +/// Provides a synchronization strategy for synchronizing IMAP folders based on the server capabilities. +/// +public interface IImapSynchronizationStrategyProvider { - /// - /// Provides a synchronization strategy for synchronizing IMAP folders based on the server capabilities. - /// - public interface IImapSynchronizationStrategyProvider - { - IImapSynchronizerStrategy GetSynchronizationStrategy(IImapClient client); - } + IImapSynchronizerStrategy GetSynchronizationStrategy(IImapClient client); } diff --git a/Wino.Core.Domain/Interfaces/IImapSynchronizer.cs b/Wino.Core.Domain/Interfaces/IImapSynchronizer.cs index 6d3fca5d..496eeb92 100644 --- a/Wino.Core.Domain/Interfaces/IImapSynchronizer.cs +++ b/Wino.Core.Domain/Interfaces/IImapSynchronizer.cs @@ -4,14 +4,13 @@ using System.Threading.Tasks; using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Models.MailItem; -namespace Wino.Core.Domain.Interfaces -{ - public interface IImapSynchronizer - { - uint InitialMessageDownloadCountPerFolder { get; } +namespace Wino.Core.Domain.Interfaces; - Task> CreateNewMailPackagesAsync(ImapMessageCreationPackage message, MailItemFolder assignedFolder, CancellationToken cancellationToken = default); - Task StartIdleClientAsync(); - Task StopIdleClientAsync(); - } +public interface IImapSynchronizer +{ + uint InitialMessageDownloadCountPerFolder { get; } + + Task> CreateNewMailPackagesAsync(ImapMessageCreationPackage message, MailItemFolder assignedFolder, CancellationToken cancellationToken = default); + Task StartIdleClientAsync(); + Task StopIdleClientAsync(); } diff --git a/Wino.Core.Domain/Interfaces/IImapSynchronizerStrategy.cs b/Wino.Core.Domain/Interfaces/IImapSynchronizerStrategy.cs index 0b1f7aff..be6e1218 100644 --- a/Wino.Core.Domain/Interfaces/IImapSynchronizerStrategy.cs +++ b/Wino.Core.Domain/Interfaces/IImapSynchronizerStrategy.cs @@ -4,19 +4,18 @@ using System.Threading.Tasks; using MailKit.Net.Imap; using Wino.Core.Domain.Entities.Mail; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IImapSynchronizerStrategy { - public interface IImapSynchronizerStrategy - { - /// - /// Synchronizes given folder with the ImapClient client from the client pool. - /// - /// Client to perform sync with. I love Mira and Jasminka - /// Folder to synchronize. - /// Imap synchronizer that downloads messages. - /// Cancellation token. - /// List of new downloaded message ids that don't exist locally. - Task> HandleSynchronizationAsync(IImapClient client, MailItemFolder folder, IImapSynchronizer synchronizer, CancellationToken cancellationToken = default); - } + /// + /// Synchronizes given folder with the ImapClient client from the client pool. + /// + /// Client to perform sync with. I love Mira and Jasminka + /// Folder to synchronize. + /// Imap synchronizer that downloads messages. + /// Cancellation token. + /// List of new downloaded message ids that don't exist locally. + Task> HandleSynchronizationAsync(IImapClient client, MailItemFolder folder, IImapSynchronizer synchronizer, CancellationToken cancellationToken = default); } diff --git a/Wino.Core.Domain/Interfaces/IImapTestService.cs b/Wino.Core.Domain/Interfaces/IImapTestService.cs index d79837e6..4ceeef68 100644 --- a/Wino.Core.Domain/Interfaces/IImapTestService.cs +++ b/Wino.Core.Domain/Interfaces/IImapTestService.cs @@ -1,10 +1,9 @@ using System.Threading.Tasks; using Wino.Core.Domain.Entities.Shared; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IImapTestService { - public interface IImapTestService - { - Task TestImapConnectionAsync(CustomServerInformation serverInformation, bool allowSSLHandShake); - } + Task TestImapConnectionAsync(CustomServerInformation serverInformation, bool allowSSLHandShake); } diff --git a/Wino.Core.Domain/Interfaces/IImapThreadingStrategy.cs b/Wino.Core.Domain/Interfaces/IImapThreadingStrategy.cs index 47883ac4..b613cd70 100644 --- a/Wino.Core.Domain/Interfaces/IImapThreadingStrategy.cs +++ b/Wino.Core.Domain/Interfaces/IImapThreadingStrategy.cs @@ -1,4 +1,3 @@ -namespace Wino.Core.Domain.Interfaces -{ - public interface IImapThreadingStrategy : IThreadingStrategy { } -} +namespace Wino.Core.Domain.Interfaces; + +public interface IImapThreadingStrategy : IThreadingStrategy { } diff --git a/Wino.Core.Domain/Interfaces/IInitializeAsync.cs b/Wino.Core.Domain/Interfaces/IInitializeAsync.cs index 1850a7c0..d12e45dd 100644 --- a/Wino.Core.Domain/Interfaces/IInitializeAsync.cs +++ b/Wino.Core.Domain/Interfaces/IInitializeAsync.cs @@ -1,12 +1,11 @@ using System.Threading.Tasks; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +/// +/// An interface that all startup services must implement. +/// +public interface IInitializeAsync { - /// - /// An interface that all startup services must implement. - /// - public interface IInitializeAsync - { - Task InitializeAsync(); - } + Task InitializeAsync(); } diff --git a/Wino.Core.Domain/Interfaces/IKeyPressService.cs b/Wino.Core.Domain/Interfaces/IKeyPressService.cs index 724ad0c4..79fb90c2 100644 --- a/Wino.Core.Domain/Interfaces/IKeyPressService.cs +++ b/Wino.Core.Domain/Interfaces/IKeyPressService.cs @@ -1,8 +1,7 @@ -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IKeyPressService { - public interface IKeyPressService - { - bool IsCtrlKeyPressed(); - bool IsShiftKeyPressed(); - } + bool IsCtrlKeyPressed(); + bool IsShiftKeyPressed(); } diff --git a/Wino.Core.Domain/Interfaces/ILogInitializer.cs b/Wino.Core.Domain/Interfaces/ILogInitializer.cs index 13accf16..35870d53 100644 --- a/Wino.Core.Domain/Interfaces/ILogInitializer.cs +++ b/Wino.Core.Domain/Interfaces/ILogInitializer.cs @@ -1,9 +1,8 @@ -namespace Wino.Core.Domain.Interfaces -{ - public interface ILogInitializer - { - void SetupLogger(string fullLogFilePath); +namespace Wino.Core.Domain.Interfaces; - void RefreshLoggingLevel(); - } +public interface ILogInitializer +{ + void SetupLogger(string fullLogFilePath); + + void RefreshLoggingLevel(); } diff --git a/Wino.Core.Domain/Interfaces/IMailDialogService.cs b/Wino.Core.Domain/Interfaces/IMailDialogService.cs index 1e122d5c..53050931 100644 --- a/Wino.Core.Domain/Interfaces/IMailDialogService.cs +++ b/Wino.Core.Domain/Interfaces/IMailDialogService.cs @@ -7,47 +7,46 @@ using Wino.Core.Domain.Entities.Shared; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.Folders; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IMailDialogService : IDialogServiceBase { - public interface IMailDialogService : IDialogServiceBase - { - Task ShowHardDeleteConfirmationAsync(); - Task HandleSystemFolderConfigurationDialogAsync(Guid accountId, IFolderService folderService); + Task ShowHardDeleteConfirmationAsync(); + Task HandleSystemFolderConfigurationDialogAsync(Guid accountId, IFolderService folderService); - // Custom dialogs - Task ShowMoveMailFolderDialogAsync(List availableFolders); - Task ShowAccountPickerDialogAsync(List availableAccounts); + // Custom dialogs + Task ShowMoveMailFolderDialogAsync(List availableFolders); + Task ShowAccountPickerDialogAsync(List availableAccounts); - /// - /// Displays a dialog to the user for reordering accounts. - /// - /// Available accounts in order. - /// Result model that has dict of AccountId-AccountOrder. - Task ShowAccountReorderDialogAsync(ObservableCollection availableAccounts); + /// + /// Displays a dialog to the user for reordering accounts. + /// + /// Available accounts in order. + /// Result model that has dict of AccountId-AccountOrder. + Task ShowAccountReorderDialogAsync(ObservableCollection availableAccounts); - /// - /// Presents a dialog to the user for selecting folder. - /// - /// Account to get folders for. - /// The reason behind the picking operation - /// Selected folder structure. Null if none. - Task PickFolderAsync(Guid accountId, PickFolderReason reason, IFolderService folderService); + /// + /// Presents a dialog to the user for selecting folder. + /// + /// Account to get folders for. + /// The reason behind the picking operation + /// Selected folder structure. Null if none. + Task PickFolderAsync(Guid accountId, PickFolderReason reason, IFolderService folderService); - /// - /// Presents a dialog to the user for signature creation/modification. - /// - /// Signature information. Null if canceled. - Task ShowSignatureEditorDialog(AccountSignature signatureModel = null); + /// + /// Presents a dialog to the user for signature creation/modification. + /// + /// Signature information. Null if canceled. + Task ShowSignatureEditorDialog(AccountSignature signatureModel = null); - /// - /// Presents a dialog to the user for account alias creation/modification. - /// - /// Created alias model if not canceled. - Task ShowCreateAccountAliasDialogAsync(); + /// + /// Presents a dialog to the user for account alias creation/modification. + /// + /// Created alias model if not canceled. + Task ShowCreateAccountAliasDialogAsync(); - /// - /// Presents a dialog to the user to show email source. - /// - Task ShowMessageSourceDialogAsync(string messageSource); - } + /// + /// Presents a dialog to the user to show email source. + /// + Task ShowMessageSourceDialogAsync(string messageSource); } diff --git a/Wino.Core.Domain/Interfaces/IMailService.cs b/Wino.Core.Domain/Interfaces/IMailService.cs index 3474d8ea..854015e5 100644 --- a/Wino.Core.Domain/Interfaces/IMailService.cs +++ b/Wino.Core.Domain/Interfaces/IMailService.cs @@ -7,115 +7,114 @@ using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Entities.Shared; using Wino.Core.Domain.Models.MailItem; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IMailService { - public interface IMailService - { - Task GetSingleMailItemAsync(string mailCopyId, string remoteFolderId); - Task GetSingleMailItemAsync(Guid uniqueMailId); - Task> FetchMailsAsync(MailListInitializationOptions options, CancellationToken cancellationToken = default); + Task GetSingleMailItemAsync(string mailCopyId, string remoteFolderId); + Task GetSingleMailItemAsync(Guid uniqueMailId); + Task> FetchMailsAsync(MailListInitializationOptions options, CancellationToken cancellationToken = default); - /// - /// Deletes all mail copies for all folders. - /// - /// Account to remove from - /// Mail copy id to remove. - Task DeleteMailAsync(Guid accountId, string mailCopyId); + /// + /// Deletes all mail copies for all folders. + /// + /// Account to remove from + /// Mail copy id to remove. + Task DeleteMailAsync(Guid accountId, string mailCopyId); - Task ChangeReadStatusAsync(string mailCopyId, bool isRead); - Task ChangeFlagStatusAsync(string mailCopyId, bool isFlagged); + Task ChangeReadStatusAsync(string mailCopyId, bool isRead); + Task ChangeFlagStatusAsync(string mailCopyId, bool isFlagged); - Task CreateAssignmentAsync(Guid accountId, string mailCopyId, string remoteFolderId); - Task DeleteAssignmentAsync(Guid accountId, string mailCopyId, string remoteFolderId); + Task CreateAssignmentAsync(Guid accountId, string mailCopyId, string remoteFolderId); + Task DeleteAssignmentAsync(Guid accountId, string mailCopyId, string remoteFolderId); - Task CreateMailAsync(Guid accountId, NewMailItemPackage package); + Task CreateMailAsync(Guid accountId, NewMailItemPackage package); - /// - /// Maps new mail item with the existing local draft copy. - /// In case of failure, it returns false. - /// Then synchronizers must insert a new mail item. - /// - /// Id of the account. It's important to map to the account since if the user use the same account with different providers, this call must map the correct one. - /// UniqueId of the local draft copy. - /// New assigned remote mail item id. - /// New assigned draft id if exists. - /// New message's thread/conversation id. - /// True if mapping is done. False if local copy doesn't exists. - Task MapLocalDraftAsync(Guid accountId, Guid localDraftCopyUniqueId, string newMailCopyId, string newDraftId, string newThreadId); + /// + /// Maps new mail item with the existing local draft copy. + /// In case of failure, it returns false. + /// Then synchronizers must insert a new mail item. + /// + /// Id of the account. It's important to map to the account since if the user use the same account with different providers, this call must map the correct one. + /// UniqueId of the local draft copy. + /// New assigned remote mail item id. + /// New assigned draft id if exists. + /// New message's thread/conversation id. + /// True if mapping is done. False if local copy doesn't exists. + Task MapLocalDraftAsync(Guid accountId, Guid localDraftCopyUniqueId, string newMailCopyId, string newDraftId, string newThreadId); - /// - /// Maps new mail item with the existing local draft copy. - /// - /// - /// - /// - Task MapLocalDraftAsync(string newMailCopyId, string newDraftId, string newThreadId); + /// + /// Maps new mail item with the existing local draft copy. + /// + /// + /// + /// + Task MapLocalDraftAsync(string newMailCopyId, string newDraftId, string newThreadId); - Task UpdateMailAsync(MailCopy mailCopy); + Task UpdateMailAsync(MailCopy mailCopy); - /// - /// Gets the new inserted unread mails after the synchronization. - /// - /// Account id. - /// - /// Mail ids that synchronizer tried to download. If there was an issue with the - /// Items that tried and actually downloaded may differ. This function will return only new inserted ones. - /// - /// Newly inserted unread mails inside the Inbox folder. - Task> GetDownloadedUnreadMailsAsync(Guid accountId, IEnumerable downloadedMailCopyIds); + /// + /// Gets the new inserted unread mails after the synchronization. + /// + /// Account id. + /// + /// Mail ids that synchronizer tried to download. If there was an issue with the + /// Items that tried and actually downloaded may differ. This function will return only new inserted ones. + /// + /// Newly inserted unread mails inside the Inbox folder. + Task> GetDownloadedUnreadMailsAsync(Guid accountId, IEnumerable downloadedMailCopyIds); - /// - /// Returns the account that this mail copy unique id is assigned. - /// Used in toast notification handler. - /// - /// Unique id of the mail item. - /// Account that mail belongs to. - Task GetMailAccountByUniqueIdAsync(Guid uniqueMailId); + /// + /// Returns the account that this mail copy unique id is assigned. + /// Used in toast notification handler. + /// + /// Unique id of the mail item. + /// Account that mail belongs to. + Task GetMailAccountByUniqueIdAsync(Guid uniqueMailId); - /// - /// Checks whether the given mail copy id exists in the database. - /// Safely used for Outlook to prevent downloading the same mail twice. - /// For Gmail, it should be avoided since one mail may belong to multiple folders. - /// - /// Native mail id of the message. - Task IsMailExistsAsync(string mailCopyId); + /// + /// Checks whether the given mail copy id exists in the database. + /// Safely used for Outlook to prevent downloading the same mail twice. + /// For Gmail, it should be avoided since one mail may belong to multiple folders. + /// + /// Native mail id of the message. + Task IsMailExistsAsync(string mailCopyId); - /// - /// Returns all mails for given folder id. - /// - /// Folder id to get mails for - Task> GetMailsByFolderIdAsync(Guid folderId); + /// + /// Returns all mails for given folder id. + /// + /// Folder id to get mails for + Task> GetMailsByFolderIdAsync(Guid folderId); - /// - /// Returns all unread mails for given folder id. - /// - /// Folder id to get unread mails for. - Task> GetUnreadMailsByFolderIdAsync(Guid folderId); + /// + /// Returns all unread mails for given folder id. + /// + /// Folder id to get unread mails for. + Task> GetUnreadMailsByFolderIdAsync(Guid folderId); - /// - /// Checks whether the mail exists in the folder. - /// When deciding Create or Update existing mail, we need to check if the mail exists in the folder. - /// - /// MailCopy id - /// Folder's local id. - /// Whether mail exists in the folder or not. - Task IsMailExistsAsync(string mailCopyId, Guid folderId); + /// + /// Checks whether the mail exists in the folder. + /// When deciding Create or Update existing mail, we need to check if the mail exists in the folder. + /// + /// MailCopy id + /// Folder's local id. + /// Whether mail exists in the folder or not. + Task IsMailExistsAsync(string mailCopyId, Guid folderId); - /// - /// Creates a draft MailCopy and MimeMessage based on the given options. - /// For forward/reply it would include the referenced message. - /// - /// AccountId which should have new draft. - /// Options like new email/forward/draft. - /// Draft MailCopy and Draft MimeMessage as base64. - Task<(MailCopy draftMailCopy, string draftBase64MimeMessage)> CreateDraftAsync(Guid accountId, DraftCreationOptions draftCreationOptions); + /// + /// Creates a draft MailCopy and MimeMessage based on the given options. + /// For forward/reply it would include the referenced message. + /// + /// AccountId which should have new draft. + /// Options like new email/forward/draft. + /// Draft MailCopy and Draft MimeMessage as base64. + Task<(MailCopy draftMailCopy, string draftBase64MimeMessage)> CreateDraftAsync(Guid accountId, DraftCreationOptions draftCreationOptions); - /// - /// Returns ids - /// - /// - /// - /// - Task> GetExistingMailsAsync(Guid folderId, IEnumerable uniqueIds); - } + /// + /// Returns ids + /// + /// + /// + /// + Task> GetExistingMailsAsync(Guid folderId, IEnumerable uniqueIds); } diff --git a/Wino.Core.Domain/Interfaces/IMenuItem.cs b/Wino.Core.Domain/Interfaces/IMenuItem.cs index 68997e3f..25195f82 100644 --- a/Wino.Core.Domain/Interfaces/IMenuItem.cs +++ b/Wino.Core.Domain/Interfaces/IMenuItem.cs @@ -1,41 +1,40 @@ using System; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IMenuItem { - public interface IMenuItem - { - /// - /// An id that this menu item holds. - /// For an account, it's AccountId. - /// For folder, it's FolderId. - /// For merged account, it's MergedAccountId. - /// Null if it's a menu item that doesn't hold any valuable entity. - /// - Guid? EntityId { get; } + /// + /// An id that this menu item holds. + /// For an account, it's AccountId. + /// For folder, it's FolderId. + /// For merged account, it's MergedAccountId. + /// Null if it's a menu item that doesn't hold any valuable entity. + /// + Guid? EntityId { get; } - /// - /// Is any of the sub items that this menu item contains selected. - /// - // bool IsChildSelected { get; } + /// + /// Is any of the sub items that this menu item contains selected. + /// + // bool IsChildSelected { get; } - /// - /// Whether the menu item is expanded or not. - /// - bool IsExpanded { get; set; } + /// + /// Whether the menu item is expanded or not. + /// + bool IsExpanded { get; set; } - /// - /// Whether the menu item is selected or not. - /// - bool IsSelected { get; set; } + /// + /// Whether the menu item is selected or not. + /// + bool IsSelected { get; set; } - /// - /// Parent menu item that contains this menu item. - /// - IMenuItem ParentMenuItem { get; } + /// + /// Parent menu item that contains this menu item. + /// + IMenuItem ParentMenuItem { get; } - /// - /// Recursively expand all parent menu items if parent exists, starting from parent. - /// - void Expand(); - } + /// + /// Recursively expand all parent menu items if parent exists, starting from parent. + /// + void Expand(); } diff --git a/Wino.Core.Domain/Interfaces/IMenuOperation.cs b/Wino.Core.Domain/Interfaces/IMenuOperation.cs index 48279547..2d588edb 100644 --- a/Wino.Core.Domain/Interfaces/IMenuOperation.cs +++ b/Wino.Core.Domain/Interfaces/IMenuOperation.cs @@ -1,8 +1,7 @@ -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IMenuOperation { - public interface IMenuOperation - { - bool IsEnabled { get; } - string Identifier { get; } - } + bool IsEnabled { get; } + string Identifier { get; } } diff --git a/Wino.Core.Domain/Interfaces/IMimeFileService.cs b/Wino.Core.Domain/Interfaces/IMimeFileService.cs index f0d584b8..f459e458 100644 --- a/Wino.Core.Domain/Interfaces/IMimeFileService.cs +++ b/Wino.Core.Domain/Interfaces/IMimeFileService.cs @@ -5,66 +5,65 @@ using MimeKit; using Wino.Core.Domain.Models.MailItem; using Wino.Core.Domain.Models.Reader; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IMimeFileService { - public interface IMimeFileService - { - /// - /// Finds the EML file for the given mail id for address, parses and returns MimeMessage. - /// - /// Cancellation token - /// Mime message information - Task GetMimeMessageInformationAsync(Guid fileId, Guid accountId, CancellationToken cancellationToken = default); + /// + /// Finds the EML file for the given mail id for address, parses and returns MimeMessage. + /// + /// Cancellation token + /// Mime message information + Task GetMimeMessageInformationAsync(Guid fileId, Guid accountId, CancellationToken cancellationToken = default); - /// - /// Gets the mime message information for the given EML file bytes. - /// This override is used when EML file association launch is used - /// because we may not have the access to the file path. - /// - /// Byte array of the file. - /// Cancellation token - /// Mime message information - Task GetMimeMessageInformationAsync(byte[] fileBytes, string emlFilePath, CancellationToken cancellationToken = default); + /// + /// Gets the mime message information for the given EML file bytes. + /// This override is used when EML file association launch is used + /// because we may not have the access to the file path. + /// + /// Byte array of the file. + /// Cancellation token + /// Mime message information + Task GetMimeMessageInformationAsync(byte[] fileBytes, string emlFilePath, CancellationToken cancellationToken = default); - /// - /// Saves EML file to the disk. - /// - /// MailCopy of the native message. - /// MimeMessage that is parsed from native message. - /// Which account Id to save this file for. - Task SaveMimeMessageAsync(Guid fileId, MimeMessage mimeMessage, Guid accountId); + /// + /// Saves EML file to the disk. + /// + /// MailCopy of the native message. + /// MimeMessage that is parsed from native message. + /// Which account Id to save this file for. + Task SaveMimeMessageAsync(Guid fileId, MimeMessage mimeMessage, Guid accountId); - /// - /// Returns a path that all Mime resources (including eml) is stored for this MailCopyId - /// This is useful for storing previously rendered attachments as well. - /// - /// Account address - /// Resource mail copy id - Task GetMimeResourcePathAsync(Guid accountId, Guid fileId); + /// + /// Returns a path that all Mime resources (including eml) is stored for this MailCopyId + /// This is useful for storing previously rendered attachments as well. + /// + /// Account address + /// Resource mail copy id + Task GetMimeResourcePathAsync(Guid accountId, Guid fileId); - /// - /// Returns whether mime file exists locally or not. - /// - Task IsMimeExistAsync(Guid accountId, Guid fileId); + /// + /// Returns whether mime file exists locally or not. + /// + Task IsMimeExistAsync(Guid accountId, Guid fileId); - /// - /// Creates HtmlPreviewVisitor for the given MimeMessage. - /// - /// Mime - /// File path that mime is located to load resources. - HtmlPreviewVisitor CreateHTMLPreviewVisitor(MimeMessage message, string mimeLocalPath); + /// + /// Creates HtmlPreviewVisitor for the given MimeMessage. + /// + /// Mime + /// File path that mime is located to load resources. + HtmlPreviewVisitor CreateHTMLPreviewVisitor(MimeMessage message, string mimeLocalPath); - /// - /// Deletes the given mime file from the disk. - /// - Task DeleteMimeMessageAsync(Guid accountId, Guid fileId); + /// + /// Deletes the given mime file from the disk. + /// + Task DeleteMimeMessageAsync(Guid accountId, Guid fileId); - /// - /// Prepares the final model containing rendering details. - /// - /// Message to render. - /// File path that physical MimeMessage is located. - /// Rendering options - MailRenderModel GetMailRenderModel(MimeMessage message, string mimeLocalPath, MailRenderingOptions options = null); - } + /// + /// Prepares the final model containing rendering details. + /// + /// Message to render. + /// File path that physical MimeMessage is located. + /// Rendering options + MailRenderModel GetMailRenderModel(MimeMessage message, string mimeLocalPath, MailRenderingOptions options = null); } diff --git a/Wino.Core.Domain/Interfaces/INativeAppService.cs b/Wino.Core.Domain/Interfaces/INativeAppService.cs index 9b6335d7..cfbea72f 100644 --- a/Wino.Core.Domain/Interfaces/INativeAppService.cs +++ b/Wino.Core.Domain/Interfaces/INativeAppService.cs @@ -1,26 +1,25 @@ using System; using System.Threading.Tasks; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface INativeAppService { - public interface INativeAppService - { - string GetWebAuthenticationBrokerUri(); - Task GetMimeMessageStoragePath(); - Task GetEditorBundlePathAsync(); - Task LaunchFileAsync(string filePath); - Task LaunchUriAsync(Uri uri); + string GetWebAuthenticationBrokerUri(); + Task GetMimeMessageStoragePath(); + Task GetEditorBundlePathAsync(); + Task LaunchFileAsync(string filePath); + Task LaunchUriAsync(Uri uri); - bool IsAppRunning(); + bool IsAppRunning(); - string GetFullAppVersion(); + string GetFullAppVersion(); - Task PinAppToTaskbarAsync(); + Task PinAppToTaskbarAsync(); - /// - /// Gets or sets the function that returns a pointer for main window hwnd for UWP. - /// This is used to display WAM broker dialog on running UWP app called by a windowless server code. - /// - Func GetCoreWindowHwnd { get; set; } - } + /// + /// Gets or sets the function that returns a pointer for main window hwnd for UWP. + /// This is used to display WAM broker dialog on running UWP app called by a windowless server code. + /// + Func GetCoreWindowHwnd { get; set; } } diff --git a/Wino.Core.Domain/Interfaces/INavigationAware.cs b/Wino.Core.Domain/Interfaces/INavigationAware.cs index 222d7c31..014be20d 100644 --- a/Wino.Core.Domain/Interfaces/INavigationAware.cs +++ b/Wino.Core.Domain/Interfaces/INavigationAware.cs @@ -1,10 +1,9 @@ using Wino.Core.Domain.Models.Navigation; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface INavigationAware { - public interface INavigationAware - { - void OnNavigatedTo(NavigationMode mode, object parameters); - void OnNavigatedFrom(NavigationMode mode, object parameters); - } + void OnNavigatedTo(NavigationMode mode, object parameters); + void OnNavigatedFrom(NavigationMode mode, object parameters); } diff --git a/Wino.Core.Domain/Interfaces/INotificationBuilder.cs b/Wino.Core.Domain/Interfaces/INotificationBuilder.cs index 683bff44..50528ab2 100644 --- a/Wino.Core.Domain/Interfaces/INotificationBuilder.cs +++ b/Wino.Core.Domain/Interfaces/INotificationBuilder.cs @@ -3,24 +3,23 @@ using System.Collections.Generic; using System.Threading.Tasks; using Wino.Core.Domain.Models.MailItem; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface INotificationBuilder { - public interface INotificationBuilder - { - /// - /// Creates toast notifications for new mails. - /// - Task CreateNotificationsAsync(Guid inboxFolderId, IEnumerable newMailItems); + /// + /// Creates toast notifications for new mails. + /// + Task CreateNotificationsAsync(Guid inboxFolderId, IEnumerable newMailItems); - /// - /// Gets the unread Inbox messages for each account and updates the taskbar icon. - /// - /// - Task UpdateTaskbarIconBadgeAsync(); + /// + /// Gets the unread Inbox messages for each account and updates the taskbar icon. + /// + /// + Task UpdateTaskbarIconBadgeAsync(); - /// - /// Creates test notification for test purposes. - /// - Task CreateTestNotificationAsync(string title, string message); - } + /// + /// Creates test notification for test purposes. + /// + Task CreateTestNotificationAsync(string title, string message); } diff --git a/Wino.Core.Domain/Interfaces/IOutlookThreadingStrategy.cs b/Wino.Core.Domain/Interfaces/IOutlookThreadingStrategy.cs index d3618c9b..03525f6f 100644 --- a/Wino.Core.Domain/Interfaces/IOutlookThreadingStrategy.cs +++ b/Wino.Core.Domain/Interfaces/IOutlookThreadingStrategy.cs @@ -1,4 +1,3 @@ -namespace Wino.Core.Domain.Interfaces -{ - public interface IOutlookThreadingStrategy : IThreadingStrategy { } -} +namespace Wino.Core.Domain.Interfaces; + +public interface IOutlookThreadingStrategy : IThreadingStrategy { } diff --git a/Wino.Core.Domain/Interfaces/IPreferencesService.cs b/Wino.Core.Domain/Interfaces/IPreferencesService.cs index afb0c515..739518c0 100644 --- a/Wino.Core.Domain/Interfaces/IPreferencesService.cs +++ b/Wino.Core.Domain/Interfaces/IPreferencesService.cs @@ -3,194 +3,193 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.Calendar; using Wino.Core.Domain.Models.Reader; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IPreferencesService { - public interface IPreferencesService - { - /// - /// When any of the preferences are changed. - /// - event EventHandler PreferenceChanged; + /// + /// When any of the preferences are changed. + /// + event EventHandler PreferenceChanged; - #region Common + #region Common - /// - /// Setting: Whether logs are enabled or not. - /// - bool IsLoggingEnabled { get; set; } + /// + /// Setting: Whether logs are enabled or not. + /// + bool IsLoggingEnabled { get; set; } - /// - /// Setting: Display language for the application. - /// - AppLanguage CurrentLanguage { get; set; } + /// + /// Setting: Display language for the application. + /// + AppLanguage CurrentLanguage { get; set; } - /// - /// Setting: Whether the navigation pane is opened on the last session or not. - /// - bool IsNavigationPaneOpened { get; set; } + /// + /// Setting: Whether the navigation pane is opened on the last session or not. + /// + bool IsNavigationPaneOpened { get; set; } - /// - /// Setting: Gets or sets what should happen to server app when the client is terminated. - /// - ServerBackgroundMode ServerTerminationBehavior { get; set; } + /// + /// Setting: Gets or sets what should happen to server app when the client is terminated. + /// + ServerBackgroundMode ServerTerminationBehavior { get; set; } - /// - /// Setting: Preferred time format for mail or calendar header display. - /// - bool Prefer24HourTimeFormat { get; set; } + /// + /// Setting: Preferred time format for mail or calendar header display. + /// + bool Prefer24HourTimeFormat { get; set; } - #endregion + #endregion - #region Mail + #region Mail - /// - /// Setting: For changing the mail display container mode. - /// - MailListDisplayMode MailItemDisplayMode { get; set; } + /// + /// Setting: For changing the mail display container mode. + /// + MailListDisplayMode MailItemDisplayMode { get; set; } - /// - /// Setting: Marking the item as read preference mode. - /// - MailMarkAsOption MarkAsPreference { get; set; } + /// + /// Setting: Marking the item as read preference mode. + /// + MailMarkAsOption MarkAsPreference { get; set; } - /// - /// Setting: How many seconds should be waited on rendering page to mark item as read. - /// - int MarkAsDelay { get; set; } + /// + /// Setting: How many seconds should be waited on rendering page to mark item as read. + /// + int MarkAsDelay { get; set; } - /// - /// Setting: Ask comfirmation from the user during permanent delete. - /// - bool IsHardDeleteProtectionEnabled { get; set; } + /// + /// Setting: Ask comfirmation from the user during permanent delete. + /// + bool IsHardDeleteProtectionEnabled { get; set; } - /// - /// Setting: Thread mails into conversations. - /// - bool IsThreadingEnabled { get; set; } + /// + /// Setting: Thread mails into conversations. + /// + bool IsThreadingEnabled { get; set; } - /// - /// Setting: Show sender pictures in mail list. - /// - bool IsShowSenderPicturesEnabled { get; set; } + /// + /// Setting: Show sender pictures in mail list. + /// + bool IsShowSenderPicturesEnabled { get; set; } - /// - /// Setting: Show preview text in mail list. - /// - bool IsShowPreviewEnabled { get; set; } + /// + /// Setting: Show preview text in mail list. + /// + bool IsShowPreviewEnabled { get; set; } - /// - /// Setting: Enable/disable semantic zoom on clicking date headers. - /// - bool IsSemanticZoomEnabled { get; set; } + /// + /// Setting: Enable/disable semantic zoom on clicking date headers. + /// + bool IsSemanticZoomEnabled { get; set; } - /// - /// Setting: Set whether 'img' tags in rendered HTMLs should be removed. - /// - bool RenderImages { get; set; } + /// + /// Setting: Set whether 'img' tags in rendered HTMLs should be removed. + /// + bool RenderImages { get; set; } - /// - /// Setting: Set whether 'style' tags in rendered HTMls should be removed. - /// - bool RenderStyles { get; set; } + /// + /// Setting: Set whether 'style' tags in rendered HTMls should be removed. + /// + bool RenderStyles { get; set; } - /// - /// Setting: Set whether plaintext links should be automatically converted to clickable links. - /// - bool RenderPlaintextLinks { get; set; } + /// + /// Setting: Set whether plaintext links should be automatically converted to clickable links. + /// + bool RenderPlaintextLinks { get; set; } - /// - /// Gets the preferred rendering options for HTML rendering. - /// - MailRenderingOptions GetRenderingOptions(); + /// + /// Gets the preferred rendering options for HTML rendering. + /// + MailRenderingOptions GetRenderingOptions(); - /// - /// Setting: Swipe mail operation when mails are swiped to right. - /// - MailOperation RightSwipeOperation { get; set; } + /// + /// Setting: Swipe mail operation when mails are swiped to right. + /// + MailOperation RightSwipeOperation { get; set; } - /// - /// Setting: Swipe mail operation when mails are swiped to left. - /// - MailOperation LeftSwipeOperation { get; set; } + /// + /// Setting: Swipe mail operation when mails are swiped to left. + /// + MailOperation LeftSwipeOperation { get; set; } - /// - /// Setting: Whether hover actions on mail pointer hover is enabled or not. - /// - bool IsHoverActionsEnabled { get; set; } + /// + /// Setting: Whether hover actions on mail pointer hover is enabled or not. + /// + bool IsHoverActionsEnabled { get; set; } - /// - /// Setting: Hover action on the left when the mail is hovered over. - /// - MailOperation LeftHoverAction { get; set; } + /// + /// Setting: Hover action on the left when the mail is hovered over. + /// + MailOperation LeftHoverAction { get; set; } - /// - /// Setting: Hover action on the center when the mail is hovered over. - /// - MailOperation CenterHoverAction { get; set; } + /// + /// Setting: Hover action on the center when the mail is hovered over. + /// + MailOperation CenterHoverAction { get; set; } - /// - /// Setting: Hover action on the right when the mail is hovered over. - /// - MailOperation RightHoverAction { get; set; } + /// + /// Setting: Hover action on the right when the mail is hovered over. + /// + MailOperation RightHoverAction { get; set; } - /// - /// Setting: Whether Mailkit Protocol Logger is enabled for ImapTestService or not. - /// - bool IsMailkitProtocolLoggerEnabled { get; set; } + /// + /// Setting: Whether Mailkit Protocol Logger is enabled for ImapTestService or not. + /// + bool IsMailkitProtocolLoggerEnabled { get; set; } - /// - /// Setting: Which entity id (merged account or folder) should be expanded automatically on startup. - /// - Guid? StartupEntityId { get; set; } + /// + /// Setting: Which entity id (merged account or folder) should be expanded automatically on startup. + /// + Guid? StartupEntityId { get; set; } - /// - /// Setting: Display font for the mail reader. - /// - string ReaderFont { get; set; } + /// + /// Setting: Display font for the mail reader. + /// + string ReaderFont { get; set; } - /// - /// Setting: Font size for the mail reader. - /// - int ReaderFontSize { get; set; } + /// + /// Setting: Font size for the mail reader. + /// + int ReaderFontSize { get; set; } - /// - /// Setting: Display font for the mail composer. - /// - string ComposerFont { get; set; } + /// + /// Setting: Display font for the mail composer. + /// + string ComposerFont { get; set; } - /// - /// Setting: Font size for the mail composer. - /// - int ComposerFontSize { get; set; } + /// + /// Setting: Font size for the mail composer. + /// + int ComposerFontSize { get; set; } - /// - /// Setting: Whether the next item should be automatically selected once the current item is moved or removed. - /// - bool AutoSelectNextItem { get; set; } + /// + /// Setting: Whether the next item should be automatically selected once the current item is moved or removed. + /// + bool AutoSelectNextItem { get; set; } - /// - /// Setting: Whether the mail list action bar is enabled or not. - /// - bool IsMailListActionBarEnabled { get; set; } + /// + /// Setting: Whether the mail list action bar is enabled or not. + /// + bool IsMailListActionBarEnabled { get; set; } - #endregion + #endregion - #region Calendar + #region Calendar - DayOfWeek FirstDayOfWeek { get; set; } - TimeSpan WorkingHourStart { get; set; } - TimeSpan WorkingHourEnd { get; set; } - DayOfWeek WorkingDayStart { get; set; } - DayOfWeek WorkingDayEnd { get; set; } - double HourHeight { get; set; } - string DiagnosticId { get; set; } + DayOfWeek FirstDayOfWeek { get; set; } + TimeSpan WorkingHourStart { get; set; } + TimeSpan WorkingHourEnd { get; set; } + DayOfWeek WorkingDayStart { get; set; } + DayOfWeek WorkingDayEnd { get; set; } + double HourHeight { get; set; } + string DiagnosticId { get; set; } - CalendarSettings GetCurrentCalendarSettings(); + CalendarSettings GetCurrentCalendarSettings(); - #endregion - } + #endregion } diff --git a/Wino.Core.Domain/Interfaces/IPrintService.cs b/Wino.Core.Domain/Interfaces/IPrintService.cs index 29578172..4d8cb33d 100644 --- a/Wino.Core.Domain/Interfaces/IPrintService.cs +++ b/Wino.Core.Domain/Interfaces/IPrintService.cs @@ -1,10 +1,9 @@ using System.Threading.Tasks; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IPrintService { - public interface IPrintService - { - Task PrintPdfFileAsync(string pdfFilePath, string printTitle); - } + Task PrintPdfFileAsync(string pdfFilePath, string printTitle); } diff --git a/Wino.Core.Domain/Interfaces/IProviderDetail.cs b/Wino.Core.Domain/Interfaces/IProviderDetail.cs index 9f4e3602..ec15f723 100644 --- a/Wino.Core.Domain/Interfaces/IProviderDetail.cs +++ b/Wino.Core.Domain/Interfaces/IProviderDetail.cs @@ -1,14 +1,13 @@ using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IProviderDetail { - public interface IProviderDetail - { - MailProviderType Type { get; } - SpecialImapProvider SpecialImapProvider { get; } - string Name { get; } - string Description { get; } - string ProviderImage { get; } - bool IsSupported { get; } - } + MailProviderType Type { get; } + SpecialImapProvider SpecialImapProvider { get; } + string Name { get; } + string Description { get; } + string ProviderImage { get; } + bool IsSupported { get; } } diff --git a/Wino.Core.Domain/Interfaces/IProviderService.cs b/Wino.Core.Domain/Interfaces/IProviderService.cs index 14dc301c..20ef2978 100644 --- a/Wino.Core.Domain/Interfaces/IProviderService.cs +++ b/Wino.Core.Domain/Interfaces/IProviderService.cs @@ -1,11 +1,10 @@ using System.Collections.Generic; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IProviderService { - public interface IProviderService - { - List GetAvailableProviders(); - IProviderDetail GetProviderDetail(MailProviderType type); - } + List GetAvailableProviders(); + IProviderDetail GetProviderDetail(MailProviderType type); } diff --git a/Wino.Core.Domain/Interfaces/IRequestBundle.cs b/Wino.Core.Domain/Interfaces/IRequestBundle.cs index 018bae3f..f88a3dc2 100644 --- a/Wino.Core.Domain/Interfaces/IRequestBundle.cs +++ b/Wino.Core.Domain/Interfaces/IRequestBundle.cs @@ -1,66 +1,65 @@ using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +/// +/// Represents a group of requests. +/// +public interface IRequestBundle +{ + string BundleId { get; set; } + IUIChangeRequest UIChangeRequest { get; } +} + +/// +/// Represents a group of requests with their native response types. +/// +/// Native request type from each synchronizer to store. +public interface IRequestBundle : IRequestBundle +{ + TRequest NativeRequest { get; } + IRequestBase Request { get; } +} + +public interface IRequestBase : IClientMessage, IUIChangeRequest { /// - /// Represents a group of requests. + /// Whether synchronizations should be delayed after executing this request. + /// Specially Outlook sometimes don't report changes back immidiately after sending the API request. + /// This results following synchronization to miss the changes. + /// We add small delay for the following synchronization after executing current requests to overcome this issue. + /// Default is false. /// - public interface IRequestBundle - { - string BundleId { get; set; } - IUIChangeRequest UIChangeRequest { get; } - } + int ResynchronizationDelay { get; } + + object GroupingKey(); +} + +public interface IUIChangeRequest +{ + /// + /// UI changes to apply to the item before sending the request to the server. + /// Changes here only affect the UI, not the item itself. + /// Changes here are reverted if the request fails by calling . + /// + void ApplyUIChanges(); /// - /// Represents a group of requests with their native response types. + /// Reverts the UI changes applied by if the request fails. /// - /// Native request type from each synchronizer to store. - public interface IRequestBundle : IRequestBundle - { - TRequest NativeRequest { get; } - IRequestBase Request { get; } - } - - public interface IRequestBase : IClientMessage, IUIChangeRequest - { - /// - /// Whether synchronizations should be delayed after executing this request. - /// Specially Outlook sometimes don't report changes back immidiately after sending the API request. - /// This results following synchronization to miss the changes. - /// We add small delay for the following synchronization after executing current requests to overcome this issue. - /// Default is false. - /// - int ResynchronizationDelay { get; } - - object GroupingKey(); - } - - public interface IUIChangeRequest - { - /// - /// UI changes to apply to the item before sending the request to the server. - /// Changes here only affect the UI, not the item itself. - /// Changes here are reverted if the request fails by calling . - /// - void ApplyUIChanges(); - - /// - /// Reverts the UI changes applied by if the request fails. - /// - void RevertUIChanges(); - } - - public interface IMailActionRequest : IRequestBase - { - MailCopy Item { get; } - MailSynchronizerOperation Operation { get; } - } - - public interface IFolderActionRequest : IRequestBase - { - MailItemFolder Folder { get; } - - FolderSynchronizerOperation Operation { get; } - } + void RevertUIChanges(); +} + +public interface IMailActionRequest : IRequestBase +{ + MailCopy Item { get; } + MailSynchronizerOperation Operation { get; } +} + +public interface IFolderActionRequest : IRequestBase +{ + MailItemFolder Folder { get; } + + FolderSynchronizerOperation Operation { get; } } diff --git a/Wino.Core.Domain/Interfaces/ISettingsBuilderService.cs b/Wino.Core.Domain/Interfaces/ISettingsBuilderService.cs index 8e94c920..7cca8604 100644 --- a/Wino.Core.Domain/Interfaces/ISettingsBuilderService.cs +++ b/Wino.Core.Domain/Interfaces/ISettingsBuilderService.cs @@ -1,10 +1,9 @@ using System.Collections.Generic; using Wino.Core.Domain.Models.Settings; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface ISettingsBuilderService { - public interface ISettingsBuilderService - { - List GetSettingItems(); - } + List GetSettingItems(); } diff --git a/Wino.Core.Domain/Interfaces/ISignatureService.cs b/Wino.Core.Domain/Interfaces/ISignatureService.cs index 0ed8c990..e1a1d458 100644 --- a/Wino.Core.Domain/Interfaces/ISignatureService.cs +++ b/Wino.Core.Domain/Interfaces/ISignatureService.cs @@ -3,45 +3,44 @@ using System.Collections.Generic; using System.Threading.Tasks; using Wino.Core.Domain.Entities.Mail; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface ISignatureService { - public interface ISignatureService - { - /// - /// Get one signature by Id. - /// - /// Signature Id. - Task GetSignatureAsync(Guid signatureId); + /// + /// Get one signature by Id. + /// + /// Signature Id. + Task GetSignatureAsync(Guid signatureId); - /// - /// Returns all signatures for specified account. - /// - /// Account id - Task> GetSignaturesAsync(Guid accountId); + /// + /// Returns all signatures for specified account. + /// + /// Account id + Task> GetSignaturesAsync(Guid accountId); - /// - /// Creates a new signature for the account. - /// - /// Signature that should be created. It should contain ID and account to which it belongs. - Task CreateSignatureAsync(AccountSignature signature); + /// + /// Creates a new signature for the account. + /// + /// Signature that should be created. It should contain ID and account to which it belongs. + Task CreateSignatureAsync(AccountSignature signature); - /// - /// Creates a default Wino signature for the account. - /// Needed only for initial account setup. - /// - /// Account Id. - Task CreateDefaultSignatureAsync(Guid accountId); + /// + /// Creates a default Wino signature for the account. + /// Needed only for initial account setup. + /// + /// Account Id. + Task CreateDefaultSignatureAsync(Guid accountId); - /// - /// Updates existing signature. - /// - /// Signature that should be updated. It should contain ID and account to which it belongs. - Task UpdateSignatureAsync(AccountSignature signature); + /// + /// Updates existing signature. + /// + /// Signature that should be updated. It should contain ID and account to which it belongs. + Task UpdateSignatureAsync(AccountSignature signature); - /// - /// Deletes existing signature. - /// - /// Signature that should be deleted. - Task DeleteSignatureAsync(AccountSignature signature); - } + /// + /// Deletes existing signature. + /// + /// Signature that should be deleted. + Task DeleteSignatureAsync(AccountSignature signature); } diff --git a/Wino.Core.Domain/Interfaces/ISpecialImapProviderConfigResolver.cs b/Wino.Core.Domain/Interfaces/ISpecialImapProviderConfigResolver.cs index 34c35dbe..de284cc6 100644 --- a/Wino.Core.Domain/Interfaces/ISpecialImapProviderConfigResolver.cs +++ b/Wino.Core.Domain/Interfaces/ISpecialImapProviderConfigResolver.cs @@ -1,10 +1,9 @@ using Wino.Core.Domain.Entities.Shared; using Wino.Core.Domain.Models.Accounts; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface ISpecialImapProviderConfigResolver { - public interface ISpecialImapProviderConfigResolver - { - CustomServerInformation GetServerInformation(MailAccount account, AccountCreationDialogResult dialogResult); - } + CustomServerInformation GetServerInformation(MailAccount account, AccountCreationDialogResult dialogResult); } diff --git a/Wino.Core.Domain/Interfaces/IStartupBehaviorService.cs b/Wino.Core.Domain/Interfaces/IStartupBehaviorService.cs index 3c0b7a61..7da3b6a3 100644 --- a/Wino.Core.Domain/Interfaces/IStartupBehaviorService.cs +++ b/Wino.Core.Domain/Interfaces/IStartupBehaviorService.cs @@ -1,20 +1,19 @@ using System.Threading.Tasks; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Interfaces -{ - public interface IStartupBehaviorService - { - /// - /// Gets whether Wino Server is set to launch on startup or not. - /// - Task GetCurrentStartupBehaviorAsync(); +namespace Wino.Core.Domain.Interfaces; - /// - /// Enables/disables the current startup behavior for Wino Server. - /// - /// Whether to launch enabled or disabled. - /// True if operation success, false if not. - Task ToggleStartupBehavior(bool isEnabled); - } +public interface IStartupBehaviorService +{ + /// + /// Gets whether Wino Server is set to launch on startup or not. + /// + Task GetCurrentStartupBehaviorAsync(); + + /// + /// Enables/disables the current startup behavior for Wino Server. + /// + /// Whether to launch enabled or disabled. + /// True if operation success, false if not. + Task ToggleStartupBehavior(bool isEnabled); } diff --git a/Wino.Core.Domain/Interfaces/IStatePersistenceService.cs b/Wino.Core.Domain/Interfaces/IStatePersistenceService.cs index 1e1599f3..8ed05626 100644 --- a/Wino.Core.Domain/Interfaces/IStatePersistenceService.cs +++ b/Wino.Core.Domain/Interfaces/IStatePersistenceService.cs @@ -2,57 +2,56 @@ using System.ComponentModel; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IStatePersistanceService : INotifyPropertyChanged { - public interface IStatePersistanceService : INotifyPropertyChanged - { - event EventHandler StatePropertyChanged; + event EventHandler StatePropertyChanged; - /// - /// True when there is an active renderer for selected mail. - /// - bool IsReadingMail { get; set; } + /// + /// True when there is an active renderer for selected mail. + /// + bool IsReadingMail { get; set; } - /// - /// Shell's app bar title string. - /// - string CoreWindowTitle { get; set; } + /// + /// Shell's app bar title string. + /// + string CoreWindowTitle { get; set; } - /// - /// When only reader page is visible in small sized window. - /// - bool IsReaderNarrowed { get; set; } + /// + /// When only reader page is visible in small sized window. + /// + bool IsReaderNarrowed { get; set; } - /// - /// Should display back button on the shell title bar. - /// - bool IsBackButtonVisible { get; } + /// + /// Should display back button on the shell title bar. + /// + bool IsBackButtonVisible { get; } - /// - /// Setting: Opened pane length for the navigation view. - /// - double OpenPaneLength { get; set; } + /// + /// Setting: Opened pane length for the navigation view. + /// + double OpenPaneLength { get; set; } - /// - /// Whether the mail rendering page should be shifted from top to adjust the design - /// for standalone EML viewer or not. - /// - bool ShouldShiftMailRenderingDesign { get; set; } + /// + /// Whether the mail rendering page should be shifted from top to adjust the design + /// for standalone EML viewer or not. + /// + bool ShouldShiftMailRenderingDesign { get; set; } - /// - /// Setting: Mail list pane length for listing mails. - /// - double MailListPaneLength { get; set; } + /// + /// Setting: Mail list pane length for listing mails. + /// + double MailListPaneLength { get; set; } - /// - /// Setting: Calendar display type. - /// - CalendarDisplayType CalendarDisplayType { get; set; } + /// + /// Setting: Calendar display type. + /// + CalendarDisplayType CalendarDisplayType { get; set; } - /// - /// Setting: Calendar display count for the day view. - /// - int DayDisplayCount { get; set; } - } + /// + /// Setting: Calendar display count for the day view. + /// + int DayDisplayCount { get; set; } } diff --git a/Wino.Core.Domain/Interfaces/IStoreManagementService.cs b/Wino.Core.Domain/Interfaces/IStoreManagementService.cs index 36e3ebc9..ea61f1b7 100644 --- a/Wino.Core.Domain/Interfaces/IStoreManagementService.cs +++ b/Wino.Core.Domain/Interfaces/IStoreManagementService.cs @@ -2,18 +2,17 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.Store; -namespace Wino.Core.Domain.Interfaces -{ - public interface IStoreManagementService - { - /// - /// Checks whether user has the type of an add-on purchased. - /// - Task HasProductAsync(StoreProductType productType); +namespace Wino.Core.Domain.Interfaces; - /// - /// Attempts to purchase the given add-on. - /// - Task PurchaseAsync(StoreProductType productType); - } +public interface IStoreManagementService +{ + /// + /// Checks whether user has the type of an add-on purchased. + /// + Task HasProductAsync(StoreProductType productType); + + /// + /// Attempts to purchase the given add-on. + /// + Task PurchaseAsync(StoreProductType productType); } diff --git a/Wino.Core.Domain/Interfaces/IStoreRatingService.cs b/Wino.Core.Domain/Interfaces/IStoreRatingService.cs index 7b1ba764..0f36112d 100644 --- a/Wino.Core.Domain/Interfaces/IStoreRatingService.cs +++ b/Wino.Core.Domain/Interfaces/IStoreRatingService.cs @@ -1,10 +1,9 @@ using System.Threading.Tasks; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IStoreRatingService { - public interface IStoreRatingService - { - Task PromptRatingDialogAsync(); - Task LaunchStorePageForReviewAsync(); - } + Task PromptRatingDialogAsync(); + Task LaunchStorePageForReviewAsync(); } diff --git a/Wino.Core.Domain/Interfaces/ISynchronizerFactory.cs b/Wino.Core.Domain/Interfaces/ISynchronizerFactory.cs index 553eb95c..99696da9 100644 --- a/Wino.Core.Domain/Interfaces/ISynchronizerFactory.cs +++ b/Wino.Core.Domain/Interfaces/ISynchronizerFactory.cs @@ -1,12 +1,11 @@ using System; using System.Threading.Tasks; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface ISynchronizerFactory { - public interface ISynchronizerFactory - { - Task GetAccountSynchronizerAsync(Guid accountId); - Task InitializeAsync(); - Task DeleteSynchronizerAsync(Guid accountId); - } + Task GetAccountSynchronizerAsync(Guid accountId); + Task InitializeAsync(); + Task DeleteSynchronizerAsync(Guid accountId); } diff --git a/Wino.Core.Domain/Interfaces/IThemeService.cs b/Wino.Core.Domain/Interfaces/IThemeService.cs index a452159d..eb504a0c 100644 --- a/Wino.Core.Domain/Interfaces/IThemeService.cs +++ b/Wino.Core.Domain/Interfaces/IThemeService.cs @@ -4,24 +4,23 @@ using System.Threading.Tasks; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.Personalization; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IThemeService : IInitializeAsync { - public interface IThemeService : IInitializeAsync - { - event EventHandler ElementThemeChanged; - event EventHandler AccentColorChanged; + event EventHandler ElementThemeChanged; + event EventHandler AccentColorChanged; - Task> GetAvailableThemesAsync(); - Task CreateNewCustomThemeAsync(string themeName, string accentColor, byte[] wallpaperData); - Task> GetCurrentCustomThemesAsync(); + Task> GetAvailableThemesAsync(); + Task CreateNewCustomThemeAsync(string themeName, string accentColor, byte[] wallpaperData); + Task> GetCurrentCustomThemesAsync(); - Task ApplyCustomThemeAsync(bool isInitializing); + Task ApplyCustomThemeAsync(bool isInitializing); - // Settings - ApplicationElementTheme RootTheme { get; set; } - Guid CurrentApplicationThemeId { get; set; } - string AccentColor { get; set; } - string GetSystemAccentColorHex(); - bool IsCustomTheme { get; } - } + // Settings + ApplicationElementTheme RootTheme { get; set; } + Guid CurrentApplicationThemeId { get; set; } + string AccentColor { get; set; } + string GetSystemAccentColorHex(); + bool IsCustomTheme { get; } } diff --git a/Wino.Core.Domain/Interfaces/IThreadingStrategy.cs b/Wino.Core.Domain/Interfaces/IThreadingStrategy.cs index 1c1acf81..c27b8e56 100644 --- a/Wino.Core.Domain/Interfaces/IThreadingStrategy.cs +++ b/Wino.Core.Domain/Interfaces/IThreadingStrategy.cs @@ -4,16 +4,15 @@ using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Models.Folders; using Wino.Core.Domain.Models.MailItem; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IThreadingStrategy { - public interface IThreadingStrategy - { - /// - /// Attach thread mails to the list. - /// - /// Original mails. - /// Original mails with thread mails. - Task> ThreadItemsAsync(List items, IMailItemFolder threadingForFolder); - bool ShouldThreadWithItem(IMailItem originalItem, IMailItem targetItem); - } + /// + /// Attach thread mails to the list. + /// + /// Original mails. + /// Original mails with thread mails. + Task> ThreadItemsAsync(List items, IMailItemFolder threadingForFolder); + bool ShouldThreadWithItem(IMailItem originalItem, IMailItem targetItem); } diff --git a/Wino.Core.Domain/Interfaces/IThreadingStrategyProvider.cs b/Wino.Core.Domain/Interfaces/IThreadingStrategyProvider.cs index 9e3fa87b..cca544f5 100644 --- a/Wino.Core.Domain/Interfaces/IThreadingStrategyProvider.cs +++ b/Wino.Core.Domain/Interfaces/IThreadingStrategyProvider.cs @@ -1,13 +1,12 @@ using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IThreadingStrategyProvider { - public interface IThreadingStrategyProvider - { - /// - /// Returns corresponding threading strategy that applies to given provider type. - /// - /// Provider type. - IThreadingStrategy GetStrategy(MailProviderType mailProviderType); - } + /// + /// Returns corresponding threading strategy that applies to given provider type. + /// + /// Provider type. + IThreadingStrategy GetStrategy(MailProviderType mailProviderType); } diff --git a/Wino.Core.Domain/Interfaces/ITranslationService.cs b/Wino.Core.Domain/Interfaces/ITranslationService.cs index e756f3cd..f1619567 100644 --- a/Wino.Core.Domain/Interfaces/ITranslationService.cs +++ b/Wino.Core.Domain/Interfaces/ITranslationService.cs @@ -3,11 +3,10 @@ using System.Threading.Tasks; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.Translations; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface ITranslationService : IInitializeAsync { - public interface ITranslationService : IInitializeAsync - { - Task InitializeLanguageAsync(AppLanguage language, bool ignoreCurrentLanguageCheck = false); - List GetAvailableLanguages(); - } + Task InitializeLanguageAsync(AppLanguage language, bool ignoreCurrentLanguageCheck = false); + List GetAvailableLanguages(); } diff --git a/Wino.Core.Domain/Interfaces/IUIMessage.cs b/Wino.Core.Domain/Interfaces/IUIMessage.cs index bace1c26..cc46e19c 100644 --- a/Wino.Core.Domain/Interfaces/IUIMessage.cs +++ b/Wino.Core.Domain/Interfaces/IUIMessage.cs @@ -1,11 +1,10 @@ -namespace Wino.Core.Domain.Interfaces -{ - /// - /// Interface for all messages to report UI changes from synchronizers to UI. - /// None of these messages can't run a code that manipulates database. - /// They are sent either from processor or view models to signal some other - /// parts of the application. - /// +namespace Wino.Core.Domain.Interfaces; - public interface IUIMessage; -} +/// +/// Interface for all messages to report UI changes from synchronizers to UI. +/// None of these messages can't run a code that manipulates database. +/// They are sent either from processor or view models to signal some other +/// parts of the application. +/// + +public interface IUIMessage; diff --git a/Wino.Core.Domain/Interfaces/IUnderlyingThemeService.cs b/Wino.Core.Domain/Interfaces/IUnderlyingThemeService.cs index 5de11c78..315dd85d 100644 --- a/Wino.Core.Domain/Interfaces/IUnderlyingThemeService.cs +++ b/Wino.Core.Domain/Interfaces/IUnderlyingThemeService.cs @@ -1,7 +1,6 @@ -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IUnderlyingThemeService { - public interface IUnderlyingThemeService - { - bool IsUnderlyingThemeDark(); - } + bool IsUnderlyingThemeDark(); } diff --git a/Wino.Core.Domain/Interfaces/IUnsubscriptionService.cs b/Wino.Core.Domain/Interfaces/IUnsubscriptionService.cs index f066895a..86d109cf 100644 --- a/Wino.Core.Domain/Interfaces/IUnsubscriptionService.cs +++ b/Wino.Core.Domain/Interfaces/IUnsubscriptionService.cs @@ -1,15 +1,14 @@ using System.Threading.Tasks; using Wino.Core.Domain.Models.Reader; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IUnsubscriptionService { - public interface IUnsubscriptionService - { - /// - /// Unsubscribes from the subscription using one-click method. - /// - /// Unsubscribtion information. - /// Whether the unsubscription is succeeded or not. - Task OneClickUnsubscribeAsync(UnsubscribeInfo info); - } + /// + /// Unsubscribes from the subscription using one-click method. + /// + /// Unsubscribtion information. + /// Whether the unsubscription is succeeded or not. + Task OneClickUnsubscribeAsync(UnsubscribeInfo info); } diff --git a/Wino.Core.Domain/Interfaces/IWinoNavigationService.cs b/Wino.Core.Domain/Interfaces/IWinoNavigationService.cs index 1fe02f7b..28b015c7 100644 --- a/Wino.Core.Domain/Interfaces/IWinoNavigationService.cs +++ b/Wino.Core.Domain/Interfaces/IWinoNavigationService.cs @@ -2,16 +2,15 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.Navigation; -namespace Wino.Core.Domain.Interfaces -{ - public interface INavigationService - { - bool Navigate(WinoPage page, - object parameter = null, - NavigationReferenceFrame frame = NavigationReferenceFrame.ShellFrame, - NavigationTransitionType transition = NavigationTransitionType.None); +namespace Wino.Core.Domain.Interfaces; - Type GetPageType(WinoPage winoPage); - void GoBack(); - } +public interface INavigationService +{ + bool Navigate(WinoPage page, + object parameter = null, + NavigationReferenceFrame frame = NavigationReferenceFrame.ShellFrame, + NavigationTransitionType transition = NavigationTransitionType.None); + + Type GetPageType(WinoPage winoPage); + void GoBack(); } diff --git a/Wino.Core.Domain/Interfaces/IWinoRequestDelegator.cs b/Wino.Core.Domain/Interfaces/IWinoRequestDelegator.cs index 07147724..de50c517 100644 --- a/Wino.Core.Domain/Interfaces/IWinoRequestDelegator.cs +++ b/Wino.Core.Domain/Interfaces/IWinoRequestDelegator.cs @@ -2,32 +2,31 @@ using Wino.Core.Domain.Models.Folders; using Wino.Core.Domain.Models.MailItem; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IWinoRequestDelegator { - public interface IWinoRequestDelegator - { - /// - /// Prepares requires IRequest collection for mail actions and executes them via proper synchronizers. - /// - /// Preperation model that encapsulates action and mail items. - Task ExecuteAsync(MailOperationPreperationRequest prerperationRequest); + /// + /// Prepares requires IRequest collection for mail actions and executes them via proper synchronizers. + /// + /// Preperation model that encapsulates action and mail items. + Task ExecuteAsync(MailOperationPreperationRequest prerperationRequest); - /// - /// Queues new draft creation request for synchronizer. - /// - /// A class that holds the parameters for creating a draft. - Task ExecuteAsync(DraftPreparationRequest draftPreperationRequest); + /// + /// Queues new draft creation request for synchronizer. + /// + /// A class that holds the parameters for creating a draft. + Task ExecuteAsync(DraftPreparationRequest draftPreperationRequest); - /// - /// Queues a new request for synchronizer to send a draft. - /// - /// Draft sending request. - Task ExecuteAsync(SendDraftPreparationRequest sendDraftPreperationRequest); + /// + /// Queues a new request for synchronizer to send a draft. + /// + /// Draft sending request. + Task ExecuteAsync(SendDraftPreparationRequest sendDraftPreperationRequest); - /// - /// Prepares requires IRequest collection for folder actions and executes them via proper synchronizers. - /// - /// Folder prep request. - Task ExecuteAsync(FolderOperationPreperationRequest folderOperationPreperationRequest); - } + /// + /// Prepares requires IRequest collection for folder actions and executes them via proper synchronizers. + /// + /// Folder prep request. + Task ExecuteAsync(FolderOperationPreperationRequest folderOperationPreperationRequest); } diff --git a/Wino.Core.Domain/Interfaces/IWinoRequestProcessor.cs b/Wino.Core.Domain/Interfaces/IWinoRequestProcessor.cs index 26cfb574..180824b9 100644 --- a/Wino.Core.Domain/Interfaces/IWinoRequestProcessor.cs +++ b/Wino.Core.Domain/Interfaces/IWinoRequestProcessor.cs @@ -3,24 +3,23 @@ using System.Threading.Tasks; using Wino.Core.Domain.Models.Folders; using Wino.Core.Domain.Models.MailItem; -namespace Wino.Core.Domain.Interfaces -{ - public interface IWinoRequestProcessor - { - /// - /// Prepares proper folder action requests for synchronizers to execute. - /// - /// - /// Base request that synchronizer can execute. - Task PrepareFolderRequestAsync(FolderOperationPreperationRequest request); +namespace Wino.Core.Domain.Interfaces; - /// - /// Prepares proper Wino requests for synchronizers to execute categorized by AccountId and FolderId. - /// - /// User action - /// Selected mails. - /// When required folder target is not available for account. - /// Base request that synchronizer can execute. - Task> PrepareRequestsAsync(MailOperationPreperationRequest request); - } +public interface IWinoRequestProcessor +{ + /// + /// Prepares proper folder action requests for synchronizers to execute. + /// + /// + /// Base request that synchronizer can execute. + Task PrepareFolderRequestAsync(FolderOperationPreperationRequest request); + + /// + /// Prepares proper Wino requests for synchronizers to execute categorized by AccountId and FolderId. + /// + /// User action + /// Selected mails. + /// When required folder target is not available for account. + /// Base request that synchronizer can execute. + Task> PrepareRequestsAsync(MailOperationPreperationRequest request); } diff --git a/Wino.Core.Domain/Interfaces/IWinoServerConnectionManager.cs b/Wino.Core.Domain/Interfaces/IWinoServerConnectionManager.cs index 4ad58446..69949a0a 100644 --- a/Wino.Core.Domain/Interfaces/IWinoServerConnectionManager.cs +++ b/Wino.Core.Domain/Interfaces/IWinoServerConnectionManager.cs @@ -4,59 +4,58 @@ using System.Threading.Tasks; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.Server; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IWinoServerConnectionManager { - public interface IWinoServerConnectionManager - { - /// - /// When the connection status changes, this event will be triggered. - /// - event EventHandler StatusChanged; + /// + /// When the connection status changes, this event will be triggered. + /// + event EventHandler StatusChanged; - /// - /// Gets the connection status. - /// - WinoServerConnectionStatus Status { get; } + /// + /// Gets the connection status. + /// + WinoServerConnectionStatus Status { get; } - /// - /// Launches Full Trust process (Wino Server) and awaits connection completion. - /// If connection is not established in 10 seconds, it will return false. - /// If the server process is already running, it'll connect to existing one. - /// If the server process is not running, it'll be launched and connection establishment is awaited. - /// - /// Whether connection is established or not. - Task ConnectAsync(); + /// + /// Launches Full Trust process (Wino Server) and awaits connection completion. + /// If connection is not established in 10 seconds, it will return false. + /// If the server process is already running, it'll connect to existing one. + /// If the server process is not running, it'll be launched and connection establishment is awaited. + /// + /// Whether connection is established or not. + Task ConnectAsync(); - /// - /// Queues a new user request to be processed by Wino Server. - /// Healthy connection must present before calling this method. - /// - /// Request to queue for synchronizer in the server. - /// Account id to queueu request for. - Task QueueRequestAsync(IRequestBase request, Guid accountId); + /// + /// Queues a new user request to be processed by Wino Server. + /// Healthy connection must present before calling this method. + /// + /// Request to queue for synchronizer in the server. + /// Account id to queueu request for. + Task QueueRequestAsync(IRequestBase request, Guid accountId); - /// - /// Returns response from server for the given request. - /// - /// Response type. - /// Request type. - /// Request type. - /// Response received from the server for the given TResponse type. - Task> GetResponseAsync(TRequestType clientMessage, CancellationToken cancellationToken = default) where TRequestType : IClientMessage; + /// + /// Returns response from server for the given request. + /// + /// Response type. + /// Request type. + /// Request type. + /// Response received from the server for the given TResponse type. + Task> GetResponseAsync(TRequestType clientMessage, CancellationToken cancellationToken = default) where TRequestType : IClientMessage; - /// - /// Handle for connecting to the server. - /// If the server is already running, it'll connect to existing one. - /// Callers can await this handle to wait for connection establishment. - /// - TaskCompletionSource ConnectingHandle { get; } - } - - public interface IWinoServerConnectionManager : IWinoServerConnectionManager, IInitializeAsync - { - /// - /// Existing connection handle to the server of TAppServiceConnection type. - /// - TAppServiceConnection Connection { get; set; } - } + /// + /// Handle for connecting to the server. + /// If the server is already running, it'll connect to existing one. + /// Callers can await this handle to wait for connection establishment. + /// + TaskCompletionSource ConnectingHandle { get; } +} + +public interface IWinoServerConnectionManager : IWinoServerConnectionManager, IInitializeAsync +{ + /// + /// Existing connection handle to the server of TAppServiceConnection type. + /// + TAppServiceConnection Connection { get; set; } } diff --git a/Wino.Core.Domain/Interfaces/IWinoSynchronizerBase.cs b/Wino.Core.Domain/Interfaces/IWinoSynchronizerBase.cs index ec4648bf..e5a3d806 100644 --- a/Wino.Core.Domain/Interfaces/IWinoSynchronizerBase.cs +++ b/Wino.Core.Domain/Interfaces/IWinoSynchronizerBase.cs @@ -4,36 +4,35 @@ using MailKit; using Wino.Core.Domain.Models.MailItem; using Wino.Core.Domain.Models.Synchronization; -namespace Wino.Core.Domain.Interfaces +namespace Wino.Core.Domain.Interfaces; + +public interface IWinoSynchronizerBase : IBaseSynchronizer { - public interface IWinoSynchronizerBase : IBaseSynchronizer - { - /// - /// Performs a full synchronization with the server with given options. - /// This will also prepares batch requests for execution. - /// Requests are executed in the order they are queued and happens before the synchronization. - /// Result of the execution queue is processed during the synchronization. - /// - /// Options for synchronization. - /// Cancellation token. - /// Result summary of synchronization. - Task SynchronizeMailsAsync(MailSynchronizationOptions options, CancellationToken cancellationToken = default); + /// + /// Performs a full synchronization with the server with given options. + /// This will also prepares batch requests for execution. + /// Requests are executed in the order they are queued and happens before the synchronization. + /// Result of the execution queue is processed during the synchronization. + /// + /// Options for synchronization. + /// Cancellation token. + /// Result summary of synchronization. + Task SynchronizeMailsAsync(MailSynchronizationOptions options, CancellationToken cancellationToken = default); - Task SynchronizeCalendarEventsAsync(CalendarSynchronizationOptions options, CancellationToken cancellationToken = default); + Task SynchronizeCalendarEventsAsync(CalendarSynchronizationOptions options, CancellationToken cancellationToken = default); - /// - /// Downloads a single MIME message from the server and saves it to disk. - /// - /// Mail item to download from server. - /// Optional progress reporting for download operation. - /// Cancellation token. - Task DownloadMissingMimeMessageAsync(IMailItem mailItem, ITransferProgress transferProgress, CancellationToken cancellationToken = default); + /// + /// Downloads a single MIME message from the server and saves it to disk. + /// + /// Mail item to download from server. + /// Optional progress reporting for download operation. + /// Cancellation token. + Task DownloadMissingMimeMessageAsync(IMailItem mailItem, ITransferProgress transferProgress, CancellationToken cancellationToken = default); - /// - /// 1. Cancel active synchronization. - /// 2. Stop all running tasks. - /// 3. Dispose all resources. - /// - Task KillSynchronizerAsync(); - } + /// + /// 1. Cancel active synchronization. + /// 2. Stop all running tasks. + /// 3. Dispose all resources. + /// + Task KillSynchronizerAsync(); } diff --git a/Wino.Core.Domain/MenuItems/AccountMenuItem.cs b/Wino.Core.Domain/MenuItems/AccountMenuItem.cs index eae3e1a9..4d5dc1b9 100644 --- a/Wino.Core.Domain/MenuItems/AccountMenuItem.cs +++ b/Wino.Core.Domain/MenuItems/AccountMenuItem.cs @@ -7,96 +7,95 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Folders; -namespace Wino.Core.Domain.MenuItems +namespace Wino.Core.Domain.MenuItems; + +public partial class AccountMenuItem : MenuItemBase>, IAccountMenuItem { - public partial class AccountMenuItem : MenuItemBase>, IAccountMenuItem + [ObservableProperty] + private int unreadItemCount; + + [ObservableProperty] + [NotifyPropertyChangedFor(nameof(IsSynchronizationProgressVisible))] + private double synchronizationProgress; + + [ObservableProperty] + private bool _isEnabled = true; + + public bool IsAttentionRequired => AttentionReason != AccountAttentionReason.None; + public bool IsSynchronizationProgressVisible => SynchronizationProgress > 0 && SynchronizationProgress < 100; + + // We can't determine the progress for gmail synchronization since it is based on history changes. + public bool IsProgressIndeterminate => Parameter?.ProviderType == MailProviderType.Gmail; + public Guid AccountId => Parameter.Id; + + private AccountAttentionReason attentionReason; + + public AccountAttentionReason AttentionReason { - [ObservableProperty] - private int unreadItemCount; - - [ObservableProperty] - [NotifyPropertyChangedFor(nameof(IsSynchronizationProgressVisible))] - private double synchronizationProgress; - - [ObservableProperty] - private bool _isEnabled = true; - - public bool IsAttentionRequired => AttentionReason != AccountAttentionReason.None; - public bool IsSynchronizationProgressVisible => SynchronizationProgress > 0 && SynchronizationProgress < 100; - - // We can't determine the progress for gmail synchronization since it is based on history changes. - public bool IsProgressIndeterminate => Parameter?.ProviderType == MailProviderType.Gmail; - public Guid AccountId => Parameter.Id; - - private AccountAttentionReason attentionReason; - - public AccountAttentionReason AttentionReason + get => attentionReason; + set { - get => attentionReason; - set + if (SetProperty(ref attentionReason, value)) { - if (SetProperty(ref attentionReason, value)) - { - OnPropertyChanged(nameof(IsAttentionRequired)); + OnPropertyChanged(nameof(IsAttentionRequired)); - UpdateFixAccountIssueMenuItem(); - } + UpdateFixAccountIssueMenuItem(); } } + } - public string AccountName + public string AccountName + { + get => Parameter.Name; + set => SetProperty(Parameter.Name, value, Parameter, (u, n) => u.Name = n); + } + + public string Base64ProfilePicture + { + get => Parameter.Name; + set => SetProperty(Parameter.Base64ProfilePictureData, value, Parameter, (u, n) => u.Base64ProfilePictureData = n); + } + + public IEnumerable HoldingAccounts => new List { Parameter }; + + public AccountMenuItem(MailAccount account, IMenuItem parent = null) : base(account, account.Id, parent) + { + UpdateAccount(account); + } + + public void UpdateAccount(MailAccount account) + { + Parameter = account; + AccountName = account.Name; + AttentionReason = account.AttentionReason; + Base64ProfilePicture = account.Base64ProfilePictureData; + + if (SubMenuItems == null) return; + + foreach (var item in SubMenuItems) { - get => Parameter.Name; - set => SetProperty(Parameter.Name, value, Parameter, (u, n) => u.Name = n); - } - - public string Base64ProfilePicture - { - get => Parameter.Name; - set => SetProperty(Parameter.Base64ProfilePictureData, value, Parameter, (u, n) => u.Base64ProfilePictureData = n); - } - - public IEnumerable HoldingAccounts => new List { Parameter }; - - public AccountMenuItem(MailAccount account, IMenuItem parent = null) : base(account, account.Id, parent) - { - UpdateAccount(account); - } - - public void UpdateAccount(MailAccount account) - { - Parameter = account; - AccountName = account.Name; - AttentionReason = account.AttentionReason; - Base64ProfilePicture = account.Base64ProfilePictureData; - - if (SubMenuItems == null) return; - - foreach (var item in SubMenuItems) + if (item is IFolderMenuItem folderMenuItem) { - if (item is IFolderMenuItem folderMenuItem) - { - folderMenuItem.UpdateParentAccounnt(account); - } + folderMenuItem.UpdateParentAccounnt(account); } } + } - private void UpdateFixAccountIssueMenuItem() + private void UpdateFixAccountIssueMenuItem() + { + if (AttentionReason != AccountAttentionReason.None && !SubMenuItems.Any(a => a is FixAccountIssuesMenuItem)) { - if (AttentionReason != AccountAttentionReason.None && !SubMenuItems.Any(a => a is FixAccountIssuesMenuItem)) - { - // Add fix issue item if not exists. - SubMenuItems.Insert(0, new FixAccountIssuesMenuItem(Parameter, this)); - } - else - { - // Remove existing if issue is resolved. - var fixAccountIssueItem = SubMenuItems.FirstOrDefault(a => a is FixAccountIssuesMenuItem); + // Add fix issue item if not exists. + SubMenuItems.Insert(0, new FixAccountIssuesMenuItem(Parameter, this)); + } + else + { + // Remove existing if issue is resolved. + var fixAccountIssueItem = SubMenuItems.FirstOrDefault(a => a is FixAccountIssuesMenuItem); - if (fixAccountIssueItem != null) - { - SubMenuItems.Remove(fixAccountIssueItem); - } + if (fixAccountIssueItem != null) + { + SubMenuItems.Remove(fixAccountIssueItem); } } } diff --git a/Wino.Core.Domain/MenuItems/FixAccountIssuesMenuItem.cs b/Wino.Core.Domain/MenuItems/FixAccountIssuesMenuItem.cs index 39a58dba..bf4d004a 100644 --- a/Wino.Core.Domain/MenuItems/FixAccountIssuesMenuItem.cs +++ b/Wino.Core.Domain/MenuItems/FixAccountIssuesMenuItem.cs @@ -2,15 +2,14 @@ using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Folders; -namespace Wino.Core.Domain.MenuItems -{ - public class FixAccountIssuesMenuItem : MenuItemBase - { - public MailAccount Account { get; } +namespace Wino.Core.Domain.MenuItems; - public FixAccountIssuesMenuItem(MailAccount account, IMenuItem parentAccountMenuItem) : base(null, null, parentAccountMenuItem) - { - Account = account; - } +public class FixAccountIssuesMenuItem : MenuItemBase +{ + public MailAccount Account { get; } + + public FixAccountIssuesMenuItem(MailAccount account, IMenuItem parentAccountMenuItem) : base(null, null, parentAccountMenuItem) + { + Account = account; } } diff --git a/Wino.Core.Domain/MenuItems/FolderMenuItem.cs b/Wino.Core.Domain/MenuItems/FolderMenuItem.cs index 2e0cc433..ce5d5abc 100644 --- a/Wino.Core.Domain/MenuItems/FolderMenuItem.cs +++ b/Wino.Core.Domain/MenuItems/FolderMenuItem.cs @@ -7,73 +7,72 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Folders; -namespace Wino.Core.Domain.MenuItems +namespace Wino.Core.Domain.MenuItems; + +public partial class FolderMenuItem : MenuItemBase, IFolderMenuItem { - public partial class FolderMenuItem : MenuItemBase, IFolderMenuItem + [ObservableProperty] + private int unreadItemCount; + + public bool HasTextColor => !string.IsNullOrEmpty(Parameter.TextColorHex); + public bool IsMoveTarget => HandlingFolders.All(a => a.IsMoveTarget); + + public SpecialFolderType SpecialFolderType => Parameter.SpecialFolderType; + public bool IsSticky => Parameter.IsSticky; + public bool IsSystemFolder => Parameter.IsSystemFolder; + + /// + /// Display name of the folder. More and Category folders have localized display names. + /// + public string FolderName { - [ObservableProperty] - private int unreadItemCount; - - public bool HasTextColor => !string.IsNullOrEmpty(Parameter.TextColorHex); - public bool IsMoveTarget => HandlingFolders.All(a => a.IsMoveTarget); - - public SpecialFolderType SpecialFolderType => Parameter.SpecialFolderType; - public bool IsSticky => Parameter.IsSticky; - public bool IsSystemFolder => Parameter.IsSystemFolder; - - /// - /// Display name of the folder. More and Category folders have localized display names. - /// - public string FolderName + get { - get - { - if (Parameter.SpecialFolderType == SpecialFolderType.More) - return Translator.MoreFolderNameOverride; - else if (Parameter.SpecialFolderType == SpecialFolderType.Category) - return Translator.CategoriesFolderNameOverride; - else - return Parameter.FolderName; - } - set => SetProperty(Parameter.FolderName, value, Parameter, (u, n) => u.FolderName = n); + if (Parameter.SpecialFolderType == SpecialFolderType.More) + return Translator.MoreFolderNameOverride; + else if (Parameter.SpecialFolderType == SpecialFolderType.Category) + return Translator.CategoriesFolderNameOverride; + else + return Parameter.FolderName; } - - public bool IsSynchronizationEnabled - { - get => Parameter.IsSynchronizationEnabled; - set => SetProperty(Parameter.IsSynchronizationEnabled, value, Parameter, (u, n) => u.IsSynchronizationEnabled = n); - } - - public IEnumerable HandlingFolders => new List() { Parameter }; - - public MailAccount ParentAccount { get; private set; } - - public string AssignedAccountName => ParentAccount?.Name; - - public bool ShowUnreadCount => Parameter.ShowUnreadCount; - - IEnumerable IBaseFolderMenuItem.SubMenuItems => SubMenuItems; - - public FolderMenuItem(IMailItemFolder folderStructure, MailAccount parentAccount, IMenuItem parentMenuItem) : base(folderStructure, folderStructure.Id, parentMenuItem) - { - ParentAccount = parentAccount; - } - - public void UpdateFolder(IMailItemFolder folder) - { - Parameter = folder; - - OnPropertyChanged(nameof(IsSynchronizationEnabled)); - OnPropertyChanged(nameof(ShowUnreadCount)); - OnPropertyChanged(nameof(HasTextColor)); - OnPropertyChanged(nameof(IsSystemFolder)); - OnPropertyChanged(nameof(SpecialFolderType)); - OnPropertyChanged(nameof(IsSticky)); - OnPropertyChanged(nameof(FolderName)); - } - - public override string ToString() => FolderName; - - public void UpdateParentAccounnt(MailAccount account) => ParentAccount = account; + set => SetProperty(Parameter.FolderName, value, Parameter, (u, n) => u.FolderName = n); } + + public bool IsSynchronizationEnabled + { + get => Parameter.IsSynchronizationEnabled; + set => SetProperty(Parameter.IsSynchronizationEnabled, value, Parameter, (u, n) => u.IsSynchronizationEnabled = n); + } + + public IEnumerable HandlingFolders => new List() { Parameter }; + + public MailAccount ParentAccount { get; private set; } + + public string AssignedAccountName => ParentAccount?.Name; + + public bool ShowUnreadCount => Parameter.ShowUnreadCount; + + IEnumerable IBaseFolderMenuItem.SubMenuItems => SubMenuItems; + + public FolderMenuItem(IMailItemFolder folderStructure, MailAccount parentAccount, IMenuItem parentMenuItem) : base(folderStructure, folderStructure.Id, parentMenuItem) + { + ParentAccount = parentAccount; + } + + public void UpdateFolder(IMailItemFolder folder) + { + Parameter = folder; + + OnPropertyChanged(nameof(IsSynchronizationEnabled)); + OnPropertyChanged(nameof(ShowUnreadCount)); + OnPropertyChanged(nameof(HasTextColor)); + OnPropertyChanged(nameof(IsSystemFolder)); + OnPropertyChanged(nameof(SpecialFolderType)); + OnPropertyChanged(nameof(IsSticky)); + OnPropertyChanged(nameof(FolderName)); + } + + public override string ToString() => FolderName; + + public void UpdateParentAccounnt(MailAccount account) => ParentAccount = account; } diff --git a/Wino.Core.Domain/MenuItems/ManageAccountsMenuItem.cs b/Wino.Core.Domain/MenuItems/ManageAccountsMenuItem.cs index 033ab2cc..147501b2 100644 --- a/Wino.Core.Domain/MenuItems/ManageAccountsMenuItem.cs +++ b/Wino.Core.Domain/MenuItems/ManageAccountsMenuItem.cs @@ -1,4 +1,3 @@ -namespace Wino.Core.Domain.MenuItems -{ - public class ManageAccountsMenuItem : MenuItemBase { } -} +namespace Wino.Core.Domain.MenuItems; + +public class ManageAccountsMenuItem : MenuItemBase { } diff --git a/Wino.Core.Domain/MenuItems/MenuItemBase.cs b/Wino.Core.Domain/MenuItems/MenuItemBase.cs index f0fd5b5f..eaf53f82 100644 --- a/Wino.Core.Domain/MenuItems/MenuItemBase.cs +++ b/Wino.Core.Domain/MenuItems/MenuItemBase.cs @@ -3,61 +3,60 @@ using System.Collections.ObjectModel; using CommunityToolkit.Mvvm.ComponentModel; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.Domain.MenuItems +namespace Wino.Core.Domain.MenuItems; + +public partial class MenuItemBase : ObservableObject, IMenuItem { - public partial class MenuItemBase : ObservableObject, IMenuItem + [ObservableProperty] + private bool _isExpanded; + + [ObservableProperty] + private bool _isSelected; + + public IMenuItem ParentMenuItem { get; } + + public Guid? EntityId { get; } + + public MenuItemBase(Guid? entityId = null, IMenuItem parentMenuItem = null) { - [ObservableProperty] - private bool _isExpanded; + EntityId = entityId; + ParentMenuItem = parentMenuItem; + } - [ObservableProperty] - private bool _isSelected; - - public IMenuItem ParentMenuItem { get; } - - public Guid? EntityId { get; } - - public MenuItemBase(Guid? entityId = null, IMenuItem parentMenuItem = null) + public void Expand() + { + // Recursively expand all parent menu items if parent exists, starting from parent. + if (ParentMenuItem != null) { - EntityId = entityId; - ParentMenuItem = parentMenuItem; - } + IMenuItem parentMenuItem = ParentMenuItem; - public void Expand() - { - // Recursively expand all parent menu items if parent exists, starting from parent. - if (ParentMenuItem != null) + while (parentMenuItem != null) { - IMenuItem parentMenuItem = ParentMenuItem; + parentMenuItem.IsExpanded = true; - while (parentMenuItem != null) - { - parentMenuItem.IsExpanded = true; - - parentMenuItem = parentMenuItem.ParentMenuItem; - } + parentMenuItem = parentMenuItem.ParentMenuItem; } - - // Finally expand itself. - IsExpanded = true; } - } - public partial class MenuItemBase : MenuItemBase - { - [ObservableProperty] - private T _parameter; - - public MenuItemBase(T parameter, Guid? entityId, IMenuItem parentMenuItem = null) : base(entityId, parentMenuItem) => Parameter = parameter; - } - - public partial class MenuItemBase : MenuItemBase - { - [ObservableProperty] - private bool _isChildSelected; - - protected MenuItemBase(TValue parameter, Guid? entityId, IMenuItem parentMenuItem = null) : base(parameter, entityId, parentMenuItem) { } - - public ObservableCollection SubMenuItems { get; set; } = []; + // Finally expand itself. + IsExpanded = true; } } + +public partial class MenuItemBase : MenuItemBase +{ + [ObservableProperty] + private T _parameter; + + public MenuItemBase(T parameter, Guid? entityId, IMenuItem parentMenuItem = null) : base(entityId, parentMenuItem) => Parameter = parameter; +} + +public partial class MenuItemBase : MenuItemBase +{ + [ObservableProperty] + private bool _isChildSelected; + + protected MenuItemBase(TValue parameter, Guid? entityId, IMenuItem parentMenuItem = null) : base(parameter, entityId, parentMenuItem) { } + + public ObservableCollection SubMenuItems { get; set; } = []; +} diff --git a/Wino.Core.Domain/MenuItems/MenuItemCollection.cs b/Wino.Core.Domain/MenuItems/MenuItemCollection.cs index 4f16d706..bd0ac6b2 100644 --- a/Wino.Core.Domain/MenuItems/MenuItemCollection.cs +++ b/Wino.Core.Domain/MenuItems/MenuItemCollection.cs @@ -6,203 +6,202 @@ using Wino.Core.Domain.Collections; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.Domain.MenuItems +namespace Wino.Core.Domain.MenuItems; + +public class MenuItemCollection : ObservableRangeCollection { - public class MenuItemCollection : ObservableRangeCollection + // Which types to remove from the list when folders are changing due to selection of new account. + // We don't clear the whole list since we want to keep the New Mail button and account menu items. + private readonly Type[] _preservingTypesForFolderArea = [typeof(AccountMenuItem), typeof(NewMailMenuItem), typeof(MergedAccountMenuItem)]; + private readonly IDispatcher _dispatcher; + + public MenuItemCollection(IDispatcher dispatcher) { - // Which types to remove from the list when folders are changing due to selection of new account. - // We don't clear the whole list since we want to keep the New Mail button and account menu items. - private readonly Type[] _preservingTypesForFolderArea = [typeof(AccountMenuItem), typeof(NewMailMenuItem), typeof(MergedAccountMenuItem)]; - private readonly IDispatcher _dispatcher; + _dispatcher = dispatcher; + } - public MenuItemCollection(IDispatcher dispatcher) + public IEnumerable GetAllAccountMenuItems() + { + foreach (var item in this) { - _dispatcher = dispatcher; - } - - public IEnumerable GetAllAccountMenuItems() - { - foreach (var item in this) + if (item is MergedAccountMenuItem mergedAccountMenuItem) { - if (item is MergedAccountMenuItem mergedAccountMenuItem) + foreach (var singleItem in mergedAccountMenuItem.SubMenuItems.OfType()) { - foreach (var singleItem in mergedAccountMenuItem.SubMenuItems.OfType()) - { - yield return singleItem; - } - - yield return mergedAccountMenuItem; + yield return singleItem; } - else if (item is IAccountMenuItem accountMenuItem) - yield return accountMenuItem; + + yield return mergedAccountMenuItem; } - } - - public IEnumerable GetAllFolderMenuItems(Guid folderId) - { - foreach (var item in this) - { - if (item is IBaseFolderMenuItem folderMenuItem) - { - if (folderMenuItem.HandlingFolders.Any(a => a.Id == folderId)) - { - yield return folderMenuItem; - } - else if (folderMenuItem.SubMenuItems.Any()) - { - foreach (var subItem in folderMenuItem.SubMenuItems.OfType()) - { - if (subItem.HandlingFolders.Any(a => a.Id == folderId)) - { - yield return subItem; - } - } - - } - } - } - } - - public bool TryGetAccountMenuItem(Guid accountId, out IAccountMenuItem value) - { - value = this.OfType().FirstOrDefault(a => a.AccountId == accountId); - value ??= this.OfType().FirstOrDefault(a => a.SubMenuItems.OfType().Where(b => b.AccountId == accountId) != null); - - return value != null; - } - - // Pattern: Look for special folder menu item inside the loaded folders for Windows Mail style menu items. - public bool TryGetWindowsStyleRootSpecialFolderMenuItem(Guid accountId, SpecialFolderType specialFolderType, out FolderMenuItem value) - { - value = this.OfType() - .FirstOrDefault(a => a.HandlingFolders.Any(b => b.MailAccountId == accountId && b.SpecialFolderType == specialFolderType)) as FolderMenuItem; - - return value != null; - } - - // Pattern: Find the merged account menu item and return the special folder menu item that belongs to the merged account menu item. - // This will not look for the folders inside individual account menu items inside merged account menu item. - public bool TryGetMergedAccountSpecialFolderMenuItem(Guid mergedInboxId, SpecialFolderType specialFolderType, out IBaseFolderMenuItem value) - { - value = this.OfType() - .Where(a => a.MergedInbox.Id == mergedInboxId) - .FirstOrDefault(a => a.SpecialFolderType == specialFolderType); - - return value != null; - } - - public bool TryGetFolderMenuItem(Guid folderId, out IBaseFolderMenuItem value) - { - // Root folders - value = this.OfType() - .FirstOrDefault(a => a.HandlingFolders.Any(b => b.Id == folderId)); - - value ??= this.OfType() - .SelectMany(a => a.SubMenuItems) - .OfType() - .FirstOrDefault(a => a.HandlingFolders.Any(b => b.Id == folderId)); - - return value != null; - } - - public void UpdateUnreadItemCountsToZero() - { - // Handle the root folders. - foreach (var item in this.OfType()) - { - RecursivelyResetUnreadItemCount(item); - } - } - - private void RecursivelyResetUnreadItemCount(IBaseFolderMenuItem baseFolderMenuItem) - { - baseFolderMenuItem.UnreadItemCount = 0; - - if (baseFolderMenuItem.SubMenuItems == null) return; - - foreach (var subMenuItem in baseFolderMenuItem.SubMenuItems.OfType()) - { - RecursivelyResetUnreadItemCount(subMenuItem); - } - } - - public bool TryGetSpecialFolderMenuItem(Guid accountId, SpecialFolderType specialFolderType, out FolderMenuItem value) - { - value = this.OfType() - .FirstOrDefault(a => a.HandlingFolders.Any(b => b.MailAccountId == accountId && b.SpecialFolderType == specialFolderType)) as FolderMenuItem; - - return value != null; - } - - /// - /// Skips the merged account menu item, but directly returns the Account menu item inside the merged account menu item. - /// - /// Account id to look for. - /// Direct AccountMenuItem inside the Merged Account menu item if exists. - public AccountMenuItem GetSpecificAccountMenuItem(Guid accountId) - { - AccountMenuItem accountMenuItem = null; - - accountMenuItem = this.OfType().FirstOrDefault(a => a.HoldingAccounts.Any(b => b.Id == accountId)); - - // Look for the items inside the merged accounts if regular menu item is not found. - accountMenuItem ??= this.OfType() - .FirstOrDefault(a => a.HoldingAccounts.Any(b => b.Id == accountId))?.SubMenuItems - .OfType() - .FirstOrDefault(a => a.AccountId == accountId); - - return accountMenuItem; - } - - public async Task ReplaceFoldersAsync(IEnumerable folders) - { - await _dispatcher.ExecuteOnUIThread(() => ClearFolderAreaMenuItems()); - await _dispatcher.ExecuteOnUIThread(() => Items.Add(new SeperatorItem())); - await _dispatcher.ExecuteOnUIThread(() => AddRange(folders, System.Collections.Specialized.NotifyCollectionChangedAction.Reset)); - } - - /// - /// Enables/disables account menu items in the list. - /// - /// Whether menu items should be enabled or disabled. - public async Task SetAccountMenuItemEnabledStatusAsync(bool isEnabled) - { - var accountItems = this.Where(a => a is IAccountMenuItem).Cast(); - - await _dispatcher.ExecuteOnUIThread(() => - { - foreach (var item in accountItems) - { - item.IsEnabled = isEnabled; - } - }); - } - - public void AddAccountMenuItem(IAccountMenuItem accountMenuItem) - { - var lastAccount = Items.OfType().LastOrDefault(); - - // Index 0 is always the New Mail button. - var insertIndex = lastAccount == null ? 1 : Items.IndexOf(lastAccount) + 1; - - Insert(insertIndex, accountMenuItem); - } - - private void ClearFolderAreaMenuItems() - { - var itemsToRemove = this.Where(a => !_preservingTypesForFolderArea.Contains(a.GetType())).ToList(); - - itemsToRemove.ForEach(item => - { - item.IsExpanded = false; - item.IsSelected = false; - - try - { - Remove(item); - } - catch (Exception) { } - }); + else if (item is IAccountMenuItem accountMenuItem) + yield return accountMenuItem; } } + + public IEnumerable GetAllFolderMenuItems(Guid folderId) + { + foreach (var item in this) + { + if (item is IBaseFolderMenuItem folderMenuItem) + { + if (folderMenuItem.HandlingFolders.Any(a => a.Id == folderId)) + { + yield return folderMenuItem; + } + else if (folderMenuItem.SubMenuItems.Any()) + { + foreach (var subItem in folderMenuItem.SubMenuItems.OfType()) + { + if (subItem.HandlingFolders.Any(a => a.Id == folderId)) + { + yield return subItem; + } + } + + } + } + } + } + + public bool TryGetAccountMenuItem(Guid accountId, out IAccountMenuItem value) + { + value = this.OfType().FirstOrDefault(a => a.AccountId == accountId); + value ??= this.OfType().FirstOrDefault(a => a.SubMenuItems.OfType().Where(b => b.AccountId == accountId) != null); + + return value != null; + } + + // Pattern: Look for special folder menu item inside the loaded folders for Windows Mail style menu items. + public bool TryGetWindowsStyleRootSpecialFolderMenuItem(Guid accountId, SpecialFolderType specialFolderType, out FolderMenuItem value) + { + value = this.OfType() + .FirstOrDefault(a => a.HandlingFolders.Any(b => b.MailAccountId == accountId && b.SpecialFolderType == specialFolderType)) as FolderMenuItem; + + return value != null; + } + + // Pattern: Find the merged account menu item and return the special folder menu item that belongs to the merged account menu item. + // This will not look for the folders inside individual account menu items inside merged account menu item. + public bool TryGetMergedAccountSpecialFolderMenuItem(Guid mergedInboxId, SpecialFolderType specialFolderType, out IBaseFolderMenuItem value) + { + value = this.OfType() + .Where(a => a.MergedInbox.Id == mergedInboxId) + .FirstOrDefault(a => a.SpecialFolderType == specialFolderType); + + return value != null; + } + + public bool TryGetFolderMenuItem(Guid folderId, out IBaseFolderMenuItem value) + { + // Root folders + value = this.OfType() + .FirstOrDefault(a => a.HandlingFolders.Any(b => b.Id == folderId)); + + value ??= this.OfType() + .SelectMany(a => a.SubMenuItems) + .OfType() + .FirstOrDefault(a => a.HandlingFolders.Any(b => b.Id == folderId)); + + return value != null; + } + + public void UpdateUnreadItemCountsToZero() + { + // Handle the root folders. + foreach (var item in this.OfType()) + { + RecursivelyResetUnreadItemCount(item); + } + } + + private void RecursivelyResetUnreadItemCount(IBaseFolderMenuItem baseFolderMenuItem) + { + baseFolderMenuItem.UnreadItemCount = 0; + + if (baseFolderMenuItem.SubMenuItems == null) return; + + foreach (var subMenuItem in baseFolderMenuItem.SubMenuItems.OfType()) + { + RecursivelyResetUnreadItemCount(subMenuItem); + } + } + + public bool TryGetSpecialFolderMenuItem(Guid accountId, SpecialFolderType specialFolderType, out FolderMenuItem value) + { + value = this.OfType() + .FirstOrDefault(a => a.HandlingFolders.Any(b => b.MailAccountId == accountId && b.SpecialFolderType == specialFolderType)) as FolderMenuItem; + + return value != null; + } + + /// + /// Skips the merged account menu item, but directly returns the Account menu item inside the merged account menu item. + /// + /// Account id to look for. + /// Direct AccountMenuItem inside the Merged Account menu item if exists. + public AccountMenuItem GetSpecificAccountMenuItem(Guid accountId) + { + AccountMenuItem accountMenuItem = null; + + accountMenuItem = this.OfType().FirstOrDefault(a => a.HoldingAccounts.Any(b => b.Id == accountId)); + + // Look for the items inside the merged accounts if regular menu item is not found. + accountMenuItem ??= this.OfType() + .FirstOrDefault(a => a.HoldingAccounts.Any(b => b.Id == accountId))?.SubMenuItems + .OfType() + .FirstOrDefault(a => a.AccountId == accountId); + + return accountMenuItem; + } + + public async Task ReplaceFoldersAsync(IEnumerable folders) + { + await _dispatcher.ExecuteOnUIThread(() => ClearFolderAreaMenuItems()); + await _dispatcher.ExecuteOnUIThread(() => Items.Add(new SeperatorItem())); + await _dispatcher.ExecuteOnUIThread(() => AddRange(folders, System.Collections.Specialized.NotifyCollectionChangedAction.Reset)); + } + + /// + /// Enables/disables account menu items in the list. + /// + /// Whether menu items should be enabled or disabled. + public async Task SetAccountMenuItemEnabledStatusAsync(bool isEnabled) + { + var accountItems = this.Where(a => a is IAccountMenuItem).Cast(); + + await _dispatcher.ExecuteOnUIThread(() => + { + foreach (var item in accountItems) + { + item.IsEnabled = isEnabled; + } + }); + } + + public void AddAccountMenuItem(IAccountMenuItem accountMenuItem) + { + var lastAccount = Items.OfType().LastOrDefault(); + + // Index 0 is always the New Mail button. + var insertIndex = lastAccount == null ? 1 : Items.IndexOf(lastAccount) + 1; + + Insert(insertIndex, accountMenuItem); + } + + private void ClearFolderAreaMenuItems() + { + var itemsToRemove = this.Where(a => !_preservingTypesForFolderArea.Contains(a.GetType())).ToList(); + + itemsToRemove.ForEach(item => + { + item.IsExpanded = false; + item.IsSelected = false; + + try + { + Remove(item); + } + catch (Exception) { } + }); + } } diff --git a/Wino.Core.Domain/MenuItems/MergedAccountFolderMenuItem.cs b/Wino.Core.Domain/MenuItems/MergedAccountFolderMenuItem.cs index 1bf51a27..0d32e513 100644 --- a/Wino.Core.Domain/MenuItems/MergedAccountFolderMenuItem.cs +++ b/Wino.Core.Domain/MenuItems/MergedAccountFolderMenuItem.cs @@ -8,105 +8,104 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Folders; -namespace Wino.Core.Domain.MenuItems +namespace Wino.Core.Domain.MenuItems; + +/// +/// Menu item that holds a list of folders under the merged account menu item. +/// +public partial class MergedAccountFolderMenuItem : MenuItemBase, IMenuItem>, IMergedAccountFolderMenuItem { - /// - /// Menu item that holds a list of folders under the merged account menu item. - /// - public partial class MergedAccountFolderMenuItem : MenuItemBase, IMenuItem>, IMergedAccountFolderMenuItem + public SpecialFolderType FolderType { get; } + + public string FolderName { get; private set; } + + // Any of the folders is enough to determine the synchronization enable/disable state. + public bool IsSynchronizationEnabled => HandlingFolders.Any(a => a.IsSynchronizationEnabled); + public bool IsMoveTarget => HandlingFolders.All(a => a.IsMoveTarget); + public IEnumerable HandlingFolders => Parameter; + + // All folders in the list should have the same type. + public SpecialFolderType SpecialFolderType => HandlingFolders.First().SpecialFolderType; + + public bool IsSticky => true; + + public bool IsSystemFolder => true; + + public string AssignedAccountName => MergedInbox?.Name; + + public MergedInbox MergedInbox { get; set; } + + public bool ShowUnreadCount => HandlingFolders?.Any(a => a.ShowUnreadCount) ?? false; + + public new IEnumerable SubMenuItems => base.SubMenuItems; + + [ObservableProperty] + private int unreadItemCount; + + // Merged account's shared folder menu item does not have an entity id. + // Navigations to specific folders are done by explicit folder id if needed. + + public MergedAccountFolderMenuItem(List parameter, IMenuItem parentMenuItem, MergedInbox mergedInbox) : base(parameter, null, parentMenuItem) { - public SpecialFolderType FolderType { get; } + Guard.IsNotNull(mergedInbox, nameof(mergedInbox)); + Guard.IsNotNull(parameter, nameof(parameter)); + Guard.HasSizeGreaterThan(parameter, 0, nameof(parameter)); - public string FolderName { get; private set; } + MergedInbox = mergedInbox; - // Any of the folders is enough to determine the synchronization enable/disable state. - public bool IsSynchronizationEnabled => HandlingFolders.Any(a => a.IsSynchronizationEnabled); - public bool IsMoveTarget => HandlingFolders.All(a => a.IsMoveTarget); - public IEnumerable HandlingFolders => Parameter; + SetFolderName(); // All folders in the list should have the same type. - public SpecialFolderType SpecialFolderType => HandlingFolders.First().SpecialFolderType; + FolderType = parameter[0].SpecialFolderType; + } - public bool IsSticky => true; + private void SetFolderName() + { + // Folders that hold more than 1 folder belong to merged account. + // These folders will be displayed as their localized names based on the + // special type they have. - public bool IsSystemFolder => true; - - public string AssignedAccountName => MergedInbox?.Name; - - public MergedInbox MergedInbox { get; set; } - - public bool ShowUnreadCount => HandlingFolders?.Any(a => a.ShowUnreadCount) ?? false; - - public new IEnumerable SubMenuItems => base.SubMenuItems; - - [ObservableProperty] - private int unreadItemCount; - - // Merged account's shared folder menu item does not have an entity id. - // Navigations to specific folders are done by explicit folder id if needed. - - public MergedAccountFolderMenuItem(List parameter, IMenuItem parentMenuItem, MergedInbox mergedInbox) : base(parameter, null, parentMenuItem) + if (HandlingFolders.Count() > 1) { - Guard.IsNotNull(mergedInbox, nameof(mergedInbox)); - Guard.IsNotNull(parameter, nameof(parameter)); - Guard.HasSizeGreaterThan(parameter, 0, nameof(parameter)); - - MergedInbox = mergedInbox; - - SetFolderName(); - - // All folders in the list should have the same type. - FolderType = parameter[0].SpecialFolderType; + FolderName = GetSpecialFolderName(HandlingFolders.First()); } - - private void SetFolderName() + else { - // Folders that hold more than 1 folder belong to merged account. - // These folders will be displayed as their localized names based on the - // special type they have. - - if (HandlingFolders.Count() > 1) - { - FolderName = GetSpecialFolderName(HandlingFolders.First()); - } - else - { - // Folder only holds 1 Id, but it's displayed as merged account folder. - FolderName = HandlingFolders.First().FolderName; - } - } - - private string GetSpecialFolderName(IMailItemFolder folder) - { - var specialType = folder.SpecialFolderType; - - // We only handle 5 different types for combining folders. - // Rest of the types are not supported. - - return specialType switch - { - SpecialFolderType.Inbox => Translator.MergedAccountCommonFolderInbox, - SpecialFolderType.Draft => Translator.MergedAccountCommonFolderDraft, - SpecialFolderType.Sent => Translator.MergedAccountCommonFolderSent, - SpecialFolderType.Deleted => Translator.MergedAccountCommonFolderTrash, - SpecialFolderType.Junk => Translator.MergedAccountCommonFolderJunk, - SpecialFolderType.Archive => Translator.MergedAccountCommonFolderArchive, - _ => folder.FolderName, - }; - } - - public void UpdateFolder(IMailItemFolder folder) - { - var existingFolder = Parameter.FirstOrDefault(a => a.Id == folder.Id); - - if (existingFolder == null) return; - - Parameter.Remove(existingFolder); - Parameter.Add(folder); - - SetFolderName(); - OnPropertyChanged(nameof(ShowUnreadCount)); - OnPropertyChanged(nameof(IsSynchronizationEnabled)); + // Folder only holds 1 Id, but it's displayed as merged account folder. + FolderName = HandlingFolders.First().FolderName; } } + + private string GetSpecialFolderName(IMailItemFolder folder) + { + var specialType = folder.SpecialFolderType; + + // We only handle 5 different types for combining folders. + // Rest of the types are not supported. + + return specialType switch + { + SpecialFolderType.Inbox => Translator.MergedAccountCommonFolderInbox, + SpecialFolderType.Draft => Translator.MergedAccountCommonFolderDraft, + SpecialFolderType.Sent => Translator.MergedAccountCommonFolderSent, + SpecialFolderType.Deleted => Translator.MergedAccountCommonFolderTrash, + SpecialFolderType.Junk => Translator.MergedAccountCommonFolderJunk, + SpecialFolderType.Archive => Translator.MergedAccountCommonFolderArchive, + _ => folder.FolderName, + }; + } + + public void UpdateFolder(IMailItemFolder folder) + { + var existingFolder = Parameter.FirstOrDefault(a => a.Id == folder.Id); + + if (existingFolder == null) return; + + Parameter.Remove(existingFolder); + Parameter.Add(folder); + + SetFolderName(); + OnPropertyChanged(nameof(ShowUnreadCount)); + OnPropertyChanged(nameof(IsSynchronizationEnabled)); + } } diff --git a/Wino.Core.Domain/MenuItems/MergedAccountMenuItem.cs b/Wino.Core.Domain/MenuItems/MergedAccountMenuItem.cs index 7cd00323..5cbf7c97 100644 --- a/Wino.Core.Domain/MenuItems/MergedAccountMenuItem.cs +++ b/Wino.Core.Domain/MenuItems/MergedAccountMenuItem.cs @@ -5,40 +5,39 @@ using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Entities.Shared; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.Domain.MenuItems +namespace Wino.Core.Domain.MenuItems; + +public partial class MergedAccountMenuItem : MenuItemBase, IMergedAccountMenuItem { - public partial class MergedAccountMenuItem : MenuItemBase, IMergedAccountMenuItem + public int MergedAccountCount => HoldingAccounts?.Count() ?? 0; + + public IEnumerable HoldingAccounts { get; } + + [ObservableProperty] + private int unreadItemCount; + + [ObservableProperty] + private double synchronizationProgress; + + [ObservableProperty] + private string mergedAccountName; + + [ObservableProperty] + private bool _isEnabled = true; + + public MergedAccountMenuItem(MergedInbox mergedInbox, IEnumerable holdingAccounts, IMenuItem parent) : base(mergedInbox, mergedInbox.Id, parent) { - public int MergedAccountCount => HoldingAccounts?.Count() ?? 0; + MergedAccountName = mergedInbox.Name; + HoldingAccounts = holdingAccounts; + } - public IEnumerable HoldingAccounts { get; } + public void RefreshFolderItemCount() + { + UnreadItemCount = SubMenuItems.OfType().Sum(a => a.UnreadItemCount); + } - [ObservableProperty] - private int unreadItemCount; + public void UpdateAccount(MailAccount account) + { - [ObservableProperty] - private double synchronizationProgress; - - [ObservableProperty] - private string mergedAccountName; - - [ObservableProperty] - private bool _isEnabled = true; - - public MergedAccountMenuItem(MergedInbox mergedInbox, IEnumerable holdingAccounts, IMenuItem parent) : base(mergedInbox, mergedInbox.Id, parent) - { - MergedAccountName = mergedInbox.Name; - HoldingAccounts = holdingAccounts; - } - - public void RefreshFolderItemCount() - { - UnreadItemCount = SubMenuItems.OfType().Sum(a => a.UnreadItemCount); - } - - public void UpdateAccount(MailAccount account) - { - - } } } diff --git a/Wino.Core.Domain/MenuItems/MergedAccountMoreFolderMenuItem.cs b/Wino.Core.Domain/MenuItems/MergedAccountMoreFolderMenuItem.cs index 05f2f240..fe50b5df 100644 --- a/Wino.Core.Domain/MenuItems/MergedAccountMoreFolderMenuItem.cs +++ b/Wino.Core.Domain/MenuItems/MergedAccountMoreFolderMenuItem.cs @@ -1,12 +1,11 @@ using System; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.Domain.MenuItems +namespace Wino.Core.Domain.MenuItems; + +public class MergedAccountMoreFolderMenuItem : MenuItemBase { - public class MergedAccountMoreFolderMenuItem : MenuItemBase + public MergedAccountMoreFolderMenuItem(object parameter, Guid? entityId, IMenuItem parentMenuItem = null) : base(parameter, entityId, parentMenuItem) { - public MergedAccountMoreFolderMenuItem(object parameter, Guid? entityId, IMenuItem parentMenuItem = null) : base(parameter, entityId, parentMenuItem) - { - } } } diff --git a/Wino.Core.Domain/MenuItems/NewMailMenuItem.cs b/Wino.Core.Domain/MenuItems/NewMailMenuItem.cs index c5bff6d7..5ea7998d 100644 --- a/Wino.Core.Domain/MenuItems/NewMailMenuItem.cs +++ b/Wino.Core.Domain/MenuItems/NewMailMenuItem.cs @@ -1,4 +1,3 @@ -namespace Wino.Core.Domain.MenuItems -{ - public class NewMailMenuItem : MenuItemBase { } -} +namespace Wino.Core.Domain.MenuItems; + +public class NewMailMenuItem : MenuItemBase { } diff --git a/Wino.Core.Domain/MenuItems/RateMenuItem.cs b/Wino.Core.Domain/MenuItems/RateMenuItem.cs index 64030e94..ecbb5610 100644 --- a/Wino.Core.Domain/MenuItems/RateMenuItem.cs +++ b/Wino.Core.Domain/MenuItems/RateMenuItem.cs @@ -1,4 +1,3 @@ -namespace Wino.Core.Domain.MenuItems -{ - public class RateMenuItem : MenuItemBase { } -} +namespace Wino.Core.Domain.MenuItems; + +public class RateMenuItem : MenuItemBase { } diff --git a/Wino.Core.Domain/MenuItems/SeperatorItem.cs b/Wino.Core.Domain/MenuItems/SeperatorItem.cs index f689497e..64d7629e 100644 --- a/Wino.Core.Domain/MenuItems/SeperatorItem.cs +++ b/Wino.Core.Domain/MenuItems/SeperatorItem.cs @@ -1,4 +1,3 @@ -namespace Wino.Core.Domain.MenuItems -{ - public class SeperatorItem : MenuItemBase { } -} +namespace Wino.Core.Domain.MenuItems; + +public class SeperatorItem : MenuItemBase { } diff --git a/Wino.Core.Domain/MenuItems/SettingsItem.cs b/Wino.Core.Domain/MenuItems/SettingsItem.cs index 80617df6..1a5c2da3 100644 --- a/Wino.Core.Domain/MenuItems/SettingsItem.cs +++ b/Wino.Core.Domain/MenuItems/SettingsItem.cs @@ -1,4 +1,3 @@ -namespace Wino.Core.Domain.MenuItems -{ - public class SettingsItem : MenuItemBase { } -} +namespace Wino.Core.Domain.MenuItems; + +public class SettingsItem : MenuItemBase { } diff --git a/Wino.Core.Domain/Models/Accounts/AccountCreationDialogResult.cs b/Wino.Core.Domain/Models/Accounts/AccountCreationDialogResult.cs index 961a0d1a..c46fb87a 100644 --- a/Wino.Core.Domain/Models/Accounts/AccountCreationDialogResult.cs +++ b/Wino.Core.Domain/Models/Accounts/AccountCreationDialogResult.cs @@ -1,6 +1,5 @@ using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Models.Accounts -{ - public record AccountCreationDialogResult(MailProviderType ProviderType, string AccountName, SpecialImapProviderDetails SpecialImapProviderDetails); -} +namespace Wino.Core.Domain.Models.Accounts; + +public record AccountCreationDialogResult(MailProviderType ProviderType, string AccountName, SpecialImapProviderDetails SpecialImapProviderDetails); diff --git a/Wino.Core.Domain/Models/Accounts/ImapAuthenticationMethodModel.cs b/Wino.Core.Domain/Models/Accounts/ImapAuthenticationMethodModel.cs index f28b9d6e..9f5c95df 100644 --- a/Wino.Core.Domain/Models/Accounts/ImapAuthenticationMethodModel.cs +++ b/Wino.Core.Domain/Models/Accounts/ImapAuthenticationMethodModel.cs @@ -1,10 +1,9 @@ using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Models.Accounts +namespace Wino.Core.Domain.Models.Accounts; + +public class ImapAuthenticationMethodModel(ImapAuthenticationMethod imapAuthenticationMethod, string displayName) { - public class ImapAuthenticationMethodModel(ImapAuthenticationMethod imapAuthenticationMethod, string displayName) - { - public ImapAuthenticationMethod ImapAuthenticationMethod { get; } = imapAuthenticationMethod; - public string DisplayName { get; } = displayName; - } + public ImapAuthenticationMethod ImapAuthenticationMethod { get; } = imapAuthenticationMethod; + public string DisplayName { get; } = displayName; } diff --git a/Wino.Core.Domain/Models/Accounts/ImapConnectionSecurityModel.cs b/Wino.Core.Domain/Models/Accounts/ImapConnectionSecurityModel.cs index a618a490..7df4c41a 100644 --- a/Wino.Core.Domain/Models/Accounts/ImapConnectionSecurityModel.cs +++ b/Wino.Core.Domain/Models/Accounts/ImapConnectionSecurityModel.cs @@ -1,10 +1,9 @@ using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Models.Accounts +namespace Wino.Core.Domain.Models.Accounts; + +public class ImapConnectionSecurityModel(ImapConnectionSecurity imapConnectionSecurity, string displayName) { - public class ImapConnectionSecurityModel(ImapConnectionSecurity imapConnectionSecurity, string displayName) - { - public ImapConnectionSecurity ImapConnectionSecurity { get; } = imapConnectionSecurity; - public string DisplayName { get; } = displayName; - } + public ImapConnectionSecurity ImapConnectionSecurity { get; } = imapConnectionSecurity; + public string DisplayName { get; } = displayName; } diff --git a/Wino.Core.Domain/Models/Accounts/ProfileInformation.cs b/Wino.Core.Domain/Models/Accounts/ProfileInformation.cs index c0d38911..454dd28f 100644 --- a/Wino.Core.Domain/Models/Accounts/ProfileInformation.cs +++ b/Wino.Core.Domain/Models/Accounts/ProfileInformation.cs @@ -1,10 +1,9 @@ -namespace Wino.Core.Domain.Models.Accounts -{ - /// - /// Encapsulates the profile information of an account. - /// - /// Display sender name for the account. - /// Base 64 encoded profile picture data of the account. Thumbnail size. - /// Address of the profile. - public record ProfileInformation(string SenderName, string Base64ProfilePictureData, string AccountAddress); -} +namespace Wino.Core.Domain.Models.Accounts; + +/// +/// Encapsulates the profile information of an account. +/// +/// Display sender name for the account. +/// Base 64 encoded profile picture data of the account. Thumbnail size. +/// Address of the profile. +public record ProfileInformation(string SenderName, string Base64ProfilePictureData, string AccountAddress); diff --git a/Wino.Core.Domain/Models/Accounts/ProviderDetail.cs b/Wino.Core.Domain/Models/Accounts/ProviderDetail.cs index 31b2f90d..c5449892 100644 --- a/Wino.Core.Domain/Models/Accounts/ProviderDetail.cs +++ b/Wino.Core.Domain/Models/Accounts/ProviderDetail.cs @@ -1,69 +1,68 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.Domain.Models.Accounts +namespace Wino.Core.Domain.Models.Accounts; + +public class ProviderDetail : IProviderDetail { - public class ProviderDetail : IProviderDetail + public MailProviderType Type { get; } + public SpecialImapProvider SpecialImapProvider { get; } + public string Name { get; } + + public string Description { get; } + + public string ProviderImage { - public MailProviderType Type { get; } - public SpecialImapProvider SpecialImapProvider { get; } - public string Name { get; } - - public string Description { get; } - - public string ProviderImage + get { - get + if (SpecialImapProvider == SpecialImapProvider.None) { - if (SpecialImapProvider == SpecialImapProvider.None) - { - return $"/Wino.Core.UWP/Assets/Providers/{Type}.png"; - } - else - { - return $"/Wino.Core.UWP/Assets/Providers/{SpecialImapProvider}.png"; - } + return $"/Wino.Core.UWP/Assets/Providers/{Type}.png"; } - } - - public bool IsSupported => Type == MailProviderType.Outlook || Type == MailProviderType.Gmail || Type == MailProviderType.IMAP4; - - public ProviderDetail(MailProviderType type, SpecialImapProvider specialImapProvider) - { - Type = type; - SpecialImapProvider = specialImapProvider; - - switch (Type) + else { - case MailProviderType.Outlook: - Name = "Outlook"; - Description = "Outlook.com, Live.com, Hotmail, MSN"; - break; - case MailProviderType.Gmail: - Name = "Gmail"; - Description = Translator.ProviderDetail_Gmail_Description; - break; - case MailProviderType.IMAP4: - switch (specialImapProvider) - { - case SpecialImapProvider.None: - Name = Translator.ProviderDetail_IMAP_Title; - Description = Translator.ProviderDetail_IMAP_Description; - break; - case SpecialImapProvider.iCloud: - Name = Translator.ProviderDetail_iCloud_Title; - Description = Translator.ProviderDetail_iCloud_Description; - break; - case SpecialImapProvider.Yahoo: - Name = Translator.ProviderDetail_Yahoo_Title; - Description = Translator.ProviderDetail_Yahoo_Description; - break; - default: - break; - } - - break; + return $"/Wino.Core.UWP/Assets/Providers/{SpecialImapProvider}.png"; } } } + + public bool IsSupported => Type == MailProviderType.Outlook || Type == MailProviderType.Gmail || Type == MailProviderType.IMAP4; + + public ProviderDetail(MailProviderType type, SpecialImapProvider specialImapProvider) + { + Type = type; + SpecialImapProvider = specialImapProvider; + + switch (Type) + { + case MailProviderType.Outlook: + Name = "Outlook"; + Description = "Outlook.com, Live.com, Hotmail, MSN"; + break; + case MailProviderType.Gmail: + Name = "Gmail"; + Description = Translator.ProviderDetail_Gmail_Description; + break; + case MailProviderType.IMAP4: + switch (specialImapProvider) + { + case SpecialImapProvider.None: + Name = Translator.ProviderDetail_IMAP_Title; + Description = Translator.ProviderDetail_IMAP_Description; + break; + case SpecialImapProvider.iCloud: + Name = Translator.ProviderDetail_iCloud_Title; + Description = Translator.ProviderDetail_iCloud_Description; + break; + case SpecialImapProvider.Yahoo: + Name = Translator.ProviderDetail_Yahoo_Title; + Description = Translator.ProviderDetail_Yahoo_Description; + break; + default: + break; + } + + break; + } + } } diff --git a/Wino.Core.Domain/Models/Accounts/SpecialImapProviderDetails.cs b/Wino.Core.Domain/Models/Accounts/SpecialImapProviderDetails.cs index 5f3b489c..1286d431 100644 --- a/Wino.Core.Domain/Models/Accounts/SpecialImapProviderDetails.cs +++ b/Wino.Core.Domain/Models/Accounts/SpecialImapProviderDetails.cs @@ -1,6 +1,5 @@ using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Models.Accounts -{ - public record SpecialImapProviderDetails(string Address, string Password, string SenderName, SpecialImapProvider SpecialImapProvider); -} +namespace Wino.Core.Domain.Models.Accounts; + +public record SpecialImapProviderDetails(string Address, string Password, string SenderName, SpecialImapProvider SpecialImapProvider); diff --git a/Wino.Core.Domain/Models/Accounts/UnreadItemCountResult.cs b/Wino.Core.Domain/Models/Accounts/UnreadItemCountResult.cs index ba5aabf5..75fbe090 100644 --- a/Wino.Core.Domain/Models/Accounts/UnreadItemCountResult.cs +++ b/Wino.Core.Domain/Models/Accounts/UnreadItemCountResult.cs @@ -1,13 +1,12 @@ using System; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Models.Accounts +namespace Wino.Core.Domain.Models.Accounts; + +public class UnreadItemCountResult { - public class UnreadItemCountResult - { - public Guid FolderId { get; set; } - public Guid AccountId { get; set; } - public SpecialFolderType SpecialFolderType { get; set; } - public int UnreadItemCount { get; set; } - } + public Guid FolderId { get; set; } + public Guid AccountId { get; set; } + public SpecialFolderType SpecialFolderType { get; set; } + public int UnreadItemCount { get; set; } } diff --git a/Wino.Core.Domain/Models/Authentication/TokenInformationEx.cs b/Wino.Core.Domain/Models/Authentication/TokenInformationEx.cs index 270d9af7..59b6d411 100644 --- a/Wino.Core.Domain/Models/Authentication/TokenInformationEx.cs +++ b/Wino.Core.Domain/Models/Authentication/TokenInformationEx.cs @@ -1,11 +1,10 @@ -namespace Wino.Core.Domain.Models.Authentication -{ - /// - /// Previously known as TokenInformation. - /// We used to store this model in the database. - /// Now we store it in the memory. - /// - /// Access token/ - /// Address of the authenticated user. - public record TokenInformationEx(string AccessToken, string AccountAddress); -} +namespace Wino.Core.Domain.Models.Authentication; + +/// +/// Previously known as TokenInformation. +/// We used to store this model in the database. +/// Now we store it in the memory. +/// +/// Access token/ +/// Address of the authenticated user. +public record TokenInformationEx(string AccessToken, string AccountAddress); diff --git a/Wino.Core.Domain/Models/Authorization/GoogleAuthorizationRequest.cs b/Wino.Core.Domain/Models/Authorization/GoogleAuthorizationRequest.cs index bef11d59..8afd078c 100644 --- a/Wino.Core.Domain/Models/Authorization/GoogleAuthorizationRequest.cs +++ b/Wino.Core.Domain/Models/Authorization/GoogleAuthorizationRequest.cs @@ -3,70 +3,69 @@ using System.Collections.Generic; using System.Linq; using Wino.Core.Domain.Exceptions; -namespace Wino.Core.Domain.Models.Authorization +namespace Wino.Core.Domain.Models.Authorization; + +public class GoogleAuthorizationRequest { - public class GoogleAuthorizationRequest + public const string RedirectUri = "google.pw.oauth2:/oauth2redirect"; + + const string authorizationEndpoint = "https://accounts.google.com/o/oauth2/v2/auth"; + const string CodeChallangeMethod = "S256"; + + public GoogleAuthorizationRequest(string state, string codeVerifier, string codeChallange) { - public const string RedirectUri = "google.pw.oauth2:/oauth2redirect"; + State = state; + CodeVerifier = codeVerifier; + CodeChallange = codeChallange; + } - const string authorizationEndpoint = "https://accounts.google.com/o/oauth2/v2/auth"; - const string CodeChallangeMethod = "S256"; + // Pre + public string State { get; set; } + public string CodeVerifier { get; set; } + public string CodeChallange { get; set; } + public string ClientId { get; set; } - public GoogleAuthorizationRequest(string state, string codeVerifier, string codeChallange) - { - State = state; - CodeVerifier = codeVerifier; - CodeChallange = codeChallange; - } + // Post + public string AuthorizationCode { get; set; } - // Pre - public string State { get; set; } - public string CodeVerifier { get; set; } - public string CodeChallange { get; set; } - public string ClientId { get; set; } + public string BuildRequest(string clientId) + { + ClientId = clientId; - // Post - public string AuthorizationCode { get; set; } + // Creates the OAuth 2.0 authorization request. + return string.Format("{0}?response_type=code&scope=https://mail.google.com/ https://www.googleapis.com/auth/gmail.labels https://www.googleapis.com/auth/userinfo.profile&redirect_uri={1}&client_id={2}&state={3}&code_challenge={4}&code_challenge_method={5}", + authorizationEndpoint, + Uri.EscapeDataString(RedirectUri), + ClientId, + State, + CodeChallange, + CodeChallangeMethod); + } - public string BuildRequest(string clientId) - { - ClientId = clientId; + public void ValidateAuthorizationCode(Uri callbackUri) + { + if (callbackUri == null) + throw new GoogleAuthenticationException(Translator.Exception_GoogleAuthCallbackNull); - // Creates the OAuth 2.0 authorization request. - return string.Format("{0}?response_type=code&scope=https://mail.google.com/ https://www.googleapis.com/auth/gmail.labels https://www.googleapis.com/auth/userinfo.profile&redirect_uri={1}&client_id={2}&state={3}&code_challenge={4}&code_challenge_method={5}", - authorizationEndpoint, - Uri.EscapeDataString(RedirectUri), - ClientId, - State, - CodeChallange, - CodeChallangeMethod); - } + string queryString = callbackUri.Query; - public void ValidateAuthorizationCode(Uri callbackUri) - { - if (callbackUri == null) - throw new GoogleAuthenticationException(Translator.Exception_GoogleAuthCallbackNull); + Dictionary queryStringParams = queryString.Substring(1).Split('&').ToDictionary(c => c.Split('=')[0], c => Uri.UnescapeDataString(c.Split('=')[1])); - string queryString = callbackUri.Query; + if (queryStringParams.ContainsKey("error")) + throw new GoogleAuthenticationException(string.Format(Translator.Exception_GoogleAuthError, queryStringParams["error"])); - Dictionary queryStringParams = queryString.Substring(1).Split('&').ToDictionary(c => c.Split('=')[0], c => Uri.UnescapeDataString(c.Split('=')[1])); + if (!queryStringParams.ContainsKey("code") || !queryStringParams.ContainsKey("state")) + throw new GoogleAuthenticationException(Translator.Exception_GoogleAuthCorruptedCode + queryString); - if (queryStringParams.ContainsKey("error")) - throw new GoogleAuthenticationException(string.Format(Translator.Exception_GoogleAuthError, queryStringParams["error"])); + // Gets the Authorization code & state + string code = queryStringParams["code"]; + string incomingState = queryStringParams["state"]; - if (!queryStringParams.ContainsKey("code") || !queryStringParams.ContainsKey("state")) - throw new GoogleAuthenticationException(Translator.Exception_GoogleAuthCorruptedCode + queryString); + // Compares the receieved state to the expected value, to ensure that + // this app made the request which resulted in authorization + if (incomingState != State) + throw new GoogleAuthenticationException(string.Format(Translator.Exception_GoogleAuthInvalidResponse, incomingState)); - // Gets the Authorization code & state - string code = queryStringParams["code"]; - string incomingState = queryStringParams["state"]; - - // Compares the receieved state to the expected value, to ensure that - // this app made the request which resulted in authorization - if (incomingState != State) - throw new GoogleAuthenticationException(string.Format(Translator.Exception_GoogleAuthInvalidResponse, incomingState)); - - AuthorizationCode = code; - } + AuthorizationCode = code; } } diff --git a/Wino.Core.Domain/Models/Authorization/GoogleTokenizationRequest.cs b/Wino.Core.Domain/Models/Authorization/GoogleTokenizationRequest.cs index 0590df09..572209c3 100644 --- a/Wino.Core.Domain/Models/Authorization/GoogleTokenizationRequest.cs +++ b/Wino.Core.Domain/Models/Authorization/GoogleTokenizationRequest.cs @@ -1,27 +1,26 @@ using System; using Wino.Core.Domain.Exceptions; -namespace Wino.Core.Domain.Models.Authorization +namespace Wino.Core.Domain.Models.Authorization; + +public class GoogleTokenizationRequest { - public class GoogleTokenizationRequest + public GoogleTokenizationRequest(GoogleAuthorizationRequest authorizationRequest) { - public GoogleTokenizationRequest(GoogleAuthorizationRequest authorizationRequest) - { - if (authorizationRequest == null) - throw new GoogleAuthenticationException("Authorization request is empty."); + if (authorizationRequest == null) + throw new GoogleAuthenticationException("Authorization request is empty."); - AuthorizationRequest = authorizationRequest; + AuthorizationRequest = authorizationRequest; - if (string.IsNullOrEmpty(AuthorizationRequest.AuthorizationCode)) - throw new GoogleAuthenticationException("Authorization request has empty code."); - } + if (string.IsNullOrEmpty(AuthorizationRequest.AuthorizationCode)) + throw new GoogleAuthenticationException("Authorization request has empty code."); + } - public GoogleAuthorizationRequest AuthorizationRequest { get; set; } + public GoogleAuthorizationRequest AuthorizationRequest { get; set; } - public string BuildRequest() - { - return string.Format("code={0}&redirect_uri={1}&client_id={2}&code_verifier={3}&scope=&grant_type=authorization_code", - AuthorizationRequest.AuthorizationCode, Uri.EscapeDataString(GoogleAuthorizationRequest.RedirectUri), AuthorizationRequest.ClientId, AuthorizationRequest.CodeVerifier); - } + public string BuildRequest() + { + return string.Format("code={0}&redirect_uri={1}&client_id={2}&code_verifier={3}&scope=&grant_type=authorization_code", + AuthorizationRequest.AuthorizationCode, Uri.EscapeDataString(GoogleAuthorizationRequest.RedirectUri), AuthorizationRequest.ClientId, AuthorizationRequest.CodeVerifier); } } diff --git a/Wino.Core.Domain/Models/AutoDiscovery/AutoDiscoveryMinimalSettings.cs b/Wino.Core.Domain/Models/AutoDiscovery/AutoDiscoveryMinimalSettings.cs index b1135a5b..e78ca312 100644 --- a/Wino.Core.Domain/Models/AutoDiscovery/AutoDiscoveryMinimalSettings.cs +++ b/Wino.Core.Domain/Models/AutoDiscovery/AutoDiscoveryMinimalSettings.cs @@ -1,9 +1,8 @@ -namespace Wino.Core.Domain.Models.AutoDiscovery +namespace Wino.Core.Domain.Models.AutoDiscovery; + +public class AutoDiscoveryMinimalSettings { - public class AutoDiscoveryMinimalSettings - { - public string DisplayName { get; set; } - public string Email { get; set; } - public string Password { get; set; } - } + public string DisplayName { get; set; } + public string Email { get; set; } + public string Password { get; set; } } diff --git a/Wino.Core.Domain/Models/AutoDiscovery/AutoDiscoveryProviderSetting.cs b/Wino.Core.Domain/Models/AutoDiscovery/AutoDiscoveryProviderSetting.cs index 59abe9ae..191b4655 100644 --- a/Wino.Core.Domain/Models/AutoDiscovery/AutoDiscoveryProviderSetting.cs +++ b/Wino.Core.Domain/Models/AutoDiscovery/AutoDiscoveryProviderSetting.cs @@ -1,22 +1,21 @@ using System.Text.Json.Serialization; -namespace Wino.Core.Domain.Models.AutoDiscovery +namespace Wino.Core.Domain.Models.AutoDiscovery; + +public class AutoDiscoveryProviderSetting { - public class AutoDiscoveryProviderSetting - { - [JsonPropertyName("protocol")] - public string Protocol { get; set; } + [JsonPropertyName("protocol")] + public string Protocol { get; set; } - [JsonPropertyName("address")] - public string Address { get; set; } + [JsonPropertyName("address")] + public string Address { get; set; } - [JsonPropertyName("port")] - public int Port { get; set; } + [JsonPropertyName("port")] + public int Port { get; set; } - [JsonPropertyName("secure")] - public string Secure { get; set; } + [JsonPropertyName("secure")] + public string Secure { get; set; } - [JsonPropertyName("username")] - public string Username { get; set; } - } + [JsonPropertyName("username")] + public string Username { get; set; } } diff --git a/Wino.Core.Domain/Models/AutoDiscovery/AutoDiscoverySettings.cs b/Wino.Core.Domain/Models/AutoDiscovery/AutoDiscoverySettings.cs index b96eb191..87494dcc 100644 --- a/Wino.Core.Domain/Models/AutoDiscovery/AutoDiscoverySettings.cs +++ b/Wino.Core.Domain/Models/AutoDiscovery/AutoDiscoverySettings.cs @@ -3,70 +3,69 @@ using System.Collections.Generic; using System.Text.Json.Serialization; using Wino.Core.Domain.Entities.Shared; -namespace Wino.Core.Domain.Models.AutoDiscovery +namespace Wino.Core.Domain.Models.AutoDiscovery; + +public class AutoDiscoverySettings { - public class AutoDiscoverySettings + [JsonPropertyName("domain")] + public string Domain { get; set; } + + [JsonPropertyName("password")] + public string Password { get; set; } + + [JsonPropertyName("settings")] + public List Settings { get; set; } + + /// + /// Gets whether this domain requires additional steps for password like app-specific password or sth. + /// + public bool IsPasswordSupportLinkAvailable => !string.IsNullOrEmpty(Password) && Uri.TryCreate(Password, UriKind.Absolute, out _); + + public AutoDiscoveryMinimalSettings UserMinimalSettings { get; set; } + + public CustomServerInformation ToServerInformation() { - [JsonPropertyName("domain")] - public string Domain { get; set; } + var imapSettings = GetImapSettings(); + var smtpSettings = GetSmptpSettings(); - [JsonPropertyName("password")] - public string Password { get; set; } + if (imapSettings == null || smtpSettings == null) return null; - [JsonPropertyName("settings")] - public List Settings { get; set; } + string imapUrl = imapSettings.Address; + string smtpUrl = smtpSettings.Address; - /// - /// Gets whether this domain requires additional steps for password like app-specific password or sth. - /// - public bool IsPasswordSupportLinkAvailable => !string.IsNullOrEmpty(Password) && Uri.TryCreate(Password, UriKind.Absolute, out _); + string imapUsername = imapSettings.Username; + string smtpUsername = smtpSettings.Username; - public AutoDiscoveryMinimalSettings UserMinimalSettings { get; set; } + int imapPort = imapSettings.Port; + int smtpPort = smtpSettings.Port; - public CustomServerInformation ToServerInformation() + var serverInfo = new CustomServerInformation { - var imapSettings = GetImapSettings(); - var smtpSettings = GetSmptpSettings(); + Id = Guid.NewGuid(), + DisplayName = UserMinimalSettings.DisplayName, + Address = UserMinimalSettings.Email, + IncomingServerPassword = UserMinimalSettings.Password, + OutgoingServerPassword = UserMinimalSettings.Password, + IncomingAuthenticationMethod = Enums.ImapAuthenticationMethod.Auto, + OutgoingAuthenticationMethod = Enums.ImapAuthenticationMethod.Auto, + OutgoingServerSocketOption = Enums.ImapConnectionSecurity.Auto, + IncomingServerSocketOption = Enums.ImapConnectionSecurity.Auto, + IncomingServer = imapUrl, + OutgoingServer = smtpUrl, + IncomingServerPort = imapPort.ToString(), + OutgoingServerPort = smtpPort.ToString(), + IncomingServerType = Enums.CustomIncomingServerType.IMAP4, + IncomingServerUsername = imapUsername, + OutgoingServerUsername = smtpUsername, + MaxConcurrentClients = 5 + }; - if (imapSettings == null || smtpSettings == null) return null; - - string imapUrl = imapSettings.Address; - string smtpUrl = smtpSettings.Address; - - string imapUsername = imapSettings.Username; - string smtpUsername = smtpSettings.Username; - - int imapPort = imapSettings.Port; - int smtpPort = smtpSettings.Port; - - var serverInfo = new CustomServerInformation - { - Id = Guid.NewGuid(), - DisplayName = UserMinimalSettings.DisplayName, - Address = UserMinimalSettings.Email, - IncomingServerPassword = UserMinimalSettings.Password, - OutgoingServerPassword = UserMinimalSettings.Password, - IncomingAuthenticationMethod = Enums.ImapAuthenticationMethod.Auto, - OutgoingAuthenticationMethod = Enums.ImapAuthenticationMethod.Auto, - OutgoingServerSocketOption = Enums.ImapConnectionSecurity.Auto, - IncomingServerSocketOption = Enums.ImapConnectionSecurity.Auto, - IncomingServer = imapUrl, - OutgoingServer = smtpUrl, - IncomingServerPort = imapPort.ToString(), - OutgoingServerPort = smtpPort.ToString(), - IncomingServerType = Enums.CustomIncomingServerType.IMAP4, - IncomingServerUsername = imapUsername, - OutgoingServerUsername = smtpUsername, - MaxConcurrentClients = 5 - }; - - return serverInfo; - } - - public AutoDiscoveryProviderSetting GetImapSettings() - => Settings?.Find(a => a.Protocol == "IMAP"); - - public AutoDiscoveryProviderSetting GetSmptpSettings() - => Settings?.Find(a => a.Protocol == "SMTP"); + return serverInfo; } + + public AutoDiscoveryProviderSetting GetImapSettings() + => Settings?.Find(a => a.Protocol == "IMAP"); + + public AutoDiscoveryProviderSetting GetSmptpSettings() + => Settings?.Find(a => a.Protocol == "SMTP"); } diff --git a/Wino.Core.Domain/Models/Calendar/CalendarDayModel.cs b/Wino.Core.Domain/Models/Calendar/CalendarDayModel.cs index f78fd495..4f3f06a8 100644 --- a/Wino.Core.Domain/Models/Calendar/CalendarDayModel.cs +++ b/Wino.Core.Domain/Models/Calendar/CalendarDayModel.cs @@ -2,26 +2,25 @@ using Itenso.TimePeriod; using Wino.Core.Domain.Collections; -namespace Wino.Core.Domain.Models.Calendar +namespace Wino.Core.Domain.Models.Calendar; + +/// +/// Represents a day in the calendar. +/// Can hold events, appointments, wheather status etc. +/// +public class CalendarDayModel { - /// - /// Represents a day in the calendar. - /// Can hold events, appointments, wheather status etc. - /// - public class CalendarDayModel + public ITimePeriod Period { get; } + public CalendarEventCollection EventsCollection { get; } + + public CalendarDayModel(DateTime representingDate, CalendarRenderOptions calendarRenderOptions) { - public ITimePeriod Period { get; } - public CalendarEventCollection EventsCollection { get; } - - public CalendarDayModel(DateTime representingDate, CalendarRenderOptions calendarRenderOptions) - { - RepresentingDate = representingDate; - Period = new TimeRange(representingDate, representingDate.AddDays(1)); - CalendarRenderOptions = calendarRenderOptions; - EventsCollection = new CalendarEventCollection(Period, calendarRenderOptions.CalendarSettings); - } - - public DateTime RepresentingDate { get; } - public CalendarRenderOptions CalendarRenderOptions { get; } + RepresentingDate = representingDate; + Period = new TimeRange(representingDate, representingDate.AddDays(1)); + CalendarRenderOptions = calendarRenderOptions; + EventsCollection = new CalendarEventCollection(Period, calendarRenderOptions.CalendarSettings); } + + public DateTime RepresentingDate { get; } + public CalendarRenderOptions CalendarRenderOptions { get; } } diff --git a/Wino.Core.Domain/Models/Calendar/CalendarItemTarget.cs b/Wino.Core.Domain/Models/Calendar/CalendarItemTarget.cs index a16cb6b6..2d5fd0d1 100644 --- a/Wino.Core.Domain/Models/Calendar/CalendarItemTarget.cs +++ b/Wino.Core.Domain/Models/Calendar/CalendarItemTarget.cs @@ -1,7 +1,6 @@ using Wino.Core.Domain.Entities.Calendar; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Models.Calendar -{ - public record CalendarItemTarget(CalendarItem Item, CalendarEventTargetType TargetType); -} +namespace Wino.Core.Domain.Models.Calendar; + +public record CalendarItemTarget(CalendarItem Item, CalendarEventTargetType TargetType); diff --git a/Wino.Core.Domain/Models/Calendar/CalendarPageNavigationArgs.cs b/Wino.Core.Domain/Models/Calendar/CalendarPageNavigationArgs.cs index e7a8f3cd..a39d536b 100644 --- a/Wino.Core.Domain/Models/Calendar/CalendarPageNavigationArgs.cs +++ b/Wino.Core.Domain/Models/Calendar/CalendarPageNavigationArgs.cs @@ -1,17 +1,16 @@ using System; -namespace Wino.Core.Domain.Models.Calendar -{ - public class CalendarPageNavigationArgs - { - /// - /// When the app launches, automatically request the default calendar navigation options. - /// - public bool RequestDefaultNavigation { get; set; } +namespace Wino.Core.Domain.Models.Calendar; - /// - /// Display the calendar view for the specified date. - /// - public DateTime NavigationDate { get; set; } - } +public class CalendarPageNavigationArgs +{ + /// + /// When the app launches, automatically request the default calendar navigation options. + /// + public bool RequestDefaultNavigation { get; set; } + + /// + /// Display the calendar view for the specified date. + /// + public DateTime NavigationDate { get; set; } } diff --git a/Wino.Core.Domain/Models/Calendar/CalendarRenderOptions.cs b/Wino.Core.Domain/Models/Calendar/CalendarRenderOptions.cs index 6765309c..2f31db08 100644 --- a/Wino.Core.Domain/Models/Calendar/CalendarRenderOptions.cs +++ b/Wino.Core.Domain/Models/Calendar/CalendarRenderOptions.cs @@ -1,14 +1,13 @@ -namespace Wino.Core.Domain.Models.Calendar +namespace Wino.Core.Domain.Models.Calendar; + +public class CalendarRenderOptions { - public class CalendarRenderOptions + public CalendarRenderOptions(DateRange dateRange, CalendarSettings calendarSettings) { - public CalendarRenderOptions(DateRange dateRange, CalendarSettings calendarSettings) - { - DateRange = dateRange; - CalendarSettings = calendarSettings; - } - public int TotalDayCount => DateRange.TotalDays; - public DateRange DateRange { get; } - public CalendarSettings CalendarSettings { get; } + DateRange = dateRange; + CalendarSettings = calendarSettings; } + public int TotalDayCount => DateRange.TotalDays; + public DateRange DateRange { get; } + public CalendarSettings CalendarSettings { get; } } diff --git a/Wino.Core.Domain/Models/Calendar/CalendarSettings.cs b/Wino.Core.Domain/Models/Calendar/CalendarSettings.cs index 7a723f1a..573654c1 100644 --- a/Wino.Core.Domain/Models/Calendar/CalendarSettings.cs +++ b/Wino.Core.Domain/Models/Calendar/CalendarSettings.cs @@ -3,46 +3,45 @@ using System.Collections.Generic; using System.Globalization; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Models.Calendar +namespace Wino.Core.Domain.Models.Calendar; + +public record CalendarSettings(DayOfWeek FirstDayOfWeek, + List WorkingDays, + TimeSpan WorkingHourStart, + TimeSpan WorkingHourEnd, + double HourHeight, + DayHeaderDisplayType DayHeaderDisplayType, + CultureInfo CultureInfo) { - public record CalendarSettings(DayOfWeek FirstDayOfWeek, - List WorkingDays, - TimeSpan WorkingHourStart, - TimeSpan WorkingHourEnd, - double HourHeight, - DayHeaderDisplayType DayHeaderDisplayType, - CultureInfo CultureInfo) + public TimeSpan? GetTimeSpan(string selectedTime) { - public TimeSpan? GetTimeSpan(string selectedTime) - { - // Regardless of the format, we need to parse the time to a TimeSpan. - // User may list as 14:00 but enters 2:00 PM by input. - // Be flexible, not annoying. + // Regardless of the format, we need to parse the time to a TimeSpan. + // User may list as 14:00 but enters 2:00 PM by input. + // Be flexible, not annoying. - if (DateTime.TryParse(selectedTime, out DateTime parsedTime)) - { - return parsedTime.TimeOfDay; - } - else - { - return null; - } + if (DateTime.TryParse(selectedTime, out DateTime parsedTime)) + { + return parsedTime.TimeOfDay; } - - public string GetTimeString(TimeSpan timeSpan) + else { - // Here we don't need to be flexible cuz we're saving back the value to the combos. - // They are populated based on the format and must be returned with the format. - - var format = DayHeaderDisplayType switch - { - DayHeaderDisplayType.TwelveHour => "h:mm tt", - DayHeaderDisplayType.TwentyFourHour => "HH:mm", - _ => throw new ArgumentOutOfRangeException(nameof(DayHeaderDisplayType)) - }; - - var dateTime = DateTime.Today.Add(timeSpan); - return dateTime.ToString(format, CultureInfo.InvariantCulture); + return null; } } + + public string GetTimeString(TimeSpan timeSpan) + { + // Here we don't need to be flexible cuz we're saving back the value to the combos. + // They are populated based on the format and must be returned with the format. + + var format = DayHeaderDisplayType switch + { + DayHeaderDisplayType.TwelveHour => "h:mm tt", + DayHeaderDisplayType.TwentyFourHour => "HH:mm", + _ => throw new ArgumentOutOfRangeException(nameof(DayHeaderDisplayType)) + }; + + var dateTime = DateTime.Today.Add(timeSpan); + return dateTime.ToString(format, CultureInfo.InvariantCulture); + } } diff --git a/Wino.Core.Domain/Models/Calendar/CalendarTypeStrategies/BaseCalendarTypeDrawingStrategy.cs b/Wino.Core.Domain/Models/Calendar/CalendarTypeStrategies/BaseCalendarTypeDrawingStrategy.cs index bfb164ba..798aa653 100644 --- a/Wino.Core.Domain/Models/Calendar/CalendarTypeStrategies/BaseCalendarTypeDrawingStrategy.cs +++ b/Wino.Core.Domain/Models/Calendar/CalendarTypeStrategies/BaseCalendarTypeDrawingStrategy.cs @@ -2,37 +2,36 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.Calendar; -namespace Wino.Core.Domain.Models.Calendar.CalendarTypeStrategies +namespace Wino.Core.Domain.Models.Calendar.CalendarTypeStrategies; + +public abstract class BaseCalendarTypeDrawingStrategy { - public abstract class BaseCalendarTypeDrawingStrategy + public CalendarSettings Settings { get; } + public CalendarDisplayType HandlingType { get; } + + /// + /// Day range of the pre-rendered items. + /// + public abstract DateRange GetRenderDateRange(DateTime DisplayDate, int DayDisplayCount); + + /// + /// Gets the previous date range for rendering. + /// For example, 1 week view with 7 days will return -7 <> 0 days. + /// + /// Current displayed date range. + /// Day display count/ + public abstract DateRange GetPreviousDateRange(DateRange CurrentDateRange, int DayDisplayCount); + + public abstract DateRange GetNextDateRange(DateRange CurrentDateRange, int DayDisplayCount); + + /// + /// How many items should be placed in 1 FlipViewItem. + /// + public abstract int GetRenderDayCount(DateTime DisplayDate, int DayDisplayCount); + + protected BaseCalendarTypeDrawingStrategy(CalendarSettings settings, CalendarDisplayType handlingType) { - public CalendarSettings Settings { get; } - public CalendarDisplayType HandlingType { get; } - - /// - /// Day range of the pre-rendered items. - /// - public abstract DateRange GetRenderDateRange(DateTime DisplayDate, int DayDisplayCount); - - /// - /// Gets the previous date range for rendering. - /// For example, 1 week view with 7 days will return -7 <> 0 days. - /// - /// Current displayed date range. - /// Day display count/ - public abstract DateRange GetPreviousDateRange(DateRange CurrentDateRange, int DayDisplayCount); - - public abstract DateRange GetNextDateRange(DateRange CurrentDateRange, int DayDisplayCount); - - /// - /// How many items should be placed in 1 FlipViewItem. - /// - public abstract int GetRenderDayCount(DateTime DisplayDate, int DayDisplayCount); - - protected BaseCalendarTypeDrawingStrategy(CalendarSettings settings, CalendarDisplayType handlingType) - { - Settings = settings; - HandlingType = handlingType; - } + Settings = settings; + HandlingType = handlingType; } } diff --git a/Wino.Core.Domain/Models/Calendar/CalendarTypeStrategies/DayCalendarDrawingStrategy.cs b/Wino.Core.Domain/Models/Calendar/CalendarTypeStrategies/DayCalendarDrawingStrategy.cs index 4b2a3256..438c301e 100644 --- a/Wino.Core.Domain/Models/Calendar/CalendarTypeStrategies/DayCalendarDrawingStrategy.cs +++ b/Wino.Core.Domain/Models/Calendar/CalendarTypeStrategies/DayCalendarDrawingStrategy.cs @@ -2,35 +2,34 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.Calendar; -namespace Wino.Core.Domain.Models.Calendar.CalendarTypeStrategies +namespace Wino.Core.Domain.Models.Calendar.CalendarTypeStrategies; + +public class DayCalendarDrawingStrategy : BaseCalendarTypeDrawingStrategy { - public class DayCalendarDrawingStrategy : BaseCalendarTypeDrawingStrategy + public DayCalendarDrawingStrategy(CalendarSettings settings) : base(settings, CalendarDisplayType.Day) { - public DayCalendarDrawingStrategy(CalendarSettings settings) : base(settings, CalendarDisplayType.Day) - { - } - - public override DateRange GetNextDateRange(DateRange CurrentDateRange, int DayDisplayCount) - { - return new DateRange(CurrentDateRange.EndDate, CurrentDateRange.EndDate.AddDays(DayDisplayCount * 5)); - } - - public override DateRange GetPreviousDateRange(DateRange CurrentDateRange, int DayDisplayCount) - { - return new DateRange(CurrentDateRange.StartDate.AddDays(-DayDisplayCount * 5), CurrentDateRange.StartDate); - } - - public override DateRange GetRenderDateRange(DateTime DisplayDate, int DayDisplayCount) - { - // Add good amount of days to the left and right of the DisplayDate. - - var start = DisplayDate.AddDays(-4 * DayDisplayCount); - var end = DisplayDate.AddDays(4 * DayDisplayCount); - - return new DateRange(start, end); - } - - public override int GetRenderDayCount(DateTime DisplayDate, int DayDisplayCount) => DayDisplayCount; } + + public override DateRange GetNextDateRange(DateRange CurrentDateRange, int DayDisplayCount) + { + return new DateRange(CurrentDateRange.EndDate, CurrentDateRange.EndDate.AddDays(DayDisplayCount * 5)); + } + + public override DateRange GetPreviousDateRange(DateRange CurrentDateRange, int DayDisplayCount) + { + return new DateRange(CurrentDateRange.StartDate.AddDays(-DayDisplayCount * 5), CurrentDateRange.StartDate); + } + + public override DateRange GetRenderDateRange(DateTime DisplayDate, int DayDisplayCount) + { + // Add good amount of days to the left and right of the DisplayDate. + + var start = DisplayDate.AddDays(-4 * DayDisplayCount); + var end = DisplayDate.AddDays(4 * DayDisplayCount); + + return new DateRange(start, end); + } + + public override int GetRenderDayCount(DateTime DisplayDate, int DayDisplayCount) => DayDisplayCount; } diff --git a/Wino.Core.Domain/Models/Calendar/CalendarTypeStrategies/MonthCalendarDrawingStrategy.cs b/Wino.Core.Domain/Models/Calendar/CalendarTypeStrategies/MonthCalendarDrawingStrategy.cs index 75febbef..9ded7c97 100644 --- a/Wino.Core.Domain/Models/Calendar/CalendarTypeStrategies/MonthCalendarDrawingStrategy.cs +++ b/Wino.Core.Domain/Models/Calendar/CalendarTypeStrategies/MonthCalendarDrawingStrategy.cs @@ -2,32 +2,31 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Extensions; -namespace Wino.Core.Domain.Models.Calendar.CalendarTypeStrategies +namespace Wino.Core.Domain.Models.Calendar.CalendarTypeStrategies; + +public class MonthCalendarDrawingStrategy : BaseCalendarTypeDrawingStrategy { - public class MonthCalendarDrawingStrategy : BaseCalendarTypeDrawingStrategy + public MonthCalendarDrawingStrategy(CalendarSettings settings) + : base(settings, CalendarDisplayType.Month) { - public MonthCalendarDrawingStrategy(CalendarSettings settings) - : base(settings, CalendarDisplayType.Month) - { - } - - public override DateRange GetNextDateRange(DateRange CurrentDateRange, int DayDisplayCount) - { - return new DateRange(CurrentDateRange.EndDate, CurrentDateRange.EndDate.AddDays(35)); - } - - public override DateRange GetPreviousDateRange(DateRange CurrentDateRange, int DayDisplayCount) - { - return new DateRange(CurrentDateRange.StartDate.AddDays(-35), CurrentDateRange.StartDate); - } - - public override DateRange GetRenderDateRange(DateTime DisplayDate, int DayDisplayCount) - { - // Get the first day of the month. - var firstDayOfMonth = new DateTime(DisplayDate.Year, DisplayDate.Month, 1); - return DateTimeExtensions.GetMonthDateRangeStartingWeekday(firstDayOfMonth, Settings.FirstDayOfWeek); - } - - public override int GetRenderDayCount(DateTime DisplayDate, int DayDisplayCount) => 35; } + + public override DateRange GetNextDateRange(DateRange CurrentDateRange, int DayDisplayCount) + { + return new DateRange(CurrentDateRange.EndDate, CurrentDateRange.EndDate.AddDays(35)); + } + + public override DateRange GetPreviousDateRange(DateRange CurrentDateRange, int DayDisplayCount) + { + return new DateRange(CurrentDateRange.StartDate.AddDays(-35), CurrentDateRange.StartDate); + } + + public override DateRange GetRenderDateRange(DateTime DisplayDate, int DayDisplayCount) + { + // Get the first day of the month. + var firstDayOfMonth = new DateTime(DisplayDate.Year, DisplayDate.Month, 1); + return DateTimeExtensions.GetMonthDateRangeStartingWeekday(firstDayOfMonth, Settings.FirstDayOfWeek); + } + + public override int GetRenderDayCount(DateTime DisplayDate, int DayDisplayCount) => 35; } diff --git a/Wino.Core.Domain/Models/Calendar/CalendarTypeStrategies/WeekCalendarDrawingStrategy.cs b/Wino.Core.Domain/Models/Calendar/CalendarTypeStrategies/WeekCalendarDrawingStrategy.cs index 7a1c108d..9a3d08c2 100644 --- a/Wino.Core.Domain/Models/Calendar/CalendarTypeStrategies/WeekCalendarDrawingStrategy.cs +++ b/Wino.Core.Domain/Models/Calendar/CalendarTypeStrategies/WeekCalendarDrawingStrategy.cs @@ -1,35 +1,34 @@ using System; using Wino.Core.Domain.Models.Calendar; -namespace Wino.Core.Domain.Models.Calendar.CalendarTypeStrategies +namespace Wino.Core.Domain.Models.Calendar.CalendarTypeStrategies; + +public class WeekCalendarDrawingStrategy : BaseCalendarTypeDrawingStrategy { - public class WeekCalendarDrawingStrategy : BaseCalendarTypeDrawingStrategy + public WeekCalendarDrawingStrategy(CalendarSettings settings) : base(settings, Enums.CalendarDisplayType.Week) { } + + public override DateRange GetNextDateRange(DateRange CurrentDateRange, int DayDisplayCount) + => new DateRange(CurrentDateRange.EndDate, CurrentDateRange.EndDate.AddDays(7 * 2)); + + public override DateRange GetPreviousDateRange(DateRange CurrentDateRange, int DayDisplayCount) + => new DateRange(CurrentDateRange.StartDate.AddDays(-7 * 2), CurrentDateRange.StartDate); + + public override DateRange GetRenderDateRange(DateTime DisplayDate, int DayDisplayCount) { - public WeekCalendarDrawingStrategy(CalendarSettings settings) : base(settings, Enums.CalendarDisplayType.Week) { } + // Detect the first day of the week that contains the selected date. + DayOfWeek firstDayOfWeek = Settings.FirstDayOfWeek; - public override DateRange GetNextDateRange(DateRange CurrentDateRange, int DayDisplayCount) - => new DateRange(CurrentDateRange.EndDate, CurrentDateRange.EndDate.AddDays(7 * 2)); + int diff = (7 + (DisplayDate.DayOfWeek - Settings.FirstDayOfWeek)) % 7; - public override DateRange GetPreviousDateRange(DateRange CurrentDateRange, int DayDisplayCount) - => new DateRange(CurrentDateRange.StartDate.AddDays(-7 * 2), CurrentDateRange.StartDate); + // Start loading from this date instead of visible date. + var weekStartDate = DisplayDate.AddDays(-diff).Date; - public override DateRange GetRenderDateRange(DateTime DisplayDate, int DayDisplayCount) - { - // Detect the first day of the week that contains the selected date. - DayOfWeek firstDayOfWeek = Settings.FirstDayOfWeek; + // Load -+ 14 days + var startDate = weekStartDate.AddDays(-14); + var endDte = weekStartDate.AddDays(14); - int diff = (7 + (DisplayDate.DayOfWeek - Settings.FirstDayOfWeek)) % 7; - - // Start loading from this date instead of visible date. - var weekStartDate = DisplayDate.AddDays(-diff).Date; - - // Load -+ 14 days - var startDate = weekStartDate.AddDays(-14); - var endDte = weekStartDate.AddDays(14); - - return new DateRange(startDate, endDte); - } - - public override int GetRenderDayCount(DateTime DisplayDate, int DayDisplayCount) => 7; + return new DateRange(startDate, endDte); } + + public override int GetRenderDayCount(DateTime DisplayDate, int DayDisplayCount) => 7; } diff --git a/Wino.Core.Domain/Models/Calendar/CalendarViewDayClickedEventArgs.cs b/Wino.Core.Domain/Models/Calendar/CalendarViewDayClickedEventArgs.cs index 2a7369c2..5f933dc9 100644 --- a/Wino.Core.Domain/Models/Calendar/CalendarViewDayClickedEventArgs.cs +++ b/Wino.Core.Domain/Models/Calendar/CalendarViewDayClickedEventArgs.cs @@ -1,10 +1,9 @@ using System; -namespace Wino.Core.Domain.Models.Calendar -{ - /// - /// Contains the clicked date on the calendar view. - /// - /// Requested date. - public record CalendarViewDayClickedEventArgs(DateTime ClickedDate); -} +namespace Wino.Core.Domain.Models.Calendar; + +/// +/// Contains the clicked date on the calendar view. +/// +/// Requested date. +public record CalendarViewDayClickedEventArgs(DateTime ClickedDate); diff --git a/Wino.Core.Domain/Models/Calendar/DateRange.cs b/Wino.Core.Domain/Models/Calendar/DateRange.cs index 3765e22e..d37169f4 100644 --- a/Wino.Core.Domain/Models/Calendar/DateRange.cs +++ b/Wino.Core.Domain/Models/Calendar/DateRange.cs @@ -1,42 +1,41 @@ using System; using System.Linq; -namespace Wino.Core.Domain.Models.Calendar +namespace Wino.Core.Domain.Models.Calendar; + +public class DateRange { - public class DateRange + public DateRange(DateTime startDate, DateTime endDate) { - public DateRange(DateTime startDate, DateTime endDate) - { - StartDate = startDate; - EndDate = endDate; - } + StartDate = startDate; + EndDate = endDate; + } - public DateTime StartDate { get; } - public DateTime EndDate { get; } + public DateTime StartDate { get; } + public DateTime EndDate { get; } - public int TotalDays => (EndDate - StartDate).Days; + public int TotalDays => (EndDate - StartDate).Days; - public override string ToString() => $"{StartDate.ToString("dd MMMM")} - {EndDate.ToString("dd MMMM")}"; + public override string ToString() => $"{StartDate.ToString("dd MMMM")} - {EndDate.ToString("dd MMMM")}"; - public bool IsInRange(DateTime date) - { - return date >= StartDate && date <= EndDate; - } + public bool IsInRange(DateTime date) + { + return date >= StartDate && date <= EndDate; + } - /// - /// Gets the most visible month index in the visible date range. - /// - public int GetMostVisibleMonthIndex() - { - var dateRange = Enumerable.Range(0, (EndDate - StartDate).Days + 1).Select(offset => StartDate.AddDays(offset)); + /// + /// Gets the most visible month index in the visible date range. + /// + public int GetMostVisibleMonthIndex() + { + var dateRange = Enumerable.Range(0, (EndDate - StartDate).Days + 1).Select(offset => StartDate.AddDays(offset)); - var groupedByMonth = dateRange.GroupBy(date => date.Month) - .Select(g => new { Month = g.Key, DayCount = g.Count() }); + var groupedByMonth = dateRange.GroupBy(date => date.Month) + .Select(g => new { Month = g.Key, DayCount = g.Count() }); - // Find the month with the maximum count of days - var mostVisibleMonth = groupedByMonth.OrderByDescending(g => g.DayCount).FirstOrDefault(); + // Find the month with the maximum count of days + var mostVisibleMonth = groupedByMonth.OrderByDescending(g => g.DayCount).FirstOrDefault(); - return mostVisibleMonth?.Month ?? -1; - } + return mostVisibleMonth?.Month ?? -1; } } diff --git a/Wino.Core.Domain/Models/Calendar/DayHeaderRenderModel.cs b/Wino.Core.Domain/Models/Calendar/DayHeaderRenderModel.cs index 4798adf4..2df4b2aa 100644 --- a/Wino.Core.Domain/Models/Calendar/DayHeaderRenderModel.cs +++ b/Wino.Core.Domain/Models/Calendar/DayHeaderRenderModel.cs @@ -1,14 +1,13 @@ -namespace Wino.Core.Domain.Models.Calendar -{ - public class DayHeaderRenderModel - { - public DayHeaderRenderModel(string dayHeader, double hourHeight) - { - DayHeader = dayHeader; - HourHeight = hourHeight; - } +namespace Wino.Core.Domain.Models.Calendar; - public string DayHeader { get; } - public double HourHeight { get; } +public class DayHeaderRenderModel +{ + public DayHeaderRenderModel(string dayHeader, double hourHeight) + { + DayHeader = dayHeader; + HourHeight = hourHeight; } + + public string DayHeader { get; } + public double HourHeight { get; } } diff --git a/Wino.Core.Domain/Models/Calendar/DayRangeRenderModel.cs b/Wino.Core.Domain/Models/Calendar/DayRangeRenderModel.cs index 830ecc26..17245c32 100644 --- a/Wino.Core.Domain/Models/Calendar/DayRangeRenderModel.cs +++ b/Wino.Core.Domain/Models/Calendar/DayRangeRenderModel.cs @@ -3,50 +3,49 @@ using System.Linq; using Itenso.TimePeriod; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Models.Calendar +namespace Wino.Core.Domain.Models.Calendar; + +/// +/// Represents a range of days in the calendar. +/// Corresponds to 1 view of the FlipView in CalendarPage. +/// +public class DayRangeRenderModel { - /// - /// Represents a range of days in the calendar. - /// Corresponds to 1 view of the FlipView in CalendarPage. - /// - public class DayRangeRenderModel + public ITimePeriod Period { get; } + public List CalendarDays { get; } = []; + + // TODO: Get rid of this at some point. + public List DayHeaders { get; } = []; + public CalendarRenderOptions CalendarRenderOptions { get; } + + public DayRangeRenderModel(CalendarRenderOptions calendarRenderOptions) { - public ITimePeriod Period { get; } - public List CalendarDays { get; } = []; + CalendarRenderOptions = calendarRenderOptions; - // TODO: Get rid of this at some point. - public List DayHeaders { get; } = []; - public CalendarRenderOptions CalendarRenderOptions { get; } - - public DayRangeRenderModel(CalendarRenderOptions calendarRenderOptions) + for (var i = 0; i < CalendarRenderOptions.TotalDayCount; i++) { - CalendarRenderOptions = calendarRenderOptions; + var representingDate = calendarRenderOptions.DateRange.StartDate.AddDays(i); + var calendarDayModel = new CalendarDayModel(representingDate, calendarRenderOptions); - for (var i = 0; i < CalendarRenderOptions.TotalDayCount; i++) + CalendarDays.Add(calendarDayModel); + } + + Period = new TimeRange(CalendarDays.First().RepresentingDate, CalendarDays.Last().RepresentingDate.AddDays(1)); + + // Create day headers based on culture info. + + for (var i = 0; i < 24; i++) + { + var representingDate = calendarRenderOptions.DateRange.StartDate.Date.AddHours(i); + + string dayHeader = calendarRenderOptions.CalendarSettings.DayHeaderDisplayType switch { - var representingDate = calendarRenderOptions.DateRange.StartDate.AddDays(i); - var calendarDayModel = new CalendarDayModel(representingDate, calendarRenderOptions); + DayHeaderDisplayType.TwelveHour => representingDate.ToString("h tt", calendarRenderOptions.CalendarSettings.CultureInfo), + DayHeaderDisplayType.TwentyFourHour => representingDate.ToString("HH", calendarRenderOptions.CalendarSettings.CultureInfo), + _ => "N/A" + }; - CalendarDays.Add(calendarDayModel); - } - - Period = new TimeRange(CalendarDays.First().RepresentingDate, CalendarDays.Last().RepresentingDate.AddDays(1)); - - // Create day headers based on culture info. - - for (var i = 0; i < 24; i++) - { - var representingDate = calendarRenderOptions.DateRange.StartDate.Date.AddHours(i); - - string dayHeader = calendarRenderOptions.CalendarSettings.DayHeaderDisplayType switch - { - DayHeaderDisplayType.TwelveHour => representingDate.ToString("h tt", calendarRenderOptions.CalendarSettings.CultureInfo), - DayHeaderDisplayType.TwentyFourHour => representingDate.ToString("HH", calendarRenderOptions.CalendarSettings.CultureInfo), - _ => "N/A" - }; - - DayHeaders.Add(new DayHeaderRenderModel(dayHeader, calendarRenderOptions.CalendarSettings.HourHeight)); - } + DayHeaders.Add(new DayHeaderRenderModel(dayHeader, calendarRenderOptions.CalendarSettings.HourHeight)); } } } diff --git a/Wino.Core.Domain/Models/Common/SharedFile.cs b/Wino.Core.Domain/Models/Common/SharedFile.cs index bace85b3..c5b28f6a 100644 --- a/Wino.Core.Domain/Models/Common/SharedFile.cs +++ b/Wino.Core.Domain/Models/Common/SharedFile.cs @@ -1,14 +1,13 @@ using System.IO; -namespace Wino.Core.Domain.Models.Common +namespace Wino.Core.Domain.Models.Common; + +/// +/// Abstraction for StorageFile +/// +/// Full path of the file. +/// Content +public record SharedFile(string FullFilePath, byte[] Data) { - /// - /// Abstraction for StorageFile - /// - /// Full path of the file. - /// Content - public record SharedFile(string FullFilePath, byte[] Data) - { - public string FileName => Path.GetFileName(FullFilePath); - } + public string FileName => Path.GetFileName(FullFilePath); } diff --git a/Wino.Core.Domain/Models/Comparers/DateComparer.cs b/Wino.Core.Domain/Models/Comparers/DateComparer.cs index c739ec9e..7729831c 100644 --- a/Wino.Core.Domain/Models/Comparers/DateComparer.cs +++ b/Wino.Core.Domain/Models/Comparers/DateComparer.cs @@ -3,30 +3,29 @@ using System.Collections; using System.Collections.Generic; using Wino.Core.Domain.Models.MailItem; -namespace Wino.Core.Domain.Models.Comparers +namespace Wino.Core.Domain.Models.Comparers; + +public class DateComparer : IComparer, IEqualityComparer { - public class DateComparer : IComparer, IEqualityComparer + public int Compare(IMailItem x, IMailItem y) { - public int Compare(IMailItem x, IMailItem y) + return DateTime.Compare(y.CreationDate, x.CreationDate); + } + + public new bool Equals(object x, object y) + { + if (x is IMailItem firstItem && y is IMailItem secondItem) { - return DateTime.Compare(y.CreationDate, x.CreationDate); + return firstItem.Equals(secondItem); } - public new bool Equals(object x, object y) - { - if (x is IMailItem firstItem && y is IMailItem secondItem) - { - return firstItem.Equals(secondItem); - } + return false; + } - return false; - } + public int GetHashCode(object obj) => (obj as IMailItem).GetHashCode(); - public int GetHashCode(object obj) => (obj as IMailItem).GetHashCode(); + public DateComparer() + { - public DateComparer() - { - - } } } diff --git a/Wino.Core.Domain/Models/Comparers/DateTimeComparer.cs b/Wino.Core.Domain/Models/Comparers/DateTimeComparer.cs index eab8185e..c5ae37a0 100644 --- a/Wino.Core.Domain/Models/Comparers/DateTimeComparer.cs +++ b/Wino.Core.Domain/Models/Comparers/DateTimeComparer.cs @@ -1,16 +1,15 @@ using System; using System.Collections.Generic; -namespace Wino.Core.Domain.Models.Comparers +namespace Wino.Core.Domain.Models.Comparers; + +/// +/// Used to insert date grouping into proper place in Reader page. +/// +public class DateTimeComparer : IComparer { - /// - /// Used to insert date grouping into proper place in Reader page. - /// - public class DateTimeComparer : IComparer + public int Compare(DateTime x, DateTime y) { - public int Compare(DateTime x, DateTime y) - { - return DateTime.Compare(y, x); - } + return DateTime.Compare(y, x); } } diff --git a/Wino.Core.Domain/Models/Comparers/FolderNameComparer.cs b/Wino.Core.Domain/Models/Comparers/FolderNameComparer.cs index c1f53430..440391f2 100644 --- a/Wino.Core.Domain/Models/Comparers/FolderNameComparer.cs +++ b/Wino.Core.Domain/Models/Comparers/FolderNameComparer.cs @@ -1,13 +1,12 @@ using System.Collections.Generic; using Wino.Core.Domain.Entities.Mail; -namespace Wino.Core.Domain.Models.Comparers +namespace Wino.Core.Domain.Models.Comparers; + +public class FolderNameComparer : IComparer { - public class FolderNameComparer : IComparer + public int Compare(MailItemFolder x, MailItemFolder y) { - public int Compare(MailItemFolder x, MailItemFolder y) - { - return x.FolderName.CompareTo(y.FolderName); - } + return x.FolderName.CompareTo(y.FolderName); } } diff --git a/Wino.Core.Domain/Models/Comparers/ListItemComparer.cs b/Wino.Core.Domain/Models/Comparers/ListItemComparer.cs index d73ca190..393b9f6b 100644 --- a/Wino.Core.Domain/Models/Comparers/ListItemComparer.cs +++ b/Wino.Core.Domain/Models/Comparers/ListItemComparer.cs @@ -2,37 +2,36 @@ using System.Collections.Generic; using Wino.Core.Domain.Models.MailItem; -namespace Wino.Core.Domain.Models.Comparers +namespace Wino.Core.Domain.Models.Comparers; + +public class ListItemComparer : IComparer { - public class ListItemComparer : IComparer + public bool SortByName { get; set; } + + public DateComparer DateComparer = new DateComparer(); + public readonly NameComparer NameComparer = new NameComparer(); + + public int Compare(object x, object y) { - public bool SortByName { get; set; } - - public DateComparer DateComparer = new DateComparer(); - public readonly NameComparer NameComparer = new NameComparer(); - - public int Compare(object x, object y) + if (x is IMailItem xMail && y is IMailItem yMail) { - if (x is IMailItem xMail && y is IMailItem yMail) - { - var itemComparer = GetItemComparer(); + var itemComparer = GetItemComparer(); - return itemComparer.Compare(xMail, yMail); - } - else if (x is DateTime dateX && y is DateTime dateY) - return DateTime.Compare(dateY, dateX); - else if (x is string stringX && y is string stringY) - return stringY.CompareTo(stringX); - - return 0; + return itemComparer.Compare(xMail, yMail); } + else if (x is DateTime dateX && y is DateTime dateY) + return DateTime.Compare(dateY, dateX); + else if (x is string stringX && y is string stringY) + return stringY.CompareTo(stringX); - public IComparer GetItemComparer() - { - if (SortByName) - return NameComparer; - else - return DateComparer; - } + return 0; + } + + public IComparer GetItemComparer() + { + if (SortByName) + return NameComparer; + else + return DateComparer; } } diff --git a/Wino.Core.Domain/Models/Comparers/NameComparer.cs b/Wino.Core.Domain/Models/Comparers/NameComparer.cs index 86b5c10f..9dd03636 100644 --- a/Wino.Core.Domain/Models/Comparers/NameComparer.cs +++ b/Wino.Core.Domain/Models/Comparers/NameComparer.cs @@ -1,13 +1,12 @@ using System.Collections.Generic; using Wino.Core.Domain.Models.MailItem; -namespace Wino.Core.Domain.Models.Comparers +namespace Wino.Core.Domain.Models.Comparers; + +public class NameComparer : IComparer { - public class NameComparer : IComparer + public int Compare(IMailItem x, IMailItem y) { - public int Compare(IMailItem x, IMailItem y) - { - return string.Compare(x.FromName, y.FromName); - } + return string.Compare(x.FromName, y.FromName); } } diff --git a/Wino.Core.Domain/Models/Connectivity/ImapClientPoolOptions.cs b/Wino.Core.Domain/Models/Connectivity/ImapClientPoolOptions.cs index a7b10cc2..9735e4f8 100644 --- a/Wino.Core.Domain/Models/Connectivity/ImapClientPoolOptions.cs +++ b/Wino.Core.Domain/Models/Connectivity/ImapClientPoolOptions.cs @@ -1,25 +1,24 @@ using System.IO; using Wino.Core.Domain.Entities.Shared; -namespace Wino.Core.Domain.Models.Connectivity +namespace Wino.Core.Domain.Models.Connectivity; + +public class ImapClientPoolOptions { - public class ImapClientPoolOptions + public Stream ProtocolLog { get; } + public CustomServerInformation ServerInformation { get; } + public bool IsTestPool { get; } + + protected ImapClientPoolOptions(CustomServerInformation serverInformation, Stream protocolLog, bool isTestPool) { - public Stream ProtocolLog { get; } - public CustomServerInformation ServerInformation { get; } - public bool IsTestPool { get; } - - protected ImapClientPoolOptions(CustomServerInformation serverInformation, Stream protocolLog, bool isTestPool) - { - ServerInformation = serverInformation; - ProtocolLog = protocolLog; - IsTestPool = isTestPool; - } - - public static ImapClientPoolOptions CreateDefault(CustomServerInformation serverInformation, Stream protocolLog) - => new(serverInformation, protocolLog, false); - - public static ImapClientPoolOptions CreateTestPool(CustomServerInformation serverInformation, Stream protocolLog) - => new(serverInformation, protocolLog, true); + ServerInformation = serverInformation; + ProtocolLog = protocolLog; + IsTestPool = isTestPool; } + + public static ImapClientPoolOptions CreateDefault(CustomServerInformation serverInformation, Stream protocolLog) + => new(serverInformation, protocolLog, false); + + public static ImapClientPoolOptions CreateTestPool(CustomServerInformation serverInformation, Stream protocolLog) + => new(serverInformation, protocolLog, true); } diff --git a/Wino.Core.Domain/Models/Connectivity/ImapConnectivityTestResults.cs b/Wino.Core.Domain/Models/Connectivity/ImapConnectivityTestResults.cs index 715385e0..4b50af52 100644 --- a/Wino.Core.Domain/Models/Connectivity/ImapConnectivityTestResults.cs +++ b/Wino.Core.Domain/Models/Connectivity/ImapConnectivityTestResults.cs @@ -3,46 +3,45 @@ using System.Linq; using System.Text.Json.Serialization; using Wino.Core.Domain.Extensions; -namespace Wino.Core.Domain.Models.Connectivity +namespace Wino.Core.Domain.Models.Connectivity; + +/// +/// Contains validation of the IMAP server connectivity during account setup. +/// +public class ImapConnectivityTestResults { - /// - /// Contains validation of the IMAP server connectivity during account setup. - /// - public class ImapConnectivityTestResults + [JsonConstructor] + protected ImapConnectivityTestResults() { } + + public bool IsSuccess { get; set; } + + public bool IsCertificateUIRequired { get; set; } + + public string FailedReason { get; set; } + public string FailureProtocolLog { get; set; } + + public static ImapConnectivityTestResults Success() => new ImapConnectivityTestResults() { IsSuccess = true }; + public static ImapConnectivityTestResults Failure(Exception ex, string failureProtocolLog) => new ImapConnectivityTestResults() { - [JsonConstructor] - protected ImapConnectivityTestResults() { } + FailedReason = string.Join(Environment.NewLine, ex.GetInnerExceptions().Select(e => e.Message)), + FailureProtocolLog = failureProtocolLog + }; - public bool IsSuccess { get; set; } - - public bool IsCertificateUIRequired { get; set; } - - public string FailedReason { get; set; } - public string FailureProtocolLog { get; set; } - - public static ImapConnectivityTestResults Success() => new ImapConnectivityTestResults() { IsSuccess = true }; - public static ImapConnectivityTestResults Failure(Exception ex, string failureProtocolLog) => new ImapConnectivityTestResults() + public static ImapConnectivityTestResults CertificateUIRequired(string issuer, + string expirationString, + string validFromString) + { + return new ImapConnectivityTestResults() { - FailedReason = string.Join(Environment.NewLine, ex.GetInnerExceptions().Select(e => e.Message)), - FailureProtocolLog = failureProtocolLog + IsSuccess = false, + IsCertificateUIRequired = true, + CertificateIssuer = issuer, + CertificateExpirationDateString = expirationString, + CertificateValidFromDateString = validFromString }; - - public static ImapConnectivityTestResults CertificateUIRequired(string issuer, - string expirationString, - string validFromString) - { - return new ImapConnectivityTestResults() - { - IsSuccess = false, - IsCertificateUIRequired = true, - CertificateIssuer = issuer, - CertificateExpirationDateString = expirationString, - CertificateValidFromDateString = validFromString - }; - } - - public string CertificateIssuer { get; set; } - public string CertificateValidFromDateString { get; set; } - public string CertificateExpirationDateString { get; set; } } + + public string CertificateIssuer { get; set; } + public string CertificateValidFromDateString { get; set; } + public string CertificateExpirationDateString { get; set; } } diff --git a/Wino.Core.Domain/Models/Folders/AccountFolderTree.cs b/Wino.Core.Domain/Models/Folders/AccountFolderTree.cs index 9a9c5173..da9eee45 100644 --- a/Wino.Core.Domain/Models/Folders/AccountFolderTree.cs +++ b/Wino.Core.Domain/Models/Folders/AccountFolderTree.cs @@ -2,32 +2,31 @@ using Wino.Core.Domain.Entities.Shared; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Models.Folders +namespace Wino.Core.Domain.Models.Folders; + +/// +/// Grouped folder information for the menu for given account. +/// +public class AccountFolderTree { - /// - /// Grouped folder information for the menu for given account. - /// - public class AccountFolderTree + public MailAccount Account { get; } + public List Folders { get; set; } = new List(); + + public AccountFolderTree(MailAccount account) { - public MailAccount Account { get; } - public List Folders { get; set; } = new List(); + Account = account; + } - public AccountFolderTree(MailAccount account) + public bool HasSpecialTypeFolder(SpecialFolderType type) + { + foreach (var folderStructure in Folders) { - Account = account; + bool hasSpecialFolder = folderStructure.ContainsSpecialFolderType(type); + + if (hasSpecialFolder) + return true; } - public bool HasSpecialTypeFolder(SpecialFolderType type) - { - foreach (var folderStructure in Folders) - { - bool hasSpecialFolder = folderStructure.ContainsSpecialFolderType(type); - - if (hasSpecialFolder) - return true; - } - - return false; - } + return false; } } diff --git a/Wino.Core.Domain/Models/Folders/FolderOperationMenuItem.cs b/Wino.Core.Domain/Models/Folders/FolderOperationMenuItem.cs index e54afa7f..ac81ad54 100644 --- a/Wino.Core.Domain/Models/Folders/FolderOperationMenuItem.cs +++ b/Wino.Core.Domain/Models/Folders/FolderOperationMenuItem.cs @@ -2,13 +2,12 @@ using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Menus; -namespace Wino.Core.Domain.Models.Folders -{ - public class FolderOperationMenuItem : MenuOperationItemBase, IMenuOperation - { - protected FolderOperationMenuItem(FolderOperation operation, bool isEnabled) : base(operation, isEnabled) { } +namespace Wino.Core.Domain.Models.Folders; - public static FolderOperationMenuItem Create(FolderOperation operation, bool isEnabled = true) - => new FolderOperationMenuItem(operation, isEnabled); - } +public class FolderOperationMenuItem : MenuOperationItemBase, IMenuOperation +{ + protected FolderOperationMenuItem(FolderOperation operation, bool isEnabled) : base(operation, isEnabled) { } + + public static FolderOperationMenuItem Create(FolderOperation operation, bool isEnabled = true) + => new FolderOperationMenuItem(operation, isEnabled); } diff --git a/Wino.Core.Domain/Models/Folders/FolderOperationPreperationRequest.cs b/Wino.Core.Domain/Models/Folders/FolderOperationPreperationRequest.cs index 2aa38883..3a5b653c 100644 --- a/Wino.Core.Domain/Models/Folders/FolderOperationPreperationRequest.cs +++ b/Wino.Core.Domain/Models/Folders/FolderOperationPreperationRequest.cs @@ -1,12 +1,11 @@ using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Models.Folders -{ - /// - /// Encapsulates a request to prepare a folder operation like Rename, Delete, etc. - /// - /// Folder operation. - /// Target folder. - public record FolderOperationPreperationRequest(FolderOperation Action, MailItemFolder Folder) { } -} +namespace Wino.Core.Domain.Models.Folders; + +/// +/// Encapsulates a request to prepare a folder operation like Rename, Delete, etc. +/// +/// Folder operation. +/// Target folder. +public record FolderOperationPreperationRequest(FolderOperation Action, MailItemFolder Folder) { } diff --git a/Wino.Core.Domain/Models/Folders/IMailItemFolder.cs b/Wino.Core.Domain/Models/Folders/IMailItemFolder.cs index 8853cbf7..866213f9 100644 --- a/Wino.Core.Domain/Models/Folders/IMailItemFolder.cs +++ b/Wino.Core.Domain/Models/Folders/IMailItemFolder.cs @@ -2,30 +2,29 @@ using System.Collections.Generic; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Models.Folders -{ - public interface IMailItemFolder - { - string BackgroundColorHex { get; set; } - string DeltaToken { get; set; } - string FolderName { get; set; } - long HighestModeSeq { get; set; } - Guid Id { get; set; } - bool IsHidden { get; set; } - bool IsSticky { get; set; } - bool IsSynchronizationEnabled { get; set; } - bool IsSystemFolder { get; set; } - DateTime? LastSynchronizedDate { get; set; } - Guid MailAccountId { get; set; } - string ParentRemoteFolderId { get; set; } - string RemoteFolderId { get; set; } - SpecialFolderType SpecialFolderType { get; set; } - string TextColorHex { get; set; } - uint UidValidity { get; set; } - List ChildFolders { get; set; } - bool IsMoveTarget { get; } - bool ShowUnreadCount { get; set; } +namespace Wino.Core.Domain.Models.Folders; - bool ContainsSpecialFolderType(SpecialFolderType type); - } +public interface IMailItemFolder +{ + string BackgroundColorHex { get; set; } + string DeltaToken { get; set; } + string FolderName { get; set; } + long HighestModeSeq { get; set; } + Guid Id { get; set; } + bool IsHidden { get; set; } + bool IsSticky { get; set; } + bool IsSynchronizationEnabled { get; set; } + bool IsSystemFolder { get; set; } + DateTime? LastSynchronizedDate { get; set; } + Guid MailAccountId { get; set; } + string ParentRemoteFolderId { get; set; } + string RemoteFolderId { get; set; } + SpecialFolderType SpecialFolderType { get; set; } + string TextColorHex { get; set; } + uint UidValidity { get; set; } + List ChildFolders { get; set; } + bool IsMoveTarget { get; } + bool ShowUnreadCount { get; set; } + + bool ContainsSpecialFolderType(SpecialFolderType type); } diff --git a/Wino.Core.Domain/Models/Folders/SystemFolderConfiguration.cs b/Wino.Core.Domain/Models/Folders/SystemFolderConfiguration.cs index d2d04a04..498a4624 100644 --- a/Wino.Core.Domain/Models/Folders/SystemFolderConfiguration.cs +++ b/Wino.Core.Domain/Models/Folders/SystemFolderConfiguration.cs @@ -1,10 +1,9 @@ using Wino.Core.Domain.Entities.Mail; -namespace Wino.Core.Domain.Models.Folders -{ - public record SystemFolderConfiguration(MailItemFolder SentFolder, - MailItemFolder DraftFolder, - MailItemFolder ArchiveFolder, - MailItemFolder TrashFolder, - MailItemFolder JunkFolder); -} +namespace Wino.Core.Domain.Models.Folders; + +public record SystemFolderConfiguration(MailItemFolder SentFolder, + MailItemFolder DraftFolder, + MailItemFolder ArchiveFolder, + MailItemFolder TrashFolder, + MailItemFolder JunkFolder); diff --git a/Wino.Core.Domain/Models/MailItem/HtmlPreviewVisitor.cs b/Wino.Core.Domain/Models/MailItem/HtmlPreviewVisitor.cs index adabd06e..deb35a54 100644 --- a/Wino.Core.Domain/Models/MailItem/HtmlPreviewVisitor.cs +++ b/Wino.Core.Domain/Models/MailItem/HtmlPreviewVisitor.cs @@ -5,251 +5,250 @@ using MimeKit; using MimeKit.Text; using MimeKit.Tnef; -namespace Wino.Core.Domain.Models.MailItem +namespace Wino.Core.Domain.Models.MailItem; + +/// +/// Visits a MimeMessage and generates HTML suitable to be rendered by a browser control. +/// +public class HtmlPreviewVisitor : MimeVisitor { + List stack = new List(); + List attachments = new List(); + + readonly string tempDir; + + public string Body { get; set; } + /// - /// Visits a MimeMessage and generates HTML suitable to be rendered by a browser control. + /// Creates a new HtmlPreviewVisitor. /// - public class HtmlPreviewVisitor : MimeVisitor + /// A temporary directory used for storing image files. + public HtmlPreviewVisitor(string tempDirectory) { - List stack = new List(); - List attachments = new List(); + tempDir = tempDirectory; + } - readonly string tempDir; + /// + /// The list of attachments that were in the MimeMessage. + /// + public IList Attachments + { + get { return attachments; } + } - public string Body { get; set; } + /// + /// The HTML string that can be set on the BrowserControl. + /// + public string HtmlBody + { + get { return Body ?? string.Empty; } + } - /// - /// Creates a new HtmlPreviewVisitor. - /// - /// A temporary directory used for storing image files. - public HtmlPreviewVisitor(string tempDirectory) + protected override void VisitMultipartAlternative(MultipartAlternative alternative) + { + // walk the multipart/alternative children backwards from greatest level of faithfulness to the least faithful + for (int i = alternative.Count - 1; i >= 0 && Body == null; i--) + alternative[i].Accept(this); + } + + protected override void VisitMultipartRelated(MultipartRelated related) + { + var root = related.Root; + + // push this multipart/related onto our stack + stack.Add(related); + + // visit the root document + root.Accept(this); + + // pop this multipart/related off our stack + stack.RemoveAt(stack.Count - 1); + } + + // look up the image based on the img src url within our multipart/related stack + bool TryGetImage(string url, out MimePart image) + { + UriKind kind; + int index; + Uri uri; + + if (Uri.IsWellFormedUriString(url, UriKind.Absolute)) + kind = UriKind.Absolute; + else if (Uri.IsWellFormedUriString(url, UriKind.Relative)) + kind = UriKind.Relative; + else + kind = UriKind.RelativeOrAbsolute; + + try { - tempDir = tempDirectory; + uri = new Uri(url, kind); } - - /// - /// The list of attachments that were in the MimeMessage. - /// - public IList Attachments + catch { - get { return attachments; } - } - - /// - /// The HTML string that can be set on the BrowserControl. - /// - public string HtmlBody - { - get { return Body ?? string.Empty; } - } - - protected override void VisitMultipartAlternative(MultipartAlternative alternative) - { - // walk the multipart/alternative children backwards from greatest level of faithfulness to the least faithful - for (int i = alternative.Count - 1; i >= 0 && Body == null; i--) - alternative[i].Accept(this); - } - - protected override void VisitMultipartRelated(MultipartRelated related) - { - var root = related.Root; - - // push this multipart/related onto our stack - stack.Add(related); - - // visit the root document - root.Accept(this); - - // pop this multipart/related off our stack - stack.RemoveAt(stack.Count - 1); - } - - // look up the image based on the img src url within our multipart/related stack - bool TryGetImage(string url, out MimePart image) - { - UriKind kind; - int index; - Uri uri; - - if (Uri.IsWellFormedUriString(url, UriKind.Absolute)) - kind = UriKind.Absolute; - else if (Uri.IsWellFormedUriString(url, UriKind.Relative)) - kind = UriKind.Relative; - else - kind = UriKind.RelativeOrAbsolute; - - try - { - uri = new Uri(url, kind); - } - catch - { - image = null; - return false; - } - - for (int i = stack.Count - 1; i >= 0; i--) - { - if ((index = stack[i].IndexOf(uri)) == -1) - continue; - - image = stack[i][index] as MimePart; - return image != null; - } - image = null; - return false; } - // Save the image to our temp directory and return a "file://" url suitable for - // the browser control to load. - // Note: if you'd rather embed the image data into the HTML, you can construct a - // "data:" url instead. - string SaveImage(MimePart image) + for (int i = stack.Count - 1; i >= 0; i--) { - using (var memory = new MemoryStream()) - { - image.Content.DecodeTo(memory); - var buffer = memory.GetBuffer(); - var length = (int)memory.Length; - var base64 = Convert.ToBase64String(buffer, 0, length); + if ((index = stack[i].IndexOf(uri)) == -1) + continue; - return string.Format("data:{0};base64,{1}", image.ContentType.MimeType, base64); - } - - //string fileName = url - // .Replace(':', '_') - // .Replace('\\', '_') - // .Replace('/', '_'); - - //string path = Path.Combine(tempDir, fileName); - - //if (!File.Exists(path)) - //{ - // using (var output = File.Create(path)) - // image.Content.DecodeTo(output); - //} - - //return "file://" + path.Replace('\\', '/'); + image = stack[i][index] as MimePart; + return image != null; } - // Replaces urls that refer to images embedded within the message with - // "file://" urls that the browser control will actually be able to load. - void HtmlTagCallback(HtmlTagContext ctx, HtmlWriter htmlWriter) + image = null; + + return false; + } + + // Save the image to our temp directory and return a "file://" url suitable for + // the browser control to load. + // Note: if you'd rather embed the image data into the HTML, you can construct a + // "data:" url instead. + string SaveImage(MimePart image) + { + using (var memory = new MemoryStream()) { - if (ctx.TagId == HtmlTagId.Image && !ctx.IsEndTag && stack.Count > 0) + image.Content.DecodeTo(memory); + var buffer = memory.GetBuffer(); + var length = (int)memory.Length; + var base64 = Convert.ToBase64String(buffer, 0, length); + + return string.Format("data:{0};base64,{1}", image.ContentType.MimeType, base64); + } + + //string fileName = url + // .Replace(':', '_') + // .Replace('\\', '_') + // .Replace('/', '_'); + + //string path = Path.Combine(tempDir, fileName); + + //if (!File.Exists(path)) + //{ + // using (var output = File.Create(path)) + // image.Content.DecodeTo(output); + //} + + //return "file://" + path.Replace('\\', '/'); + } + + // Replaces urls that refer to images embedded within the message with + // "file://" urls that the browser control will actually be able to load. + void HtmlTagCallback(HtmlTagContext ctx, HtmlWriter htmlWriter) + { + if (ctx.TagId == HtmlTagId.Image && !ctx.IsEndTag && stack.Count > 0) + { + ctx.WriteTag(htmlWriter, false); + + // replace the src attribute with a file:// URL + foreach (var attribute in ctx.Attributes) { - ctx.WriteTag(htmlWriter, false); - - // replace the src attribute with a file:// URL - foreach (var attribute in ctx.Attributes) + if (attribute.Id == HtmlAttributeId.Src) { - if (attribute.Id == HtmlAttributeId.Src) - { - MimePart image; - string url; + MimePart image; + string url; - if (!TryGetImage(attribute.Value, out image)) - { - htmlWriter.WriteAttribute(attribute); - continue; - } - - url = SaveImage(image); - - htmlWriter.WriteAttributeName(attribute.Name); - htmlWriter.WriteAttributeValue(url); - } - else + if (!TryGetImage(attribute.Value, out image)) { htmlWriter.WriteAttribute(attribute); - } - } - } - else if (ctx.TagId == HtmlTagId.Body && !ctx.IsEndTag) - { - ctx.WriteTag(htmlWriter, false); - - // add and/or replace oncontextmenu="return false;" - foreach (var attribute in ctx.Attributes) - { - if (attribute.Name.ToLowerInvariant() == "oncontextmenu") continue; + } - htmlWriter.WriteAttribute(attribute); - } + url = SaveImage(image); - htmlWriter.WriteAttribute("oncontextmenu", "return false;"); - } - else - { - if (ctx.TagId == HtmlTagId.Unknown) - { - ctx.DeleteTag = true; - ctx.DeleteEndTag = true; + htmlWriter.WriteAttributeName(attribute.Name); + htmlWriter.WriteAttributeValue(url); } else { - ctx.WriteTag(htmlWriter, true); + htmlWriter.WriteAttribute(attribute); } } } - - protected override void VisitTextPart(TextPart entity) + else if (ctx.TagId == HtmlTagId.Body && !ctx.IsEndTag) { - TextConverter converter; + ctx.WriteTag(htmlWriter, false); - if (Body != null) + // add and/or replace oncontextmenu="return false;" + foreach (var attribute in ctx.Attributes) { - // since we've already found the body, treat this as an attachment - attachments.Add(entity); - return; + if (attribute.Name.ToLowerInvariant() == "oncontextmenu") + continue; + + htmlWriter.WriteAttribute(attribute); } - if (entity.IsHtml) + htmlWriter.WriteAttribute("oncontextmenu", "return false;"); + } + else + { + if (ctx.TagId == HtmlTagId.Unknown) { - converter = new HtmlToHtml - { - HtmlTagCallback = HtmlTagCallback - }; - } - else if (entity.IsFlowed) - { - var flowed = new FlowedToHtml(); - string delsp; - - if (entity.ContentType.Parameters.TryGetValue("delsp", out delsp)) - flowed.DeleteSpace = delsp.ToLowerInvariant() == "yes"; - - converter = flowed; + ctx.DeleteTag = true; + ctx.DeleteEndTag = true; } else { - converter = new TextToHtml(); + ctx.WriteTag(htmlWriter, true); } - - Body = converter.Convert(entity.Text); - } - - protected override void VisitTnefPart(TnefPart entity) - { - // extract any attachments in the MS-TNEF part - attachments.AddRange(entity.ExtractAttachments()); - } - - protected override void VisitMessagePart(MessagePart entity) - { - // treat message/rfc822 parts as attachments - attachments.Add(entity); - } - - protected override void VisitMimePart(MimePart entity) - { - // realistically, if we've gotten this far, then we can treat this as an attachment - // even if the IsAttachment property is false. - attachments.Add(entity); } } + + protected override void VisitTextPart(TextPart entity) + { + TextConverter converter; + + if (Body != null) + { + // since we've already found the body, treat this as an attachment + attachments.Add(entity); + return; + } + + if (entity.IsHtml) + { + converter = new HtmlToHtml + { + HtmlTagCallback = HtmlTagCallback + }; + } + else if (entity.IsFlowed) + { + var flowed = new FlowedToHtml(); + string delsp; + + if (entity.ContentType.Parameters.TryGetValue("delsp", out delsp)) + flowed.DeleteSpace = delsp.ToLowerInvariant() == "yes"; + + converter = flowed; + } + else + { + converter = new TextToHtml(); + } + + Body = converter.Convert(entity.Text); + } + + protected override void VisitTnefPart(TnefPart entity) + { + // extract any attachments in the MS-TNEF part + attachments.AddRange(entity.ExtractAttachments()); + } + + protected override void VisitMessagePart(MessagePart entity) + { + // treat message/rfc822 parts as attachments + attachments.Add(entity); + } + + protected override void VisitMimePart(MimePart entity) + { + // realistically, if we've gotten this far, then we can treat this as an attachment + // even if the IsAttachment property is false. + attachments.Add(entity); + } } diff --git a/Wino.Core.Domain/Models/MailItem/IMailHashContainer.cs b/Wino.Core.Domain/Models/MailItem/IMailHashContainer.cs index 1426bc04..52cd64ad 100644 --- a/Wino.Core.Domain/Models/MailItem/IMailHashContainer.cs +++ b/Wino.Core.Domain/Models/MailItem/IMailHashContainer.cs @@ -1,15 +1,14 @@ using System; using System.Collections.Generic; -namespace Wino.Core.Domain.Models.MailItem +namespace Wino.Core.Domain.Models.MailItem; + +/// +/// An interface that returns the UniqueId store for IMailItem. +/// For threads, it may be multiple items. +/// For single mails, it'll always be one item. +/// +public interface IMailHashContainer { - /// - /// An interface that returns the UniqueId store for IMailItem. - /// For threads, it may be multiple items. - /// For single mails, it'll always be one item. - /// - public interface IMailHashContainer - { - IEnumerable GetContainingIds(); - } + IEnumerable GetContainingIds(); } diff --git a/Wino.Core.Domain/Models/MailItem/IMailItem.cs b/Wino.Core.Domain/Models/MailItem/IMailItem.cs index c3edd4fc..b5cd99b2 100644 --- a/Wino.Core.Domain/Models/MailItem/IMailItem.cs +++ b/Wino.Core.Domain/Models/MailItem/IMailItem.cs @@ -2,34 +2,33 @@ using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Entities.Shared; -namespace Wino.Core.Domain.Models.MailItem -{ - /// - /// Interface of simplest representation of a MailCopy. - /// - public interface IMailItem : IMailHashContainer - { - Guid UniqueId { get; } - string Id { get; } - string Subject { get; } - string ThreadId { get; } - string MessageId { get; } - string References { get; } - string InReplyTo { get; } - string PreviewText { get; } - string FromName { get; } - DateTime CreationDate { get; } - string FromAddress { get; } - bool HasAttachments { get; } - bool IsFlagged { get; } - bool IsFocused { get; } - bool IsRead { get; } - string DraftId { get; } - bool IsDraft { get; } - Guid FileId { get; } +namespace Wino.Core.Domain.Models.MailItem; - MailItemFolder AssignedFolder { get; } - MailAccount AssignedAccount { get; } - AccountContact SenderContact { get; } - } +/// +/// Interface of simplest representation of a MailCopy. +/// +public interface IMailItem : IMailHashContainer +{ + Guid UniqueId { get; } + string Id { get; } + string Subject { get; } + string ThreadId { get; } + string MessageId { get; } + string References { get; } + string InReplyTo { get; } + string PreviewText { get; } + string FromName { get; } + DateTime CreationDate { get; } + string FromAddress { get; } + bool HasAttachments { get; } + bool IsFlagged { get; } + bool IsFocused { get; } + bool IsRead { get; } + string DraftId { get; } + bool IsDraft { get; } + Guid FileId { get; } + + MailItemFolder AssignedFolder { get; } + MailAccount AssignedAccount { get; } + AccountContact SenderContact { get; } } diff --git a/Wino.Core.Domain/Models/MailItem/IMailItemThread.cs b/Wino.Core.Domain/Models/MailItem/IMailItemThread.cs index 22fd0699..5c3cd554 100644 --- a/Wino.Core.Domain/Models/MailItem/IMailItemThread.cs +++ b/Wino.Core.Domain/Models/MailItem/IMailItemThread.cs @@ -1,16 +1,15 @@ using System.Collections.ObjectModel; -namespace Wino.Core.Domain.Models.MailItem +namespace Wino.Core.Domain.Models.MailItem; + +/// +/// Interface that represents conversation threads. +/// Even though this type has 1 single UI representation most of the time, +/// it can contain multiple IMailItem. +/// +public interface IMailItemThread : IMailItem { - /// - /// Interface that represents conversation threads. - /// Even though this type has 1 single UI representation most of the time, - /// it can contain multiple IMailItem. - /// - public interface IMailItemThread : IMailItem - { - ObservableCollection ThreadItems { get; } - IMailItem LatestMailItem { get; } - IMailItem FirstMailItem { get; } - } + ObservableCollection ThreadItems { get; } + IMailItem LatestMailItem { get; } + IMailItem FirstMailItem { get; } } diff --git a/Wino.Core.Domain/Models/MailItem/ImapMessageCreationPackage.cs b/Wino.Core.Domain/Models/MailItem/ImapMessageCreationPackage.cs index 1fb23688..c1c4545d 100644 --- a/Wino.Core.Domain/Models/MailItem/ImapMessageCreationPackage.cs +++ b/Wino.Core.Domain/Models/MailItem/ImapMessageCreationPackage.cs @@ -1,20 +1,19 @@ using MailKit; using MimeKit; -namespace Wino.Core.Domain.Models.MailItem -{ - /// - /// Encapsulates all required information to create a MimeMessage for IMAP synchronizer. - /// - public class ImapMessageCreationPackage - { - public IMessageSummary MessageSummary { get; } - public MimeMessage MimeMessage { get; } +namespace Wino.Core.Domain.Models.MailItem; - public ImapMessageCreationPackage(IMessageSummary messageSummary, MimeMessage mimeMessage) - { - MessageSummary = messageSummary; - MimeMessage = mimeMessage; - } +/// +/// Encapsulates all required information to create a MimeMessage for IMAP synchronizer. +/// +public class ImapMessageCreationPackage +{ + public IMessageSummary MessageSummary { get; } + public MimeMessage MimeMessage { get; } + + public ImapMessageCreationPackage(IMessageSummary messageSummary, MimeMessage mimeMessage) + { + MessageSummary = messageSummary; + MimeMessage = mimeMessage; } } diff --git a/Wino.Core.Domain/Models/MailItem/MailDetailInformation.cs b/Wino.Core.Domain/Models/MailItem/MailDetailInformation.cs index c79f1039..4ce8afa5 100644 --- a/Wino.Core.Domain/Models/MailItem/MailDetailInformation.cs +++ b/Wino.Core.Domain/Models/MailItem/MailDetailInformation.cs @@ -1,18 +1,17 @@ using System; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Models.MailItem -{ - public class MailDetailInformation - { - public string Id { get; set; } +namespace Wino.Core.Domain.Models.MailItem; - public Guid AccountId { get; set; } - public Guid FolderId { get; set; } - public string RemoteFolderId { get; set; } - public SpecialFolderType SpecialFolderType { get; set; } - public bool IsRead { get; set; } - public bool IsFlagged { get; set; } - public bool IsDraft { get; set; } - } +public class MailDetailInformation +{ + public string Id { get; set; } + + public Guid AccountId { get; set; } + public Guid FolderId { get; set; } + public string RemoteFolderId { get; set; } + public SpecialFolderType SpecialFolderType { get; set; } + public bool IsRead { get; set; } + public bool IsFlagged { get; set; } + public bool IsDraft { get; set; } } diff --git a/Wino.Core.Domain/Models/MailItem/MailDragPackage.cs b/Wino.Core.Domain/Models/MailItem/MailDragPackage.cs index 2f47a267..e2fb2949 100644 --- a/Wino.Core.Domain/Models/MailItem/MailDragPackage.cs +++ b/Wino.Core.Domain/Models/MailItem/MailDragPackage.cs @@ -1,25 +1,24 @@ using System.Collections.Generic; -namespace Wino.Core.Domain.Models.MailItem +namespace Wino.Core.Domain.Models.MailItem; + +/// +/// Class that holds information when the drag/drop of mails are performed. +/// +public class MailDragPackage { - /// - /// Class that holds information when the drag/drop of mails are performed. - /// - public class MailDragPackage + public MailDragPackage(IEnumerable draggingMails) { - public MailDragPackage(IEnumerable draggingMails) - { - DraggingMails = draggingMails; - } - - public MailDragPackage(IMailItem draggingMail) - { - DraggingMails = - [ - draggingMail - ]; - } - - public IEnumerable DraggingMails { get; set; } + DraggingMails = draggingMails; } + + public MailDragPackage(IMailItem draggingMail) + { + DraggingMails = + [ + draggingMail + ]; + } + + public IEnumerable DraggingMails { get; set; } } diff --git a/Wino.Core.Domain/Models/MailItem/MailFolderPairMetadata.cs b/Wino.Core.Domain/Models/MailItem/MailFolderPairMetadata.cs index 158425c8..35359104 100644 --- a/Wino.Core.Domain/Models/MailItem/MailFolderPairMetadata.cs +++ b/Wino.Core.Domain/Models/MailItem/MailFolderPairMetadata.cs @@ -1,11 +1,10 @@ using System; -namespace Wino.Core.Domain.Models.MailItem +namespace Wino.Core.Domain.Models.MailItem; + +public class MailFolderPairMetadata { - public class MailFolderPairMetadata - { - public Guid FolderId { get; set; } - public string RemoteFolderId { get; set; } - public string MailCopyId { get; set; } - } + public Guid FolderId { get; set; } + public string RemoteFolderId { get; set; } + public string MailCopyId { get; set; } } diff --git a/Wino.Core.Domain/Models/MailItem/MailInsertPackage.cs b/Wino.Core.Domain/Models/MailItem/MailInsertPackage.cs index 99aee765..f1eec88c 100644 --- a/Wino.Core.Domain/Models/MailItem/MailInsertPackage.cs +++ b/Wino.Core.Domain/Models/MailItem/MailInsertPackage.cs @@ -1,7 +1,6 @@ using MimeKit; using Wino.Core.Domain.Entities.Mail; -namespace Wino.Core.Domain.Models.MailItem -{ - public record NewMailItemPackage(MailCopy Copy, MimeMessage Mime, string AssignedRemoteFolderId); -} +namespace Wino.Core.Domain.Models.MailItem; + +public record NewMailItemPackage(MailCopy Copy, MimeMessage Mime, string AssignedRemoteFolderId); diff --git a/Wino.Core.Domain/Models/MailItem/MailListInitializationOptions.cs b/Wino.Core.Domain/Models/MailItem/MailListInitializationOptions.cs index 170adcf6..5d3df2f4 100644 --- a/Wino.Core.Domain/Models/MailItem/MailListInitializationOptions.cs +++ b/Wino.Core.Domain/Models/MailItem/MailListInitializationOptions.cs @@ -3,13 +3,12 @@ using System.Collections.Generic; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.Folders; -namespace Wino.Core.Domain.Models.MailItem -{ - public record MailListInitializationOptions(IEnumerable Folders, - FilterOptionType FilterType, - SortingOptionType SortingOptionType, - bool CreateThreads, - bool? IsFocusedOnly, - string SearchQuery, - IEnumerable ExistingUniqueIds); -} +namespace Wino.Core.Domain.Models.MailItem; + +public record MailListInitializationOptions(IEnumerable Folders, + FilterOptionType FilterType, + SortingOptionType SortingOptionType, + bool CreateThreads, + bool? IsFocusedOnly, + string SearchQuery, + IEnumerable ExistingUniqueIds); diff --git a/Wino.Core.Domain/Models/MailItem/MailOperationPreperationRequest.cs b/Wino.Core.Domain/Models/MailItem/MailOperationPreperationRequest.cs index 71c93094..7e816edb 100644 --- a/Wino.Core.Domain/Models/MailItem/MailOperationPreperationRequest.cs +++ b/Wino.Core.Domain/Models/MailItem/MailOperationPreperationRequest.cs @@ -4,36 +4,35 @@ using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.Folders; -namespace Wino.Core.Domain.Models.MailItem -{ - /// - /// Encapsulates the options for preparing requests to execute mail operations for mail items like Move, Delete, MarkAsRead, etc. - /// - /// Action to execute. - /// Mail copies execute the action on. - /// Whether the operation can be reverted if needed. - /// eg. MarkAsRead on already read item will set the action to MarkAsUnread. - /// This is used in hover actions for example. - /// Whether hard delete protection should be ignored. - /// Discard draft requests for example should ignore hard delete protection. - /// Moving folder for the Move operation. - /// If null and the action is Move, the user will be prompted to select a folder. - public record MailOperationPreperationRequest(MailOperation Action, IEnumerable MailItems, bool ToggleExecution, bool IgnoreHardDeleteProtection, IMailItemFolder MoveTargetFolder) - { - public MailOperationPreperationRequest(MailOperation action, - IEnumerable mailItems, - bool toggleExecution = false, - IMailItemFolder moveTargetFolder = null, - bool ignoreHardDeleteProtection = false) : this(action, mailItems ?? throw new ArgumentNullException(nameof(mailItems)), toggleExecution, ignoreHardDeleteProtection, moveTargetFolder) - { - } +namespace Wino.Core.Domain.Models.MailItem; - public MailOperationPreperationRequest(MailOperation action, - MailCopy singleMailItem, - bool toggleExecution = false, - IMailItemFolder moveTargetFolder = null, - bool ignoreHardDeleteProtection = false) : this(action, new List() { singleMailItem }, toggleExecution, ignoreHardDeleteProtection, moveTargetFolder) - { - } +/// +/// Encapsulates the options for preparing requests to execute mail operations for mail items like Move, Delete, MarkAsRead, etc. +/// +/// Action to execute. +/// Mail copies execute the action on. +/// Whether the operation can be reverted if needed. +/// eg. MarkAsRead on already read item will set the action to MarkAsUnread. +/// This is used in hover actions for example. +/// Whether hard delete protection should be ignored. +/// Discard draft requests for example should ignore hard delete protection. +/// Moving folder for the Move operation. +/// If null and the action is Move, the user will be prompted to select a folder. +public record MailOperationPreperationRequest(MailOperation Action, IEnumerable MailItems, bool ToggleExecution, bool IgnoreHardDeleteProtection, IMailItemFolder MoveTargetFolder) +{ + public MailOperationPreperationRequest(MailOperation action, + IEnumerable mailItems, + bool toggleExecution = false, + IMailItemFolder moveTargetFolder = null, + bool ignoreHardDeleteProtection = false) : this(action, mailItems ?? throw new ArgumentNullException(nameof(mailItems)), toggleExecution, ignoreHardDeleteProtection, moveTargetFolder) + { + } + + public MailOperationPreperationRequest(MailOperation action, + MailCopy singleMailItem, + bool toggleExecution = false, + IMailItemFolder moveTargetFolder = null, + bool ignoreHardDeleteProtection = false) : this(action, new List() { singleMailItem }, toggleExecution, ignoreHardDeleteProtection, moveTargetFolder) + { } } diff --git a/Wino.Core.Domain/Models/MailItem/MimeMessageInformation.cs b/Wino.Core.Domain/Models/MailItem/MimeMessageInformation.cs index ce8b4404..d583cfb3 100644 --- a/Wino.Core.Domain/Models/MailItem/MimeMessageInformation.cs +++ b/Wino.Core.Domain/Models/MailItem/MimeMessageInformation.cs @@ -1,9 +1,8 @@ using MimeKit; -namespace Wino.Core.Domain.Models.MailItem -{ - /// - /// Encapsulates MimeMessage and the path to the file. - /// - public record MimeMessageInformation(MimeMessage MimeMessage, string Path); -} +namespace Wino.Core.Domain.Models.MailItem; + +/// +/// Encapsulates MimeMessage and the path to the file. +/// +public record MimeMessageInformation(MimeMessage MimeMessage, string Path); diff --git a/Wino.Core.Domain/Models/MailItem/OutlookSpecialFolderIdInformation.cs b/Wino.Core.Domain/Models/MailItem/OutlookSpecialFolderIdInformation.cs index 9eadd52a..56239cb6 100644 --- a/Wino.Core.Domain/Models/MailItem/OutlookSpecialFolderIdInformation.cs +++ b/Wino.Core.Domain/Models/MailItem/OutlookSpecialFolderIdInformation.cs @@ -1,13 +1,12 @@ -namespace Wino.Core.Domain.Models.MailItem -{ - /// - /// Class that holds immutable information about special folders in Outlook. - /// - /// - /// - /// - /// - /// - /// - public record OutlookSpecialFolderIdInformation(string InboxId, string TrashId, string JunkId, string DraftId, string SentId, string ArchiveId); -} +namespace Wino.Core.Domain.Models.MailItem; + +/// +/// Class that holds immutable information about special folders in Outlook. +/// +/// +/// +/// +/// +/// +/// +public record OutlookSpecialFolderIdInformation(string InboxId, string TrashId, string JunkId, string DraftId, string SentId, string ArchiveId); diff --git a/Wino.Core.Domain/Models/MailItem/SendDraftPreparationRequest.cs b/Wino.Core.Domain/Models/MailItem/SendDraftPreparationRequest.cs index b1f26ec1..ece44c40 100644 --- a/Wino.Core.Domain/Models/MailItem/SendDraftPreparationRequest.cs +++ b/Wino.Core.Domain/Models/MailItem/SendDraftPreparationRequest.cs @@ -4,19 +4,18 @@ using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Entities.Shared; using Wino.Core.Domain.Extensions; -namespace Wino.Core.Domain.Models.MailItem -{ - public record SendDraftPreparationRequest(MailCopy MailItem, - MailAccountAlias SendingAlias, - MailItemFolder SentFolder, - MailItemFolder DraftFolder, - MailAccountPreferences AccountPreferences, - string Base64MimeMessage) - { - [JsonIgnore] - private MimeMessage mime; +namespace Wino.Core.Domain.Models.MailItem; - [JsonIgnore] - public MimeMessage Mime => mime ??= Base64MimeMessage.GetMimeMessageFromBase64(); - } +public record SendDraftPreparationRequest(MailCopy MailItem, + MailAccountAlias SendingAlias, + MailItemFolder SentFolder, + MailItemFolder DraftFolder, + MailAccountPreferences AccountPreferences, + string Base64MimeMessage) +{ + [JsonIgnore] + private MimeMessage mime; + + [JsonIgnore] + public MimeMessage Mime => mime ??= Base64MimeMessage.GetMimeMessageFromBase64(); } diff --git a/Wino.Core.Domain/Models/MailItem/ThreadMailItem.cs b/Wino.Core.Domain/Models/MailItem/ThreadMailItem.cs index 07efac99..1d13f909 100644 --- a/Wino.Core.Domain/Models/MailItem/ThreadMailItem.cs +++ b/Wino.Core.Domain/Models/MailItem/ThreadMailItem.cs @@ -5,91 +5,90 @@ using System.Linq; using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Entities.Shared; -namespace Wino.Core.Domain.Models.MailItem +namespace Wino.Core.Domain.Models.MailItem; + +public class ThreadMailItem : IMailItemThread { - public class ThreadMailItem : IMailItemThread + // TODO: Ideally this should be SortedList. + public ObservableCollection ThreadItems { get; } = new ObservableCollection(); + + public IMailItem LatestMailItem => ThreadItems.LastOrDefault(); + public IMailItem FirstMailItem => ThreadItems.FirstOrDefault(); + + public bool AddThreadItem(IMailItem item) { - // TODO: Ideally this should be SortedList. - public ObservableCollection ThreadItems { get; } = new ObservableCollection(); + if (item == null) return false; - public IMailItem LatestMailItem => ThreadItems.LastOrDefault(); - public IMailItem FirstMailItem => ThreadItems.FirstOrDefault(); - - public bool AddThreadItem(IMailItem item) + if (ThreadItems.Any(a => a.Id == item.Id)) { - if (item == null) return false; - - if (ThreadItems.Any(a => a.Id == item.Id)) - { - return false; - } - - if (item != null && item.IsDraft) - { - ThreadItems.Insert(0, item); - return true; - } - - var insertItem = ThreadItems.FirstOrDefault(a => !a.IsDraft && a.CreationDate < item.CreationDate); - - if (insertItem == null) - ThreadItems.Insert(ThreadItems.Count, item); - else - { - var index = ThreadItems.IndexOf(insertItem); - - ThreadItems.Insert(index, item); - } + return false; + } + if (item != null && item.IsDraft) + { + ThreadItems.Insert(0, item); return true; } - public IEnumerable GetContainingIds() => ThreadItems?.Select(a => a.UniqueId) ?? default; + var insertItem = ThreadItems.FirstOrDefault(a => !a.IsDraft && a.CreationDate < item.CreationDate); - #region IMailItem + if (insertItem == null) + ThreadItems.Insert(ThreadItems.Count, item); + else + { + var index = ThreadItems.IndexOf(insertItem); - public Guid UniqueId => LatestMailItem?.UniqueId ?? Guid.Empty; - public string Id => LatestMailItem?.Id ?? string.Empty; + ThreadItems.Insert(index, item); + } - // Show subject from last item. - public string Subject => LatestMailItem?.Subject ?? string.Empty; - - public string ThreadId => LatestMailItem?.ThreadId ?? string.Empty; - - public string PreviewText => FirstMailItem?.PreviewText ?? string.Empty; - - public string FromName => LatestMailItem?.FromName ?? string.Empty; - - public string FromAddress => LatestMailItem?.FromAddress ?? string.Empty; - - public bool HasAttachments => ThreadItems.Any(a => a.HasAttachments); - - public bool IsFlagged => ThreadItems.Any(a => a.IsFlagged); - - public bool IsFocused => LatestMailItem?.IsFocused ?? false; - - public bool IsRead => ThreadItems.All(a => a.IsRead); - - public DateTime CreationDate => FirstMailItem?.CreationDate ?? DateTime.MinValue; - - public bool IsDraft => ThreadItems.Any(a => a.IsDraft); - - public string DraftId => string.Empty; - - public string MessageId => LatestMailItem?.MessageId; - - public string References => LatestMailItem?.References ?? string.Empty; - - public string InReplyTo => LatestMailItem?.InReplyTo ?? string.Empty; - - public MailItemFolder AssignedFolder => LatestMailItem?.AssignedFolder; - - public MailAccount AssignedAccount => LatestMailItem?.AssignedAccount; - - public Guid FileId => LatestMailItem?.FileId ?? Guid.Empty; - - public AccountContact SenderContact => LatestMailItem?.SenderContact; - - #endregion + return true; } + + public IEnumerable GetContainingIds() => ThreadItems?.Select(a => a.UniqueId) ?? default; + + #region IMailItem + + public Guid UniqueId => LatestMailItem?.UniqueId ?? Guid.Empty; + public string Id => LatestMailItem?.Id ?? string.Empty; + + // Show subject from last item. + public string Subject => LatestMailItem?.Subject ?? string.Empty; + + public string ThreadId => LatestMailItem?.ThreadId ?? string.Empty; + + public string PreviewText => FirstMailItem?.PreviewText ?? string.Empty; + + public string FromName => LatestMailItem?.FromName ?? string.Empty; + + public string FromAddress => LatestMailItem?.FromAddress ?? string.Empty; + + public bool HasAttachments => ThreadItems.Any(a => a.HasAttachments); + + public bool IsFlagged => ThreadItems.Any(a => a.IsFlagged); + + public bool IsFocused => LatestMailItem?.IsFocused ?? false; + + public bool IsRead => ThreadItems.All(a => a.IsRead); + + public DateTime CreationDate => FirstMailItem?.CreationDate ?? DateTime.MinValue; + + public bool IsDraft => ThreadItems.Any(a => a.IsDraft); + + public string DraftId => string.Empty; + + public string MessageId => LatestMailItem?.MessageId; + + public string References => LatestMailItem?.References ?? string.Empty; + + public string InReplyTo => LatestMailItem?.InReplyTo ?? string.Empty; + + public MailItemFolder AssignedFolder => LatestMailItem?.AssignedFolder; + + public MailAccount AssignedAccount => LatestMailItem?.AssignedAccount; + + public Guid FileId => LatestMailItem?.FileId ?? Guid.Empty; + + public AccountContact SenderContact => LatestMailItem?.SenderContact; + + #endregion } diff --git a/Wino.Core.Domain/Models/MailItem/ToggleRequestRule.cs b/Wino.Core.Domain/Models/MailItem/ToggleRequestRule.cs index 9ed10f48..70045ead 100644 --- a/Wino.Core.Domain/Models/MailItem/ToggleRequestRule.cs +++ b/Wino.Core.Domain/Models/MailItem/ToggleRequestRule.cs @@ -1,14 +1,13 @@ using System; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Models.MailItem -{ - /// - /// Defines a single rule for toggling user actions if needed. - /// For example: If user wants to mark a mail as read, but it's already read, then it should be marked as unread. - /// - /// - /// - /// - public record ToggleRequestRule(MailOperation SourceAction, MailOperation TargetAction, Func Condition); -} +namespace Wino.Core.Domain.Models.MailItem; + +/// +/// Defines a single rule for toggling user actions if needed. +/// For example: If user wants to mark a mail as read, but it's already read, then it should be marked as unread. +/// +/// +/// +/// +public record ToggleRequestRule(MailOperation SourceAction, MailOperation TargetAction, Func Condition); diff --git a/Wino.Core.Domain/Models/Menus/MailOperationMenuItem.cs b/Wino.Core.Domain/Models/Menus/MailOperationMenuItem.cs index c14d7604..7c243f55 100644 --- a/Wino.Core.Domain/Models/Menus/MailOperationMenuItem.cs +++ b/Wino.Core.Domain/Models/Menus/MailOperationMenuItem.cs @@ -1,21 +1,20 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.Domain.Models.Menus +namespace Wino.Core.Domain.Models.Menus; + +public class MailOperationMenuItem : MenuOperationItemBase, IMenuOperation { - public class MailOperationMenuItem : MenuOperationItemBase, IMenuOperation + /// + /// Gets or sets whether this menu item should be placed in SecondaryCommands if used in CommandBar. + /// + public bool IsSecondaryMenuPreferred { get; set; } + + protected MailOperationMenuItem(MailOperation operation, bool isEnabled, bool isSecondaryMenuItem = false) : base(operation, isEnabled) { - /// - /// Gets or sets whether this menu item should be placed in SecondaryCommands if used in CommandBar. - /// - public bool IsSecondaryMenuPreferred { get; set; } - - protected MailOperationMenuItem(MailOperation operation, bool isEnabled, bool isSecondaryMenuItem = false) : base(operation, isEnabled) - { - IsSecondaryMenuPreferred = isSecondaryMenuItem; - } - - public static MailOperationMenuItem Create(MailOperation operation, bool isEnabled = true, bool isSecondaryMenuItem = false) - => new MailOperationMenuItem(operation, isEnabled, isSecondaryMenuItem); + IsSecondaryMenuPreferred = isSecondaryMenuItem; } + + public static MailOperationMenuItem Create(MailOperation operation, bool isEnabled = true, bool isSecondaryMenuItem = false) + => new MailOperationMenuItem(operation, isEnabled, isSecondaryMenuItem); } diff --git a/Wino.Core.Domain/Models/Menus/MenuOperationItemBase.cs b/Wino.Core.Domain/Models/Menus/MenuOperationItemBase.cs index 462cfe14..30f4a1a0 100644 --- a/Wino.Core.Domain/Models/Menus/MenuOperationItemBase.cs +++ b/Wino.Core.Domain/Models/Menus/MenuOperationItemBase.cs @@ -1,18 +1,17 @@ using System; -namespace Wino.Core.Domain.Models.Menus -{ - public class MenuOperationItemBase where TOperation : Enum - { - public MenuOperationItemBase(TOperation operation, bool isEnabled) - { - Operation = operation; - IsEnabled = isEnabled; - Identifier = operation.ToString(); - } +namespace Wino.Core.Domain.Models.Menus; - public TOperation Operation { get; set; } - public string Identifier { get; set; } - public bool IsEnabled { get; set; } +public class MenuOperationItemBase where TOperation : Enum +{ + public MenuOperationItemBase(TOperation operation, bool isEnabled) + { + Operation = operation; + IsEnabled = isEnabled; + Identifier = operation.ToString(); } + + public TOperation Operation { get; set; } + public string Identifier { get; set; } + public bool IsEnabled { get; set; } } diff --git a/Wino.Core.Domain/Models/Navigation/NavigateMailFolderEventArgs.cs b/Wino.Core.Domain/Models/Navigation/NavigateMailFolderEventArgs.cs index de6a38ea..edfade98 100644 --- a/Wino.Core.Domain/Models/Navigation/NavigateMailFolderEventArgs.cs +++ b/Wino.Core.Domain/Models/Navigation/NavigateMailFolderEventArgs.cs @@ -1,24 +1,23 @@ using System.Threading.Tasks; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.Domain.Models.Navigation +namespace Wino.Core.Domain.Models.Navigation; + +public class NavigateMailFolderEventArgs { - public class NavigateMailFolderEventArgs + public NavigateMailFolderEventArgs(IBaseFolderMenuItem baseFolderMenuItem, TaskCompletionSource folderInitLoadAwaitTask = null) { - public NavigateMailFolderEventArgs(IBaseFolderMenuItem baseFolderMenuItem, TaskCompletionSource folderInitLoadAwaitTask = null) - { - BaseFolderMenuItem = baseFolderMenuItem; - FolderInitLoadAwaitTask = folderInitLoadAwaitTask; - } - - /// - /// Base folder menu item. - /// - public IBaseFolderMenuItem BaseFolderMenuItem { get; set; } - - /// - /// Completion source for waiting folder's mail initialization. - /// - public TaskCompletionSource FolderInitLoadAwaitTask { get; } + BaseFolderMenuItem = baseFolderMenuItem; + FolderInitLoadAwaitTask = folderInitLoadAwaitTask; } + + /// + /// Base folder menu item. + /// + public IBaseFolderMenuItem BaseFolderMenuItem { get; set; } + + /// + /// Completion source for waiting folder's mail initialization. + /// + public TaskCompletionSource FolderInitLoadAwaitTask { get; } } diff --git a/Wino.Core.Domain/Models/Navigation/NavigationMode.cs b/Wino.Core.Domain/Models/Navigation/NavigationMode.cs index fbeb0fdd..f5b33d10 100644 --- a/Wino.Core.Domain/Models/Navigation/NavigationMode.cs +++ b/Wino.Core.Domain/Models/Navigation/NavigationMode.cs @@ -1,10 +1,9 @@ -namespace Wino.Core.Domain.Models.Navigation +namespace Wino.Core.Domain.Models.Navigation; + +public enum NavigationMode { - public enum NavigationMode - { - New, - Back, - Forward, - Refresh - } + New, + Back, + Forward, + Refresh } diff --git a/Wino.Core.Domain/Models/Navigation/NavigationTransitionType.cs b/Wino.Core.Domain/Models/Navigation/NavigationTransitionType.cs index ad7112b8..48b0f667 100644 --- a/Wino.Core.Domain/Models/Navigation/NavigationTransitionType.cs +++ b/Wino.Core.Domain/Models/Navigation/NavigationTransitionType.cs @@ -1,9 +1,8 @@ -namespace Wino.Core.Domain.Models.Navigation +namespace Wino.Core.Domain.Models.Navigation; + +public enum NavigationTransitionType { - public enum NavigationTransitionType - { - None, // Supress - DrillIn, - Entrance, - } + None, // Supress + DrillIn, + Entrance, } diff --git a/Wino.Core.Domain/Models/Personalization/AppThemeBase.cs b/Wino.Core.Domain/Models/Personalization/AppThemeBase.cs index f9b74a40..f2c01114 100644 --- a/Wino.Core.Domain/Models/Personalization/AppThemeBase.cs +++ b/Wino.Core.Domain/Models/Personalization/AppThemeBase.cs @@ -2,28 +2,27 @@ using System.Threading.Tasks; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Models.Personalization +namespace Wino.Core.Domain.Models.Personalization; + +/// +/// Base class for all app themes. +/// +public abstract class AppThemeBase { - /// - /// Base class for all app themes. - /// - public abstract class AppThemeBase + public Guid Id { get; set; } + public string ThemeName { get; set; } + public ApplicationElementTheme ForceElementTheme { get; set; } + public string AccentColor { get; set; } + public bool IsAccentColorAssigned => !string.IsNullOrEmpty(AccentColor); + public string BackgroundPreviewImage => GetBackgroundPreviewImagePath(); + public abstract AppThemeType AppThemeType { get; } + + protected AppThemeBase(string themeName, Guid id) { - public Guid Id { get; set; } - public string ThemeName { get; set; } - public ApplicationElementTheme ForceElementTheme { get; set; } - public string AccentColor { get; set; } - public bool IsAccentColorAssigned => !string.IsNullOrEmpty(AccentColor); - public string BackgroundPreviewImage => GetBackgroundPreviewImagePath(); - public abstract AppThemeType AppThemeType { get; } - - protected AppThemeBase(string themeName, Guid id) - { - ThemeName = themeName; - Id = id; - } - - public abstract Task GetThemeResourceDictionaryContentAsync(); - public abstract string GetBackgroundPreviewImagePath(); + ThemeName = themeName; + Id = id; } + + public abstract Task GetThemeResourceDictionaryContentAsync(); + public abstract string GetBackgroundPreviewImagePath(); } diff --git a/Wino.Core.Domain/Models/Personalization/CustomThemeMetadata.cs b/Wino.Core.Domain/Models/Personalization/CustomThemeMetadata.cs index e6206725..da92d00f 100644 --- a/Wino.Core.Domain/Models/Personalization/CustomThemeMetadata.cs +++ b/Wino.Core.Domain/Models/Personalization/CustomThemeMetadata.cs @@ -1,12 +1,11 @@ using System; -namespace Wino.Core.Domain.Models.Personalization +namespace Wino.Core.Domain.Models.Personalization; + +public class CustomThemeMetadata { - public class CustomThemeMetadata - { - public Guid Id { get; set; } - public string Name { get; set; } - public string AccentColorHex { get; set; } - public bool HasCustomAccentColor => !string.IsNullOrEmpty(AccentColorHex); - } + public Guid Id { get; set; } + public string Name { get; set; } + public string AccentColorHex { get; set; } + public bool HasCustomAccentColor => !string.IsNullOrEmpty(AccentColorHex); } diff --git a/Wino.Core.Domain/Models/Personalization/ElementThemeContainer.cs b/Wino.Core.Domain/Models/Personalization/ElementThemeContainer.cs index 42f79fc5..c5611187 100644 --- a/Wino.Core.Domain/Models/Personalization/ElementThemeContainer.cs +++ b/Wino.Core.Domain/Models/Personalization/ElementThemeContainer.cs @@ -1,16 +1,15 @@ using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Models.Personalization -{ - public class ElementThemeContainer - { - public ElementThemeContainer(ApplicationElementTheme nativeTheme, string title) - { - NativeTheme = nativeTheme; - Title = title; - } +namespace Wino.Core.Domain.Models.Personalization; - public ApplicationElementTheme NativeTheme { get; set; } - public string Title { get; set; } +public class ElementThemeContainer +{ + public ElementThemeContainer(ApplicationElementTheme nativeTheme, string title) + { + NativeTheme = nativeTheme; + Title = title; } + + public ApplicationElementTheme NativeTheme { get; set; } + public string Title { get; set; } } diff --git a/Wino.Core.Domain/Models/Printing/PrintInformation.cs b/Wino.Core.Domain/Models/Printing/PrintInformation.cs index b0dd289b..2d5d91b9 100644 --- a/Wino.Core.Domain/Models/Printing/PrintInformation.cs +++ b/Wino.Core.Domain/Models/Printing/PrintInformation.cs @@ -1,16 +1,15 @@ using System; -namespace Wino.Core.Domain.Models.Printing -{ - public class PrintInformation - { - public PrintInformation(string pDFFilePath, string pDFTitle) - { - PDFFilePath = pDFFilePath ?? throw new ArgumentNullException(nameof(pDFFilePath)); - PDFTitle = pDFTitle ?? throw new ArgumentNullException(nameof(pDFTitle)); - } +namespace Wino.Core.Domain.Models.Printing; - public string PDFFilePath { get; } - public string PDFTitle { get; } +public class PrintInformation +{ + public PrintInformation(string pDFFilePath, string pDFTitle) + { + PDFFilePath = pDFFilePath ?? throw new ArgumentNullException(nameof(pDFFilePath)); + PDFTitle = pDFTitle ?? throw new ArgumentNullException(nameof(pDFTitle)); } + + public string PDFFilePath { get; } + public string PDFTitle { get; } } diff --git a/Wino.Core.Domain/Models/Reader/FilterOption.cs b/Wino.Core.Domain/Models/Reader/FilterOption.cs index 883a8174..a6a5e164 100644 --- a/Wino.Core.Domain/Models/Reader/FilterOption.cs +++ b/Wino.Core.Domain/Models/Reader/FilterOption.cs @@ -1,16 +1,15 @@ using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Models.Reader -{ - public class FilterOption - { - public FilterOptionType Type { get; set; } - public string Title { get; set; } +namespace Wino.Core.Domain.Models.Reader; - public FilterOption(string title, FilterOptionType type) - { - Title = title; - Type = type; - } +public class FilterOption +{ + public FilterOptionType Type { get; set; } + public string Title { get; set; } + + public FilterOption(string title, FilterOptionType type) + { + Title = title; + Type = type; } } diff --git a/Wino.Core.Domain/Models/Reader/MailRenderModel.cs b/Wino.Core.Domain/Models/Reader/MailRenderModel.cs index 918457a2..5ca16b78 100644 --- a/Wino.Core.Domain/Models/Reader/MailRenderModel.cs +++ b/Wino.Core.Domain/Models/Reader/MailRenderModel.cs @@ -1,32 +1,31 @@ using System.Collections.Generic; using MimeKit; -namespace Wino.Core.Domain.Models.Reader +namespace Wino.Core.Domain.Models.Reader; + +/// +/// Final model to be passed to renderer page. +/// Data here are created based on rendering settings. +/// +public class MailRenderModel { - /// - /// Final model to be passed to renderer page. - /// Data here are created based on rendering settings. - /// - public class MailRenderModel + public string RenderHtml { get; } + public MailRenderingOptions MailRenderingOptions { get; } + public List Attachments { get; set; } = []; + + public UnsubscribeInfo UnsubscribeInfo { get; set; } + + public MailRenderModel(string renderHtml, MailRenderingOptions mailRenderingOptions = null) { - public string RenderHtml { get; } - public MailRenderingOptions MailRenderingOptions { get; } - public List Attachments { get; set; } = []; - - public UnsubscribeInfo UnsubscribeInfo { get; set; } - - public MailRenderModel(string renderHtml, MailRenderingOptions mailRenderingOptions = null) - { - RenderHtml = renderHtml; - MailRenderingOptions = mailRenderingOptions; - } - } - - public class UnsubscribeInfo - { - public string HttpLink { get; set; } - public string MailToLink { get; set; } - public bool IsOneClick { get; set; } - public bool CanUnsubscribe => HttpLink != null || MailToLink != null; + RenderHtml = renderHtml; + MailRenderingOptions = mailRenderingOptions; } } + +public class UnsubscribeInfo +{ + public string HttpLink { get; set; } + public string MailToLink { get; set; } + public bool IsOneClick { get; set; } + public bool CanUnsubscribe => HttpLink != null || MailToLink != null; +} diff --git a/Wino.Core.Domain/Models/Reader/MailRenderingOptions.cs b/Wino.Core.Domain/Models/Reader/MailRenderingOptions.cs index 1c3fb5e5..874a62ef 100644 --- a/Wino.Core.Domain/Models/Reader/MailRenderingOptions.cs +++ b/Wino.Core.Domain/Models/Reader/MailRenderingOptions.cs @@ -1,21 +1,20 @@ -namespace Wino.Core.Domain.Models.Reader +namespace Wino.Core.Domain.Models.Reader; + +/// +/// Rendering options for mail. +/// +public class MailRenderingOptions { - /// - /// Rendering options for mail. - /// - public class MailRenderingOptions - { - private const bool DefaultLoadImageValue = true; - private const bool DefaultLoadStylesValue = true; - private const bool DefaultRenderPlaintextLinksValue = true; + private const bool DefaultLoadImageValue = true; + private const bool DefaultLoadStylesValue = true; + private const bool DefaultRenderPlaintextLinksValue = true; - public bool LoadImages { get; set; } = DefaultLoadImageValue; - public bool LoadStyles { get; set; } = DefaultLoadStylesValue; - public bool RenderPlaintextLinks { get; set; } = DefaultRenderPlaintextLinksValue; + public bool LoadImages { get; set; } = DefaultLoadImageValue; + public bool LoadStyles { get; set; } = DefaultLoadStylesValue; + public bool RenderPlaintextLinks { get; set; } = DefaultRenderPlaintextLinksValue; - // HtmlDocument.Load call is redundant if all the settings are in default values. - // Therefore we will purify the HTML only if needed. + // HtmlDocument.Load call is redundant if all the settings are in default values. + // Therefore we will purify the HTML only if needed. - public bool IsPurifyingNeeded() => LoadImages != DefaultLoadImageValue || LoadStyles != DefaultLoadStylesValue; - } + public bool IsPurifyingNeeded() => LoadImages != DefaultLoadImageValue || LoadStyles != DefaultLoadStylesValue; } diff --git a/Wino.Core.Domain/Models/Reader/SortingOption.cs b/Wino.Core.Domain/Models/Reader/SortingOption.cs index 3d253453..09deec80 100644 --- a/Wino.Core.Domain/Models/Reader/SortingOption.cs +++ b/Wino.Core.Domain/Models/Reader/SortingOption.cs @@ -3,27 +3,26 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.Comparers; using Wino.Core.Domain.Models.MailItem; -namespace Wino.Core.Domain.Models.Reader -{ - public class SortingOption - { - public SortingOptionType Type { get; set; } - public string Title { get; set; } - public IComparer Comparer - { - get - { - if (Type == SortingOptionType.ReceiveDate) - return new DateComparer(); - else - return new NameComparer(); - } - } +namespace Wino.Core.Domain.Models.Reader; - public SortingOption(string title, SortingOptionType type) +public class SortingOption +{ + public SortingOptionType Type { get; set; } + public string Title { get; set; } + public IComparer Comparer + { + get { - Title = title; - Type = type; + if (Type == SortingOptionType.ReceiveDate) + return new DateComparer(); + else + return new NameComparer(); } } + + public SortingOption(string title, SortingOptionType type) + { + Title = title; + Type = type; + } } diff --git a/Wino.Core.Domain/Models/Reader/WebViewMessage.cs b/Wino.Core.Domain/Models/Reader/WebViewMessage.cs index 98c4ab9e..afd76e97 100644 --- a/Wino.Core.Domain/Models/Reader/WebViewMessage.cs +++ b/Wino.Core.Domain/Models/Reader/WebViewMessage.cs @@ -1,16 +1,15 @@ using System.Text.Json.Serialization; -namespace Wino.Core.Domain.Models.Reader -{ - /// - /// Used to pass messages from the webview to the app. - /// - public class WebViewMessage - { - [JsonPropertyName("type")] - public string Type { get; set; } +namespace Wino.Core.Domain.Models.Reader; - [JsonPropertyName("value")] - public string Value { get; set; } - } +/// +/// Used to pass messages from the webview to the app. +/// +public class WebViewMessage +{ + [JsonPropertyName("type")] + public string Type { get; set; } + + [JsonPropertyName("value")] + public string Value { get; set; } } diff --git a/Wino.Core.Domain/Models/Requests/RequestBase.cs b/Wino.Core.Domain/Models/Requests/RequestBase.cs index 3f65aca1..af7b6039 100644 --- a/Wino.Core.Domain/Models/Requests/RequestBase.cs +++ b/Wino.Core.Domain/Models/Requests/RequestBase.cs @@ -4,37 +4,36 @@ using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.Domain.Models.Requests +namespace Wino.Core.Domain.Models.Requests; + +public abstract record RequestBase where TOperation : Enum { - public abstract record RequestBase where TOperation : Enum - { - public virtual void ApplyUIChanges() { } - public virtual void RevertUIChanges() { } - public virtual int ResynchronizationDelay => 0; - public abstract TOperation Operation { get; } - public virtual object GroupingKey() { return Operation; } - } - - public abstract record MailRequestBase(MailCopy Item) : RequestBase, IMailActionRequest - { - } - - public abstract record FolderRequestBase(MailItemFolder Folder, FolderSynchronizerOperation Operation) : IFolderActionRequest - { - public abstract void ApplyUIChanges(); - public abstract void RevertUIChanges(); - - public virtual int ResynchronizationDelay => 0; - - public virtual object GroupingKey() { return Operation; } - } - - public class BatchCollection : List, IUIChangeRequest where TRequestType : IUIChangeRequest - { - public BatchCollection(IEnumerable collection) : base(collection) - { - } - public void ApplyUIChanges() => ForEach(x => x.ApplyUIChanges()); - public void RevertUIChanges() => ForEach(x => x.RevertUIChanges()); - } + public virtual void ApplyUIChanges() { } + public virtual void RevertUIChanges() { } + public virtual int ResynchronizationDelay => 0; + public abstract TOperation Operation { get; } + public virtual object GroupingKey() { return Operation; } +} + +public abstract record MailRequestBase(MailCopy Item) : RequestBase, IMailActionRequest +{ +} + +public abstract record FolderRequestBase(MailItemFolder Folder, FolderSynchronizerOperation Operation) : IFolderActionRequest +{ + public abstract void ApplyUIChanges(); + public abstract void RevertUIChanges(); + + public virtual int ResynchronizationDelay => 0; + + public virtual object GroupingKey() { return Operation; } +} + +public class BatchCollection : List, IUIChangeRequest where TRequestType : IUIChangeRequest +{ + public BatchCollection(IEnumerable collection) : base(collection) + { + } + public void ApplyUIChanges() => ForEach(x => x.ApplyUIChanges()); + public void RevertUIChanges() => ForEach(x => x.RevertUIChanges()); } diff --git a/Wino.Core.Domain/Models/Requests/ServerRequestPackage.cs b/Wino.Core.Domain/Models/Requests/ServerRequestPackage.cs index 31a408a2..aec992db 100644 --- a/Wino.Core.Domain/Models/Requests/ServerRequestPackage.cs +++ b/Wino.Core.Domain/Models/Requests/ServerRequestPackage.cs @@ -1,15 +1,14 @@ using System; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.Domain.Models.Requests +namespace Wino.Core.Domain.Models.Requests; + +/// +/// Encapsulates request to queue and account for synchronizer. +/// +/// Which account to execute this request for. +/// Prepared request for the server. +public record ServerRequestPackage(Guid AccountId, IRequestBase Request) : IClientMessage { - /// - /// Encapsulates request to queue and account for synchronizer. - /// - /// Which account to execute this request for. - /// Prepared request for the server. - public record ServerRequestPackage(Guid AccountId, IRequestBase Request) : IClientMessage - { - public override string ToString() => $"Server Package: {Request.GetType().Name}"; - } + public override string ToString() => $"Server Package: {Request.GetType().Name}"; } diff --git a/Wino.Core.Domain/Models/Server/WinoServerResponse.cs b/Wino.Core.Domain/Models/Server/WinoServerResponse.cs index d903aa6e..d334c89a 100644 --- a/Wino.Core.Domain/Models/Server/WinoServerResponse.cs +++ b/Wino.Core.Domain/Models/Server/WinoServerResponse.cs @@ -1,40 +1,39 @@ using Wino.Core.Domain.Exceptions; -namespace Wino.Core.Domain.Models.Server +namespace Wino.Core.Domain.Models.Server; + +/// +/// Encapsulates responses from the Wino server. +/// Exceptions are stored separately in the Message and StackTrace properties due to serialization issues. +/// +/// Type of the expected response. +public class WinoServerResponse { - /// - /// Encapsulates responses from the Wino server. - /// Exceptions are stored separately in the Message and StackTrace properties due to serialization issues. - /// - /// Type of the expected response. - public class WinoServerResponse + public bool IsSuccess { get; set; } + public string Message { get; set; } + public T Data { get; set; } + + public static WinoServerResponse CreateSuccessResponse(T data) { - public bool IsSuccess { get; set; } - public string Message { get; set; } - public T Data { get; set; } - - public static WinoServerResponse CreateSuccessResponse(T data) + return new WinoServerResponse { - return new WinoServerResponse - { - IsSuccess = true, - Data = data - }; - } + IsSuccess = true, + Data = data + }; + } - public static WinoServerResponse CreateErrorResponse(string message) + public static WinoServerResponse CreateErrorResponse(string message) + { + return new WinoServerResponse { - return new WinoServerResponse - { - IsSuccess = false, - Message = message - }; - } + IsSuccess = false, + Message = message + }; + } - public void ThrowIfFailed() - { - if (!IsSuccess) - throw new WinoServerException(Message); - } + public void ThrowIfFailed() + { + if (!IsSuccess) + throw new WinoServerException(Message); } } diff --git a/Wino.Core.Domain/Models/Settings/SettingOption.cs b/Wino.Core.Domain/Models/Settings/SettingOption.cs index ef3e8c4b..68871d99 100644 --- a/Wino.Core.Domain/Models/Settings/SettingOption.cs +++ b/Wino.Core.Domain/Models/Settings/SettingOption.cs @@ -1,6 +1,5 @@ using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Models.Settings -{ - public record SettingOption(string Title, string Description, WinoPage NavigationPage, string PathIcon); -} +namespace Wino.Core.Domain.Models.Settings; + +public record SettingOption(string Title, string Description, WinoPage NavigationPage, string PathIcon); diff --git a/Wino.Core.Domain/Models/Store/StoreProductType.cs b/Wino.Core.Domain/Models/Store/StoreProductType.cs index 5c82003e..f8c620ed 100644 --- a/Wino.Core.Domain/Models/Store/StoreProductType.cs +++ b/Wino.Core.Domain/Models/Store/StoreProductType.cs @@ -1,7 +1,6 @@ -namespace Wino.Core.Domain.Models.Store +namespace Wino.Core.Domain.Models.Store; + +public enum StoreProductType { - public enum StoreProductType - { - UnlimitedAccounts - } + UnlimitedAccounts } diff --git a/Wino.Core.Domain/Models/Synchronization/CalendarSynchronizationOptions.cs b/Wino.Core.Domain/Models/Synchronization/CalendarSynchronizationOptions.cs index 8bdc4585..5b508ea2 100644 --- a/Wino.Core.Domain/Models/Synchronization/CalendarSynchronizationOptions.cs +++ b/Wino.Core.Domain/Models/Synchronization/CalendarSynchronizationOptions.cs @@ -2,30 +2,29 @@ using System.Collections.Generic; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Models.Synchronization +namespace Wino.Core.Domain.Models.Synchronization; + +public class CalendarSynchronizationOptions { - public class CalendarSynchronizationOptions - { - /// - /// Unique id of synchronization. - /// - public Guid Id { get; } = Guid.NewGuid(); + /// + /// Unique id of synchronization. + /// + public Guid Id { get; } = Guid.NewGuid(); - /// - /// Account to execute synchronization for. - /// - public Guid AccountId { get; set; } + /// + /// Account to execute synchronization for. + /// + public Guid AccountId { get; set; } - /// - /// Type of the synchronization to be performed. - /// - public CalendarSynchronizationType Type { get; set; } + /// + /// Type of the synchronization to be performed. + /// + public CalendarSynchronizationType Type { get; set; } - /// - /// Calendar ids to synchronize. - /// - public List SynchronizationCalendarIds { get; set; } + /// + /// Calendar ids to synchronize. + /// + public List SynchronizationCalendarIds { get; set; } - public override string ToString() => $"Type: {Type}, Calendars: {(SynchronizationCalendarIds == null ? "All" : string.Join(",", SynchronizationCalendarIds))}"; - } + public override string ToString() => $"Type: {Type}, Calendars: {(SynchronizationCalendarIds == null ? "All" : string.Join(",", SynchronizationCalendarIds))}"; } diff --git a/Wino.Core.Domain/Models/Synchronization/CalendarSynchronizationResult.cs b/Wino.Core.Domain/Models/Synchronization/CalendarSynchronizationResult.cs index 1f12d819..86de1b5c 100644 --- a/Wino.Core.Domain/Models/Synchronization/CalendarSynchronizationResult.cs +++ b/Wino.Core.Domain/Models/Synchronization/CalendarSynchronizationResult.cs @@ -4,43 +4,42 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Accounts; -namespace Wino.Core.Domain.Models.Synchronization +namespace Wino.Core.Domain.Models.Synchronization; + +public class CalendarSynchronizationResult { - public class CalendarSynchronizationResult - { - public CalendarSynchronizationResult() { } + public CalendarSynchronizationResult() { } - /// - /// Gets the new downloaded events from synchronization. - /// Server will create notifications for these event. - /// It's ignored in serialization. Client should not react to this. - /// - [JsonIgnore] - public IEnumerable DownloadedEvents { get; set; } = []; + /// + /// Gets the new downloaded events from synchronization. + /// Server will create notifications for these event. + /// It's ignored in serialization. Client should not react to this. + /// + [JsonIgnore] + public IEnumerable DownloadedEvents { get; set; } = []; - public ProfileInformation ProfileInformation { get; set; } + public ProfileInformation ProfileInformation { get; set; } - public SynchronizationCompletedState CompletedState { get; set; } + public SynchronizationCompletedState CompletedState { get; set; } - public static CalendarSynchronizationResult Empty => new() { CompletedState = SynchronizationCompletedState.Success }; + public static CalendarSynchronizationResult Empty => new() { CompletedState = SynchronizationCompletedState.Success }; - // Mail synchronization - public static CalendarSynchronizationResult Completed(IEnumerable downloadedEvent) - => new() - { - DownloadedEvents = downloadedEvent, - CompletedState = SynchronizationCompletedState.Success - }; + // Mail synchronization + public static CalendarSynchronizationResult Completed(IEnumerable downloadedEvent) + => new() + { + DownloadedEvents = downloadedEvent, + CompletedState = SynchronizationCompletedState.Success + }; - // Profile synchronization - public static CalendarSynchronizationResult Completed(ProfileInformation profileInformation) - => new() - { - ProfileInformation = profileInformation, - CompletedState = SynchronizationCompletedState.Success - }; + // Profile synchronization + public static CalendarSynchronizationResult Completed(ProfileInformation profileInformation) + => new() + { + ProfileInformation = profileInformation, + CompletedState = SynchronizationCompletedState.Success + }; - public static CalendarSynchronizationResult Canceled => new() { CompletedState = SynchronizationCompletedState.Canceled }; - public static CalendarSynchronizationResult Failed => new() { CompletedState = SynchronizationCompletedState.Failed }; - } + public static CalendarSynchronizationResult Canceled => new() { CompletedState = SynchronizationCompletedState.Canceled }; + public static CalendarSynchronizationResult Failed => new() { CompletedState = SynchronizationCompletedState.Failed }; } diff --git a/Wino.Core.Domain/Models/Synchronization/MailSynchronizationOptions.cs b/Wino.Core.Domain/Models/Synchronization/MailSynchronizationOptions.cs index 17115213..b0d33345 100644 --- a/Wino.Core.Domain/Models/Synchronization/MailSynchronizationOptions.cs +++ b/Wino.Core.Domain/Models/Synchronization/MailSynchronizationOptions.cs @@ -2,43 +2,42 @@ using System.Collections.Generic; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Models.Synchronization +namespace Wino.Core.Domain.Models.Synchronization; + +public class MailSynchronizationOptions { - public class MailSynchronizationOptions - { - /// - /// Unique id of synchronization. - /// - public Guid Id { get; set; } = Guid.NewGuid(); + /// + /// Unique id of synchronization. + /// + public Guid Id { get; set; } = Guid.NewGuid(); - /// - /// Account to execute synchronization for. - /// - public Guid AccountId { get; set; } + /// + /// Account to execute synchronization for. + /// + public Guid AccountId { get; set; } - /// - /// Type of the synchronization to be performed. - /// - public MailSynchronizationType Type { get; set; } + /// + /// Type of the synchronization to be performed. + /// + public MailSynchronizationType Type { get; set; } - /// - /// Collection of FolderId to perform SynchronizationType.Custom type sync. - /// - public List SynchronizationFolderIds { get; set; } + /// + /// Collection of FolderId to perform SynchronizationType.Custom type sync. + /// + public List SynchronizationFolderIds { get; set; } - /// - /// If true, additional folders like Sent,Drafts and Deleted will not be synchronized - /// with InboxOnly and CustomFolders sync type. - /// - public bool ExcludeMustHaveFolders { get; set; } + /// + /// If true, additional folders like Sent,Drafts and Deleted will not be synchronized + /// with InboxOnly and CustomFolders sync type. + /// + public bool ExcludeMustHaveFolders { get; set; } - /// - /// When doing a linked inbox synchronization, we must ignore reporting completion to the caller for each folder. - /// This Id will help tracking that. Id is unique, but this one can be the same for all sync requests - /// inside the same linked inbox sync. - /// - public Guid? GroupedSynchronizationTrackingId { get; set; } + /// + /// When doing a linked inbox synchronization, we must ignore reporting completion to the caller for each folder. + /// This Id will help tracking that. Id is unique, but this one can be the same for all sync requests + /// inside the same linked inbox sync. + /// + public Guid? GroupedSynchronizationTrackingId { get; set; } - public override string ToString() => $"Type: {Type}"; - } + public override string ToString() => $"Type: {Type}"; } diff --git a/Wino.Core.Domain/Models/Synchronization/MailSynchronizationResult.cs b/Wino.Core.Domain/Models/Synchronization/MailSynchronizationResult.cs index 271d64ab..f7280889 100644 --- a/Wino.Core.Domain/Models/Synchronization/MailSynchronizationResult.cs +++ b/Wino.Core.Domain/Models/Synchronization/MailSynchronizationResult.cs @@ -4,43 +4,42 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.Accounts; using Wino.Core.Domain.Models.MailItem; -namespace Wino.Core.Domain.Models.Synchronization +namespace Wino.Core.Domain.Models.Synchronization; + +public class MailSynchronizationResult { - public class MailSynchronizationResult - { - public MailSynchronizationResult() { } + public MailSynchronizationResult() { } - /// - /// Gets the new downloaded messages from synchronization. - /// Server will create notifications for these messages. - /// It's ignored in serialization. Client should not react to this. - /// - [JsonIgnore] - public IEnumerable DownloadedMessages { get; set; } = []; + /// + /// Gets the new downloaded messages from synchronization. + /// Server will create notifications for these messages. + /// It's ignored in serialization. Client should not react to this. + /// + [JsonIgnore] + public IEnumerable DownloadedMessages { get; set; } = []; - public ProfileInformation ProfileInformation { get; set; } + public ProfileInformation ProfileInformation { get; set; } - public SynchronizationCompletedState CompletedState { get; set; } + public SynchronizationCompletedState CompletedState { get; set; } - public static MailSynchronizationResult Empty => new() { CompletedState = SynchronizationCompletedState.Success }; + public static MailSynchronizationResult Empty => new() { CompletedState = SynchronizationCompletedState.Success }; - // Mail synchronization - public static MailSynchronizationResult Completed(IEnumerable downloadedMessages) - => new() - { - DownloadedMessages = downloadedMessages, - CompletedState = SynchronizationCompletedState.Success - }; + // Mail synchronization + public static MailSynchronizationResult Completed(IEnumerable downloadedMessages) + => new() + { + DownloadedMessages = downloadedMessages, + CompletedState = SynchronizationCompletedState.Success + }; - // Profile synchronization - public static MailSynchronizationResult Completed(ProfileInformation profileInformation) - => new() - { - ProfileInformation = profileInformation, - CompletedState = SynchronizationCompletedState.Success - }; + // Profile synchronization + public static MailSynchronizationResult Completed(ProfileInformation profileInformation) + => new() + { + ProfileInformation = profileInformation, + CompletedState = SynchronizationCompletedState.Success + }; - public static MailSynchronizationResult Canceled => new() { CompletedState = SynchronizationCompletedState.Canceled }; - public static MailSynchronizationResult Failed => new() { CompletedState = SynchronizationCompletedState.Failed }; - } + public static MailSynchronizationResult Canceled => new() { CompletedState = SynchronizationCompletedState.Canceled }; + public static MailSynchronizationResult Failed => new() { CompletedState = SynchronizationCompletedState.Failed }; } diff --git a/Wino.Core.Domain/Models/Translations/AppLanguageModel.cs b/Wino.Core.Domain/Models/Translations/AppLanguageModel.cs index 65032c61..1c779508 100644 --- a/Wino.Core.Domain/Models/Translations/AppLanguageModel.cs +++ b/Wino.Core.Domain/Models/Translations/AppLanguageModel.cs @@ -1,6 +1,5 @@ using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Models.Translations -{ - public record AppLanguageModel(AppLanguage Language, string DisplayName); -} +namespace Wino.Core.Domain.Models.Translations; + +public record AppLanguageModel(AppLanguage Language, string DisplayName); diff --git a/Wino.Core.Domain/Translations/WinoTranslationDictionary.cs b/Wino.Core.Domain/Translations/WinoTranslationDictionary.cs index 4aa9b8c8..6026d74e 100644 --- a/Wino.Core.Domain/Translations/WinoTranslationDictionary.cs +++ b/Wino.Core.Domain/Translations/WinoTranslationDictionary.cs @@ -3,50 +3,49 @@ using System.IO; using System.Reflection; using Wino.Core.Domain.Enums; -namespace Wino.Core.Domain.Translations +namespace Wino.Core.Domain.Translations; + +public class WinoTranslationDictionary : Dictionary { - public class WinoTranslationDictionary : Dictionary + // Return the key itself in case of translation is not found. + public string GetTranslatedString(string key) => TryGetValue(key, out string keyValue) ? keyValue : key; + + public static Stream GetLanguageStream(AppLanguage language) { - // Return the key itself in case of translation is not found. - public string GetTranslatedString(string key) => TryGetValue(key, out string keyValue) ? keyValue : key; + var path = GetLanguageFileNameRelativePath(language); + var executingAssembly = Assembly.GetExecutingAssembly(); - public static Stream GetLanguageStream(AppLanguage language) + // Use the assembly's name instead of the module name to construct the resource path + string assemblyName = executingAssembly.GetName().Name; + string languageResourcePath = $"{assemblyName}.Translations.{path}.resources.json"; + return executingAssembly.GetManifestResourceStream(languageResourcePath); + } + + /// + /// Returns the relative path of the language file. + /// All translations are under Translations\{langCode}\resources.json + /// + /// Language + /// Relative folder for the language + public static string GetLanguageFileNameRelativePath(AppLanguage language) + { + return language switch { - var path = GetLanguageFileNameRelativePath(language); - var executingAssembly = Assembly.GetExecutingAssembly(); - - // Use the assembly's name instead of the module name to construct the resource path - string assemblyName = executingAssembly.GetName().Name; - string languageResourcePath = $"{assemblyName}.Translations.{path}.resources.json"; - return executingAssembly.GetManifestResourceStream(languageResourcePath); - } - - /// - /// Returns the relative path of the language file. - /// All translations are under Translations\{langCode}\resources.json - /// - /// Language - /// Relative folder for the language - public static string GetLanguageFileNameRelativePath(AppLanguage language) - { - return language switch - { - AppLanguage.English => "en_US", - AppLanguage.Turkish => "tr_TR", - AppLanguage.Deutsch => "de_DE", - AppLanguage.Russian => "ru_RU", - AppLanguage.Polish => "pl_PL", - AppLanguage.Czech => "cs_CZ", - AppLanguage.French => "fr_FR", - AppLanguage.Chinese => "zh_CN", - AppLanguage.Spanish => "es_ES", - AppLanguage.Indonesian => "id_ID", - AppLanguage.Italian => "it_IT", - AppLanguage.Greek => "el_GR", - AppLanguage.PortugeseBrazil => "pt_BR", - AppLanguage.Romanian => "ro_RO", - _ => "en_US", - }; - } + AppLanguage.English => "en_US", + AppLanguage.Turkish => "tr_TR", + AppLanguage.Deutsch => "de_DE", + AppLanguage.Russian => "ru_RU", + AppLanguage.Polish => "pl_PL", + AppLanguage.Czech => "cs_CZ", + AppLanguage.French => "fr_FR", + AppLanguage.Chinese => "zh_CN", + AppLanguage.Spanish => "es_ES", + AppLanguage.Indonesian => "id_ID", + AppLanguage.Italian => "it_IT", + AppLanguage.Greek => "el_GR", + AppLanguage.PortugeseBrazil => "pt_BR", + AppLanguage.Romanian => "ro_RO", + _ => "en_US", + }; } } diff --git a/Wino.Core.UWP/Activation/ActivationHandler.cs b/Wino.Core.UWP/Activation/ActivationHandler.cs index 63322abc..bbe692f1 100644 --- a/Wino.Core.UWP/Activation/ActivationHandler.cs +++ b/Wino.Core.UWP/Activation/ActivationHandler.cs @@ -1,37 +1,36 @@ using System.Threading.Tasks; -namespace Wino.Activation -{ - public abstract class ActivationHandler - { - public abstract bool CanHandle(object args); +namespace Wino.Activation; - public abstract Task HandleAsync(object args); +public abstract class ActivationHandler +{ + public abstract bool CanHandle(object args); + + public abstract Task HandleAsync(object args); +} + +// Extend this class to implement new ActivationHandlers +public abstract class ActivationHandler : ActivationHandler + where T : class +{ + // Override this method to add the activation logic in your activation handler + protected abstract Task HandleInternalAsync(T args); + + public override async Task HandleAsync(object args) + { + await HandleInternalAsync(args as T); } - // Extend this class to implement new ActivationHandlers - public abstract class ActivationHandler : ActivationHandler - where T : class + public override bool CanHandle(object args) { - // Override this method to add the activation logic in your activation handler - protected abstract Task HandleInternalAsync(T args); + // CanHandle checks the args is of type you have configured + return args is T && CanHandleInternal(args as T); + } - public override async Task HandleAsync(object args) - { - await HandleInternalAsync(args as T); - } - - public override bool CanHandle(object args) - { - // CanHandle checks the args is of type you have configured - return args is T && CanHandleInternal(args as T); - } - - // You can override this method to add extra validation on activation args - // to determine if your ActivationHandler should handle this activation args - protected virtual bool CanHandleInternal(T args) - { - return true; - } + // You can override this method to add extra validation on activation args + // to determine if your ActivationHandler should handle this activation args + protected virtual bool CanHandleInternal(T args) + { + return true; } } diff --git a/Wino.Core.UWP/BasePage.cs b/Wino.Core.UWP/BasePage.cs index 5857bd09..ace946c9 100644 --- a/Wino.Core.UWP/BasePage.cs +++ b/Wino.Core.UWP/BasePage.cs @@ -8,81 +8,80 @@ using Windows.UI.Xaml.Navigation; using Wino.Core.ViewModels; using Wino.Messaging.Client.Shell; -namespace Wino.Core.UWP +namespace Wino.Core.UWP; + +public partial class BasePage : Page, IRecipient { - public partial class BasePage : Page, IRecipient + public UIElement ShellContent { - public UIElement ShellContent - { - get { return (UIElement)GetValue(ShellContentProperty); } - set { SetValue(ShellContentProperty, value); } - } - - public static readonly DependencyProperty ShellContentProperty = DependencyProperty.Register(nameof(ShellContent), typeof(UIElement), typeof(BasePage), new PropertyMetadata(null)); - - public void Receive(LanguageChanged message) - { - OnLanguageChanged(); - } - - public virtual void OnLanguageChanged() { } + get { return (UIElement)GetValue(ShellContentProperty); } + set { SetValue(ShellContentProperty, value); } } - public abstract class BasePage : BasePage where T : CoreBaseViewModel + public static readonly DependencyProperty ShellContentProperty = DependencyProperty.Register(nameof(ShellContent), typeof(UIElement), typeof(BasePage), new PropertyMetadata(null)); + + public void Receive(LanguageChanged message) { - public T ViewModel { get; } = WinoApplication.Current.Services.GetService(); + OnLanguageChanged(); + } - protected BasePage() - { - ViewModel.Dispatcher = new UWPDispatcher(Dispatcher); + public virtual void OnLanguageChanged() { } +} - Loaded += PageLoaded; - Unloaded += PageUnloaded; - } +public abstract class BasePage : BasePage where T : CoreBaseViewModel +{ + public T ViewModel { get; } = WinoApplication.Current.Services.GetService(); - private void PageUnloaded(object sender, RoutedEventArgs e) - { - Loaded -= PageLoaded; - Unloaded -= PageUnloaded; - } + protected BasePage() + { + ViewModel.Dispatcher = new UWPDispatcher(Dispatcher); - private void PageLoaded(object sender, RoutedEventArgs e) => ViewModel.OnPageLoaded(); + Loaded += PageLoaded; + Unloaded += PageUnloaded; + } - ~BasePage() - { - Debug.WriteLine($"Disposed {GetType().Name}"); - } + private void PageUnloaded(object sender, RoutedEventArgs e) + { + Loaded -= PageLoaded; + Unloaded -= PageUnloaded; + } - protected override void OnNavigatedTo(NavigationEventArgs e) - { - base.OnNavigatedTo(e); + private void PageLoaded(object sender, RoutedEventArgs e) => ViewModel.OnPageLoaded(); - var mode = GetNavigationMode(e.NavigationMode); - var parameter = e.Parameter; + ~BasePage() + { + Debug.WriteLine($"Disposed {GetType().Name}"); + } - WeakReferenceMessenger.Default.UnregisterAll(this); - WeakReferenceMessenger.Default.RegisterAll(this); + protected override void OnNavigatedTo(NavigationEventArgs e) + { + base.OnNavigatedTo(e); - ViewModel.OnNavigatedTo(mode, parameter); - } + var mode = GetNavigationMode(e.NavigationMode); + var parameter = e.Parameter; - protected override void OnNavigatingFrom(NavigatingCancelEventArgs e) - { - base.OnNavigatingFrom(e); + WeakReferenceMessenger.Default.UnregisterAll(this); + WeakReferenceMessenger.Default.RegisterAll(this); - var mode = GetNavigationMode(e.NavigationMode); - var parameter = e.Parameter; + ViewModel.OnNavigatedTo(mode, parameter); + } - WeakReferenceMessenger.Default.UnregisterAll(this); + protected override void OnNavigatingFrom(NavigatingCancelEventArgs e) + { + base.OnNavigatingFrom(e); - ViewModel.OnNavigatedFrom(mode, parameter); + var mode = GetNavigationMode(e.NavigationMode); + var parameter = e.Parameter; - GC.Collect(); - } + WeakReferenceMessenger.Default.UnregisterAll(this); - private Domain.Models.Navigation.NavigationMode GetNavigationMode(NavigationMode mode) - { - return (Domain.Models.Navigation.NavigationMode)mode; - } + ViewModel.OnNavigatedFrom(mode, parameter); + + GC.Collect(); + } + + private Domain.Models.Navigation.NavigationMode GetNavigationMode(NavigationMode mode) + { + return (Domain.Models.Navigation.NavigationMode)mode; } } diff --git a/Wino.Core.UWP/Controls/AccountCreationDialogControl.xaml.cs b/Wino.Core.UWP/Controls/AccountCreationDialogControl.xaml.cs index ac556d22..0cd1c098 100644 --- a/Wino.Core.UWP/Controls/AccountCreationDialogControl.xaml.cs +++ b/Wino.Core.UWP/Controls/AccountCreationDialogControl.xaml.cs @@ -9,68 +9,67 @@ using Wino.Core.Domain.Interfaces; using Wino.Messaging.UI; -namespace Wino.Core.UWP.Controls +namespace Wino.Core.UWP.Controls; + +public sealed partial class AccountCreationDialogControl : UserControl, IRecipient { - public sealed partial class AccountCreationDialogControl : UserControl, IRecipient + private string copyClipboardURL; + + public event EventHandler CancelClicked; + + public AccountCreationDialogState State { - private string copyClipboardURL; - - public event EventHandler CancelClicked; - - public AccountCreationDialogState State - { - get { return (AccountCreationDialogState)GetValue(StateProperty); } - set { SetValue(StateProperty, value); } - } - - public static readonly DependencyProperty StateProperty = DependencyProperty.Register(nameof(State), typeof(AccountCreationDialogState), typeof(AccountCreationDialogControl), new PropertyMetadata(AccountCreationDialogState.Idle, new PropertyChangedCallback(OnStateChanged))); - - public AccountCreationDialogControl() - { - InitializeComponent(); - } - - private static void OnStateChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) - { - if (obj is AccountCreationDialogControl dialog) - { - dialog.UpdateVisualStates(); - } - } - - private void UpdateVisualStates() => VisualStateManager.GoToState(this, State.ToString(), false); - - public async void Receive(CopyAuthURLRequested message) - { - copyClipboardURL = message.AuthURL; - - await Task.Delay(2000); - - await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => - { - AuthHelpDialogButton.Visibility = Windows.UI.Xaml.Visibility.Visible; - }); - } - - private void ControlLoaded(object sender, Windows.UI.Xaml.RoutedEventArgs e) - { - WeakReferenceMessenger.Default.Register(this); - } - - private void ControlUnloaded(object sender, Windows.UI.Xaml.RoutedEventArgs e) - { - WeakReferenceMessenger.Default.UnregisterAll(this); - } - - private async void CopyClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e) - { - if (string.IsNullOrEmpty(copyClipboardURL)) return; - - var clipboardService = WinoApplication.Current.Services.GetService(); - await clipboardService.CopyClipboardAsync(copyClipboardURL); - } - - - private void CancelButtonClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e) => CancelClicked?.Invoke(this, null); + get { return (AccountCreationDialogState)GetValue(StateProperty); } + set { SetValue(StateProperty, value); } } + + public static readonly DependencyProperty StateProperty = DependencyProperty.Register(nameof(State), typeof(AccountCreationDialogState), typeof(AccountCreationDialogControl), new PropertyMetadata(AccountCreationDialogState.Idle, new PropertyChangedCallback(OnStateChanged))); + + public AccountCreationDialogControl() + { + InitializeComponent(); + } + + private static void OnStateChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) + { + if (obj is AccountCreationDialogControl dialog) + { + dialog.UpdateVisualStates(); + } + } + + private void UpdateVisualStates() => VisualStateManager.GoToState(this, State.ToString(), false); + + public async void Receive(CopyAuthURLRequested message) + { + copyClipboardURL = message.AuthURL; + + await Task.Delay(2000); + + await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => + { + AuthHelpDialogButton.Visibility = Windows.UI.Xaml.Visibility.Visible; + }); + } + + private void ControlLoaded(object sender, Windows.UI.Xaml.RoutedEventArgs e) + { + WeakReferenceMessenger.Default.Register(this); + } + + private void ControlUnloaded(object sender, Windows.UI.Xaml.RoutedEventArgs e) + { + WeakReferenceMessenger.Default.UnregisterAll(this); + } + + private async void CopyClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e) + { + if (string.IsNullOrEmpty(copyClipboardURL)) return; + + var clipboardService = WinoApplication.Current.Services.GetService(); + await clipboardService.CopyClipboardAsync(copyClipboardURL); + } + + + private void CancelButtonClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e) => CancelClicked?.Invoke(this, null); } diff --git a/Wino.Core.UWP/Controls/ControlConstants.cs b/Wino.Core.UWP/Controls/ControlConstants.cs index 7ce5c58c..db693d77 100644 --- a/Wino.Core.UWP/Controls/ControlConstants.cs +++ b/Wino.Core.UWP/Controls/ControlConstants.cs @@ -1,106 +1,105 @@ using System.Collections.Generic; -namespace Wino.Core.UWP.Controls +namespace Wino.Core.UWP.Controls; + +public static class ControlConstants { - public static class ControlConstants + public static Dictionary WinoIconFontDictionary = new Dictionary() { - public static Dictionary WinoIconFontDictionary = new Dictionary() - { - { WinoIconGlyph.None, "\u0020" }, - { WinoIconGlyph.Archive, "\uE066" }, - { WinoIconGlyph.UnArchive, "\uE06C" }, - { WinoIconGlyph.Reply, "\uF176" }, - { WinoIconGlyph.ReplyAll, "\uF17A" }, - { WinoIconGlyph.Sync, "\uE895" }, - { WinoIconGlyph.Send, "\uEA8E" }, - { WinoIconGlyph.LightEditor, "\uE1F6" }, - { WinoIconGlyph.Delete, "\uEEA6" }, - { WinoIconGlyph.DarkEditor, "\uEE44" }, - { WinoIconGlyph.Draft, "\uF3BE" }, - { WinoIconGlyph.Flag, "\uF40C" }, - { WinoIconGlyph.ClearFlag, "\uF40F" }, - { WinoIconGlyph.Folder, "\uE643" }, - { WinoIconGlyph.Forward, "\uE7AA" }, - { WinoIconGlyph.Inbox, "\uF516" }, - { WinoIconGlyph.MarkRead, "\uF522" }, - { WinoIconGlyph.MarkUnread, "\uF529" }, - { WinoIconGlyph.MultiSelect, "\uE84D" }, - { WinoIconGlyph.Save, "\uEA43" }, - { WinoIconGlyph.CreateFolder, "\uE645" }, - { WinoIconGlyph.Pin, "\uF5FF" }, - { WinoIconGlyph.UnPin, "\uE985" }, - { WinoIconGlyph.Star, "\uE734" }, - { WinoIconGlyph.Ignore, "\uF5D0" }, - { WinoIconGlyph.Find, "\uEA7D" }, - { WinoIconGlyph.Zoom, "\uEE8E" }, - { WinoIconGlyph.SpecialFolderInbox, "\uF516" }, - { WinoIconGlyph.SpecialFolderStarred, "\uF70D" }, - { WinoIconGlyph.SpecialFolderImportant, "\uE2F4" }, - { WinoIconGlyph.SpecialFolderSent, "\uEA8E" }, - { WinoIconGlyph.SpecialFolderDraft, "\uF3BE" }, - { WinoIconGlyph.SpecialFolderArchive, "\uE066" }, - { WinoIconGlyph.SpecialFolderDeleted, "\uEEA6" }, - { WinoIconGlyph.SpecialFolderJunk, "\uF140" }, - { WinoIconGlyph.SpecialFolderChat, "\uE8BD" }, - { WinoIconGlyph.SpecialFolderCategory, "\uF599" }, - { WinoIconGlyph.SpecialFolderUnread, "\uF529" }, - { WinoIconGlyph.SpecialFolderForums, "\uF5B8" }, - { WinoIconGlyph.SpecialFolderUpdated, "\uF565" }, - { WinoIconGlyph.SpecialFolderPersonal, "\uE25A" }, - { WinoIconGlyph.SpecialFolderPromotions, "\uF7B6" }, - { WinoIconGlyph.SpecialFolderSocial, "\uEEEB" }, - { WinoIconGlyph.SpecialFolderOther, "\uE643" }, - { WinoIconGlyph.SpecialFolderMore, "\uF0F4" }, - { WinoIconGlyph.Microsoft, "\uE904" }, - { WinoIconGlyph.Google, "\uE905" }, - { WinoIconGlyph.NewMail, "\uF107" }, - { WinoIconGlyph.TurnOfNotifications, "\uF11D" }, - { WinoIconGlyph.Rename, "\uF668" }, - { WinoIconGlyph.EmptyFolder, "\uE47E" }, - { WinoIconGlyph.DontSync, "\uF195" }, - { WinoIconGlyph.Move, "\uE7B8" }, - { WinoIconGlyph.Mail, "\uF509" }, - { WinoIconGlyph.More, "\uE824" }, - { WinoIconGlyph.CustomServer, "\uF509" }, - { WinoIconGlyph.Print, "\uE922" }, - { WinoIconGlyph.Attachment, "\uE723" }, - { WinoIconGlyph.SortTextDesc, "\U000F3606" }, - { WinoIconGlyph.SortLinesDesc, "\U000F038A" }, - { WinoIconGlyph.Certificate, "\uEB95" }, - { WinoIconGlyph.OpenInNewWindow, "\uE8A7" }, - { WinoIconGlyph.Message, "\uE8BD" }, - { WinoIconGlyph.New, "\U000F002A" }, - { WinoIconGlyph.Blocked,"\uF140" }, - { WinoIconGlyph.IMAP, "\uE715" }, - { WinoIconGlyph.Calendar, "\uE912" }, - { WinoIconGlyph.CalendarToday, "\uE911" }, - { WinoIconGlyph.CalendarDay, "\uE913" }, - { WinoIconGlyph.CalendarWeek, "\uE914" }, - { WinoIconGlyph.CalendarMonth, "\uE91c" }, - { WinoIconGlyph.CalendarYear, "\uE917" }, - { WinoIconGlyph.WeatherBlow, "\uE907" }, - { WinoIconGlyph.WeatherCloudy, "\uE920" }, - { WinoIconGlyph.WeatherSunny, "\uE90e" }, - { WinoIconGlyph.WeatherRainy, "\uE908" }, - { WinoIconGlyph.WeatherSnowy, "\uE90a" }, - { WinoIconGlyph.WeatherSnowShowerAtNight, "\uE90c" }, - { WinoIconGlyph.WeatherThunderstorm, "\uE906" }, - { WinoIconGlyph.CalendarEventRepeat, "\uE915" }, - { WinoIconGlyph.CalendarEventMuiltiDay, "\uE91b" }, - { WinoIconGlyph.Reminder, "\uE918" }, - { WinoIconGlyph.CalendarAttendee, "\uE91a" }, - { WinoIconGlyph.CalendarSync, "\uE91d" }, - { WinoIconGlyph.CalendarError, "\uE916" }, - { WinoIconGlyph.CalendarAttendees, "\uE929" }, - { WinoIconGlyph.EventEditSeries, "\uE92A" }, - { WinoIconGlyph.EventTentative, "\uE928" }, - { WinoIconGlyph.EventAccept, "\uE925" }, - { WinoIconGlyph.EventRespond, "\uE924" }, - { WinoIconGlyph.EventReminder, "\uE923" }, - { WinoIconGlyph.EventJoinOnline, "\uE926" }, - { WinoIconGlyph.ViewMessageSource, "\uE943" }, - { WinoIconGlyph.Apple, "\uE92B" }, - { WinoIconGlyph.Yahoo, "\uE92C" } - }; - } + { WinoIconGlyph.None, "\u0020" }, + { WinoIconGlyph.Archive, "\uE066" }, + { WinoIconGlyph.UnArchive, "\uE06C" }, + { WinoIconGlyph.Reply, "\uF176" }, + { WinoIconGlyph.ReplyAll, "\uF17A" }, + { WinoIconGlyph.Sync, "\uE895" }, + { WinoIconGlyph.Send, "\uEA8E" }, + { WinoIconGlyph.LightEditor, "\uE1F6" }, + { WinoIconGlyph.Delete, "\uEEA6" }, + { WinoIconGlyph.DarkEditor, "\uEE44" }, + { WinoIconGlyph.Draft, "\uF3BE" }, + { WinoIconGlyph.Flag, "\uF40C" }, + { WinoIconGlyph.ClearFlag, "\uF40F" }, + { WinoIconGlyph.Folder, "\uE643" }, + { WinoIconGlyph.Forward, "\uE7AA" }, + { WinoIconGlyph.Inbox, "\uF516" }, + { WinoIconGlyph.MarkRead, "\uF522" }, + { WinoIconGlyph.MarkUnread, "\uF529" }, + { WinoIconGlyph.MultiSelect, "\uE84D" }, + { WinoIconGlyph.Save, "\uEA43" }, + { WinoIconGlyph.CreateFolder, "\uE645" }, + { WinoIconGlyph.Pin, "\uF5FF" }, + { WinoIconGlyph.UnPin, "\uE985" }, + { WinoIconGlyph.Star, "\uE734" }, + { WinoIconGlyph.Ignore, "\uF5D0" }, + { WinoIconGlyph.Find, "\uEA7D" }, + { WinoIconGlyph.Zoom, "\uEE8E" }, + { WinoIconGlyph.SpecialFolderInbox, "\uF516" }, + { WinoIconGlyph.SpecialFolderStarred, "\uF70D" }, + { WinoIconGlyph.SpecialFolderImportant, "\uE2F4" }, + { WinoIconGlyph.SpecialFolderSent, "\uEA8E" }, + { WinoIconGlyph.SpecialFolderDraft, "\uF3BE" }, + { WinoIconGlyph.SpecialFolderArchive, "\uE066" }, + { WinoIconGlyph.SpecialFolderDeleted, "\uEEA6" }, + { WinoIconGlyph.SpecialFolderJunk, "\uF140" }, + { WinoIconGlyph.SpecialFolderChat, "\uE8BD" }, + { WinoIconGlyph.SpecialFolderCategory, "\uF599" }, + { WinoIconGlyph.SpecialFolderUnread, "\uF529" }, + { WinoIconGlyph.SpecialFolderForums, "\uF5B8" }, + { WinoIconGlyph.SpecialFolderUpdated, "\uF565" }, + { WinoIconGlyph.SpecialFolderPersonal, "\uE25A" }, + { WinoIconGlyph.SpecialFolderPromotions, "\uF7B6" }, + { WinoIconGlyph.SpecialFolderSocial, "\uEEEB" }, + { WinoIconGlyph.SpecialFolderOther, "\uE643" }, + { WinoIconGlyph.SpecialFolderMore, "\uF0F4" }, + { WinoIconGlyph.Microsoft, "\uE904" }, + { WinoIconGlyph.Google, "\uE905" }, + { WinoIconGlyph.NewMail, "\uF107" }, + { WinoIconGlyph.TurnOfNotifications, "\uF11D" }, + { WinoIconGlyph.Rename, "\uF668" }, + { WinoIconGlyph.EmptyFolder, "\uE47E" }, + { WinoIconGlyph.DontSync, "\uF195" }, + { WinoIconGlyph.Move, "\uE7B8" }, + { WinoIconGlyph.Mail, "\uF509" }, + { WinoIconGlyph.More, "\uE824" }, + { WinoIconGlyph.CustomServer, "\uF509" }, + { WinoIconGlyph.Print, "\uE922" }, + { WinoIconGlyph.Attachment, "\uE723" }, + { WinoIconGlyph.SortTextDesc, "\U000F3606" }, + { WinoIconGlyph.SortLinesDesc, "\U000F038A" }, + { WinoIconGlyph.Certificate, "\uEB95" }, + { WinoIconGlyph.OpenInNewWindow, "\uE8A7" }, + { WinoIconGlyph.Message, "\uE8BD" }, + { WinoIconGlyph.New, "\U000F002A" }, + { WinoIconGlyph.Blocked,"\uF140" }, + { WinoIconGlyph.IMAP, "\uE715" }, + { WinoIconGlyph.Calendar, "\uE912" }, + { WinoIconGlyph.CalendarToday, "\uE911" }, + { WinoIconGlyph.CalendarDay, "\uE913" }, + { WinoIconGlyph.CalendarWeek, "\uE914" }, + { WinoIconGlyph.CalendarMonth, "\uE91c" }, + { WinoIconGlyph.CalendarYear, "\uE917" }, + { WinoIconGlyph.WeatherBlow, "\uE907" }, + { WinoIconGlyph.WeatherCloudy, "\uE920" }, + { WinoIconGlyph.WeatherSunny, "\uE90e" }, + { WinoIconGlyph.WeatherRainy, "\uE908" }, + { WinoIconGlyph.WeatherSnowy, "\uE90a" }, + { WinoIconGlyph.WeatherSnowShowerAtNight, "\uE90c" }, + { WinoIconGlyph.WeatherThunderstorm, "\uE906" }, + { WinoIconGlyph.CalendarEventRepeat, "\uE915" }, + { WinoIconGlyph.CalendarEventMuiltiDay, "\uE91b" }, + { WinoIconGlyph.Reminder, "\uE918" }, + { WinoIconGlyph.CalendarAttendee, "\uE91a" }, + { WinoIconGlyph.CalendarSync, "\uE91d" }, + { WinoIconGlyph.CalendarError, "\uE916" }, + { WinoIconGlyph.CalendarAttendees, "\uE929" }, + { WinoIconGlyph.EventEditSeries, "\uE92A" }, + { WinoIconGlyph.EventTentative, "\uE928" }, + { WinoIconGlyph.EventAccept, "\uE925" }, + { WinoIconGlyph.EventRespond, "\uE924" }, + { WinoIconGlyph.EventReminder, "\uE923" }, + { WinoIconGlyph.EventJoinOnline, "\uE926" }, + { WinoIconGlyph.ViewMessageSource, "\uE943" }, + { WinoIconGlyph.Apple, "\uE92B" }, + { WinoIconGlyph.Yahoo, "\uE92C" } + }; } diff --git a/Wino.Core.UWP/Controls/EqualGridPanel.cs b/Wino.Core.UWP/Controls/EqualGridPanel.cs index b2687f95..e87eee1f 100644 --- a/Wino.Core.UWP/Controls/EqualGridPanel.cs +++ b/Wino.Core.UWP/Controls/EqualGridPanel.cs @@ -2,86 +2,85 @@ using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; -namespace Wino.Core.UWP.Controls +namespace Wino.Core.UWP.Controls; + +public partial class EqualGridPanel : Panel { - public partial class EqualGridPanel : Panel + public int Rows { - public int Rows + get { return (int)GetValue(RowsProperty); } + set { SetValue(RowsProperty, value); } + } + + public static readonly DependencyProperty RowsProperty = + DependencyProperty.Register( + nameof(Rows), + typeof(int), + typeof(EqualGridPanel), + new PropertyMetadata(1, OnLayoutPropertyChanged)); + + public int Columns + { + get { return (int)GetValue(ColumnsProperty); } + set { SetValue(ColumnsProperty, value); } + } + + public static readonly DependencyProperty ColumnsProperty = + DependencyProperty.Register( + nameof(Columns), + typeof(int), + typeof(EqualGridPanel), + new PropertyMetadata(1, OnLayoutPropertyChanged)); + + private static void OnLayoutPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is EqualGridPanel panel) { - get { return (int)GetValue(RowsProperty); } - set { SetValue(RowsProperty, value); } - } - - public static readonly DependencyProperty RowsProperty = - DependencyProperty.Register( - nameof(Rows), - typeof(int), - typeof(EqualGridPanel), - new PropertyMetadata(1, OnLayoutPropertyChanged)); - - public int Columns - { - get { return (int)GetValue(ColumnsProperty); } - set { SetValue(ColumnsProperty, value); } - } - - public static readonly DependencyProperty ColumnsProperty = - DependencyProperty.Register( - nameof(Columns), - typeof(int), - typeof(EqualGridPanel), - new PropertyMetadata(1, OnLayoutPropertyChanged)); - - private static void OnLayoutPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - if (d is EqualGridPanel panel) - { - panel.InvalidateMeasure(); - panel.InvalidateArrange(); - } - } - - protected override Size MeasureOverride(Size availableSize) - { - if (Rows <= 0 || Columns <= 0) - { - return new Size(0, 0); - } - - double cellWidth = availableSize.Width / Columns; - double cellHeight = availableSize.Height / Rows; - - foreach (UIElement child in Children) - { - child.Measure(new Size(cellWidth, cellHeight)); - } - - return availableSize; - } - - protected override Size ArrangeOverride(Size finalSize) - { - if (Rows <= 0 || Columns <= 0) - { - return new Size(0, 0); - } - - double cellWidth = finalSize.Width / Columns; - double cellHeight = finalSize.Height / Rows; - - for (int i = 0; i < Children.Count; i++) - { - int row = i / Columns; - int column = i % Columns; - - double x = column * cellWidth; - double y = row * cellHeight; - - Rect rect = new Rect(x, y, cellWidth, cellHeight); - Children[i].Arrange(rect); - } - - return finalSize; + panel.InvalidateMeasure(); + panel.InvalidateArrange(); } } + + protected override Size MeasureOverride(Size availableSize) + { + if (Rows <= 0 || Columns <= 0) + { + return new Size(0, 0); + } + + double cellWidth = availableSize.Width / Columns; + double cellHeight = availableSize.Height / Rows; + + foreach (UIElement child in Children) + { + child.Measure(new Size(cellWidth, cellHeight)); + } + + return availableSize; + } + + protected override Size ArrangeOverride(Size finalSize) + { + if (Rows <= 0 || Columns <= 0) + { + return new Size(0, 0); + } + + double cellWidth = finalSize.Width / Columns; + double cellHeight = finalSize.Height / Rows; + + for (int i = 0; i < Children.Count; i++) + { + int row = i / Columns; + int column = i % Columns; + + double x = column * cellWidth; + double y = row * cellHeight; + + Rect rect = new Rect(x, y, cellWidth, cellHeight); + Children[i].Arrange(rect); + } + + return finalSize; + } } diff --git a/Wino.Core.UWP/Controls/WinoAppTitleBar.xaml.cs b/Wino.Core.UWP/Controls/WinoAppTitleBar.xaml.cs index a361dff9..734650a6 100644 --- a/Wino.Core.UWP/Controls/WinoAppTitleBar.xaml.cs +++ b/Wino.Core.UWP/Controls/WinoAppTitleBar.xaml.cs @@ -4,193 +4,208 @@ using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Wino.Core.Domain.Enums; -namespace Wino.Core.UWP.Controls +namespace Wino.Core.UWP.Controls; + +public sealed partial class WinoAppTitleBar : UserControl { - public sealed partial class WinoAppTitleBar : UserControl + public event TypedEventHandler BackButtonClicked; + + public static readonly DependencyProperty IsRenderingPaneVisibleProperty = DependencyProperty.Register(nameof(IsRenderingPaneVisible), typeof(bool), typeof(WinoAppTitleBar), new PropertyMetadata(false, OnDrawingPropertyChanged)); + public static readonly DependencyProperty IsReaderNarrowedProperty = DependencyProperty.Register(nameof(IsReaderNarrowed), typeof(bool), typeof(WinoAppTitleBar), new PropertyMetadata(false, OnIsReaderNarrowedChanged)); + public static readonly DependencyProperty IsBackButtonVisibleProperty = DependencyProperty.Register(nameof(IsBackButtonVisible), typeof(bool), typeof(WinoAppTitleBar), new PropertyMetadata(false, OnDrawingPropertyChanged)); + public static readonly DependencyProperty OpenPaneLengthProperty = DependencyProperty.Register(nameof(OpenPaneLength), typeof(double), typeof(WinoAppTitleBar), new PropertyMetadata(0d, OnDrawingPropertyChanged)); + public static readonly DependencyProperty IsNavigationPaneOpenProperty = DependencyProperty.Register(nameof(IsNavigationPaneOpen), typeof(bool), typeof(WinoAppTitleBar), new PropertyMetadata(false, OnDrawingPropertyChanged)); + public static readonly DependencyProperty NavigationViewDisplayModeProperty = DependencyProperty.Register(nameof(NavigationViewDisplayMode), typeof(Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode), typeof(WinoAppTitleBar), new PropertyMetadata(Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Compact, OnDrawingPropertyChanged)); + public static readonly DependencyProperty ShellFrameContentProperty = DependencyProperty.Register(nameof(ShellFrameContent), typeof(UIElement), typeof(WinoAppTitleBar), new PropertyMetadata(null, OnDrawingPropertyChanged)); + public static readonly DependencyProperty SystemReservedProperty = DependencyProperty.Register(nameof(SystemReserved), typeof(double), typeof(WinoAppTitleBar), new PropertyMetadata(0, OnDrawingPropertyChanged)); + public static readonly DependencyProperty CoreWindowTextProperty = DependencyProperty.Register(nameof(CoreWindowText), typeof(string), typeof(WinoAppTitleBar), new PropertyMetadata(string.Empty, OnDrawingPropertyChanged)); + public static readonly DependencyProperty ReadingPaneLengthProperty = DependencyProperty.Register(nameof(ReadingPaneLength), typeof(double), typeof(WinoAppTitleBar), new PropertyMetadata(420d, OnDrawingPropertyChanged)); + public static readonly DependencyProperty ConnectionStatusProperty = DependencyProperty.Register(nameof(ConnectionStatus), typeof(WinoServerConnectionStatus), typeof(WinoAppTitleBar), new PropertyMetadata(WinoServerConnectionStatus.None, new PropertyChangedCallback(OnConnectionStatusChanged))); + public static readonly DependencyProperty ReconnectCommandProperty = DependencyProperty.Register(nameof(ReconnectCommand), typeof(ICommand), typeof(WinoAppTitleBar), new PropertyMetadata(null)); + public static readonly DependencyProperty ShrinkShellContentOnExpansionProperty = DependencyProperty.Register(nameof(ShrinkShellContentOnExpansion), typeof(bool), typeof(WinoAppTitleBar), new PropertyMetadata(true)); + public static readonly DependencyProperty IsDragAreaProperty = DependencyProperty.Register(nameof(IsDragArea), typeof(bool), typeof(WinoAppTitleBar), new PropertyMetadata(false, new PropertyChangedCallback(OnIsDragAreaChanged))); + public static readonly DependencyProperty IsShellFrameContentVisibleProperty = DependencyProperty.Register(nameof(IsShellFrameContentVisible), typeof(bool), typeof(WinoAppTitleBar), new PropertyMetadata(true)); + public static readonly DependencyProperty IsMenuButtonVisibleProperty = DependencyProperty.Register(nameof(IsMenuButtonVisible), typeof(bool), typeof(WinoAppTitleBar), new PropertyMetadata(true)); + + public bool IsShellFrameContentVisible { - public event TypedEventHandler BackButtonClicked; + get { return (bool)GetValue(IsShellFrameContentVisibleProperty); } + set { SetValue(IsShellFrameContentVisibleProperty, value); } + } - public static readonly DependencyProperty IsRenderingPaneVisibleProperty = DependencyProperty.Register(nameof(IsRenderingPaneVisible), typeof(bool), typeof(WinoAppTitleBar), new PropertyMetadata(false, OnDrawingPropertyChanged)); - public static readonly DependencyProperty IsReaderNarrowedProperty = DependencyProperty.Register(nameof(IsReaderNarrowed), typeof(bool), typeof(WinoAppTitleBar), new PropertyMetadata(false, OnIsReaderNarrowedChanged)); - public static readonly DependencyProperty IsBackButtonVisibleProperty = DependencyProperty.Register(nameof(IsBackButtonVisible), typeof(bool), typeof(WinoAppTitleBar), new PropertyMetadata(false, OnDrawingPropertyChanged)); - public static readonly DependencyProperty OpenPaneLengthProperty = DependencyProperty.Register(nameof(OpenPaneLength), typeof(double), typeof(WinoAppTitleBar), new PropertyMetadata(0d, OnDrawingPropertyChanged)); - public static readonly DependencyProperty IsNavigationPaneOpenProperty = DependencyProperty.Register(nameof(IsNavigationPaneOpen), typeof(bool), typeof(WinoAppTitleBar), new PropertyMetadata(false, OnDrawingPropertyChanged)); - public static readonly DependencyProperty NavigationViewDisplayModeProperty = DependencyProperty.Register(nameof(NavigationViewDisplayMode), typeof(Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode), typeof(WinoAppTitleBar), new PropertyMetadata(Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Compact, OnDrawingPropertyChanged)); - public static readonly DependencyProperty ShellFrameContentProperty = DependencyProperty.Register(nameof(ShellFrameContent), typeof(UIElement), typeof(WinoAppTitleBar), new PropertyMetadata(null, OnDrawingPropertyChanged)); - public static readonly DependencyProperty SystemReservedProperty = DependencyProperty.Register(nameof(SystemReserved), typeof(double), typeof(WinoAppTitleBar), new PropertyMetadata(0, OnDrawingPropertyChanged)); - public static readonly DependencyProperty CoreWindowTextProperty = DependencyProperty.Register(nameof(CoreWindowText), typeof(string), typeof(WinoAppTitleBar), new PropertyMetadata(string.Empty, OnDrawingPropertyChanged)); - public static readonly DependencyProperty ReadingPaneLengthProperty = DependencyProperty.Register(nameof(ReadingPaneLength), typeof(double), typeof(WinoAppTitleBar), new PropertyMetadata(420d, OnDrawingPropertyChanged)); - public static readonly DependencyProperty ConnectionStatusProperty = DependencyProperty.Register(nameof(ConnectionStatus), typeof(WinoServerConnectionStatus), typeof(WinoAppTitleBar), new PropertyMetadata(WinoServerConnectionStatus.None, new PropertyChangedCallback(OnConnectionStatusChanged))); - public static readonly DependencyProperty ReconnectCommandProperty = DependencyProperty.Register(nameof(ReconnectCommand), typeof(ICommand), typeof(WinoAppTitleBar), new PropertyMetadata(null)); - public static readonly DependencyProperty ShrinkShellContentOnExpansionProperty = DependencyProperty.Register(nameof(ShrinkShellContentOnExpansion), typeof(bool), typeof(WinoAppTitleBar), new PropertyMetadata(true)); - public static readonly DependencyProperty IsDragAreaProperty = DependencyProperty.Register(nameof(IsDragArea), typeof(bool), typeof(WinoAppTitleBar), new PropertyMetadata(false, new PropertyChangedCallback(OnIsDragAreaChanged))); - public static readonly DependencyProperty IsShellFrameContentVisibleProperty = DependencyProperty.Register(nameof(IsShellFrameContentVisible), typeof(bool), typeof(WinoAppTitleBar), new PropertyMetadata(true)); - public static readonly DependencyProperty IsMenuButtonVisibleProperty = DependencyProperty.Register(nameof(IsMenuButtonVisible), typeof(bool), typeof(WinoAppTitleBar), new PropertyMetadata(true)); + public ICommand ReconnectCommand + { + get { return (ICommand)GetValue(ReconnectCommandProperty); } + set { SetValue(ReconnectCommandProperty, value); } + } - public bool IsShellFrameContentVisible + public WinoServerConnectionStatus ConnectionStatus + { + get { return (WinoServerConnectionStatus)GetValue(ConnectionStatusProperty); } + set { SetValue(ConnectionStatusProperty, value); } + } + + public string CoreWindowText + { + get { return (string)GetValue(CoreWindowTextProperty); } + set { SetValue(CoreWindowTextProperty, value); } + } + + public bool IsDragArea + { + get { return (bool)GetValue(IsDragAreaProperty); } + set { SetValue(IsDragAreaProperty, value); } + } + + + public double SystemReserved + { + get { return (double)GetValue(SystemReservedProperty); } + set { SetValue(SystemReservedProperty, value); } + } + + public UIElement ShellFrameContent + { + get { return (UIElement)GetValue(ShellFrameContentProperty); } + set { SetValue(ShellFrameContentProperty, value); } + } + + public Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode NavigationViewDisplayMode + { + get { return (Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode)GetValue(NavigationViewDisplayModeProperty); } + set { SetValue(NavigationViewDisplayModeProperty, value); } + } + + public bool ShrinkShellContentOnExpansion + { + get { return (bool)GetValue(ShrinkShellContentOnExpansionProperty); } + set { SetValue(ShrinkShellContentOnExpansionProperty, value); } + } + + public bool IsNavigationPaneOpen + { + get { return (bool)GetValue(IsNavigationPaneOpenProperty); } + set { SetValue(IsNavigationPaneOpenProperty, value); } + } + + public double OpenPaneLength + { + get { return (double)GetValue(OpenPaneLengthProperty); } + set { SetValue(OpenPaneLengthProperty, value); } + } + + + + public bool IsMenuButtonVisible + { + get { return (bool)GetValue(IsMenuButtonVisibleProperty); } + set { SetValue(IsMenuButtonVisibleProperty, value); } + } + + + public bool IsBackButtonVisible + { + get { return (bool)GetValue(IsBackButtonVisibleProperty); } + set { SetValue(IsBackButtonVisibleProperty, value); } + } + + public bool IsReaderNarrowed + { + get { return (bool)GetValue(IsReaderNarrowedProperty); } + set { SetValue(IsReaderNarrowedProperty, value); } + } + + public bool IsRenderingPaneVisible + { + get { return (bool)GetValue(IsRenderingPaneVisibleProperty); } + set { SetValue(IsRenderingPaneVisibleProperty, value); } + } + + public double ReadingPaneLength + { + get { return (double)GetValue(ReadingPaneLengthProperty); } + set { SetValue(ReadingPaneLengthProperty, value); } + } + + private static void OnIsReaderNarrowedChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) + { + if (obj is WinoAppTitleBar bar) { - get { return (bool)GetValue(IsShellFrameContentVisibleProperty); } - set { SetValue(IsShellFrameContentVisibleProperty, value); } + bar.DrawTitleBar(); } + } - public ICommand ReconnectCommand + private static void OnDrawingPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) + { + if (obj is WinoAppTitleBar bar) { - get { return (ICommand)GetValue(ReconnectCommandProperty); } - set { SetValue(ReconnectCommandProperty, value); } + bar.DrawTitleBar(); } + } - public WinoServerConnectionStatus ConnectionStatus + private static void OnConnectionStatusChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) + { + if (obj is WinoAppTitleBar bar) { - get { return (WinoServerConnectionStatus)GetValue(ConnectionStatusProperty); } - set { SetValue(ConnectionStatusProperty, value); } + bar.UpdateConnectionStatus(); } + } - public string CoreWindowText + private static void OnIsDragAreaChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) + { + if (obj is WinoAppTitleBar bar) { - get { return (string)GetValue(CoreWindowTextProperty); } - set { SetValue(CoreWindowTextProperty, value); } + bar.SetDragArea(); } + } - public bool IsDragArea + private void SetDragArea() + { + if (IsDragArea) { - get { return (bool)GetValue(IsDragAreaProperty); } - set { SetValue(IsDragAreaProperty, value); } + Window.Current.SetTitleBar(dragbar); } + } + private void UpdateConnectionStatus() + { - public double SystemReserved + } + + private void DrawTitleBar() + { + UpdateLayout(); + + CoreWindowTitleTextBlock.Visibility = Visibility.Collapsed; + ShellContentContainer.Width = double.NaN; + ShellContentContainer.Margin = new Thickness(0, 0, 0, 0); + ShellContentContainer.HorizontalAlignment = HorizontalAlignment.Stretch; + + EmptySpaceWidth.Width = new GridLength(1, GridUnitType.Star); + + // Menu is not visible. + if (NavigationViewDisplayMode == Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Minimal) { - get { return (double)GetValue(SystemReservedProperty); } - set { SetValue(SystemReservedProperty, value); } + } - - public UIElement ShellFrameContent + else if (NavigationViewDisplayMode == Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Compact) { - get { return (UIElement)GetValue(ShellFrameContentProperty); } - set { SetValue(ShellFrameContentProperty, value); } - } + // Icons are visible. - public Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode NavigationViewDisplayMode - { - get { return (Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode)GetValue(NavigationViewDisplayModeProperty); } - set { SetValue(NavigationViewDisplayModeProperty, value); } - } - - public bool ShrinkShellContentOnExpansion - { - get { return (bool)GetValue(ShrinkShellContentOnExpansionProperty); } - set { SetValue(ShrinkShellContentOnExpansionProperty, value); } - } - - public bool IsNavigationPaneOpen - { - get { return (bool)GetValue(IsNavigationPaneOpenProperty); } - set { SetValue(IsNavigationPaneOpenProperty, value); } - } - - public double OpenPaneLength - { - get { return (double)GetValue(OpenPaneLengthProperty); } - set { SetValue(OpenPaneLengthProperty, value); } - } - - - - public bool IsMenuButtonVisible - { - get { return (bool)GetValue(IsMenuButtonVisibleProperty); } - set { SetValue(IsMenuButtonVisibleProperty, value); } - } - - - public bool IsBackButtonVisible - { - get { return (bool)GetValue(IsBackButtonVisibleProperty); } - set { SetValue(IsBackButtonVisibleProperty, value); } - } - - public bool IsReaderNarrowed - { - get { return (bool)GetValue(IsReaderNarrowedProperty); } - set { SetValue(IsReaderNarrowedProperty, value); } - } - - public bool IsRenderingPaneVisible - { - get { return (bool)GetValue(IsRenderingPaneVisibleProperty); } - set { SetValue(IsRenderingPaneVisibleProperty, value); } - } - - public double ReadingPaneLength - { - get { return (double)GetValue(ReadingPaneLengthProperty); } - set { SetValue(ReadingPaneLengthProperty, value); } - } - - private static void OnIsReaderNarrowedChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) - { - if (obj is WinoAppTitleBar bar) + if (!IsReaderNarrowed && ShrinkShellContentOnExpansion) { - bar.DrawTitleBar(); + ShellContentContainer.HorizontalAlignment = HorizontalAlignment.Left; + ShellContentContainer.Width = ReadingPaneLength; } } - - private static void OnDrawingPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) + else if (NavigationViewDisplayMode == Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Expanded) { - if (obj is WinoAppTitleBar bar) + if (IsNavigationPaneOpen) { - bar.DrawTitleBar(); - } - } + CoreWindowTitleTextBlock.Visibility = Visibility.Visible; - private static void OnConnectionStatusChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) - { - if (obj is WinoAppTitleBar bar) - { - bar.UpdateConnectionStatus(); - } - } - - private static void OnIsDragAreaChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) - { - if (obj is WinoAppTitleBar bar) - { - bar.SetDragArea(); - } - } - - private void SetDragArea() - { - if (IsDragArea) - { - Window.Current.SetTitleBar(dragbar); - } - } - - private void UpdateConnectionStatus() - { - - } - - private void DrawTitleBar() - { - UpdateLayout(); - - CoreWindowTitleTextBlock.Visibility = Visibility.Collapsed; - ShellContentContainer.Width = double.NaN; - ShellContentContainer.Margin = new Thickness(0, 0, 0, 0); - ShellContentContainer.HorizontalAlignment = HorizontalAlignment.Stretch; - - EmptySpaceWidth.Width = new GridLength(1, GridUnitType.Star); - - // Menu is not visible. - if (NavigationViewDisplayMode == Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Minimal) - { - - } - else if (NavigationViewDisplayMode == Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Compact) - { - // Icons are visible. + // LMargin = OpenPaneLength - LeftMenuStackPanel + ShellContentContainer.Margin = new Thickness(OpenPaneLength - LeftMenuStackPanel.ActualSize.X, 0, 0, 0); if (!IsReaderNarrowed && ShrinkShellContentOnExpansion) { @@ -198,59 +213,43 @@ namespace Wino.Core.UWP.Controls ShellContentContainer.Width = ReadingPaneLength; } } - else if (NavigationViewDisplayMode == Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Expanded) + else { - if (IsNavigationPaneOpen) + if (ShrinkShellContentOnExpansion) { - CoreWindowTitleTextBlock.Visibility = Visibility.Visible; - - // LMargin = OpenPaneLength - LeftMenuStackPanel - ShellContentContainer.Margin = new Thickness(OpenPaneLength - LeftMenuStackPanel.ActualSize.X, 0, 0, 0); - - if (!IsReaderNarrowed && ShrinkShellContentOnExpansion) - { - ShellContentContainer.HorizontalAlignment = HorizontalAlignment.Left; - ShellContentContainer.Width = ReadingPaneLength; - } + EmptySpaceWidth.Width = new GridLength(ReadingPaneLength, GridUnitType.Pixel); } else { - if (ShrinkShellContentOnExpansion) - { - EmptySpaceWidth.Width = new GridLength(ReadingPaneLength, GridUnitType.Pixel); - } - else - { - EmptySpaceWidth.Width = new GridLength(ReadingPaneLength, GridUnitType.Star); - } + EmptySpaceWidth.Width = new GridLength(ReadingPaneLength, GridUnitType.Star); } } } + } - public WinoAppTitleBar() - { - InitializeComponent(); - } + public WinoAppTitleBar() + { + InitializeComponent(); + } - private void BackClicked(object sender, RoutedEventArgs e) - { - BackButtonClicked?.Invoke(this, e); - } + private void BackClicked(object sender, RoutedEventArgs e) + { + BackButtonClicked?.Invoke(this, e); + } - private void PaneClicked(object sender, RoutedEventArgs e) - { - IsNavigationPaneOpen = !IsNavigationPaneOpen; - } + private void PaneClicked(object sender, RoutedEventArgs e) + { + IsNavigationPaneOpen = !IsNavigationPaneOpen; + } - private void TitlebarSizeChanged(object sender, SizeChangedEventArgs e) => DrawTitleBar(); + private void TitlebarSizeChanged(object sender, SizeChangedEventArgs e) => DrawTitleBar(); - private void ReconnectClicked(object sender, RoutedEventArgs e) - { - // Close the popup for reconnect button. - ReconnectFlyout.Hide(); + private void ReconnectClicked(object sender, RoutedEventArgs e) + { + // Close the popup for reconnect button. + ReconnectFlyout.Hide(); - // Execute the reconnect command. - ReconnectCommand?.Execute(null); - } + // Execute the reconnect command. + ReconnectCommand?.Execute(null); } } diff --git a/Wino.Core.UWP/Controls/WinoFontIcon.cs b/Wino.Core.UWP/Controls/WinoFontIcon.cs index 98472ed7..da9fe61e 100644 --- a/Wino.Core.UWP/Controls/WinoFontIcon.cs +++ b/Wino.Core.UWP/Controls/WinoFontIcon.cs @@ -1,136 +1,135 @@ using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; -namespace Wino.Core.UWP.Controls +namespace Wino.Core.UWP.Controls; + +public enum WinoIconGlyph { - public enum WinoIconGlyph + None, + NewMail, + Google, + Microsoft, + CustomServer, + Archive, + UnArchive, + Reply, + ReplyAll, + LightEditor, + DarkEditor, + Delete, + Move, + Mail, + Draft, + Flag, + ClearFlag, + Folder, + Forward, + Inbox, + MarkRead, + MarkUnread, + Send, + Save, + Sync, + MultiSelect, + Zoom, + Pin, + UnPin, + Ignore, + Star, + CreateFolder, + More, + Find, + SpecialFolderInbox, + SpecialFolderStarred, + SpecialFolderImportant, + SpecialFolderSent, + SpecialFolderDraft, + SpecialFolderArchive, + SpecialFolderDeleted, + SpecialFolderJunk, + SpecialFolderChat, + SpecialFolderCategory, + SpecialFolderUnread, + SpecialFolderForums, + SpecialFolderUpdated, + SpecialFolderPersonal, + SpecialFolderPromotions, + SpecialFolderSocial, + SpecialFolderOther, + SpecialFolderMore, + TurnOfNotifications, + EmptyFolder, + Rename, + DontSync, + Attachment, + SortTextDesc, + SortLinesDesc, + Certificate, + OpenInNewWindow, + Blocked, + Message, + New, + IMAP, + Print, + Calendar, + CalendarToday, + CalendarDay, + CalendarWeek, + CalendarWorkWeek, + CalendarMonth, + CalendarYear, + WeatherBlow, + WeatherCloudy, + WeatherSunny, + WeatherRainy, + WeatherSnowy, + WeatherSnowShowerAtNight, + WeatherThunderstorm, + CalendarEventRepeat, + CalendarEventMuiltiDay, + CalendarError, + Reminder, + CalendarAttendee, + CalendarAttendees, + CalendarSync, + EventRespond, + EventAccept, + EventTentative, + EventDecline, + EventReminder, + EventEditSeries, + EventJoinOnline, + ViewMessageSource, + Apple, + Yahoo +} + +public partial class WinoFontIcon : FontIcon +{ + public WinoIconGlyph Icon { - None, - NewMail, - Google, - Microsoft, - CustomServer, - Archive, - UnArchive, - Reply, - ReplyAll, - LightEditor, - DarkEditor, - Delete, - Move, - Mail, - Draft, - Flag, - ClearFlag, - Folder, - Forward, - Inbox, - MarkRead, - MarkUnread, - Send, - Save, - Sync, - MultiSelect, - Zoom, - Pin, - UnPin, - Ignore, - Star, - CreateFolder, - More, - Find, - SpecialFolderInbox, - SpecialFolderStarred, - SpecialFolderImportant, - SpecialFolderSent, - SpecialFolderDraft, - SpecialFolderArchive, - SpecialFolderDeleted, - SpecialFolderJunk, - SpecialFolderChat, - SpecialFolderCategory, - SpecialFolderUnread, - SpecialFolderForums, - SpecialFolderUpdated, - SpecialFolderPersonal, - SpecialFolderPromotions, - SpecialFolderSocial, - SpecialFolderOther, - SpecialFolderMore, - TurnOfNotifications, - EmptyFolder, - Rename, - DontSync, - Attachment, - SortTextDesc, - SortLinesDesc, - Certificate, - OpenInNewWindow, - Blocked, - Message, - New, - IMAP, - Print, - Calendar, - CalendarToday, - CalendarDay, - CalendarWeek, - CalendarWorkWeek, - CalendarMonth, - CalendarYear, - WeatherBlow, - WeatherCloudy, - WeatherSunny, - WeatherRainy, - WeatherSnowy, - WeatherSnowShowerAtNight, - WeatherThunderstorm, - CalendarEventRepeat, - CalendarEventMuiltiDay, - CalendarError, - Reminder, - CalendarAttendee, - CalendarAttendees, - CalendarSync, - EventRespond, - EventAccept, - EventTentative, - EventDecline, - EventReminder, - EventEditSeries, - EventJoinOnline, - ViewMessageSource, - Apple, - Yahoo + get { return (WinoIconGlyph)GetValue(IconProperty); } + set { SetValue(IconProperty, value); } } - public partial class WinoFontIcon : FontIcon + public static readonly DependencyProperty IconProperty = DependencyProperty.Register(nameof(Icon), typeof(WinoIconGlyph), typeof(WinoFontIcon), new PropertyMetadata(WinoIconGlyph.Flag, OnIconChanged)); + + public WinoFontIcon() { - public WinoIconGlyph Icon - { - get { return (WinoIconGlyph)GetValue(IconProperty); } - set { SetValue(IconProperty, value); } - } + FontFamily = new Windows.UI.Xaml.Media.FontFamily("ms-appx:///Wino.Core.UWP/Assets/WinoIcons.ttf#WinoIcons"); + FontSize = 32; + } - public static readonly DependencyProperty IconProperty = DependencyProperty.Register(nameof(Icon), typeof(WinoIconGlyph), typeof(WinoFontIcon), new PropertyMetadata(WinoIconGlyph.Flag, OnIconChanged)); - - public WinoFontIcon() + private static void OnIconChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) + { + if (obj is WinoFontIcon fontIcon) { - FontFamily = new Windows.UI.Xaml.Media.FontFamily("ms-appx:///Wino.Core.UWP/Assets/WinoIcons.ttf#WinoIcons"); - FontSize = 32; + fontIcon.UpdateGlyph(); } + } - private static void OnIconChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) - { - if (obj is WinoFontIcon fontIcon) - { - fontIcon.UpdateGlyph(); - } - } - - private void UpdateGlyph() - { - Glyph = ControlConstants.WinoIconFontDictionary[Icon]; - } + private void UpdateGlyph() + { + Glyph = ControlConstants.WinoIconFontDictionary[Icon]; } } diff --git a/Wino.Core.UWP/Controls/WinoFontIconSource.cs b/Wino.Core.UWP/Controls/WinoFontIconSource.cs index 2b433e79..7b2b0d1a 100644 --- a/Wino.Core.UWP/Controls/WinoFontIconSource.cs +++ b/Wino.Core.UWP/Controls/WinoFontIconSource.cs @@ -1,35 +1,34 @@ using Windows.UI.Xaml; using Wino.Core.UWP.Controls; -namespace Wino.Controls +namespace Wino.Controls; + +public partial class WinoFontIconSource : Microsoft.UI.Xaml.Controls.FontIconSource { - public partial class WinoFontIconSource : Microsoft.UI.Xaml.Controls.FontIconSource + public WinoIconGlyph Icon { - public WinoIconGlyph Icon - { - get { return (WinoIconGlyph)GetValue(IconProperty); } - set { SetValue(IconProperty, value); } - } + get { return (WinoIconGlyph)GetValue(IconProperty); } + set { SetValue(IconProperty, value); } + } - public static readonly DependencyProperty IconProperty = DependencyProperty.Register(nameof(Icon), typeof(WinoIconGlyph), typeof(WinoFontIconSource), new PropertyMetadata(WinoIconGlyph.Flag, OnIconChanged)); + public static readonly DependencyProperty IconProperty = DependencyProperty.Register(nameof(Icon), typeof(WinoIconGlyph), typeof(WinoFontIconSource), new PropertyMetadata(WinoIconGlyph.Flag, OnIconChanged)); - public WinoFontIconSource() - { - FontFamily = new Windows.UI.Xaml.Media.FontFamily("ms-appx:///Assets/WinoIcons.ttf#WinoIcons"); - FontSize = 32; - } + public WinoFontIconSource() + { + FontFamily = new Windows.UI.Xaml.Media.FontFamily("ms-appx:///Assets/WinoIcons.ttf#WinoIcons"); + FontSize = 32; + } - private static void OnIconChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) + private static void OnIconChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) + { + if (obj is WinoFontIconSource fontIcon) { - if (obj is WinoFontIconSource fontIcon) - { - fontIcon.UpdateGlyph(); - } - } - - private void UpdateGlyph() - { - Glyph = ControlConstants.WinoIconFontDictionary[Icon]; + fontIcon.UpdateGlyph(); } } + + private void UpdateGlyph() + { + Glyph = ControlConstants.WinoIconFontDictionary[Icon]; + } } diff --git a/Wino.Core.UWP/Controls/WinoInfoBar.cs b/Wino.Core.UWP/Controls/WinoInfoBar.cs index 7eb788fd..4b6f60b0 100644 --- a/Wino.Core.UWP/Controls/WinoInfoBar.cs +++ b/Wino.Core.UWP/Controls/WinoInfoBar.cs @@ -5,87 +5,86 @@ using Microsoft.UI.Xaml.Controls; using Windows.UI.Xaml; using Wino.Core.Domain.Enums; -namespace Wino.Core.UWP.Controls +namespace Wino.Core.UWP.Controls; + +public partial class WinoInfoBar : InfoBar { - public partial class WinoInfoBar : InfoBar + public static readonly DependencyProperty AnimationTypeProperty = DependencyProperty.Register(nameof(AnimationType), typeof(InfoBarAnimationType), typeof(WinoInfoBar), new PropertyMetadata(InfoBarAnimationType.SlideFromRightToLeft)); + public static readonly DependencyProperty DismissIntervalProperty = DependencyProperty.Register(nameof(DismissInterval), typeof(int), typeof(WinoInfoBar), new PropertyMetadata(5, new PropertyChangedCallback(OnDismissIntervalChanged))); + + public InfoBarAnimationType AnimationType { - public static readonly DependencyProperty AnimationTypeProperty = DependencyProperty.Register(nameof(AnimationType), typeof(InfoBarAnimationType), typeof(WinoInfoBar), new PropertyMetadata(InfoBarAnimationType.SlideFromRightToLeft)); - public static readonly DependencyProperty DismissIntervalProperty = DependencyProperty.Register(nameof(DismissInterval), typeof(int), typeof(WinoInfoBar), new PropertyMetadata(5, new PropertyChangedCallback(OnDismissIntervalChanged))); + get { return (InfoBarAnimationType)GetValue(AnimationTypeProperty); } + set { SetValue(AnimationTypeProperty, value); } + } - public InfoBarAnimationType AnimationType + public int DismissInterval + { + get { return (int)GetValue(DismissIntervalProperty); } + set { SetValue(DismissIntervalProperty, value); } + } + + private readonly DispatcherTimer _dispatcherTimer = new DispatcherTimer(); + + public WinoInfoBar() + { + RegisterPropertyChangedCallback(IsOpenProperty, IsOpenChanged); + + _dispatcherTimer.Interval = TimeSpan.FromSeconds(DismissInterval); + } + + private static void OnDismissIntervalChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) + { + if (obj is WinoInfoBar bar) { - get { return (InfoBarAnimationType)GetValue(AnimationTypeProperty); } - set { SetValue(AnimationTypeProperty, value); } + bar.UpdateInterval(bar.DismissInterval); } + } - public int DismissInterval + private void UpdateInterval(int seconds) => _dispatcherTimer.Interval = TimeSpan.FromSeconds(seconds); + + private async void IsOpenChanged(DependencyObject sender, DependencyProperty dp) + { + if (sender is WinoInfoBar control) { - get { return (int)GetValue(DismissIntervalProperty); } - set { SetValue(DismissIntervalProperty, value); } - } + // Message shown. + if (!control.IsOpen) return; - private readonly DispatcherTimer _dispatcherTimer = new DispatcherTimer(); + Opacity = 1; - public WinoInfoBar() - { - RegisterPropertyChangedCallback(IsOpenProperty, IsOpenChanged); - - _dispatcherTimer.Interval = TimeSpan.FromSeconds(DismissInterval); - } - - private static void OnDismissIntervalChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) - { - if (obj is WinoInfoBar bar) - { - bar.UpdateInterval(bar.DismissInterval); - } - } - - private void UpdateInterval(int seconds) => _dispatcherTimer.Interval = TimeSpan.FromSeconds(seconds); - - private async void IsOpenChanged(DependencyObject sender, DependencyProperty dp) - { - if (sender is WinoInfoBar control) - { - // Message shown. - if (!control.IsOpen) return; - - Opacity = 1; - - _dispatcherTimer.Stop(); - - _dispatcherTimer.Tick -= TimerTick; - _dispatcherTimer.Tick += TimerTick; - - _dispatcherTimer.Start(); - - // Slide from right. - if (AnimationType == InfoBarAnimationType.SlideFromRightToLeft) - { - await AnimationBuilder.Create().Translation(new Vector3(0, 0, 0), new Vector3(150, 0, 0), null, TimeSpan.FromSeconds(0.5)).StartAsync(this); - } - else if (AnimationType == InfoBarAnimationType.SlideFromBottomToTop) - { - await AnimationBuilder.Create().Translation(new Vector3(0, 0, 0), new Vector3(0, 50, 0), null, TimeSpan.FromSeconds(0.5)).StartAsync(this); - } - } - } - - private async void TimerTick(object sender, object e) - { _dispatcherTimer.Stop(); - _dispatcherTimer.Tick -= TimerTick; + _dispatcherTimer.Tick -= TimerTick; + _dispatcherTimer.Tick += TimerTick; + + _dispatcherTimer.Start(); + + // Slide from right. if (AnimationType == InfoBarAnimationType.SlideFromRightToLeft) { - await AnimationBuilder.Create().Translation(new Vector3((float)ActualWidth, 0, 0), new Vector3(0, 0, 0), null, TimeSpan.FromSeconds(0.5)).StartAsync(this); + await AnimationBuilder.Create().Translation(new Vector3(0, 0, 0), new Vector3(150, 0, 0), null, TimeSpan.FromSeconds(0.5)).StartAsync(this); } else if (AnimationType == InfoBarAnimationType.SlideFromBottomToTop) { - await AnimationBuilder.Create().Translation(new Vector3(0, (float)ActualHeight, 0), new Vector3(0, 0, 0), null, TimeSpan.FromSeconds(0.5)).StartAsync(this); + await AnimationBuilder.Create().Translation(new Vector3(0, 0, 0), new Vector3(0, 50, 0), null, TimeSpan.FromSeconds(0.5)).StartAsync(this); } - - IsOpen = false; } } + + private async void TimerTick(object sender, object e) + { + _dispatcherTimer.Stop(); + _dispatcherTimer.Tick -= TimerTick; + + if (AnimationType == InfoBarAnimationType.SlideFromRightToLeft) + { + await AnimationBuilder.Create().Translation(new Vector3((float)ActualWidth, 0, 0), new Vector3(0, 0, 0), null, TimeSpan.FromSeconds(0.5)).StartAsync(this); + } + else if (AnimationType == InfoBarAnimationType.SlideFromBottomToTop) + { + await AnimationBuilder.Create().Translation(new Vector3(0, (float)ActualHeight, 0), new Vector3(0, 0, 0), null, TimeSpan.FromSeconds(0.5)).StartAsync(this); + } + + IsOpen = false; + } } diff --git a/Wino.Core.UWP/Controls/WinoNavigationViewItem.cs b/Wino.Core.UWP/Controls/WinoNavigationViewItem.cs index 5a763e08..10e5149a 100644 --- a/Wino.Core.UWP/Controls/WinoNavigationViewItem.cs +++ b/Wino.Core.UWP/Controls/WinoNavigationViewItem.cs @@ -3,45 +3,44 @@ using Microsoft.UI.Xaml.Controls; using Windows.UI.Xaml; using Windows.UI.Xaml.Hosting; -namespace Wino.Core.UWP.Controls +namespace Wino.Core.UWP.Controls; + +public partial class WinoNavigationViewItem : NavigationViewItem { - public partial class WinoNavigationViewItem : NavigationViewItem + public bool IsDraggingItemOver { - public bool IsDraggingItemOver + get { return (bool)GetValue(IsDraggingItemOverProperty); } + set { SetValue(IsDraggingItemOverProperty, value); } + } + + public static readonly DependencyProperty IsDraggingItemOverProperty = DependencyProperty.Register(nameof(IsDraggingItemOver), typeof(bool), typeof(WinoNavigationViewItem), new PropertyMetadata(false, OnIsDraggingItemOverChanged)); + + private static void OnIsDraggingItemOverChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) + { + if (obj is WinoNavigationViewItem control) + control.UpdateDragEnterState(); + } + + private void UpdateDragEnterState() + { + // TODO: Add animation. Maybe after overriding DragUI in shell? + + //if (IsDraggingItemOver) + //{ + // ScaleAnimation(new System.Numerics.Vector3(1.2f, 1.2f, 1.2f)); + //} + //else + //{ + // ScaleAnimation(new System.Numerics.Vector3(1f, 1f, 1f)); + //} + } + + private void ScaleAnimation(Vector3 vector) + { + if (Content is UIElement content) { - get { return (bool)GetValue(IsDraggingItemOverProperty); } - set { SetValue(IsDraggingItemOverProperty, value); } - } - - public static readonly DependencyProperty IsDraggingItemOverProperty = DependencyProperty.Register(nameof(IsDraggingItemOver), typeof(bool), typeof(WinoNavigationViewItem), new PropertyMetadata(false, OnIsDraggingItemOverChanged)); - - private static void OnIsDraggingItemOverChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) - { - if (obj is WinoNavigationViewItem control) - control.UpdateDragEnterState(); - } - - private void UpdateDragEnterState() - { - // TODO: Add animation. Maybe after overriding DragUI in shell? - - //if (IsDraggingItemOver) - //{ - // ScaleAnimation(new System.Numerics.Vector3(1.2f, 1.2f, 1.2f)); - //} - //else - //{ - // ScaleAnimation(new System.Numerics.Vector3(1f, 1f, 1f)); - //} - } - - private void ScaleAnimation(Vector3 vector) - { - if (Content is UIElement content) - { - var visual = ElementCompositionPreview.GetElementVisual(content); - visual.Scale = vector; - } + var visual = ElementCompositionPreview.GetElementVisual(content); + visual.Scale = vector; } } } diff --git a/Wino.Core.UWP/Converters/GridLengthConverter.cs b/Wino.Core.UWP/Converters/GridLengthConverter.cs index 9ef553a0..367e2f0e 100644 --- a/Wino.Core.UWP/Converters/GridLengthConverter.cs +++ b/Wino.Core.UWP/Converters/GridLengthConverter.cs @@ -2,26 +2,25 @@ using System; using Windows.UI.Xaml; using Windows.UI.Xaml.Data; -namespace Wino.Converters -{ - public partial class GridLengthConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, string language) - { - if (value is double doubleValue) - { - return new GridLength(doubleValue); - } - return new GridLength(1, GridUnitType.Auto); - } +namespace Wino.Converters; - public object ConvertBack(object value, Type targetType, object parameter, string language) +public partial class GridLengthConverter : IValueConverter +{ + public object Convert(object value, Type targetType, object parameter, string language) + { + if (value is double doubleValue) { - if (value is GridLength gridLength) - { - return gridLength.Value; - } - return 0.0; + return new GridLength(doubleValue); } + return new GridLength(1, GridUnitType.Auto); + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + if (value is GridLength gridLength) + { + return gridLength.Value; + } + return 0.0; } } diff --git a/Wino.Core.UWP/Converters/ReverseBooleanConverter.cs b/Wino.Core.UWP/Converters/ReverseBooleanConverter.cs index 2fdf9c35..1e5a9f06 100644 --- a/Wino.Core.UWP/Converters/ReverseBooleanConverter.cs +++ b/Wino.Core.UWP/Converters/ReverseBooleanConverter.cs @@ -1,21 +1,20 @@ using System; using Windows.UI.Xaml.Data; -namespace Wino.Converters +namespace Wino.Converters; + +public partial class ReverseBooleanConverter : IValueConverter { - public partial class ReverseBooleanConverter : IValueConverter + public object Convert(object value, Type targetType, object parameter, string language) { - public object Convert(object value, Type targetType, object parameter, string language) - { - if (value is bool boolval) - return !boolval; + if (value is bool boolval) + return !boolval; - return false; - } + return false; + } - public object ConvertBack(object value, Type targetType, object parameter, string language) - { - throw new NotImplementedException(); - } + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + throw new NotImplementedException(); } } diff --git a/Wino.Core.UWP/Converters/ReverseBooleanToVisibilityConverter.cs b/Wino.Core.UWP/Converters/ReverseBooleanToVisibilityConverter.cs index 3102cea4..39e2e0c3 100644 --- a/Wino.Core.UWP/Converters/ReverseBooleanToVisibilityConverter.cs +++ b/Wino.Core.UWP/Converters/ReverseBooleanToVisibilityConverter.cs @@ -2,18 +2,17 @@ using Windows.UI.Xaml; using Windows.UI.Xaml.Data; -namespace Wino.Converters -{ - public partial class ReverseBooleanToVisibilityConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, string language) - { - return ((bool)value) ? Visibility.Collapsed : Visibility.Visible; - } +namespace Wino.Converters; - public object ConvertBack(object value, Type targetType, object parameter, string language) - { - throw new NotImplementedException(); - } +public partial class ReverseBooleanToVisibilityConverter : IValueConverter +{ + public object Convert(object value, Type targetType, object parameter, string language) + { + return ((bool)value) ? Visibility.Collapsed : Visibility.Visible; + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + throw new NotImplementedException(); } } diff --git a/Wino.Core.UWP/CoreGeneric.xaml.cs b/Wino.Core.UWP/CoreGeneric.xaml.cs index 116a0255..a480b6a2 100644 --- a/Wino.Core.UWP/CoreGeneric.xaml.cs +++ b/Wino.Core.UWP/CoreGeneric.xaml.cs @@ -1,9 +1,8 @@ using Windows.UI.Xaml; -namespace Wino.Core.UWP +namespace Wino.Core.UWP; + +public partial class CoreGeneric : ResourceDictionary { - public partial class CoreGeneric : ResourceDictionary - { - public CoreGeneric() => InitializeComponent(); - } + public CoreGeneric() => InitializeComponent(); } diff --git a/Wino.Core.UWP/CoreUWPContainerSetup.cs b/Wino.Core.UWP/CoreUWPContainerSetup.cs index 9d775080..ddb230b6 100644 --- a/Wino.Core.UWP/CoreUWPContainerSetup.cs +++ b/Wino.Core.UWP/CoreUWPContainerSetup.cs @@ -6,46 +6,45 @@ using Wino.Core.UWP.Services; using Wino.Core.ViewModels; using Wino.Services; -namespace Wino.Core.UWP +namespace Wino.Core.UWP; + +public static class CoreUWPContainerSetup { - public static class CoreUWPContainerSetup + public static void RegisterCoreUWPServices(this IServiceCollection services) { - public static void RegisterCoreUWPServices(this IServiceCollection services) - { - var serverConnectionManager = new WinoServerConnectionManager(); + var serverConnectionManager = new WinoServerConnectionManager(); - services.AddSingleton(serverConnectionManager); - services.AddSingleton>(serverConnectionManager); - services.AddSingleton, ApplicationResourceManager>(); + services.AddSingleton(serverConnectionManager); + services.AddSingleton>(serverConnectionManager); + services.AddSingleton, ApplicationResourceManager>(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); - services.AddSingleton(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddSingleton(); + services.AddSingleton(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddSingleton(); - } + } - public static void RegisterCoreViewModels(this IServiceCollection services) - { - services.AddTransient(typeof(SettingsDialogViewModel)); - services.AddTransient(typeof(PersonalizationPageViewModel)); - services.AddTransient(typeof(SettingOptionsPageViewModel)); - services.AddTransient(typeof(AboutPageViewModel)); - services.AddTransient(typeof(SettingsPageViewModel)); - services.AddTransient(typeof(ManageAccountsPagePageViewModel)); - } + public static void RegisterCoreViewModels(this IServiceCollection services) + { + services.AddTransient(typeof(SettingsDialogViewModel)); + services.AddTransient(typeof(PersonalizationPageViewModel)); + services.AddTransient(typeof(SettingOptionsPageViewModel)); + services.AddTransient(typeof(AboutPageViewModel)); + services.AddTransient(typeof(SettingsPageViewModel)); + services.AddTransient(typeof(ManageAccountsPagePageViewModel)); } } diff --git a/Wino.Core.UWP/Dialogs/AccountCreationDialog.xaml.cs b/Wino.Core.UWP/Dialogs/AccountCreationDialog.xaml.cs index 1e978e53..f10fbc1d 100644 --- a/Wino.Core.UWP/Dialogs/AccountCreationDialog.xaml.cs +++ b/Wino.Core.UWP/Dialogs/AccountCreationDialog.xaml.cs @@ -5,67 +5,66 @@ using Windows.UI.Xaml.Controls; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; -namespace Wino.Dialogs +namespace Wino.Dialogs; + +public sealed partial class AccountCreationDialog : ContentDialog, IAccountCreationDialog { - public sealed partial class AccountCreationDialog : ContentDialog, IAccountCreationDialog + private TaskCompletionSource dialogOpened = new TaskCompletionSource(); + public CancellationTokenSource CancellationTokenSource { get; private set; } + + public AccountCreationDialogState State { - private TaskCompletionSource dialogOpened = new TaskCompletionSource(); - public CancellationTokenSource CancellationTokenSource { get; private set; } + get { return (AccountCreationDialogState)GetValue(StateProperty); } + set { SetValue(StateProperty, value); } + } - public AccountCreationDialogState State + public static readonly DependencyProperty StateProperty = DependencyProperty.Register(nameof(State), typeof(AccountCreationDialogState), typeof(AccountCreationDialog), new PropertyMetadata(AccountCreationDialogState.Idle)); + + public AccountCreationDialog() + { + InitializeComponent(); + } + + // Prevent users from dismissing it by ESC key. + public void DialogClosing(ContentDialog sender, ContentDialogClosingEventArgs args) + { + if (args.Result == ContentDialogResult.None) { - get { return (AccountCreationDialogState)GetValue(StateProperty); } - set { SetValue(StateProperty, value); } - } - - public static readonly DependencyProperty StateProperty = DependencyProperty.Register(nameof(State), typeof(AccountCreationDialogState), typeof(AccountCreationDialog), new PropertyMetadata(AccountCreationDialogState.Idle)); - - public AccountCreationDialog() - { - InitializeComponent(); - } - - // Prevent users from dismissing it by ESC key. - public void DialogClosing(ContentDialog sender, ContentDialogClosingEventArgs args) - { - if (args.Result == ContentDialogResult.None) - { - args.Cancel = true; - } - } - - public void Complete(bool cancel) - { - State = cancel ? AccountCreationDialogState.Canceled : AccountCreationDialogState.Completed; - - // Unregister from closing event. - Closing -= DialogClosing; - - if (cancel && !CancellationTokenSource.IsCancellationRequested) - { - CancellationTokenSource.Cancel(); - } - - Hide(); - } - - private void CancelClicked(object sender, System.EventArgs e) => Complete(true); - - public async Task ShowDialogAsync(CancellationTokenSource cancellationTokenSource) - { - CancellationTokenSource = cancellationTokenSource; - - Opened += DialogOpened; - _ = ShowAsync(); - - await dialogOpened.Task; - } - - private void DialogOpened(ContentDialog sender, ContentDialogOpenedEventArgs args) - { - Opened -= DialogOpened; - - dialogOpened?.SetResult(true); + args.Cancel = true; } } + + public void Complete(bool cancel) + { + State = cancel ? AccountCreationDialogState.Canceled : AccountCreationDialogState.Completed; + + // Unregister from closing event. + Closing -= DialogClosing; + + if (cancel && !CancellationTokenSource.IsCancellationRequested) + { + CancellationTokenSource.Cancel(); + } + + Hide(); + } + + private void CancelClicked(object sender, System.EventArgs e) => Complete(true); + + public async Task ShowDialogAsync(CancellationTokenSource cancellationTokenSource) + { + CancellationTokenSource = cancellationTokenSource; + + Opened += DialogOpened; + _ = ShowAsync(); + + await dialogOpened.Task; + } + + private void DialogOpened(ContentDialog sender, ContentDialogOpenedEventArgs args) + { + Opened -= DialogOpened; + + dialogOpened?.SetResult(true); + } } diff --git a/Wino.Core.UWP/Dialogs/AccountEditDialog.xaml.cs b/Wino.Core.UWP/Dialogs/AccountEditDialog.xaml.cs index dae0a599..e6d72dd0 100644 --- a/Wino.Core.UWP/Dialogs/AccountEditDialog.xaml.cs +++ b/Wino.Core.UWP/Dialogs/AccountEditDialog.xaml.cs @@ -1,22 +1,21 @@ using Windows.UI.Xaml.Controls; using Wino.Core.Domain.Entities.Shared; -namespace Wino.Dialogs +namespace Wino.Dialogs; + +public sealed partial class AccountEditDialog : ContentDialog { - public sealed partial class AccountEditDialog : ContentDialog + public MailAccount Account { get; private set; } + public bool IsSaved { get; set; } + + public AccountEditDialog(MailAccount account) { - public MailAccount Account { get; private set; } - public bool IsSaved { get; set; } + InitializeComponent(); + Account = account; + } - public AccountEditDialog(MailAccount account) - { - InitializeComponent(); - Account = account; - } - - private void SaveClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args) - { - IsSaved = true; - } + private void SaveClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args) + { + IsSaved = true; } } diff --git a/Wino.Core.UWP/Dialogs/AccountPickerDialog.xaml.cs b/Wino.Core.UWP/Dialogs/AccountPickerDialog.xaml.cs index a8d50246..f07a4071 100644 --- a/Wino.Core.UWP/Dialogs/AccountPickerDialog.xaml.cs +++ b/Wino.Core.UWP/Dialogs/AccountPickerDialog.xaml.cs @@ -2,26 +2,25 @@ using Windows.UI.Xaml.Controls; using Wino.Core.Domain.Entities.Shared; -namespace Wino.Dialogs +namespace Wino.Dialogs; + +public sealed partial class AccountPickerDialog : ContentDialog { - public sealed partial class AccountPickerDialog : ContentDialog + public MailAccount PickedAccount { get; set; } + + public List AvailableAccounts { get; set; } + + public AccountPickerDialog(List availableAccounts) { - public MailAccount PickedAccount { get; set; } + AvailableAccounts = availableAccounts; - public List AvailableAccounts { get; set; } + InitializeComponent(); + } - public AccountPickerDialog(List availableAccounts) - { - AvailableAccounts = availableAccounts; + private void AccountClicked(object sender, ItemClickEventArgs e) + { + PickedAccount = e.ClickedItem as MailAccount; - InitializeComponent(); - } - - private void AccountClicked(object sender, ItemClickEventArgs e) - { - PickedAccount = e.ClickedItem as MailAccount; - - Hide(); - } + Hide(); } } diff --git a/Wino.Core.UWP/Dialogs/CustomMessageDialogInformationContainer.cs b/Wino.Core.UWP/Dialogs/CustomMessageDialogInformationContainer.cs index ceac338e..4715ea3a 100644 --- a/Wino.Core.UWP/Dialogs/CustomMessageDialogInformationContainer.cs +++ b/Wino.Core.UWP/Dialogs/CustomMessageDialogInformationContainer.cs @@ -1,24 +1,23 @@ using CommunityToolkit.Mvvm.ComponentModel; using Wino.Core.Domain.Enums; -namespace Wino.Dialogs +namespace Wino.Dialogs; + +public partial class CustomMessageDialogInformationContainer : ObservableObject { - public partial class CustomMessageDialogInformationContainer : ObservableObject + [ObservableProperty] + public partial bool IsDontAskChecked { get; set; } + + public CustomMessageDialogInformationContainer(string title, string description, WinoCustomMessageDialogIcon icon, bool isDontAskAgainEnabled) { - [ObservableProperty] - public partial bool IsDontAskChecked { get; set; } - - public CustomMessageDialogInformationContainer(string title, string description, WinoCustomMessageDialogIcon icon, bool isDontAskAgainEnabled) - { - Title = title; - Description = description; - Icon = icon; - IsDontAskAgainEnabled = isDontAskAgainEnabled; - } - - public string Title { get; } - public string Description { get; } - public WinoCustomMessageDialogIcon Icon { get; } - public bool IsDontAskAgainEnabled { get; } + Title = title; + Description = description; + Icon = icon; + IsDontAskAgainEnabled = isDontAskAgainEnabled; } + + public string Title { get; } + public string Description { get; } + public WinoCustomMessageDialogIcon Icon { get; } + public bool IsDontAskAgainEnabled { get; } } diff --git a/Wino.Core.UWP/Dialogs/CustomThemeBuilderDialog.xaml.cs b/Wino.Core.UWP/Dialogs/CustomThemeBuilderDialog.xaml.cs index a4154918..d50dcc89 100644 --- a/Wino.Core.UWP/Dialogs/CustomThemeBuilderDialog.xaml.cs +++ b/Wino.Core.UWP/Dialogs/CustomThemeBuilderDialog.xaml.cs @@ -6,60 +6,59 @@ using Windows.UI.Xaml.Media; using Wino.Core.Domain.Interfaces; using Wino.Core.UWP; -namespace Wino.Dialogs +namespace Wino.Dialogs; + +public sealed partial class CustomThemeBuilderDialog : ContentDialog { - public sealed partial class CustomThemeBuilderDialog : ContentDialog + public byte[] WallpaperData { get; private set; } + public string AccentColor { get; private set; } + + private IThemeService _themeService; + + public CustomThemeBuilderDialog() { - public byte[] WallpaperData { get; private set; } - public string AccentColor { get; private set; } + InitializeComponent(); - private IThemeService _themeService; + _themeService = WinoApplication.Current.Services.GetService(); + } - public CustomThemeBuilderDialog() + private async void ApplyClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args) + { + if (Array.Empty() == WallpaperData) + return; + + var deferal = args.GetDeferral(); + + try { - InitializeComponent(); - - _themeService = WinoApplication.Current.Services.GetService(); + await _themeService.CreateNewCustomThemeAsync(ThemeNameBox.Text, AccentColor, WallpaperData); } - - private async void ApplyClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args) + catch (Exception exception) { - if (Array.Empty() == WallpaperData) - return; - - var deferal = args.GetDeferral(); - - try - { - await _themeService.CreateNewCustomThemeAsync(ThemeNameBox.Text, AccentColor, WallpaperData); - } - catch (Exception exception) - { - ErrorTextBlock.Text = exception.Message; - } - finally - { - deferal.Complete(); - } + ErrorTextBlock.Text = exception.Message; } - - private async void BrowseWallpaperClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e) + finally { - var dialogService = WinoApplication.Current.Services.GetService(); - - var pickedFileData = await dialogService.PickWindowsFileContentAsync(".jpg", ".png"); - - if (pickedFileData == Array.Empty()) return; - - IsPrimaryButtonEnabled = true; - - WallpaperData = pickedFileData; - } - - private void PickerColorChanged(Microsoft.UI.Xaml.Controls.ColorPicker sender, Microsoft.UI.Xaml.Controls.ColorChangedEventArgs args) - { - PreviewAccentColorGrid.Background = new SolidColorBrush(args.NewColor); - AccentColor = args.NewColor.ToHex(); + deferal.Complete(); } } + + private async void BrowseWallpaperClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e) + { + var dialogService = WinoApplication.Current.Services.GetService(); + + var pickedFileData = await dialogService.PickWindowsFileContentAsync(".jpg", ".png"); + + if (pickedFileData == Array.Empty()) return; + + IsPrimaryButtonEnabled = true; + + WallpaperData = pickedFileData; + } + + private void PickerColorChanged(Microsoft.UI.Xaml.Controls.ColorPicker sender, Microsoft.UI.Xaml.Controls.ColorChangedEventArgs args) + { + PreviewAccentColorGrid.Background = new SolidColorBrush(args.NewColor); + AccentColor = args.NewColor.ToHex(); + } } diff --git a/Wino.Core.UWP/Dialogs/NewAccountDialog.xaml.cs b/Wino.Core.UWP/Dialogs/NewAccountDialog.xaml.cs index 9ba9efca..26a738ac 100644 --- a/Wino.Core.UWP/Dialogs/NewAccountDialog.xaml.cs +++ b/Wino.Core.UWP/Dialogs/NewAccountDialog.xaml.cs @@ -7,146 +7,145 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Accounts; -namespace Wino.Core.UWP.Dialogs +namespace Wino.Core.UWP.Dialogs; + +public sealed partial class NewAccountDialog : ContentDialog { - public sealed partial class NewAccountDialog : ContentDialog + private Dictionary helpingLinks = new Dictionary() { - private Dictionary helpingLinks = new Dictionary() + { SpecialImapProvider.iCloud, "https://support.apple.com/en-us/102654" }, + { SpecialImapProvider.Yahoo, "http://help.yahoo.com/kb/SLN15241.html" }, + }; + + public static readonly DependencyProperty IsProviderSelectionVisibleProperty = DependencyProperty.Register(nameof(IsProviderSelectionVisible), typeof(bool), typeof(NewAccountDialog), new PropertyMetadata(true)); + public static readonly DependencyProperty IsSpecialImapServerPartVisibleProperty = DependencyProperty.Register(nameof(IsSpecialImapServerPartVisible), typeof(bool), typeof(NewAccountDialog), new PropertyMetadata(false)); + public static readonly DependencyProperty SelectedMailProviderProperty = DependencyProperty.Register(nameof(SelectedMailProvider), typeof(ProviderDetail), typeof(NewAccountDialog), new PropertyMetadata(null, new PropertyChangedCallback(OnSelectedProviderChanged))); + + + /// + /// Gets or sets current selected mail provider in the dialog. + /// + public ProviderDetail SelectedMailProvider + { + get { return (ProviderDetail)GetValue(SelectedMailProviderProperty); } + set { SetValue(SelectedMailProviderProperty, value); } + } + + + public bool IsProviderSelectionVisible + { + get { return (bool)GetValue(IsProviderSelectionVisibleProperty); } + set { SetValue(IsProviderSelectionVisibleProperty, value); } + } + + public bool IsSpecialImapServerPartVisible + { + get { return (bool)GetValue(IsSpecialImapServerPartVisibleProperty); } + set { SetValue(IsSpecialImapServerPartVisibleProperty, value); } + } + + // List of available mail providers for now. + + public List Providers { get; set; } + + public AccountCreationDialogResult Result = null; + + public NewAccountDialog() + { + InitializeComponent(); + + // AccountColorPicker.Color = Colors.Blue; + } + + private static void OnSelectedProviderChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) + { + if (obj is NewAccountDialog dialog) + dialog.Validate(); + } + + private void CancelClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args) + { + Hide(); + } + + private void CreateClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args) + { + if (IsSpecialImapServerPartVisible) { - { SpecialImapProvider.iCloud, "https://support.apple.com/en-us/102654" }, - { SpecialImapProvider.Yahoo, "http://help.yahoo.com/kb/SLN15241.html" }, - }; + // Special imap detail input. - public static readonly DependencyProperty IsProviderSelectionVisibleProperty = DependencyProperty.Register(nameof(IsProviderSelectionVisible), typeof(bool), typeof(NewAccountDialog), new PropertyMetadata(true)); - public static readonly DependencyProperty IsSpecialImapServerPartVisibleProperty = DependencyProperty.Register(nameof(IsSpecialImapServerPartVisible), typeof(bool), typeof(NewAccountDialog), new PropertyMetadata(false)); - public static readonly DependencyProperty SelectedMailProviderProperty = DependencyProperty.Register(nameof(SelectedMailProvider), typeof(ProviderDetail), typeof(NewAccountDialog), new PropertyMetadata(null, new PropertyChangedCallback(OnSelectedProviderChanged))); - - - /// - /// Gets or sets current selected mail provider in the dialog. - /// - public ProviderDetail SelectedMailProvider - { - get { return (ProviderDetail)GetValue(SelectedMailProviderProperty); } - set { SetValue(SelectedMailProviderProperty, value); } - } - - - public bool IsProviderSelectionVisible - { - get { return (bool)GetValue(IsProviderSelectionVisibleProperty); } - set { SetValue(IsProviderSelectionVisibleProperty, value); } - } - - public bool IsSpecialImapServerPartVisible - { - get { return (bool)GetValue(IsSpecialImapServerPartVisibleProperty); } - set { SetValue(IsSpecialImapServerPartVisibleProperty, value); } - } - - // List of available mail providers for now. - - public List Providers { get; set; } - - public AccountCreationDialogResult Result = null; - - public NewAccountDialog() - { - InitializeComponent(); - - // AccountColorPicker.Color = Colors.Blue; - } - - private static void OnSelectedProviderChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) - { - if (obj is NewAccountDialog dialog) - dialog.Validate(); - } - - private void CancelClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args) - { + var details = new SpecialImapProviderDetails(SpecialImapAddress.Text.Trim(), AppSpecificPassword.Password.Trim(), DisplayNameTextBox.Text.Trim(), SelectedMailProvider.SpecialImapProvider); + Result = new AccountCreationDialogResult(SelectedMailProvider.Type, AccountNameTextbox.Text.Trim(), details); Hide(); + + return; } - private void CreateClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args) - { - if (IsSpecialImapServerPartVisible) - { - // Special imap detail input. + Validate(); - var details = new SpecialImapProviderDetails(SpecialImapAddress.Text.Trim(), AppSpecificPassword.Password.Trim(), DisplayNameTextBox.Text.Trim(), SelectedMailProvider.SpecialImapProvider); - Result = new AccountCreationDialogResult(SelectedMailProvider.Type, AccountNameTextbox.Text.Trim(), details); + if (IsSecondaryButtonEnabled) + { + if (SelectedMailProvider.SpecialImapProvider != SpecialImapProvider.None) + { + // This step requires app-sepcific password login for some providers. + args.Cancel = true; + + IsProviderSelectionVisible = false; + IsSpecialImapServerPartVisible = true; + + Validate(); + } + else + { + Result = new AccountCreationDialogResult(SelectedMailProvider.Type, AccountNameTextbox.Text.Trim(), null); Hide(); - - return; } - - Validate(); - - if (IsSecondaryButtonEnabled) - { - if (SelectedMailProvider.SpecialImapProvider != SpecialImapProvider.None) - { - // This step requires app-sepcific password login for some providers. - args.Cancel = true; - - IsProviderSelectionVisible = false; - IsSpecialImapServerPartVisible = true; - - Validate(); - } - else - { - Result = new AccountCreationDialogResult(SelectedMailProvider.Type, AccountNameTextbox.Text.Trim(), null); - Hide(); - } - } - } - - private void InputChanged(object sender, TextChangedEventArgs e) => Validate(); - private void SenderNameChanged(object sender, TextChangedEventArgs e) => Validate(); - - private void Validate() - { - ValidateCreateButton(); - ValidateNames(); - } - - // Returns whether we can create account or not. - private void ValidateCreateButton() - { - bool shouldEnable = SelectedMailProvider != null - && SelectedMailProvider.IsSupported - && !string.IsNullOrEmpty(AccountNameTextbox.Text) - && (IsSpecialImapServerPartVisible ? (!string.IsNullOrEmpty(AppSpecificPassword.Password) - && !string.IsNullOrEmpty(DisplayNameTextBox.Text) - && EmailValidation.EmailValidator.Validate(SpecialImapAddress.Text)) : true); - - IsPrimaryButtonEnabled = shouldEnable; - } - - private void ValidateNames() - { - AccountNameTextbox.IsEnabled = SelectedMailProvider != null; - } - - private void DialogOpened(ContentDialog sender, ContentDialogOpenedEventArgs args) => Validate(); - - private void BackClicked(object sender, RoutedEventArgs e) - { - IsSpecialImapServerPartVisible = false; - IsProviderSelectionVisible = true; - - Validate(); - } - - private void ImapPasswordChanged(object sender, RoutedEventArgs e) => Validate(); - - private async void AppSpecificHelpButtonClicked(object sender, RoutedEventArgs e) - { - var helpUrl = helpingLinks[SelectedMailProvider.SpecialImapProvider]; - - await Launcher.LaunchUriAsync(new Uri(helpUrl)); } } + + private void InputChanged(object sender, TextChangedEventArgs e) => Validate(); + private void SenderNameChanged(object sender, TextChangedEventArgs e) => Validate(); + + private void Validate() + { + ValidateCreateButton(); + ValidateNames(); + } + + // Returns whether we can create account or not. + private void ValidateCreateButton() + { + bool shouldEnable = SelectedMailProvider != null + && SelectedMailProvider.IsSupported + && !string.IsNullOrEmpty(AccountNameTextbox.Text) + && (IsSpecialImapServerPartVisible ? (!string.IsNullOrEmpty(AppSpecificPassword.Password) + && !string.IsNullOrEmpty(DisplayNameTextBox.Text) + && EmailValidation.EmailValidator.Validate(SpecialImapAddress.Text)) : true); + + IsPrimaryButtonEnabled = shouldEnable; + } + + private void ValidateNames() + { + AccountNameTextbox.IsEnabled = SelectedMailProvider != null; + } + + private void DialogOpened(ContentDialog sender, ContentDialogOpenedEventArgs args) => Validate(); + + private void BackClicked(object sender, RoutedEventArgs e) + { + IsSpecialImapServerPartVisible = false; + IsProviderSelectionVisible = true; + + Validate(); + } + + private void ImapPasswordChanged(object sender, RoutedEventArgs e) => Validate(); + + private async void AppSpecificHelpButtonClicked(object sender, RoutedEventArgs e) + { + var helpUrl = helpingLinks[SelectedMailProvider.SpecialImapProvider]; + + await Launcher.LaunchUriAsync(new Uri(helpUrl)); + } } diff --git a/Wino.Core.UWP/Dialogs/TextInputDialog.xaml.cs b/Wino.Core.UWP/Dialogs/TextInputDialog.xaml.cs index 443505d2..c0fabef2 100644 --- a/Wino.Core.UWP/Dialogs/TextInputDialog.xaml.cs +++ b/Wino.Core.UWP/Dialogs/TextInputDialog.xaml.cs @@ -1,45 +1,44 @@ using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; -namespace Wino.Dialogs +namespace Wino.Dialogs; + +public sealed partial class TextInputDialog : ContentDialog { - public sealed partial class TextInputDialog : ContentDialog + public bool? HasInput { get; set; } + + public string CurrentInput { - public bool? HasInput { get; set; } + get { return (string)GetValue(CurrentInputProperty); } + set { SetValue(CurrentInputProperty, value); } + } - public string CurrentInput - { - get { return (string)GetValue(CurrentInputProperty); } - set { SetValue(CurrentInputProperty, value); } - } + public static readonly DependencyProperty CurrentInputProperty = DependencyProperty.Register(nameof(CurrentInput), typeof(string), typeof(TextInputDialog), new PropertyMetadata(string.Empty)); - public static readonly DependencyProperty CurrentInputProperty = DependencyProperty.Register(nameof(CurrentInput), typeof(string), typeof(TextInputDialog), new PropertyMetadata(string.Empty)); + public TextInputDialog() + { + InitializeComponent(); + } - public TextInputDialog() - { - InitializeComponent(); - } + public void SetDescription(string description) + { + DialogDescription.Text = description; + } - public void SetDescription(string description) - { - DialogDescription.Text = description; - } + public void SetPrimaryButtonText(string text) + { + PrimaryButtonText = text; + } - public void SetPrimaryButtonText(string text) - { - PrimaryButtonText = text; - } + private void CancelClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args) + { + Hide(); + } - private void CancelClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args) - { - Hide(); - } + private void UpdateOrCreateClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args) + { + HasInput = true; - private void UpdateOrCreateClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args) - { - HasInput = true; - - Hide(); - } + Hide(); } } diff --git a/Wino.Core.UWP/Dispatcher.cs b/Wino.Core.UWP/Dispatcher.cs index 060607f8..34b5b576 100644 --- a/Wino.Core.UWP/Dispatcher.cs +++ b/Wino.Core.UWP/Dispatcher.cs @@ -3,18 +3,17 @@ using System.Threading.Tasks; using Windows.UI.Core; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.UWP +namespace Wino.Core.UWP; + +public class UWPDispatcher : IDispatcher { - public class UWPDispatcher : IDispatcher + private readonly CoreDispatcher _coreDispatcher; + + public UWPDispatcher(CoreDispatcher coreDispatcher) { - private readonly CoreDispatcher _coreDispatcher; - - public UWPDispatcher(CoreDispatcher coreDispatcher) - { - _coreDispatcher = coreDispatcher; - } - - public Task ExecuteOnUIThread(Action action) - => _coreDispatcher.RunAsync(CoreDispatcherPriority.Normal, () => action()).AsTask(); + _coreDispatcher = coreDispatcher; } + + public Task ExecuteOnUIThread(Action action) + => _coreDispatcher.RunAsync(CoreDispatcherPriority.Normal, () => action()).AsTask(); } diff --git a/Wino.Core.UWP/Extensions/AnimationExtensions.cs b/Wino.Core.UWP/Extensions/AnimationExtensions.cs index 6ad7cb8a..12c4d7d0 100644 --- a/Wino.Core.UWP/Extensions/AnimationExtensions.cs +++ b/Wino.Core.UWP/Extensions/AnimationExtensions.cs @@ -8,109 +8,108 @@ using Windows.UI.Composition; using Windows.UI.Xaml; using Windows.UI.Xaml.Media.Animation; -namespace Wino.Extensions +namespace Wino.Extensions; + +public static class AnimationExtensions { - public static class AnimationExtensions + #region Composition + + public static ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation(this Compositor compositor, float? from, float to, + double duration, double delay, CompositionEasingFunction easing, AnimationIterationBehavior iterationBehavior) { - #region Composition + var animation = compositor.CreateScalarKeyFrameAnimation(); - public static ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation(this Compositor compositor, float? from, float to, - double duration, double delay, CompositionEasingFunction easing, AnimationIterationBehavior iterationBehavior) - { - var animation = compositor.CreateScalarKeyFrameAnimation(); + animation.Duration = TimeSpan.FromMilliseconds(duration); + if (!delay.Equals(0)) animation.DelayTime = TimeSpan.FromMilliseconds(delay); + if (from.HasValue) animation.InsertKeyFrame(0.0f, from.Value, easing); + animation.InsertKeyFrame(1.0f, to, easing); + animation.IterationBehavior = iterationBehavior; - animation.Duration = TimeSpan.FromMilliseconds(duration); - if (!delay.Equals(0)) animation.DelayTime = TimeSpan.FromMilliseconds(delay); - if (from.HasValue) animation.InsertKeyFrame(0.0f, from.Value, easing); - animation.InsertKeyFrame(1.0f, to, easing); - animation.IterationBehavior = iterationBehavior; - - return animation; - } - - public static Vector2KeyFrameAnimation CreateVector2KeyFrameAnimation(this Compositor compositor, Vector2? from, Vector2 to, - double duration, double delay, CompositionEasingFunction easing, AnimationIterationBehavior iterationBehavior) - { - var animation = compositor.CreateVector2KeyFrameAnimation(); - - animation.Duration = TimeSpan.FromMilliseconds(duration); - animation.DelayTime = TimeSpan.FromMilliseconds(delay); - if (from.HasValue) animation.InsertKeyFrame(0.0f, from.Value, easing); - animation.InsertKeyFrame(1.0f, to, easing); - animation.IterationBehavior = iterationBehavior; - - return animation; - } - - public static Vector3KeyFrameAnimation CreateVector3KeyFrameAnimation(this Compositor compositor, Vector2? from, Vector2 to, - double duration, double delay, CompositionEasingFunction easing, AnimationIterationBehavior iterationBehavior) - { - var animation = compositor.CreateVector3KeyFrameAnimation(); - - animation.Duration = TimeSpan.FromMilliseconds(duration); - animation.DelayTime = TimeSpan.FromMilliseconds(delay); - if (from.HasValue) animation.InsertKeyFrame(0.0f, new Vector3(from.Value, 1.0f), easing); - animation.InsertKeyFrame(1.0f, new Vector3(to, 1.0f), easing); - animation.IterationBehavior = iterationBehavior; - - return animation; - } - - public static Vector3KeyFrameAnimation CreateVector3KeyFrameAnimation(this Compositor compositor, Vector3? from, Vector3 to, - double duration, double delay, CompositionEasingFunction easing, AnimationIterationBehavior iterationBehavior) - { - var animation = compositor.CreateVector3KeyFrameAnimation(); - - animation.Duration = TimeSpan.FromMilliseconds(duration); - animation.DelayTime = TimeSpan.FromMilliseconds(delay); - if (from.HasValue) animation.InsertKeyFrame(0.0f, from.Value, easing); - animation.InsertKeyFrame(1.0f, to, easing); - animation.IterationBehavior = iterationBehavior; - - return animation; - } - - #endregion - - #region Xaml Storyboard - - public static void Animate(this DependencyObject target, double? from, double to, - string propertyPath, int duration = 400, int startTime = 0, - EasingFunctionBase easing = null, Action completed = null, bool enableDependentAnimation = false) - { - if (easing == null) - { - easing = new ExponentialEase(); - } - - var db = new DoubleAnimation - { - EnableDependentAnimation = enableDependentAnimation, - To = to, - From = from, - EasingFunction = easing, - Duration = TimeSpan.FromMilliseconds(duration) - }; - Storyboard.SetTarget(db, target); - Storyboard.SetTargetProperty(db, propertyPath); - - var sb = new Storyboard - { - BeginTime = TimeSpan.FromMilliseconds(startTime) - }; - - if (completed != null) - { - sb.Completed += (s, e) => - { - completed(); - }; - } - - sb.Children.Add(db); - sb.Begin(); - } - - #endregion + return animation; } + + public static Vector2KeyFrameAnimation CreateVector2KeyFrameAnimation(this Compositor compositor, Vector2? from, Vector2 to, + double duration, double delay, CompositionEasingFunction easing, AnimationIterationBehavior iterationBehavior) + { + var animation = compositor.CreateVector2KeyFrameAnimation(); + + animation.Duration = TimeSpan.FromMilliseconds(duration); + animation.DelayTime = TimeSpan.FromMilliseconds(delay); + if (from.HasValue) animation.InsertKeyFrame(0.0f, from.Value, easing); + animation.InsertKeyFrame(1.0f, to, easing); + animation.IterationBehavior = iterationBehavior; + + return animation; + } + + public static Vector3KeyFrameAnimation CreateVector3KeyFrameAnimation(this Compositor compositor, Vector2? from, Vector2 to, + double duration, double delay, CompositionEasingFunction easing, AnimationIterationBehavior iterationBehavior) + { + var animation = compositor.CreateVector3KeyFrameAnimation(); + + animation.Duration = TimeSpan.FromMilliseconds(duration); + animation.DelayTime = TimeSpan.FromMilliseconds(delay); + if (from.HasValue) animation.InsertKeyFrame(0.0f, new Vector3(from.Value, 1.0f), easing); + animation.InsertKeyFrame(1.0f, new Vector3(to, 1.0f), easing); + animation.IterationBehavior = iterationBehavior; + + return animation; + } + + public static Vector3KeyFrameAnimation CreateVector3KeyFrameAnimation(this Compositor compositor, Vector3? from, Vector3 to, + double duration, double delay, CompositionEasingFunction easing, AnimationIterationBehavior iterationBehavior) + { + var animation = compositor.CreateVector3KeyFrameAnimation(); + + animation.Duration = TimeSpan.FromMilliseconds(duration); + animation.DelayTime = TimeSpan.FromMilliseconds(delay); + if (from.HasValue) animation.InsertKeyFrame(0.0f, from.Value, easing); + animation.InsertKeyFrame(1.0f, to, easing); + animation.IterationBehavior = iterationBehavior; + + return animation; + } + + #endregion + + #region Xaml Storyboard + + public static void Animate(this DependencyObject target, double? from, double to, + string propertyPath, int duration = 400, int startTime = 0, + EasingFunctionBase easing = null, Action completed = null, bool enableDependentAnimation = false) + { + if (easing == null) + { + easing = new ExponentialEase(); + } + + var db = new DoubleAnimation + { + EnableDependentAnimation = enableDependentAnimation, + To = to, + From = from, + EasingFunction = easing, + Duration = TimeSpan.FromMilliseconds(duration) + }; + Storyboard.SetTarget(db, target); + Storyboard.SetTargetProperty(db, propertyPath); + + var sb = new Storyboard + { + BeginTime = TimeSpan.FromMilliseconds(startTime) + }; + + if (completed != null) + { + sb.Completed += (s, e) => + { + completed(); + }; + } + + sb.Children.Add(db); + sb.Begin(); + } + + #endregion } diff --git a/Wino.Core.UWP/Extensions/CompositionEnums.cs b/Wino.Core.UWP/Extensions/CompositionEnums.cs index 4ac01d05..06f1f169 100644 --- a/Wino.Core.UWP/Extensions/CompositionEnums.cs +++ b/Wino.Core.UWP/Extensions/CompositionEnums.cs @@ -4,70 +4,69 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Wino.Extensions +namespace Wino.Extensions; + +public enum TransitionDirection { - public enum TransitionDirection - { - TopToBottom, - BottomToTop, - LeftToRight, - RightToLeft - } - - public enum ClipAnimationDirection - { - Top, - Bottom, - Left, - Right - } - - public enum AnimationAxis - { - X, - Y, - Z - } - - public enum AnimationType - { - KeyFrame, - Expression - } - - public enum FlickDirection - { - None, - Up, - Down, - Left, - Right - } - - public enum ViewState - { - Empty, - Small, - Big, - Full - } - - public enum Gesture - { - Initial, - Tap, - Swipe - } - - [Flags] - public enum VisualPropertyType - { - None = 0, - Opacity = 1 << 0, - Offset = 1 << 1, - Scale = 1 << 2, - Size = 1 << 3, - RotationAngleInDegrees = 1 << 4, - All = ~0 - } + TopToBottom, + BottomToTop, + LeftToRight, + RightToLeft +} + +public enum ClipAnimationDirection +{ + Top, + Bottom, + Left, + Right +} + +public enum AnimationAxis +{ + X, + Y, + Z +} + +public enum AnimationType +{ + KeyFrame, + Expression +} + +public enum FlickDirection +{ + None, + Up, + Down, + Left, + Right +} + +public enum ViewState +{ + Empty, + Small, + Big, + Full +} + +public enum Gesture +{ + Initial, + Tap, + Swipe +} + +[Flags] +public enum VisualPropertyType +{ + None = 0, + Opacity = 1 << 0, + Offset = 1 << 1, + Scale = 1 << 2, + Size = 1 << 3, + RotationAngleInDegrees = 1 << 4, + All = ~0 } diff --git a/Wino.Core.UWP/Extensions/CompositionExtensions.Implicit.cs b/Wino.Core.UWP/Extensions/CompositionExtensions.Implicit.cs index d043fd45..17d1b0fb 100644 --- a/Wino.Core.UWP/Extensions/CompositionExtensions.Implicit.cs +++ b/Wino.Core.UWP/Extensions/CompositionExtensions.Implicit.cs @@ -8,193 +8,192 @@ using Windows.UI.Composition; using Windows.UI.Xaml; using Windows.UI.Xaml.Hosting; -namespace Wino.Extensions +namespace Wino.Extensions; + +public static partial class CompositionExtensions { - public static partial class CompositionExtensions + public static void EnableFluidVisibilityAnimation(this UIElement element, AnimationAxis? axis = null, + float showFromOffset = 0.0f, float hideToOffset = 0.0f, Vector3? centerPoint = null, + float showFromScale = 1.0f, float hideToScale = 1.0f, float showDuration = 800.0f, float hideDuration = 800.0f, + int showDelay = 0, int hideDelay = 0, bool animateOpacity = true) { - public static void EnableFluidVisibilityAnimation(this UIElement element, AnimationAxis? axis = null, - float showFromOffset = 0.0f, float hideToOffset = 0.0f, Vector3? centerPoint = null, - float showFromScale = 1.0f, float hideToScale = 1.0f, float showDuration = 800.0f, float hideDuration = 800.0f, - int showDelay = 0, int hideDelay = 0, bool animateOpacity = true) + var elementVisual = element.Visual(); + var compositor = elementVisual.Compositor; + ElementCompositionPreview.SetIsTranslationEnabled(element, true); + + ScalarKeyFrameAnimation hideOpacityAnimation = null; + ScalarKeyFrameAnimation showOpacityAnimation = null; + ScalarKeyFrameAnimation hideOffsetAnimation = null; + ScalarKeyFrameAnimation showOffsetAnimation = null; + Vector2KeyFrameAnimation hideScaleAnimation = null; + Vector2KeyFrameAnimation showeScaleAnimation = null; + + if (animateOpacity) { - var elementVisual = element.Visual(); - var compositor = elementVisual.Compositor; - ElementCompositionPreview.SetIsTranslationEnabled(element, true); - - ScalarKeyFrameAnimation hideOpacityAnimation = null; - ScalarKeyFrameAnimation showOpacityAnimation = null; - ScalarKeyFrameAnimation hideOffsetAnimation = null; - ScalarKeyFrameAnimation showOffsetAnimation = null; - Vector2KeyFrameAnimation hideScaleAnimation = null; - Vector2KeyFrameAnimation showeScaleAnimation = null; - - if (animateOpacity) - { - hideOpacityAnimation = compositor.CreateScalarKeyFrameAnimation(); - hideOpacityAnimation.InsertKeyFrame(1.0f, 0.0f); - hideOpacityAnimation.Duration = TimeSpan.FromMilliseconds(hideDuration); - hideOpacityAnimation.DelayTime = TimeSpan.FromMilliseconds(hideDelay); - hideOpacityAnimation.Target = "Opacity"; - } - - if (!hideToOffset.Equals(0.0f)) - { - hideOffsetAnimation = compositor.CreateScalarKeyFrameAnimation(); - hideOffsetAnimation.InsertKeyFrame(1.0f, hideToOffset); - hideOffsetAnimation.Duration = TimeSpan.FromMilliseconds(hideDuration); - hideOffsetAnimation.DelayTime = TimeSpan.FromMilliseconds(hideDelay); - hideOffsetAnimation.Target = $"Translation.{axis}"; - } - - if (centerPoint.HasValue) - { - elementVisual.CenterPoint = centerPoint.Value; - } - - if (!hideToScale.Equals(1.0f)) - { - hideScaleAnimation = compositor.CreateVector2KeyFrameAnimation(); - hideScaleAnimation.InsertKeyFrame(1.0f, new Vector2(hideToScale)); - hideScaleAnimation.Duration = TimeSpan.FromMilliseconds(hideDuration); - hideScaleAnimation.DelayTime = TimeSpan.FromMilliseconds(hideDelay); - hideScaleAnimation.Target = "Scale.XY"; - } - - var hideAnimationGroup = compositor.CreateAnimationGroup(); - if (hideOpacityAnimation != null) - { - hideAnimationGroup.Add(hideOpacityAnimation); - } - if (hideOffsetAnimation != null) - { - hideAnimationGroup.Add(hideOffsetAnimation); - } - if (hideScaleAnimation != null) - { - hideAnimationGroup.Add(hideScaleAnimation); - } - - ElementCompositionPreview.SetImplicitHideAnimation(element, hideAnimationGroup); - - if (animateOpacity) - { - showOpacityAnimation = compositor.CreateScalarKeyFrameAnimation(); - showOpacityAnimation.InsertKeyFrame(1.0f, 1.0f); - showOpacityAnimation.Duration = TimeSpan.FromMilliseconds(showDuration); - showOpacityAnimation.DelayTime = TimeSpan.FromMilliseconds(showDelay); - showOpacityAnimation.Target = "Opacity"; - } - - if (!showFromOffset.Equals(0.0f)) - { - showOffsetAnimation = compositor.CreateScalarKeyFrameAnimation(); - showOffsetAnimation.InsertKeyFrame(0.0f, showFromOffset); - showOffsetAnimation.InsertKeyFrame(1.0f, 0.0f); - showOffsetAnimation.Duration = TimeSpan.FromMilliseconds(showDuration); - showOffsetAnimation.DelayTime = TimeSpan.FromMilliseconds(showDelay); - showOffsetAnimation.Target = $"Translation.{axis}"; - } - - if (!showFromScale.Equals(1.0f)) - { - showeScaleAnimation = compositor.CreateVector2KeyFrameAnimation(); - showeScaleAnimation.InsertKeyFrame(0.0f, new Vector2(showFromScale)); - showeScaleAnimation.InsertKeyFrame(1.0f, Vector2.One); - showeScaleAnimation.Duration = TimeSpan.FromMilliseconds(showDuration); - showeScaleAnimation.DelayTime = TimeSpan.FromMilliseconds(showDelay); - showeScaleAnimation.Target = "Scale.XY"; - } - - var showAnimationGroup = compositor.CreateAnimationGroup(); - if (showOpacityAnimation != null) - { - showAnimationGroup.Add(showOpacityAnimation); - } - if (showOffsetAnimation != null) - { - showAnimationGroup.Add(showOffsetAnimation); - } - if (showeScaleAnimation != null) - { - showAnimationGroup.Add(showeScaleAnimation); - } - - ElementCompositionPreview.SetImplicitShowAnimation(element, showAnimationGroup); + hideOpacityAnimation = compositor.CreateScalarKeyFrameAnimation(); + hideOpacityAnimation.InsertKeyFrame(1.0f, 0.0f); + hideOpacityAnimation.Duration = TimeSpan.FromMilliseconds(hideDuration); + hideOpacityAnimation.DelayTime = TimeSpan.FromMilliseconds(hideDelay); + hideOpacityAnimation.Target = "Opacity"; } - public static void EnableImplicitAnimation(this UIElement element, VisualPropertyType typeToAnimate, - double duration = 800, double delay = 0, CompositionEasingFunction easing = null) + if (!hideToOffset.Equals(0.0f)) { - var visual = element.Visual(); - var compositor = visual.Compositor; - - var animationCollection = compositor.CreateImplicitAnimationCollection(); - - foreach (var type in UtilExtensions.GetValues()) - { - if (!typeToAnimate.HasFlag(type)) continue; - - var animation = CreateAnimationByType(compositor, type, duration, delay, easing); - - if (animation != null) - { - animationCollection[type.ToString()] = animation; - } - } - - visual.ImplicitAnimations = animationCollection; + hideOffsetAnimation = compositor.CreateScalarKeyFrameAnimation(); + hideOffsetAnimation.InsertKeyFrame(1.0f, hideToOffset); + hideOffsetAnimation.Duration = TimeSpan.FromMilliseconds(hideDuration); + hideOffsetAnimation.DelayTime = TimeSpan.FromMilliseconds(hideDelay); + hideOffsetAnimation.Target = $"Translation.{axis}"; } - public static void EnableImplicitAnimation(this Visual visual, VisualPropertyType typeToAnimate, - double duration = 800, double delay = 0, CompositionEasingFunction easing = null) + if (centerPoint.HasValue) { - var compositor = visual.Compositor; - - var animationCollection = compositor.CreateImplicitAnimationCollection(); - - foreach (var type in UtilExtensions.GetValues()) - { - if (!typeToAnimate.HasFlag(type)) continue; - - var animation = CreateAnimationByType(compositor, type, duration, delay, easing); - - if (animation != null) - { - animationCollection[type.ToString()] = animation; - } - } - - visual.ImplicitAnimations = animationCollection; + elementVisual.CenterPoint = centerPoint.Value; } - private static KeyFrameAnimation CreateAnimationByType(Compositor compositor, VisualPropertyType type, - double duration = 800, double delay = 0, CompositionEasingFunction easing = null) + if (!hideToScale.Equals(1.0f)) { - KeyFrameAnimation animation; - - switch (type) - { - case VisualPropertyType.Offset: - case VisualPropertyType.Scale: - animation = compositor.CreateVector3KeyFrameAnimation(); - break; - case VisualPropertyType.Size: - animation = compositor.CreateVector2KeyFrameAnimation(); - break; - case VisualPropertyType.Opacity: - case VisualPropertyType.RotationAngleInDegrees: - animation = compositor.CreateScalarKeyFrameAnimation(); - break; - default: - return null; - } - - animation.InsertExpressionKeyFrame(1.0f, "this.FinalValue", easing); - animation.Duration = TimeSpan.FromMilliseconds(duration); - animation.DelayTime = TimeSpan.FromMilliseconds(delay); - animation.Target = type.ToString(); - - return animation; + hideScaleAnimation = compositor.CreateVector2KeyFrameAnimation(); + hideScaleAnimation.InsertKeyFrame(1.0f, new Vector2(hideToScale)); + hideScaleAnimation.Duration = TimeSpan.FromMilliseconds(hideDuration); + hideScaleAnimation.DelayTime = TimeSpan.FromMilliseconds(hideDelay); + hideScaleAnimation.Target = "Scale.XY"; } + + var hideAnimationGroup = compositor.CreateAnimationGroup(); + if (hideOpacityAnimation != null) + { + hideAnimationGroup.Add(hideOpacityAnimation); + } + if (hideOffsetAnimation != null) + { + hideAnimationGroup.Add(hideOffsetAnimation); + } + if (hideScaleAnimation != null) + { + hideAnimationGroup.Add(hideScaleAnimation); + } + + ElementCompositionPreview.SetImplicitHideAnimation(element, hideAnimationGroup); + + if (animateOpacity) + { + showOpacityAnimation = compositor.CreateScalarKeyFrameAnimation(); + showOpacityAnimation.InsertKeyFrame(1.0f, 1.0f); + showOpacityAnimation.Duration = TimeSpan.FromMilliseconds(showDuration); + showOpacityAnimation.DelayTime = TimeSpan.FromMilliseconds(showDelay); + showOpacityAnimation.Target = "Opacity"; + } + + if (!showFromOffset.Equals(0.0f)) + { + showOffsetAnimation = compositor.CreateScalarKeyFrameAnimation(); + showOffsetAnimation.InsertKeyFrame(0.0f, showFromOffset); + showOffsetAnimation.InsertKeyFrame(1.0f, 0.0f); + showOffsetAnimation.Duration = TimeSpan.FromMilliseconds(showDuration); + showOffsetAnimation.DelayTime = TimeSpan.FromMilliseconds(showDelay); + showOffsetAnimation.Target = $"Translation.{axis}"; + } + + if (!showFromScale.Equals(1.0f)) + { + showeScaleAnimation = compositor.CreateVector2KeyFrameAnimation(); + showeScaleAnimation.InsertKeyFrame(0.0f, new Vector2(showFromScale)); + showeScaleAnimation.InsertKeyFrame(1.0f, Vector2.One); + showeScaleAnimation.Duration = TimeSpan.FromMilliseconds(showDuration); + showeScaleAnimation.DelayTime = TimeSpan.FromMilliseconds(showDelay); + showeScaleAnimation.Target = "Scale.XY"; + } + + var showAnimationGroup = compositor.CreateAnimationGroup(); + if (showOpacityAnimation != null) + { + showAnimationGroup.Add(showOpacityAnimation); + } + if (showOffsetAnimation != null) + { + showAnimationGroup.Add(showOffsetAnimation); + } + if (showeScaleAnimation != null) + { + showAnimationGroup.Add(showeScaleAnimation); + } + + ElementCompositionPreview.SetImplicitShowAnimation(element, showAnimationGroup); + } + + public static void EnableImplicitAnimation(this UIElement element, VisualPropertyType typeToAnimate, + double duration = 800, double delay = 0, CompositionEasingFunction easing = null) + { + var visual = element.Visual(); + var compositor = visual.Compositor; + + var animationCollection = compositor.CreateImplicitAnimationCollection(); + + foreach (var type in UtilExtensions.GetValues()) + { + if (!typeToAnimate.HasFlag(type)) continue; + + var animation = CreateAnimationByType(compositor, type, duration, delay, easing); + + if (animation != null) + { + animationCollection[type.ToString()] = animation; + } + } + + visual.ImplicitAnimations = animationCollection; + } + + public static void EnableImplicitAnimation(this Visual visual, VisualPropertyType typeToAnimate, + double duration = 800, double delay = 0, CompositionEasingFunction easing = null) + { + var compositor = visual.Compositor; + + var animationCollection = compositor.CreateImplicitAnimationCollection(); + + foreach (var type in UtilExtensions.GetValues()) + { + if (!typeToAnimate.HasFlag(type)) continue; + + var animation = CreateAnimationByType(compositor, type, duration, delay, easing); + + if (animation != null) + { + animationCollection[type.ToString()] = animation; + } + } + + visual.ImplicitAnimations = animationCollection; + } + + private static KeyFrameAnimation CreateAnimationByType(Compositor compositor, VisualPropertyType type, + double duration = 800, double delay = 0, CompositionEasingFunction easing = null) + { + KeyFrameAnimation animation; + + switch (type) + { + case VisualPropertyType.Offset: + case VisualPropertyType.Scale: + animation = compositor.CreateVector3KeyFrameAnimation(); + break; + case VisualPropertyType.Size: + animation = compositor.CreateVector2KeyFrameAnimation(); + break; + case VisualPropertyType.Opacity: + case VisualPropertyType.RotationAngleInDegrees: + animation = compositor.CreateScalarKeyFrameAnimation(); + break; + default: + return null; + } + + animation.InsertExpressionKeyFrame(1.0f, "this.FinalValue", easing); + animation.Duration = TimeSpan.FromMilliseconds(duration); + animation.DelayTime = TimeSpan.FromMilliseconds(delay); + animation.Target = type.ToString(); + + return animation; } } diff --git a/Wino.Core.UWP/Extensions/CompositionExtensions.Size.cs b/Wino.Core.UWP/Extensions/CompositionExtensions.Size.cs index 42adf0af..93bcb248 100644 --- a/Wino.Core.UWP/Extensions/CompositionExtensions.Size.cs +++ b/Wino.Core.UWP/Extensions/CompositionExtensions.Size.cs @@ -4,124 +4,123 @@ using System.Threading.Tasks; using Windows.UI.Composition; using Windows.UI.Xaml; -namespace Wino.Extensions +namespace Wino.Extensions; + +public static partial class CompositionExtensions { - public static partial class CompositionExtensions + public static void StartSizeAnimation(this UIElement element, Vector2? from = null, Vector2? to = null, + double duration = 800, int delay = 0, CompositionEasingFunction easing = null, Action completed = null, + AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count) { - public static void StartSizeAnimation(this UIElement element, Vector2? from = null, Vector2? to = null, - double duration = 800, int delay = 0, CompositionEasingFunction easing = null, Action completed = null, - AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count) + CompositionScopedBatch batch = null; + + var visual = element.Visual(); + var compositor = visual.Compositor; + + if (completed != null) { - CompositionScopedBatch batch = null; - - var visual = element.Visual(); - var compositor = visual.Compositor; - - if (completed != null) - { - batch = compositor.CreateScopedBatch(CompositionBatchTypes.Animation); - batch.Completed += (s, e) => completed(); - } - - if (to == null) - { - to = Vector2.One; - } - - visual.StartAnimation("Size", - compositor.CreateVector2KeyFrameAnimation(from, to.Value, duration, delay, easing, iterationBehavior)); - - batch?.End(); - } - - public static void StartSizeAnimation(this Visual visual, Vector2? from = null, Vector2? to = null, - double duration = 800, int delay = 0, CompositionEasingFunction easing = null, Action completed = null, - AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count) - { - CompositionScopedBatch batch = null; - var compositor = visual.Compositor; - - if (completed != null) - { - batch = compositor.CreateScopedBatch(CompositionBatchTypes.Animation); - batch.Completed += (s, e) => completed(); - } - - if (to == null) - { - to = Vector2.One; - } - - visual.StartAnimation("Size", - compositor.CreateVector2KeyFrameAnimation(from, to.Value, duration, delay, easing, iterationBehavior)); - - batch?.End(); - } - - public static Task StartSizeAnimationAsync(this UIElement element, Vector2? from = null, Vector2? to = null, - double duration = 800, int delay = 0, CompositionEasingFunction easing = null, - AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count) - { - CompositionScopedBatch batch; - - var visual = element.Visual(); - var compositor = visual.Compositor; - - var taskSource = new TaskCompletionSource(); - - void Completed(object o, CompositionBatchCompletedEventArgs e) - { - batch.Completed -= Completed; - taskSource.SetResult(true); - } - batch = compositor.CreateScopedBatch(CompositionBatchTypes.Animation); - batch.Completed += Completed; - - if (to == null) - { - to = Vector2.One; - } - - visual.StartAnimation("Size", - compositor.CreateVector2KeyFrameAnimation(from, to.Value, duration, delay, easing, iterationBehavior)); - - batch.End(); - - return taskSource.Task; + batch.Completed += (s, e) => completed(); } - public static Task StartSizeAnimationAsync(this Visual visual, Vector2? from = null, Vector2? to = null, - double duration = 800, int delay = 0, CompositionEasingFunction easing = null, - AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count) + if (to == null) { - CompositionScopedBatch batch; - - var compositor = visual.Compositor; - - var taskSource = new TaskCompletionSource(); - - void Completed(object o, CompositionBatchCompletedEventArgs e) - { - batch.Completed -= Completed; - taskSource.SetResult(true); - } - - batch = compositor.CreateScopedBatch(CompositionBatchTypes.Animation); - batch.Completed += Completed; - - if (to == null) - { - to = Vector2.One; - } - - visual.StartAnimation("Size", - compositor.CreateVector2KeyFrameAnimation(from, to.Value, duration, delay, easing, iterationBehavior)); - - batch.End(); - - return taskSource.Task; + to = Vector2.One; } + visual.StartAnimation("Size", + compositor.CreateVector2KeyFrameAnimation(from, to.Value, duration, delay, easing, iterationBehavior)); + + batch?.End(); } + + public static void StartSizeAnimation(this Visual visual, Vector2? from = null, Vector2? to = null, + double duration = 800, int delay = 0, CompositionEasingFunction easing = null, Action completed = null, + AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count) + { + CompositionScopedBatch batch = null; + var compositor = visual.Compositor; + + if (completed != null) + { + batch = compositor.CreateScopedBatch(CompositionBatchTypes.Animation); + batch.Completed += (s, e) => completed(); + } + + if (to == null) + { + to = Vector2.One; + } + + visual.StartAnimation("Size", + compositor.CreateVector2KeyFrameAnimation(from, to.Value, duration, delay, easing, iterationBehavior)); + + batch?.End(); + } + + public static Task StartSizeAnimationAsync(this UIElement element, Vector2? from = null, Vector2? to = null, + double duration = 800, int delay = 0, CompositionEasingFunction easing = null, + AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count) + { + CompositionScopedBatch batch; + + var visual = element.Visual(); + var compositor = visual.Compositor; + + var taskSource = new TaskCompletionSource(); + + void Completed(object o, CompositionBatchCompletedEventArgs e) + { + batch.Completed -= Completed; + taskSource.SetResult(true); + } + + batch = compositor.CreateScopedBatch(CompositionBatchTypes.Animation); + batch.Completed += Completed; + + if (to == null) + { + to = Vector2.One; + } + + visual.StartAnimation("Size", + compositor.CreateVector2KeyFrameAnimation(from, to.Value, duration, delay, easing, iterationBehavior)); + + batch.End(); + + return taskSource.Task; + } + + public static Task StartSizeAnimationAsync(this Visual visual, Vector2? from = null, Vector2? to = null, + double duration = 800, int delay = 0, CompositionEasingFunction easing = null, + AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count) + { + CompositionScopedBatch batch; + + var compositor = visual.Compositor; + + var taskSource = new TaskCompletionSource(); + + void Completed(object o, CompositionBatchCompletedEventArgs e) + { + batch.Completed -= Completed; + taskSource.SetResult(true); + } + + batch = compositor.CreateScopedBatch(CompositionBatchTypes.Animation); + batch.Completed += Completed; + + if (to == null) + { + to = Vector2.One; + } + + visual.StartAnimation("Size", + compositor.CreateVector2KeyFrameAnimation(from, to.Value, duration, delay, easing, iterationBehavior)); + + batch.End(); + + return taskSource.Task; + } + } diff --git a/Wino.Core.UWP/Extensions/ElementThemeExtensions.cs b/Wino.Core.UWP/Extensions/ElementThemeExtensions.cs index 4f7fd145..4413a2a6 100644 --- a/Wino.Core.UWP/Extensions/ElementThemeExtensions.cs +++ b/Wino.Core.UWP/Extensions/ElementThemeExtensions.cs @@ -1,34 +1,33 @@ using Windows.UI.Xaml; using Wino.Core.Domain.Enums; -namespace Wino.Core.UWP.Extensions +namespace Wino.Core.UWP.Extensions; + +public static class ElementThemeExtensions { - public static class ElementThemeExtensions + public static ApplicationElementTheme ToWinoElementTheme(this ElementTheme elementTheme) { - public static ApplicationElementTheme ToWinoElementTheme(this ElementTheme elementTheme) + switch (elementTheme) { - switch (elementTheme) - { - case ElementTheme.Light: - return ApplicationElementTheme.Light; - case ElementTheme.Dark: - return ApplicationElementTheme.Dark; - } - - return ApplicationElementTheme.Default; + case ElementTheme.Light: + return ApplicationElementTheme.Light; + case ElementTheme.Dark: + return ApplicationElementTheme.Dark; } - public static ElementTheme ToWindowsElementTheme(this ApplicationElementTheme elementTheme) - { - switch (elementTheme) - { - case ApplicationElementTheme.Light: - return ElementTheme.Light; - case ApplicationElementTheme.Dark: - return ElementTheme.Dark; - } + return ApplicationElementTheme.Default; + } - return ElementTheme.Default; + public static ElementTheme ToWindowsElementTheme(this ApplicationElementTheme elementTheme) + { + switch (elementTheme) + { + case ApplicationElementTheme.Light: + return ElementTheme.Light; + case ApplicationElementTheme.Dark: + return ElementTheme.Dark; } + + return ElementTheme.Default; } } diff --git a/Wino.Core.UWP/Extensions/StartupTaskStateExtensions.cs b/Wino.Core.UWP/Extensions/StartupTaskStateExtensions.cs index 652fb2fa..87ab5ec2 100644 --- a/Wino.Core.UWP/Extensions/StartupTaskStateExtensions.cs +++ b/Wino.Core.UWP/Extensions/StartupTaskStateExtensions.cs @@ -1,25 +1,24 @@ using Windows.ApplicationModel; using Wino.Core.Domain.Enums; -namespace Wino.Core.UWP.Extensions +namespace Wino.Core.UWP.Extensions; + +public static class StartupTaskStateExtensions { - public static class StartupTaskStateExtensions + public static StartupBehaviorResult AsStartupBehaviorResult(this StartupTaskState state) { - public static StartupBehaviorResult AsStartupBehaviorResult(this StartupTaskState state) + switch (state) { - switch (state) - { - case StartupTaskState.Disabled: - case StartupTaskState.DisabledByPolicy: - return StartupBehaviorResult.Disabled; - case StartupTaskState.DisabledByUser: - return StartupBehaviorResult.DisabledByUser; - case StartupTaskState.Enabled: - case StartupTaskState.EnabledByPolicy: - return StartupBehaviorResult.Enabled; - default: - return StartupBehaviorResult.Fatal; - } + case StartupTaskState.Disabled: + case StartupTaskState.DisabledByPolicy: + return StartupBehaviorResult.Disabled; + case StartupTaskState.DisabledByUser: + return StartupBehaviorResult.DisabledByUser; + case StartupTaskState.Enabled: + case StartupTaskState.EnabledByPolicy: + return StartupBehaviorResult.Enabled; + default: + return StartupBehaviorResult.Fatal; } } } diff --git a/Wino.Core.UWP/Extensions/StorageFileExtensions.cs b/Wino.Core.UWP/Extensions/StorageFileExtensions.cs index 98b2aae4..7cd6f118 100644 --- a/Wino.Core.UWP/Extensions/StorageFileExtensions.cs +++ b/Wino.Core.UWP/Extensions/StorageFileExtensions.cs @@ -4,28 +4,27 @@ using System.Threading.Tasks; using Windows.Storage; using Wino.Core.Domain.Models.Common; -namespace Wino.Core.UWP.Extensions +namespace Wino.Core.UWP.Extensions; + +public static class StorageFileExtensions { - public static class StorageFileExtensions + public static async Task ToSharedFileAsync(this Windows.Storage.StorageFile storageFile) { - public static async Task ToSharedFileAsync(this Windows.Storage.StorageFile storageFile) + var content = await storageFile.ToByteArrayAsync(); + + return new SharedFile(storageFile.Path, content); + } + + public static async Task ToByteArrayAsync(this StorageFile file) + { + if (file == null) + throw new ArgumentNullException(nameof(file)); + + using (var stream = await file.OpenReadAsync()) + using (var memoryStream = new MemoryStream()) { - var content = await storageFile.ToByteArrayAsync(); - - return new SharedFile(storageFile.Path, content); - } - - public static async Task ToByteArrayAsync(this StorageFile file) - { - if (file == null) - throw new ArgumentNullException(nameof(file)); - - using (var stream = await file.OpenReadAsync()) - using (var memoryStream = new MemoryStream()) - { - await stream.AsStreamForRead().CopyToAsync(memoryStream); - return memoryStream.ToArray(); - } + await stream.AsStreamForRead().CopyToAsync(memoryStream); + return memoryStream.ToArray(); } } } diff --git a/Wino.Core.UWP/Extensions/UIExtensions.cs b/Wino.Core.UWP/Extensions/UIExtensions.cs index 65a4723b..698b654a 100644 --- a/Wino.Core.UWP/Extensions/UIExtensions.cs +++ b/Wino.Core.UWP/Extensions/UIExtensions.cs @@ -1,20 +1,19 @@ using Microsoft.UI.Xaml.Controls; using Wino.Core.Domain.Enums; -namespace Wino.Extensions +namespace Wino.Extensions; + +public static class UIExtensions { - public static class UIExtensions + public static InfoBarSeverity AsMUXCInfoBarSeverity(this InfoBarMessageType messageType) { - public static InfoBarSeverity AsMUXCInfoBarSeverity(this InfoBarMessageType messageType) + return messageType switch { - return messageType switch - { - InfoBarMessageType.Error => InfoBarSeverity.Error, - InfoBarMessageType.Warning => InfoBarSeverity.Warning, - InfoBarMessageType.Information => InfoBarSeverity.Informational, - InfoBarMessageType.Success => InfoBarSeverity.Success, - _ => InfoBarSeverity.Informational - }; - } + InfoBarMessageType.Error => InfoBarSeverity.Error, + InfoBarMessageType.Warning => InfoBarSeverity.Warning, + InfoBarMessageType.Information => InfoBarSeverity.Informational, + InfoBarMessageType.Success => InfoBarSeverity.Success, + _ => InfoBarSeverity.Informational + }; } } diff --git a/Wino.Core.UWP/Extensions/UtilExtensions.cs b/Wino.Core.UWP/Extensions/UtilExtensions.cs index ff64530e..6360a5df 100644 --- a/Wino.Core.UWP/Extensions/UtilExtensions.cs +++ b/Wino.Core.UWP/Extensions/UtilExtensions.cs @@ -8,101 +8,100 @@ using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Hosting; using Windows.UI.Xaml.Media; -namespace Wino.Extensions +namespace Wino.Extensions; + +public static class UtilExtensions { - public static class UtilExtensions + public static float ToFloat(this double value) => (float)value; + + public static List Children(this DependencyObject parent) { - public static float ToFloat(this double value) => (float)value; + var list = new List(); - public static List Children(this DependencyObject parent) + for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) { - var list = new List(); + var child = VisualTreeHelper.GetChild(parent, i); - for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) + if (child is FrameworkElement) { - var child = VisualTreeHelper.GetChild(parent, i); - - if (child is FrameworkElement) - { - list.Add(child as FrameworkElement); - } - - list.AddRange(Children(child)); + list.Add(child as FrameworkElement); } - return list; + list.AddRange(Children(child)); } - public static T GetChildByName(this DependencyObject parent, string name) - { - var childControls = Children(parent); - var controls = childControls.OfType(); - - if (controls == null) - { - return default(T); - } - - var control = controls - .Where(x => x.Name.Equals(name)) - .Cast() - .First(); - - return control; - } - - public static Visual Visual(this UIElement element) => - ElementCompositionPreview.GetElementVisual(element); - - public static void SetChildVisual(this UIElement element, Visual childVisual) => - ElementCompositionPreview.SetElementChildVisual(element, childVisual); - - public static Point RelativePosition(this UIElement element, UIElement other) => - element.TransformToVisual(other).TransformPoint(new Point(0, 0)); - - public static bool IsFullyVisibile(this FrameworkElement element, FrameworkElement parent) - { - if (element == null || parent == null) - return false; - - if (element.Visibility != Visibility.Visible) - return false; - - var elementBounds = element.TransformToVisual(parent).TransformBounds(new Windows.Foundation.Rect(0, 0, element.ActualWidth, element.ActualHeight)); - var containerBounds = new Windows.Foundation.Rect(0, 0, parent.ActualWidth, parent.ActualHeight); - - var originalElementWidth = elementBounds.Width; - var originalElementHeight = elementBounds.Height; - - elementBounds.Intersect(containerBounds); - - var newElementWidth = elementBounds.Width; - var newElementHeight = elementBounds.Height; - - return originalElementWidth.Equals(newElementWidth) && originalElementHeight.Equals(newElementHeight); - } - - public static void ScrollToElement(this ScrollViewer scrollViewer, FrameworkElement element, - bool isVerticalScrolling = true, bool smoothScrolling = true, float? zoomFactor = null, bool bringToTopOrLeft = true, bool addMargin = true) - { - if (!bringToTopOrLeft && element.IsFullyVisibile(scrollViewer)) - return; - - var contentArea = (FrameworkElement)scrollViewer.Content; - var position = element.RelativePosition(contentArea); - - if (isVerticalScrolling) - { - // Accomodate for additional header. - scrollViewer.ChangeView(null, Math.Max(0, position.Y - (addMargin ? 48 : 0)), zoomFactor, !smoothScrolling); - } - else - { - scrollViewer.ChangeView(position.X, null, zoomFactor, !smoothScrolling); - } - } - - - public static T[] GetValues() where T : struct, Enum => Enum.GetValues(); + return list; } + + public static T GetChildByName(this DependencyObject parent, string name) + { + var childControls = Children(parent); + var controls = childControls.OfType(); + + if (controls == null) + { + return default(T); + } + + var control = controls + .Where(x => x.Name.Equals(name)) + .Cast() + .First(); + + return control; + } + + public static Visual Visual(this UIElement element) => + ElementCompositionPreview.GetElementVisual(element); + + public static void SetChildVisual(this UIElement element, Visual childVisual) => + ElementCompositionPreview.SetElementChildVisual(element, childVisual); + + public static Point RelativePosition(this UIElement element, UIElement other) => + element.TransformToVisual(other).TransformPoint(new Point(0, 0)); + + public static bool IsFullyVisibile(this FrameworkElement element, FrameworkElement parent) + { + if (element == null || parent == null) + return false; + + if (element.Visibility != Visibility.Visible) + return false; + + var elementBounds = element.TransformToVisual(parent).TransformBounds(new Windows.Foundation.Rect(0, 0, element.ActualWidth, element.ActualHeight)); + var containerBounds = new Windows.Foundation.Rect(0, 0, parent.ActualWidth, parent.ActualHeight); + + var originalElementWidth = elementBounds.Width; + var originalElementHeight = elementBounds.Height; + + elementBounds.Intersect(containerBounds); + + var newElementWidth = elementBounds.Width; + var newElementHeight = elementBounds.Height; + + return originalElementWidth.Equals(newElementWidth) && originalElementHeight.Equals(newElementHeight); + } + + public static void ScrollToElement(this ScrollViewer scrollViewer, FrameworkElement element, + bool isVerticalScrolling = true, bool smoothScrolling = true, float? zoomFactor = null, bool bringToTopOrLeft = true, bool addMargin = true) + { + if (!bringToTopOrLeft && element.IsFullyVisibile(scrollViewer)) + return; + + var contentArea = (FrameworkElement)scrollViewer.Content; + var position = element.RelativePosition(contentArea); + + if (isVerticalScrolling) + { + // Accomodate for additional header. + scrollViewer.ChangeView(null, Math.Max(0, position.Y - (addMargin ? 48 : 0)), zoomFactor, !smoothScrolling); + } + else + { + scrollViewer.ChangeView(position.X, null, zoomFactor, !smoothScrolling); + } + } + + + public static T[] GetValues() where T : struct, Enum => Enum.GetValues(); } diff --git a/Wino.Core.UWP/Helpers/WinoVisualTreeHelper.cs b/Wino.Core.UWP/Helpers/WinoVisualTreeHelper.cs index 10c15bc7..86f8181c 100644 --- a/Wino.Core.UWP/Helpers/WinoVisualTreeHelper.cs +++ b/Wino.Core.UWP/Helpers/WinoVisualTreeHelper.cs @@ -2,51 +2,50 @@ using Windows.UI.Xaml; using Windows.UI.Xaml.Media; -namespace Wino.Helpers +namespace Wino.Helpers; + +public static class WinoVisualTreeHelper { - public static class WinoVisualTreeHelper + public static T GetChildObject(DependencyObject obj, string name) where T : FrameworkElement { - public static T GetChildObject(DependencyObject obj, string name) where T : FrameworkElement + DependencyObject child = null; + T grandChild = null; + + for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++) { - DependencyObject child = null; - T grandChild = null; + child = VisualTreeHelper.GetChild(obj, i); - for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++) + if (child is T && (((T)child).Name == name | string.IsNullOrEmpty(name))) { - child = VisualTreeHelper.GetChild(obj, i); - - if (child is T && (((T)child).Name == name | string.IsNullOrEmpty(name))) - { - return (T)child; - } - else - { - grandChild = GetChildObject(child, name); - } - if (grandChild != null) - { - return grandChild; - } + return (T)child; } - return null; - } - - public static IEnumerable FindDescendants(this DependencyObject depObj) where T : DependencyObject - { - if (depObj != null) + else { - for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) - { - var child = VisualTreeHelper.GetChild(depObj, i); - if (child != null && child is T) - { - yield return (T)child; - } + grandChild = GetChildObject(child, name); + } + if (grandChild != null) + { + return grandChild; + } + } + return null; + } - foreach (T childOfChild in FindDescendants(child)) - { - yield return childOfChild; - } + public static IEnumerable FindDescendants(this DependencyObject depObj) where T : DependencyObject + { + if (depObj != null) + { + for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) + { + var child = VisualTreeHelper.GetChild(depObj, i); + if (child != null && child is T) + { + yield return (T)child; + } + + foreach (T childOfChild in FindDescendants(child)) + { + yield return childOfChild; } } } diff --git a/Wino.Core.UWP/Helpers/XamlHelpers.cs b/Wino.Core.UWP/Helpers/XamlHelpers.cs index 45205fdf..98d54e56 100644 --- a/Wino.Core.UWP/Helpers/XamlHelpers.cs +++ b/Wino.Core.UWP/Helpers/XamlHelpers.cs @@ -16,351 +16,350 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.MailItem; using Wino.Core.UWP.Controls; -namespace Wino.Helpers +namespace Wino.Helpers; + +public static class XamlHelpers { - public static class XamlHelpers + private const string TwentyFourHourTimeFormat = "HH:mm"; + private const string TwelveHourTimeFormat = "hh:mm tt"; + + #region Converters + + public static bool IsMultiple(int count) => count > 1; + public static bool ReverseIsMultiple(int count) => count < 1; + public static PopupPlacementMode GetPlaccementModeForCalendarType(CalendarDisplayType type) { - private const string TwentyFourHourTimeFormat = "HH:mm"; - private const string TwelveHourTimeFormat = "hh:mm tt"; - - #region Converters - - public static bool IsMultiple(int count) => count > 1; - public static bool ReverseIsMultiple(int count) => count < 1; - public static PopupPlacementMode GetPlaccementModeForCalendarType(CalendarDisplayType type) + return type switch { - return type switch - { - CalendarDisplayType.Week => PopupPlacementMode.Right, - _ => PopupPlacementMode.Bottom, - }; - } - - - - - public static Visibility ReverseBoolToVisibilityConverter(bool value) => value ? Visibility.Collapsed : Visibility.Visible; - public static Visibility ReverseVisibilityConverter(Visibility visibility) => visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible; - public static bool ReverseBoolConverter(bool value) => !value; - public static bool ShouldDisplayPreview(string text) => text.Any(x => char.IsLetter(x)); - public static bool CountToBooleanConverter(int value) => value > 0; - public static bool ObjectEquals(object obj1, object obj2) => object.Equals(obj1, obj2); - public static Visibility CountToVisibilityConverter(int value) => value > 0 ? Visibility.Visible : Visibility.Collapsed; - public static Visibility CountToVisibilityConverterWithThreshold(int value, int threshold) => value > threshold ? Visibility.Visible : Visibility.Collapsed; - public static InfoBarSeverity InfoBarSeverityConverter(InfoBarMessageType messageType) - { - return messageType switch - { - InfoBarMessageType.Information => InfoBarSeverity.Informational, - InfoBarMessageType.Success => InfoBarSeverity.Success, - InfoBarMessageType.Warning => InfoBarSeverity.Warning, - InfoBarMessageType.Error => InfoBarSeverity.Error, - _ => InfoBarSeverity.Informational, - }; - } - - public static SolidColorBrush GetReadableTextColor(string backgroundColor) - { - if (!backgroundColor.StartsWith("#")) throw new ArgumentException("Hex color must start with #."); - - backgroundColor = backgroundColor.TrimStart('#'); - - if (backgroundColor.Length == 6) - { - var r = int.Parse(backgroundColor.Substring(0, 2), NumberStyles.HexNumber); - var g = int.Parse(backgroundColor.Substring(2, 2), NumberStyles.HexNumber); - var b = int.Parse(backgroundColor.Substring(4, 2), NumberStyles.HexNumber); - - // Calculate relative luminance - double luminance = (0.2126 * GetLinearValue(r)) + - (0.7152 * GetLinearValue(g)) + - (0.0722 * GetLinearValue(b)); - - return luminance > 0.5 ? new SolidColorBrush(Colors.Black) : new SolidColorBrush(Colors.White); - } - else - { - throw new ArgumentException("Hex color must be 6 characters long (e.g., #RRGGBB)."); - } - } - - private static double GetLinearValue(int colorComponent) - { - double sRGB = colorComponent / 255.0; - return sRGB <= 0.03928 ? sRGB / 12.92 : Math.Pow((sRGB + 0.055) / 1.055, 2.4); - } - - public static Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode NavigationViewDisplayModeConverter(SplitViewDisplayMode splitViewDisplayMode) - { - return splitViewDisplayMode switch - { - SplitViewDisplayMode.CompactOverlay => Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Compact, - SplitViewDisplayMode.CompactInline => Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Minimal, - SplitViewDisplayMode.Overlay => Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Expanded, - SplitViewDisplayMode.Inline => Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Expanded, - _ => Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Minimal, - }; - } - - public static string GetColorFromHex(Color color) => color.ToHex(); - public static Color GetWindowsColorFromHex(string hex) => hex.ToColor(); - - public static SolidColorBrush GetSolidColorBrushFromHex(string colorHex) => string.IsNullOrEmpty(colorHex) ? new SolidColorBrush(Colors.Transparent) : new SolidColorBrush(colorHex.ToColor()); - public static Visibility IsSelectionModeMultiple(ListViewSelectionMode mode) => mode == ListViewSelectionMode.Multiple ? Visibility.Visible : Visibility.Collapsed; - public static FontWeight GetFontWeightBySyncState(bool isSyncing) => isSyncing ? FontWeights.SemiBold : FontWeights.Normal; - public static FontWeight GetFontWeightByChildSelectedState(bool isChildSelected) => isChildSelected ? FontWeights.SemiBold : FontWeights.Normal; - public static Visibility StringToVisibilityConverter(string value) => string.IsNullOrWhiteSpace(value) ? Visibility.Collapsed : Visibility.Visible; - public static Visibility StringToVisibilityReversedConverter(string value) => string.IsNullOrWhiteSpace(value) ? Visibility.Visible : Visibility.Collapsed; - public static string GetMailItemDisplaySummaryForListing(bool isDraft, DateTime receivedDate, bool prefer24HourTime) - { - if (isDraft) - return Translator.Draft; - else - { - var localTime = receivedDate.ToLocalTime(); - - return prefer24HourTime ? localTime.ToString(TwentyFourHourTimeFormat) : localTime.ToString(TwelveHourTimeFormat); - } - } - public static string GetCreationDateString(DateTime date, bool prefer24HourTime) - { - var localTime = date.ToLocalTime(); - return $"{localTime.ToLongDateString()} {(prefer24HourTime ? localTime.ToString(TwentyFourHourTimeFormat) : localTime.ToString(TwelveHourTimeFormat))}"; - } - public static string GetMailGroupDateString(object groupObject) - { - if (groupObject is string stringObject) - return stringObject; - - object dateObject = null; - - // From regular mail header template - if (groupObject is DateTime groupedDate) - dateObject = groupedDate; - else if (groupObject is IGrouping groupKey) - { - // From semantic group header. - dateObject = groupKey.Key; - } - - if (dateObject != null) - { - if (dateObject is DateTime dateTimeValue) - { - if (dateTimeValue == DateTime.Today) - return Translator.Today; - else if (dateTimeValue == DateTime.Today.AddDays(-1)) - return Translator.Yesterday; - else - return dateTimeValue.ToLongDateString(); - } - else - return dateObject.ToString(); - } - - return Translator.UnknownDateHeader; - } - public static bool ConnectionStatusEquals(WinoServerConnectionStatus winoServerConnectionStatus, WinoServerConnectionStatus connectionStatus) => winoServerConnectionStatus == connectionStatus; - - #endregion - - #region Wino Font Icon Transformation - - public static WinoIconGlyph GetWinoIconGlyph(FilterOptionType type) => type switch - { - FilterOptionType.All => WinoIconGlyph.Mail, - FilterOptionType.Unread => WinoIconGlyph.MarkUnread, - FilterOptionType.Flagged => WinoIconGlyph.Flag, - FilterOptionType.Mentions => WinoIconGlyph.NewMail, - FilterOptionType.Files => WinoIconGlyph.Attachment, - _ => WinoIconGlyph.None, + CalendarDisplayType.Week => PopupPlacementMode.Right, + _ => PopupPlacementMode.Bottom, }; - - public static WinoIconGlyph GetWinoIconGlyph(SortingOptionType type) => type switch - { - SortingOptionType.Sender => WinoIconGlyph.SortTextDesc, - SortingOptionType.ReceiveDate => WinoIconGlyph.SortLinesDesc, - _ => WinoIconGlyph.None, - }; - - public static WinoIconGlyph GetWinoIconGlyph(MailOperation operation) - { - return operation switch - { - MailOperation.None => WinoIconGlyph.None, - MailOperation.Archive => WinoIconGlyph.Archive, - MailOperation.UnArchive => WinoIconGlyph.UnArchive, - MailOperation.SoftDelete => WinoIconGlyph.Delete, - MailOperation.HardDelete => WinoIconGlyph.Delete, - MailOperation.Move => WinoIconGlyph.Forward, - MailOperation.MoveToJunk => WinoIconGlyph.Blocked, - MailOperation.MoveToFocused => WinoIconGlyph.None, - MailOperation.MoveToOther => WinoIconGlyph.None, - MailOperation.AlwaysMoveToOther => WinoIconGlyph.None, - MailOperation.AlwaysMoveToFocused => WinoIconGlyph.None, - MailOperation.SetFlag => WinoIconGlyph.Flag, - MailOperation.ClearFlag => WinoIconGlyph.ClearFlag, - MailOperation.MarkAsRead => WinoIconGlyph.MarkRead, - MailOperation.MarkAsUnread => WinoIconGlyph.MarkUnread, - MailOperation.MarkAsNotJunk => WinoIconGlyph.Blocked, - MailOperation.Ignore => WinoIconGlyph.Ignore, - MailOperation.Reply => WinoIconGlyph.Reply, - MailOperation.ReplyAll => WinoIconGlyph.ReplyAll, - MailOperation.Zoom => WinoIconGlyph.Zoom, - MailOperation.SaveAs => WinoIconGlyph.Save, - MailOperation.Print => WinoIconGlyph.Print, - MailOperation.Find => WinoIconGlyph.Find, - MailOperation.Forward => WinoIconGlyph.Forward, - MailOperation.DarkEditor => WinoIconGlyph.DarkEditor, - MailOperation.LightEditor => WinoIconGlyph.LightEditor, - MailOperation.ViewMessageSource => WinoIconGlyph.ViewMessageSource, - _ => WinoIconGlyph.None, - }; - } - - public static WinoIconGlyph GetPathGeometry(FolderOperation operation) - { - return operation switch - { - FolderOperation.None => WinoIconGlyph.None, - FolderOperation.Pin => WinoIconGlyph.Pin, - FolderOperation.Unpin => WinoIconGlyph.UnPin, - FolderOperation.MarkAllAsRead => WinoIconGlyph.MarkRead, - FolderOperation.DontSync => WinoIconGlyph.DontSync, - FolderOperation.Empty => WinoIconGlyph.EmptyFolder, - FolderOperation.Rename => WinoIconGlyph.Rename, - FolderOperation.Delete => WinoIconGlyph.Delete, - FolderOperation.Move => WinoIconGlyph.Forward, - FolderOperation.TurnOffNotifications => WinoIconGlyph.TurnOfNotifications, - FolderOperation.CreateSubFolder => WinoIconGlyph.CreateFolder, - _ => WinoIconGlyph.None, - }; - } - - public static WinoIconGlyph GetSpecialFolderPathIconGeometry(SpecialFolderType specialFolderType) - { - return specialFolderType switch - { - SpecialFolderType.Inbox => WinoIconGlyph.SpecialFolderInbox, - SpecialFolderType.Starred => WinoIconGlyph.SpecialFolderStarred, - SpecialFolderType.Important => WinoIconGlyph.SpecialFolderImportant, - SpecialFolderType.Sent => WinoIconGlyph.SpecialFolderSent, - SpecialFolderType.Draft => WinoIconGlyph.SpecialFolderDraft, - SpecialFolderType.Archive => WinoIconGlyph.SpecialFolderArchive, - SpecialFolderType.Deleted => WinoIconGlyph.SpecialFolderDeleted, - SpecialFolderType.Junk => WinoIconGlyph.SpecialFolderJunk, - SpecialFolderType.Chat => WinoIconGlyph.SpecialFolderChat, - SpecialFolderType.Category => WinoIconGlyph.SpecialFolderCategory, - SpecialFolderType.Unread => WinoIconGlyph.SpecialFolderUnread, - SpecialFolderType.Forums => WinoIconGlyph.SpecialFolderForums, - SpecialFolderType.Updates => WinoIconGlyph.SpecialFolderUpdated, - SpecialFolderType.Personal => WinoIconGlyph.SpecialFolderPersonal, - SpecialFolderType.Promotions => WinoIconGlyph.SpecialFolderPromotions, - SpecialFolderType.Social => WinoIconGlyph.SpecialFolderSocial, - SpecialFolderType.Other => WinoIconGlyph.SpecialFolderOther, - SpecialFolderType.More => WinoIconGlyph.SpecialFolderMore, - _ => WinoIconGlyph.None, - }; - } - - - public static WinoIconGlyph GetProviderIcon(MailProviderType providerType, SpecialImapProvider specialImapProvider) - { - if (specialImapProvider == SpecialImapProvider.None) - { - return providerType switch - { - MailProviderType.Outlook => WinoIconGlyph.Microsoft, - MailProviderType.Gmail => WinoIconGlyph.Google, - MailProviderType.IMAP4 => WinoIconGlyph.IMAP, - _ => WinoIconGlyph.None, - }; - } - else - { - return specialImapProvider switch - { - SpecialImapProvider.iCloud => WinoIconGlyph.Apple, - SpecialImapProvider.Yahoo => WinoIconGlyph.Yahoo, - _ => WinoIconGlyph.None, - }; - } - } - public static WinoIconGlyph GetProviderIcon(MailAccount account) - => GetProviderIcon(account.ProviderType, account.SpecialImapProvider); - - public static Geometry GetPathGeometry(string pathMarkup) - { - string xaml = - "" + - "" + pathMarkup + ""; - var path = XamlReader.Load(xaml) as Windows.UI.Xaml.Shapes.Path; - - Geometry geometry = path.Data; - path.Data = null; - return geometry; - } - - #endregion - - #region Internationalization - - public static string GetOperationString(MailOperation operation) - { - return operation switch - { - MailOperation.None => "unknown", - MailOperation.Archive => Translator.MailOperation_Archive, - MailOperation.UnArchive => Translator.MailOperation_Unarchive, - MailOperation.SoftDelete => Translator.MailOperation_Delete, - MailOperation.HardDelete => Translator.MailOperation_Delete, - MailOperation.Move => Translator.MailOperation_Move, - MailOperation.MoveToJunk => Translator.MailOperation_MoveJunk, - MailOperation.MoveToFocused => Translator.MailOperation_MoveFocused, - MailOperation.MoveToOther => Translator.MailOperation_MoveOther, - MailOperation.AlwaysMoveToOther => Translator.MailOperation_AlwaysMoveOther, - MailOperation.AlwaysMoveToFocused => Translator.MailOperation_AlwaysMoveFocused, - MailOperation.SetFlag => Translator.MailOperation_SetFlag, - MailOperation.ClearFlag => Translator.MailOperation_ClearFlag, - MailOperation.MarkAsRead => Translator.MailOperation_MarkAsRead, - MailOperation.MarkAsUnread => Translator.MailOperation_MarkAsUnread, - MailOperation.MarkAsNotJunk => Translator.MailOperation_MarkNotJunk, - MailOperation.Seperator => string.Empty, - MailOperation.Ignore => Translator.MailOperation_Ignore, - MailOperation.Reply => Translator.MailOperation_Reply, - MailOperation.ReplyAll => Translator.MailOperation_ReplyAll, - MailOperation.Zoom => Translator.MailOperation_Zoom, - MailOperation.SaveAs => Translator.MailOperation_SaveAs, - MailOperation.Find => Translator.MailOperation_Find, - MailOperation.Forward => Translator.MailOperation_Forward, - MailOperation.DarkEditor => string.Empty, - MailOperation.LightEditor => string.Empty, - MailOperation.Print => Translator.MailOperation_Print, - MailOperation.ViewMessageSource => Translator.MailOperation_ViewMessageSource, - MailOperation.Navigate => Translator.MailOperation_Navigate, - _ => "unknown", - }; - } - - public static string GetOperationString(FolderOperation operation) - { - return operation switch - { - FolderOperation.None => string.Empty, - FolderOperation.Pin => Translator.FolderOperation_Pin, - FolderOperation.Unpin => Translator.FolderOperation_Unpin, - FolderOperation.MarkAllAsRead => Translator.FolderOperation_MarkAllAsRead, - FolderOperation.DontSync => Translator.FolderOperation_DontSync, - FolderOperation.Empty => Translator.FolderOperation_Empty, - FolderOperation.Rename => Translator.FolderOperation_Rename, - FolderOperation.Delete => Translator.FolderOperation_Delete, - FolderOperation.Move => Translator.FolderOperation_Move, - FolderOperation.CreateSubFolder => Translator.FolderOperation_CreateSubFolder, - _ => string.Empty, - }; - } - - #endregion } + + + + + public static Visibility ReverseBoolToVisibilityConverter(bool value) => value ? Visibility.Collapsed : Visibility.Visible; + public static Visibility ReverseVisibilityConverter(Visibility visibility) => visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible; + public static bool ReverseBoolConverter(bool value) => !value; + public static bool ShouldDisplayPreview(string text) => text.Any(x => char.IsLetter(x)); + public static bool CountToBooleanConverter(int value) => value > 0; + public static bool ObjectEquals(object obj1, object obj2) => object.Equals(obj1, obj2); + public static Visibility CountToVisibilityConverter(int value) => value > 0 ? Visibility.Visible : Visibility.Collapsed; + public static Visibility CountToVisibilityConverterWithThreshold(int value, int threshold) => value > threshold ? Visibility.Visible : Visibility.Collapsed; + public static InfoBarSeverity InfoBarSeverityConverter(InfoBarMessageType messageType) + { + return messageType switch + { + InfoBarMessageType.Information => InfoBarSeverity.Informational, + InfoBarMessageType.Success => InfoBarSeverity.Success, + InfoBarMessageType.Warning => InfoBarSeverity.Warning, + InfoBarMessageType.Error => InfoBarSeverity.Error, + _ => InfoBarSeverity.Informational, + }; + } + + public static SolidColorBrush GetReadableTextColor(string backgroundColor) + { + if (!backgroundColor.StartsWith("#")) throw new ArgumentException("Hex color must start with #."); + + backgroundColor = backgroundColor.TrimStart('#'); + + if (backgroundColor.Length == 6) + { + var r = int.Parse(backgroundColor.Substring(0, 2), NumberStyles.HexNumber); + var g = int.Parse(backgroundColor.Substring(2, 2), NumberStyles.HexNumber); + var b = int.Parse(backgroundColor.Substring(4, 2), NumberStyles.HexNumber); + + // Calculate relative luminance + double luminance = (0.2126 * GetLinearValue(r)) + + (0.7152 * GetLinearValue(g)) + + (0.0722 * GetLinearValue(b)); + + return luminance > 0.5 ? new SolidColorBrush(Colors.Black) : new SolidColorBrush(Colors.White); + } + else + { + throw new ArgumentException("Hex color must be 6 characters long (e.g., #RRGGBB)."); + } + } + + private static double GetLinearValue(int colorComponent) + { + double sRGB = colorComponent / 255.0; + return sRGB <= 0.03928 ? sRGB / 12.92 : Math.Pow((sRGB + 0.055) / 1.055, 2.4); + } + + public static Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode NavigationViewDisplayModeConverter(SplitViewDisplayMode splitViewDisplayMode) + { + return splitViewDisplayMode switch + { + SplitViewDisplayMode.CompactOverlay => Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Compact, + SplitViewDisplayMode.CompactInline => Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Minimal, + SplitViewDisplayMode.Overlay => Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Expanded, + SplitViewDisplayMode.Inline => Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Expanded, + _ => Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Minimal, + }; + } + + public static string GetColorFromHex(Color color) => color.ToHex(); + public static Color GetWindowsColorFromHex(string hex) => hex.ToColor(); + + public static SolidColorBrush GetSolidColorBrushFromHex(string colorHex) => string.IsNullOrEmpty(colorHex) ? new SolidColorBrush(Colors.Transparent) : new SolidColorBrush(colorHex.ToColor()); + public static Visibility IsSelectionModeMultiple(ListViewSelectionMode mode) => mode == ListViewSelectionMode.Multiple ? Visibility.Visible : Visibility.Collapsed; + public static FontWeight GetFontWeightBySyncState(bool isSyncing) => isSyncing ? FontWeights.SemiBold : FontWeights.Normal; + public static FontWeight GetFontWeightByChildSelectedState(bool isChildSelected) => isChildSelected ? FontWeights.SemiBold : FontWeights.Normal; + public static Visibility StringToVisibilityConverter(string value) => string.IsNullOrWhiteSpace(value) ? Visibility.Collapsed : Visibility.Visible; + public static Visibility StringToVisibilityReversedConverter(string value) => string.IsNullOrWhiteSpace(value) ? Visibility.Visible : Visibility.Collapsed; + public static string GetMailItemDisplaySummaryForListing(bool isDraft, DateTime receivedDate, bool prefer24HourTime) + { + if (isDraft) + return Translator.Draft; + else + { + var localTime = receivedDate.ToLocalTime(); + + return prefer24HourTime ? localTime.ToString(TwentyFourHourTimeFormat) : localTime.ToString(TwelveHourTimeFormat); + } + } + public static string GetCreationDateString(DateTime date, bool prefer24HourTime) + { + var localTime = date.ToLocalTime(); + return $"{localTime.ToLongDateString()} {(prefer24HourTime ? localTime.ToString(TwentyFourHourTimeFormat) : localTime.ToString(TwelveHourTimeFormat))}"; + } + public static string GetMailGroupDateString(object groupObject) + { + if (groupObject is string stringObject) + return stringObject; + + object dateObject = null; + + // From regular mail header template + if (groupObject is DateTime groupedDate) + dateObject = groupedDate; + else if (groupObject is IGrouping groupKey) + { + // From semantic group header. + dateObject = groupKey.Key; + } + + if (dateObject != null) + { + if (dateObject is DateTime dateTimeValue) + { + if (dateTimeValue == DateTime.Today) + return Translator.Today; + else if (dateTimeValue == DateTime.Today.AddDays(-1)) + return Translator.Yesterday; + else + return dateTimeValue.ToLongDateString(); + } + else + return dateObject.ToString(); + } + + return Translator.UnknownDateHeader; + } + public static bool ConnectionStatusEquals(WinoServerConnectionStatus winoServerConnectionStatus, WinoServerConnectionStatus connectionStatus) => winoServerConnectionStatus == connectionStatus; + + #endregion + + #region Wino Font Icon Transformation + + public static WinoIconGlyph GetWinoIconGlyph(FilterOptionType type) => type switch + { + FilterOptionType.All => WinoIconGlyph.Mail, + FilterOptionType.Unread => WinoIconGlyph.MarkUnread, + FilterOptionType.Flagged => WinoIconGlyph.Flag, + FilterOptionType.Mentions => WinoIconGlyph.NewMail, + FilterOptionType.Files => WinoIconGlyph.Attachment, + _ => WinoIconGlyph.None, + }; + + public static WinoIconGlyph GetWinoIconGlyph(SortingOptionType type) => type switch + { + SortingOptionType.Sender => WinoIconGlyph.SortTextDesc, + SortingOptionType.ReceiveDate => WinoIconGlyph.SortLinesDesc, + _ => WinoIconGlyph.None, + }; + + public static WinoIconGlyph GetWinoIconGlyph(MailOperation operation) + { + return operation switch + { + MailOperation.None => WinoIconGlyph.None, + MailOperation.Archive => WinoIconGlyph.Archive, + MailOperation.UnArchive => WinoIconGlyph.UnArchive, + MailOperation.SoftDelete => WinoIconGlyph.Delete, + MailOperation.HardDelete => WinoIconGlyph.Delete, + MailOperation.Move => WinoIconGlyph.Forward, + MailOperation.MoveToJunk => WinoIconGlyph.Blocked, + MailOperation.MoveToFocused => WinoIconGlyph.None, + MailOperation.MoveToOther => WinoIconGlyph.None, + MailOperation.AlwaysMoveToOther => WinoIconGlyph.None, + MailOperation.AlwaysMoveToFocused => WinoIconGlyph.None, + MailOperation.SetFlag => WinoIconGlyph.Flag, + MailOperation.ClearFlag => WinoIconGlyph.ClearFlag, + MailOperation.MarkAsRead => WinoIconGlyph.MarkRead, + MailOperation.MarkAsUnread => WinoIconGlyph.MarkUnread, + MailOperation.MarkAsNotJunk => WinoIconGlyph.Blocked, + MailOperation.Ignore => WinoIconGlyph.Ignore, + MailOperation.Reply => WinoIconGlyph.Reply, + MailOperation.ReplyAll => WinoIconGlyph.ReplyAll, + MailOperation.Zoom => WinoIconGlyph.Zoom, + MailOperation.SaveAs => WinoIconGlyph.Save, + MailOperation.Print => WinoIconGlyph.Print, + MailOperation.Find => WinoIconGlyph.Find, + MailOperation.Forward => WinoIconGlyph.Forward, + MailOperation.DarkEditor => WinoIconGlyph.DarkEditor, + MailOperation.LightEditor => WinoIconGlyph.LightEditor, + MailOperation.ViewMessageSource => WinoIconGlyph.ViewMessageSource, + _ => WinoIconGlyph.None, + }; + } + + public static WinoIconGlyph GetPathGeometry(FolderOperation operation) + { + return operation switch + { + FolderOperation.None => WinoIconGlyph.None, + FolderOperation.Pin => WinoIconGlyph.Pin, + FolderOperation.Unpin => WinoIconGlyph.UnPin, + FolderOperation.MarkAllAsRead => WinoIconGlyph.MarkRead, + FolderOperation.DontSync => WinoIconGlyph.DontSync, + FolderOperation.Empty => WinoIconGlyph.EmptyFolder, + FolderOperation.Rename => WinoIconGlyph.Rename, + FolderOperation.Delete => WinoIconGlyph.Delete, + FolderOperation.Move => WinoIconGlyph.Forward, + FolderOperation.TurnOffNotifications => WinoIconGlyph.TurnOfNotifications, + FolderOperation.CreateSubFolder => WinoIconGlyph.CreateFolder, + _ => WinoIconGlyph.None, + }; + } + + public static WinoIconGlyph GetSpecialFolderPathIconGeometry(SpecialFolderType specialFolderType) + { + return specialFolderType switch + { + SpecialFolderType.Inbox => WinoIconGlyph.SpecialFolderInbox, + SpecialFolderType.Starred => WinoIconGlyph.SpecialFolderStarred, + SpecialFolderType.Important => WinoIconGlyph.SpecialFolderImportant, + SpecialFolderType.Sent => WinoIconGlyph.SpecialFolderSent, + SpecialFolderType.Draft => WinoIconGlyph.SpecialFolderDraft, + SpecialFolderType.Archive => WinoIconGlyph.SpecialFolderArchive, + SpecialFolderType.Deleted => WinoIconGlyph.SpecialFolderDeleted, + SpecialFolderType.Junk => WinoIconGlyph.SpecialFolderJunk, + SpecialFolderType.Chat => WinoIconGlyph.SpecialFolderChat, + SpecialFolderType.Category => WinoIconGlyph.SpecialFolderCategory, + SpecialFolderType.Unread => WinoIconGlyph.SpecialFolderUnread, + SpecialFolderType.Forums => WinoIconGlyph.SpecialFolderForums, + SpecialFolderType.Updates => WinoIconGlyph.SpecialFolderUpdated, + SpecialFolderType.Personal => WinoIconGlyph.SpecialFolderPersonal, + SpecialFolderType.Promotions => WinoIconGlyph.SpecialFolderPromotions, + SpecialFolderType.Social => WinoIconGlyph.SpecialFolderSocial, + SpecialFolderType.Other => WinoIconGlyph.SpecialFolderOther, + SpecialFolderType.More => WinoIconGlyph.SpecialFolderMore, + _ => WinoIconGlyph.None, + }; + } + + + public static WinoIconGlyph GetProviderIcon(MailProviderType providerType, SpecialImapProvider specialImapProvider) + { + if (specialImapProvider == SpecialImapProvider.None) + { + return providerType switch + { + MailProviderType.Outlook => WinoIconGlyph.Microsoft, + MailProviderType.Gmail => WinoIconGlyph.Google, + MailProviderType.IMAP4 => WinoIconGlyph.IMAP, + _ => WinoIconGlyph.None, + }; + } + else + { + return specialImapProvider switch + { + SpecialImapProvider.iCloud => WinoIconGlyph.Apple, + SpecialImapProvider.Yahoo => WinoIconGlyph.Yahoo, + _ => WinoIconGlyph.None, + }; + } + } + public static WinoIconGlyph GetProviderIcon(MailAccount account) + => GetProviderIcon(account.ProviderType, account.SpecialImapProvider); + + public static Geometry GetPathGeometry(string pathMarkup) + { + string xaml = + "" + + "" + pathMarkup + ""; + var path = XamlReader.Load(xaml) as Windows.UI.Xaml.Shapes.Path; + + Geometry geometry = path.Data; + path.Data = null; + return geometry; + } + + #endregion + + #region Internationalization + + public static string GetOperationString(MailOperation operation) + { + return operation switch + { + MailOperation.None => "unknown", + MailOperation.Archive => Translator.MailOperation_Archive, + MailOperation.UnArchive => Translator.MailOperation_Unarchive, + MailOperation.SoftDelete => Translator.MailOperation_Delete, + MailOperation.HardDelete => Translator.MailOperation_Delete, + MailOperation.Move => Translator.MailOperation_Move, + MailOperation.MoveToJunk => Translator.MailOperation_MoveJunk, + MailOperation.MoveToFocused => Translator.MailOperation_MoveFocused, + MailOperation.MoveToOther => Translator.MailOperation_MoveOther, + MailOperation.AlwaysMoveToOther => Translator.MailOperation_AlwaysMoveOther, + MailOperation.AlwaysMoveToFocused => Translator.MailOperation_AlwaysMoveFocused, + MailOperation.SetFlag => Translator.MailOperation_SetFlag, + MailOperation.ClearFlag => Translator.MailOperation_ClearFlag, + MailOperation.MarkAsRead => Translator.MailOperation_MarkAsRead, + MailOperation.MarkAsUnread => Translator.MailOperation_MarkAsUnread, + MailOperation.MarkAsNotJunk => Translator.MailOperation_MarkNotJunk, + MailOperation.Seperator => string.Empty, + MailOperation.Ignore => Translator.MailOperation_Ignore, + MailOperation.Reply => Translator.MailOperation_Reply, + MailOperation.ReplyAll => Translator.MailOperation_ReplyAll, + MailOperation.Zoom => Translator.MailOperation_Zoom, + MailOperation.SaveAs => Translator.MailOperation_SaveAs, + MailOperation.Find => Translator.MailOperation_Find, + MailOperation.Forward => Translator.MailOperation_Forward, + MailOperation.DarkEditor => string.Empty, + MailOperation.LightEditor => string.Empty, + MailOperation.Print => Translator.MailOperation_Print, + MailOperation.ViewMessageSource => Translator.MailOperation_ViewMessageSource, + MailOperation.Navigate => Translator.MailOperation_Navigate, + _ => "unknown", + }; + } + + public static string GetOperationString(FolderOperation operation) + { + return operation switch + { + FolderOperation.None => string.Empty, + FolderOperation.Pin => Translator.FolderOperation_Pin, + FolderOperation.Unpin => Translator.FolderOperation_Unpin, + FolderOperation.MarkAllAsRead => Translator.FolderOperation_MarkAllAsRead, + FolderOperation.DontSync => Translator.FolderOperation_DontSync, + FolderOperation.Empty => Translator.FolderOperation_Empty, + FolderOperation.Rename => Translator.FolderOperation_Rename, + FolderOperation.Delete => Translator.FolderOperation_Delete, + FolderOperation.Move => Translator.FolderOperation_Move, + FolderOperation.CreateSubFolder => Translator.FolderOperation_CreateSubFolder, + _ => string.Empty, + }; + } + + #endregion } diff --git a/Wino.Core.UWP/Models/Personalization/CustomAppTheme.cs b/Wino.Core.UWP/Models/Personalization/CustomAppTheme.cs index 0e02d319..78049f61 100644 --- a/Wino.Core.UWP/Models/Personalization/CustomAppTheme.cs +++ b/Wino.Core.UWP/Models/Personalization/CustomAppTheme.cs @@ -5,27 +5,26 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.Personalization; using Wino.Services; -namespace Wino.Core.UWP.Models.Personalization +namespace Wino.Core.UWP.Models.Personalization; + +/// +/// Custom themes that are generated by users. +/// +public class CustomAppTheme : AppThemeBase { - /// - /// Custom themes that are generated by users. - /// - public class CustomAppTheme : AppThemeBase + public CustomAppTheme(CustomThemeMetadata metadata) : base(metadata.Name, metadata.Id) { - public CustomAppTheme(CustomThemeMetadata metadata) : base(metadata.Name, metadata.Id) - { - AccentColor = metadata.AccentColorHex; - } + AccentColor = metadata.AccentColorHex; + } - public override AppThemeType AppThemeType => AppThemeType.Custom; + public override AppThemeType AppThemeType => AppThemeType.Custom; - public override string GetBackgroundPreviewImagePath() - => $"ms-appdata:///local/{ThemeService.CustomThemeFolderName}/{Id}_preview.jpg"; + public override string GetBackgroundPreviewImagePath() + => $"ms-appdata:///local/{ThemeService.CustomThemeFolderName}/{Id}_preview.jpg"; - public override async Task GetThemeResourceDictionaryContentAsync() - { - var customAppThemeFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Wino.Core.UWP/AppThemes/Custom.xaml")); - return await FileIO.ReadTextAsync(customAppThemeFile); - } + public override async Task GetThemeResourceDictionaryContentAsync() + { + var customAppThemeFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Wino.Core.UWP/AppThemes/Custom.xaml")); + return await FileIO.ReadTextAsync(customAppThemeFile); } } diff --git a/Wino.Core.UWP/Models/Personalization/PreDefinedAppTheme.cs b/Wino.Core.UWP/Models/Personalization/PreDefinedAppTheme.cs index 56a35975..960e5722 100644 --- a/Wino.Core.UWP/Models/Personalization/PreDefinedAppTheme.cs +++ b/Wino.Core.UWP/Models/Personalization/PreDefinedAppTheme.cs @@ -4,31 +4,30 @@ using Windows.Storage; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.Personalization; -namespace Wino.Core.UWP.Models.Personalization +namespace Wino.Core.UWP.Models.Personalization; + +/// +/// Forest, Nighty, Clouds etc. applies to pre-defined themes in Wino. +/// +public class PreDefinedAppTheme : AppThemeBase { - /// - /// Forest, Nighty, Clouds etc. applies to pre-defined themes in Wino. - /// - public class PreDefinedAppTheme : AppThemeBase + public PreDefinedAppTheme(string themeName, + Guid id, + string accentColor = "", + ApplicationElementTheme forcedElementTheme = ApplicationElementTheme.Default) : base(themeName, id) { - public PreDefinedAppTheme(string themeName, - Guid id, - string accentColor = "", - ApplicationElementTheme forcedElementTheme = ApplicationElementTheme.Default) : base(themeName, id) - { - AccentColor = accentColor; - ForceElementTheme = forcedElementTheme; - } + AccentColor = accentColor; + ForceElementTheme = forcedElementTheme; + } - public override AppThemeType AppThemeType => AppThemeType.PreDefined; + public override AppThemeType AppThemeType => AppThemeType.PreDefined; - public override string GetBackgroundPreviewImagePath() - => $"ms-appx:///Wino.Core.UWP/BackgroundImages/{ThemeName}.jpg"; + public override string GetBackgroundPreviewImagePath() + => $"ms-appx:///Wino.Core.UWP/BackgroundImages/{ThemeName}.jpg"; - public override async Task GetThemeResourceDictionaryContentAsync() - { - var xamlDictionaryFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri($"ms-appx:///Wino.Core.UWP/AppThemes/{ThemeName}.xaml")); - return await FileIO.ReadTextAsync(xamlDictionaryFile); - } + public override async Task GetThemeResourceDictionaryContentAsync() + { + var xamlDictionaryFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri($"ms-appx:///Wino.Core.UWP/AppThemes/{ThemeName}.xaml")); + return await FileIO.ReadTextAsync(xamlDictionaryFile); } } diff --git a/Wino.Core.UWP/Models/Personalization/SystemAppTheme.cs b/Wino.Core.UWP/Models/Personalization/SystemAppTheme.cs index 3580b1d0..f836ffb0 100644 --- a/Wino.Core.UWP/Models/Personalization/SystemAppTheme.cs +++ b/Wino.Core.UWP/Models/Personalization/SystemAppTheme.cs @@ -1,13 +1,12 @@ using System; using Wino.Core.Domain.Enums; -namespace Wino.Core.UWP.Models.Personalization -{ - // Mica - Acrylic. - public class SystemAppTheme : PreDefinedAppTheme - { - public SystemAppTheme(string themeName, Guid id) : base(themeName, id, "") { } +namespace Wino.Core.UWP.Models.Personalization; - public override AppThemeType AppThemeType => AppThemeType.System; - } +// Mica - Acrylic. +public class SystemAppTheme : PreDefinedAppTheme +{ + public SystemAppTheme(string themeName, Guid id) : base(themeName, id, "") { } + + public override AppThemeType AppThemeType => AppThemeType.System; } diff --git a/Wino.Core.UWP/Selectors/AppThemePreviewTemplateSelector.cs b/Wino.Core.UWP/Selectors/AppThemePreviewTemplateSelector.cs index 5df00d6f..6ed85638 100644 --- a/Wino.Core.UWP/Selectors/AppThemePreviewTemplateSelector.cs +++ b/Wino.Core.UWP/Selectors/AppThemePreviewTemplateSelector.cs @@ -2,24 +2,23 @@ using Windows.UI.Xaml.Controls; using Wino.Core.UWP.Models.Personalization; -namespace Wino.Core.UWP.Selectors +namespace Wino.Core.UWP.Selectors; + +public partial class AppThemePreviewTemplateSelector : DataTemplateSelector { - public partial class AppThemePreviewTemplateSelector : DataTemplateSelector + public DataTemplate SystemThemeTemplate { get; set; } + public DataTemplate PreDefinedThemeTemplate { get; set; } + public DataTemplate CustomAppTemplate { get; set; } + + protected override DataTemplate SelectTemplateCore(object item) { - public DataTemplate SystemThemeTemplate { get; set; } - public DataTemplate PreDefinedThemeTemplate { get; set; } - public DataTemplate CustomAppTemplate { get; set; } + if (item is SystemAppTheme) + return SystemThemeTemplate; + else if (item is PreDefinedAppTheme) + return PreDefinedThemeTemplate; + else if (item is CustomAppTheme) + return CustomAppTemplate; - protected override DataTemplate SelectTemplateCore(object item) - { - if (item is SystemAppTheme) - return SystemThemeTemplate; - else if (item is PreDefinedAppTheme) - return PreDefinedThemeTemplate; - else if (item is CustomAppTheme) - return CustomAppTemplate; - - return base.SelectTemplateCore(item); - } + return base.SelectTemplateCore(item); } } diff --git a/Wino.Core.UWP/Selectors/CustomWinoMessageDialogIconSelector.cs b/Wino.Core.UWP/Selectors/CustomWinoMessageDialogIconSelector.cs index d1229556..bed04e3f 100644 --- a/Wino.Core.UWP/Selectors/CustomWinoMessageDialogIconSelector.cs +++ b/Wino.Core.UWP/Selectors/CustomWinoMessageDialogIconSelector.cs @@ -3,36 +3,35 @@ using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Wino.Core.Domain.Enums; -namespace Wino.Core.UWP.Selectors +namespace Wino.Core.UWP.Selectors; + +public partial class CustomWinoMessageDialogIconSelector : DataTemplateSelector { - public partial class CustomWinoMessageDialogIconSelector : DataTemplateSelector + public DataTemplate InfoIconTemplate { get; set; } + public DataTemplate WarningIconTemplate { get; set; } + public DataTemplate QuestionIconTemplate { get; set; } + public DataTemplate ErrorIconTemplate { get; set; } + + protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) { - public DataTemplate InfoIconTemplate { get; set; } - public DataTemplate WarningIconTemplate { get; set; } - public DataTemplate QuestionIconTemplate { get; set; } - public DataTemplate ErrorIconTemplate { get; set; } + if (item == null) return null; - protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) + if (item is WinoCustomMessageDialogIcon icon) { - if (item == null) return null; - - if (item is WinoCustomMessageDialogIcon icon) + switch (icon) { - switch (icon) - { - case WinoCustomMessageDialogIcon.Information: - return InfoIconTemplate; - case WinoCustomMessageDialogIcon.Warning: - return WarningIconTemplate; - case WinoCustomMessageDialogIcon.Error: - return ErrorIconTemplate; - case WinoCustomMessageDialogIcon.Question: - return QuestionIconTemplate; - default: - throw new Exception("Unknown custom message dialog icon."); - } + case WinoCustomMessageDialogIcon.Information: + return InfoIconTemplate; + case WinoCustomMessageDialogIcon.Warning: + return WarningIconTemplate; + case WinoCustomMessageDialogIcon.Error: + return ErrorIconTemplate; + case WinoCustomMessageDialogIcon.Question: + return QuestionIconTemplate; + default: + throw new Exception("Unknown custom message dialog icon."); } - return base.SelectTemplateCore(item, container); } + return base.SelectTemplateCore(item, container); } } diff --git a/Wino.Core.UWP/Selectors/FileAttachmentTypeSelector.cs b/Wino.Core.UWP/Selectors/FileAttachmentTypeSelector.cs index 075dc9d3..1bef19a3 100644 --- a/Wino.Core.UWP/Selectors/FileAttachmentTypeSelector.cs +++ b/Wino.Core.UWP/Selectors/FileAttachmentTypeSelector.cs @@ -2,51 +2,50 @@ using Windows.UI.Xaml.Controls; using Wino.Core.Domain.Enums; -namespace Wino.Core.UWP.Selectors +namespace Wino.Core.UWP.Selectors; + +public partial class FileAttachmentTypeSelector : DataTemplateSelector { - public partial class FileAttachmentTypeSelector : DataTemplateSelector + public DataTemplate None { get; set; } + public DataTemplate Executable { get; set; } + public DataTemplate Image { get; set; } + public DataTemplate Audio { get; set; } + public DataTemplate Video { get; set; } + public DataTemplate PDF { get; set; } + public DataTemplate HTML { get; set; } + public DataTemplate RarArchive { get; set; } + public DataTemplate Archive { get; set; } + public DataTemplate Other { get; set; } + + protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) { - public DataTemplate None { get; set; } - public DataTemplate Executable { get; set; } - public DataTemplate Image { get; set; } - public DataTemplate Audio { get; set; } - public DataTemplate Video { get; set; } - public DataTemplate PDF { get; set; } - public DataTemplate HTML { get; set; } - public DataTemplate RarArchive { get; set; } - public DataTemplate Archive { get; set; } - public DataTemplate Other { get; set; } + if (item == null) + return None; - protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) + var type = (MailAttachmentType)item; + + switch (type) { - if (item == null) + case MailAttachmentType.None: return None; - - var type = (MailAttachmentType)item; - - switch (type) - { - case MailAttachmentType.None: - return None; - case MailAttachmentType.Executable: - return Executable; - case MailAttachmentType.Image: - return Image; - case MailAttachmentType.Audio: - return Audio; - case MailAttachmentType.Video: - return Video; - case MailAttachmentType.PDF: - return PDF; - case MailAttachmentType.HTML: - return HTML; - case MailAttachmentType.RarArchive: - return RarArchive; - case MailAttachmentType.Archive: - return Archive; - default: - return Other; - } + case MailAttachmentType.Executable: + return Executable; + case MailAttachmentType.Image: + return Image; + case MailAttachmentType.Audio: + return Audio; + case MailAttachmentType.Video: + return Video; + case MailAttachmentType.PDF: + return PDF; + case MailAttachmentType.HTML: + return HTML; + case MailAttachmentType.RarArchive: + return RarArchive; + case MailAttachmentType.Archive: + return Archive; + default: + return Other; } } } diff --git a/Wino.Core.UWP/Selectors/NavigationMenuTemplateSelector.cs b/Wino.Core.UWP/Selectors/NavigationMenuTemplateSelector.cs index 64faf8e1..516f82ca 100644 --- a/Wino.Core.UWP/Selectors/NavigationMenuTemplateSelector.cs +++ b/Wino.Core.UWP/Selectors/NavigationMenuTemplateSelector.cs @@ -2,58 +2,57 @@ using Windows.UI.Xaml.Controls; using Wino.Core.Domain.MenuItems; -namespace Wino.Core.UWP.Selectors -{ - public partial class NavigationMenuTemplateSelector : DataTemplateSelector - { - public DataTemplate MenuItemTemplate { get; set; } - public DataTemplate AccountManagementTemplate { get; set; } - public DataTemplate ClickableAccountMenuTemplate { get; set; } - public DataTemplate MergedAccountTemplate { get; set; } - public DataTemplate MergedAccountFolderTemplate { get; set; } - public DataTemplate MergedAccountMoreExpansionItemTemplate { get; set; } - public DataTemplate FolderMenuTemplate { get; set; } - public DataTemplate SettingsItemTemplate { get; set; } - public DataTemplate MoreItemsFolderTemplate { get; set; } - public DataTemplate RatingItemTemplate { get; set; } - public DataTemplate CreateNewFolderTemplate { get; set; } - public DataTemplate SeperatorTemplate { get; set; } - public DataTemplate NewMailTemplate { get; set; } - public DataTemplate CategoryItemsTemplate { get; set; } - public DataTemplate FixAuthenticationIssueTemplate { get; set; } - public DataTemplate FixMissingFolderConfigTemplate { get; set; } +namespace Wino.Core.UWP.Selectors; - protected override DataTemplate SelectTemplateCore(object item) +public partial class NavigationMenuTemplateSelector : DataTemplateSelector +{ + public DataTemplate MenuItemTemplate { get; set; } + public DataTemplate AccountManagementTemplate { get; set; } + public DataTemplate ClickableAccountMenuTemplate { get; set; } + public DataTemplate MergedAccountTemplate { get; set; } + public DataTemplate MergedAccountFolderTemplate { get; set; } + public DataTemplate MergedAccountMoreExpansionItemTemplate { get; set; } + public DataTemplate FolderMenuTemplate { get; set; } + public DataTemplate SettingsItemTemplate { get; set; } + public DataTemplate MoreItemsFolderTemplate { get; set; } + public DataTemplate RatingItemTemplate { get; set; } + public DataTemplate CreateNewFolderTemplate { get; set; } + public DataTemplate SeperatorTemplate { get; set; } + public DataTemplate NewMailTemplate { get; set; } + public DataTemplate CategoryItemsTemplate { get; set; } + public DataTemplate FixAuthenticationIssueTemplate { get; set; } + public DataTemplate FixMissingFolderConfigTemplate { get; set; } + + protected override DataTemplate SelectTemplateCore(object item) + { + if (item is NewMailMenuItem) + return NewMailTemplate; + else if (item is SettingsItem) + return SettingsItemTemplate; + else if (item is SeperatorItem) + return SeperatorTemplate; + else if (item is AccountMenuItem accountMenuItem) + // Merged inbox account menu items must be nested. + return ClickableAccountMenuTemplate; + else if (item is ManageAccountsMenuItem) + return AccountManagementTemplate; + else if (item is RateMenuItem) + return RatingItemTemplate; + else if (item is MergedAccountMenuItem) + return MergedAccountTemplate; + else if (item is MergedAccountMoreFolderMenuItem) + return MergedAccountMoreExpansionItemTemplate; + else if (item is MergedAccountFolderMenuItem) + return MergedAccountFolderTemplate; + else if (item is FolderMenuItem) + return FolderMenuTemplate; + else if (item is FixAccountIssuesMenuItem fixAccountIssuesMenuItem) + return fixAccountIssuesMenuItem.Account.AttentionReason == Domain.Enums.AccountAttentionReason.MissingSystemFolderConfiguration + ? FixMissingFolderConfigTemplate : FixAuthenticationIssueTemplate; + else { - if (item is NewMailMenuItem) - return NewMailTemplate; - else if (item is SettingsItem) - return SettingsItemTemplate; - else if (item is SeperatorItem) - return SeperatorTemplate; - else if (item is AccountMenuItem accountMenuItem) - // Merged inbox account menu items must be nested. - return ClickableAccountMenuTemplate; - else if (item is ManageAccountsMenuItem) - return AccountManagementTemplate; - else if (item is RateMenuItem) - return RatingItemTemplate; - else if (item is MergedAccountMenuItem) - return MergedAccountTemplate; - else if (item is MergedAccountMoreFolderMenuItem) - return MergedAccountMoreExpansionItemTemplate; - else if (item is MergedAccountFolderMenuItem) - return MergedAccountFolderTemplate; - else if (item is FolderMenuItem) - return FolderMenuTemplate; - else if (item is FixAccountIssuesMenuItem fixAccountIssuesMenuItem) - return fixAccountIssuesMenuItem.Account.AttentionReason == Domain.Enums.AccountAttentionReason.MissingSystemFolderConfiguration - ? FixMissingFolderConfigTemplate : FixAuthenticationIssueTemplate; - else - { - var type = item.GetType(); - return null; - } + var type = item.GetType(); + return null; } } } diff --git a/Wino.Core.UWP/Services/ApplicationResourceManager.cs b/Wino.Core.UWP/Services/ApplicationResourceManager.cs index 0e50dc1f..d572c9e8 100644 --- a/Wino.Core.UWP/Services/ApplicationResourceManager.cs +++ b/Wino.Core.UWP/Services/ApplicationResourceManager.cs @@ -3,25 +3,24 @@ using Windows.UI.Xaml; using Wino.Core.Domain.Interfaces; using Wino.Core.UWP; -namespace Wino.Services +namespace Wino.Services; + +public class ApplicationResourceManager : IApplicationResourceManager { - public class ApplicationResourceManager : IApplicationResourceManager - { - public void AddResource(ResourceDictionary resource) - => WinoApplication.Current.Resources.MergedDictionaries.Add(resource); - public void RemoveResource(ResourceDictionary resource) - => WinoApplication.Current.Resources.MergedDictionaries.Remove(resource); + public void AddResource(ResourceDictionary resource) + => WinoApplication.Current.Resources.MergedDictionaries.Add(resource); + public void RemoveResource(ResourceDictionary resource) + => WinoApplication.Current.Resources.MergedDictionaries.Remove(resource); - public bool ContainsResourceKey(string resourceKey) - => WinoApplication.Current.Resources.ContainsKey(resourceKey); + public bool ContainsResourceKey(string resourceKey) + => WinoApplication.Current.Resources.ContainsKey(resourceKey); - public ResourceDictionary GetLastResource() - => WinoApplication.Current.Resources.MergedDictionaries.LastOrDefault(); + public ResourceDictionary GetLastResource() + => WinoApplication.Current.Resources.MergedDictionaries.LastOrDefault(); - public void ReplaceResource(string resourceKey, object resource) - => WinoApplication.Current.Resources[resourceKey] = resource; + public void ReplaceResource(string resourceKey, object resource) + => WinoApplication.Current.Resources[resourceKey] = resource; - public TReturnType GetResource(string resourceKey) - => (TReturnType)WinoApplication.Current.Resources[resourceKey]; - } + public TReturnType GetResource(string resourceKey) + => (TReturnType)WinoApplication.Current.Resources[resourceKey]; } diff --git a/Wino.Core.UWP/Services/BackgroundTaskService.cs b/Wino.Core.UWP/Services/BackgroundTaskService.cs index 3a94f4e6..829f1b8f 100644 --- a/Wino.Core.UWP/Services/BackgroundTaskService.cs +++ b/Wino.Core.UWP/Services/BackgroundTaskService.cs @@ -5,59 +5,58 @@ using Serilog; using Windows.ApplicationModel.Background; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.UWP.Services +namespace Wino.Core.UWP.Services; + +public class BackgroundTaskService : IBackgroundTaskService { - public class BackgroundTaskService : IBackgroundTaskService + private const string IsBackgroundTasksUnregisteredKey = nameof(IsBackgroundTasksUnregisteredKey); + public const string ToastNotificationActivationHandlerTaskName = "ToastNotificationActivationHandlerTask"; + + private readonly IConfigurationService _configurationService; + + public BackgroundTaskService(IConfigurationService configurationService) { - private const string IsBackgroundTasksUnregisteredKey = nameof(IsBackgroundTasksUnregisteredKey); - public const string ToastNotificationActivationHandlerTaskName = "ToastNotificationActivationHandlerTask"; + _configurationService = configurationService; + } - private readonly IConfigurationService _configurationService; - - public BackgroundTaskService(IConfigurationService configurationService) + public void UnregisterAllBackgroundTask() + { + if (_configurationService.Get(IsBackgroundTasksUnregisteredKey, false)) { - _configurationService = configurationService; - } - - public void UnregisterAllBackgroundTask() - { - if (_configurationService.Get(IsBackgroundTasksUnregisteredKey, false)) + foreach (var task in BackgroundTaskRegistration.AllTasks) { - foreach (var task in BackgroundTaskRegistration.AllTasks) - { - task.Value.Unregister(true); - } - - Log.Information("Unregistered all background tasks."); - _configurationService.Set(IsBackgroundTasksUnregisteredKey, true); + task.Value.Unregister(true); } - } - public Task RegisterBackgroundTasksAsync() - { - return RegisterToastNotificationHandlerBackgroundTaskAsync(); - } - - public async Task RegisterToastNotificationHandlerBackgroundTaskAsync() - { - // If background task is already registered, do nothing. - if (BackgroundTaskRegistration.AllTasks.Any(i => i.Value.Name.Equals(ToastNotificationActivationHandlerTaskName))) - return; - - // Otherwise request access - BackgroundAccessStatus status = await BackgroundExecutionManager.RequestAccessAsync(); - - // Create the background task - BackgroundTaskBuilder builder = new BackgroundTaskBuilder() - { - Name = ToastNotificationActivationHandlerTaskName - }; - - // Assign the toast action trigger - builder.SetTrigger(new ToastNotificationActionTrigger()); - - // And register the task - BackgroundTaskRegistration registration = builder.Register(); + Log.Information("Unregistered all background tasks."); + _configurationService.Set(IsBackgroundTasksUnregisteredKey, true); } } + + public Task RegisterBackgroundTasksAsync() + { + return RegisterToastNotificationHandlerBackgroundTaskAsync(); + } + + public async Task RegisterToastNotificationHandlerBackgroundTaskAsync() + { + // If background task is already registered, do nothing. + if (BackgroundTaskRegistration.AllTasks.Any(i => i.Value.Name.Equals(ToastNotificationActivationHandlerTaskName))) + return; + + // Otherwise request access + BackgroundAccessStatus status = await BackgroundExecutionManager.RequestAccessAsync(); + + // Create the background task + BackgroundTaskBuilder builder = new BackgroundTaskBuilder() + { + Name = ToastNotificationActivationHandlerTaskName + }; + + // Assign the toast action trigger + builder.SetTrigger(new ToastNotificationActionTrigger()); + + // And register the task + BackgroundTaskRegistration registration = builder.Register(); + } } diff --git a/Wino.Core.UWP/Services/ClipboardService.cs b/Wino.Core.UWP/Services/ClipboardService.cs index 9e3f5c02..bbfb94dc 100644 --- a/Wino.Core.UWP/Services/ClipboardService.cs +++ b/Wino.Core.UWP/Services/ClipboardService.cs @@ -2,18 +2,17 @@ using Windows.ApplicationModel.DataTransfer; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.UWP.Services +namespace Wino.Core.UWP.Services; + +public class ClipboardService : IClipboardService { - public class ClipboardService : IClipboardService + public Task CopyClipboardAsync(string text) { - public Task CopyClipboardAsync(string text) - { - var package = new DataPackage(); - package.SetText(text); + var package = new DataPackage(); + package.SetText(text); - Clipboard.SetContent(package); + Clipboard.SetContent(package); - return Task.CompletedTask; - } + return Task.CompletedTask; } } diff --git a/Wino.Core.UWP/Services/ConfigurationService.cs b/Wino.Core.UWP/Services/ConfigurationService.cs index 1cff9923..83d5c744 100644 --- a/Wino.Core.UWP/Services/ConfigurationService.cs +++ b/Wino.Core.UWP/Services/ConfigurationService.cs @@ -5,48 +5,47 @@ using Windows.Foundation.Collections; using Windows.Storage; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.UWP.Services +namespace Wino.Core.UWP.Services; + +public class ConfigurationService : IConfigurationService { - public class ConfigurationService : IConfigurationService + public T Get(string key, T defaultValue = default) + => GetInternal(key, ApplicationData.Current.LocalSettings.Values, defaultValue); + + public T GetRoaming(string key, T defaultValue = default) + => GetInternal(key, ApplicationData.Current.RoamingSettings.Values, defaultValue); + + public void Set(string key, object value) + => SetInternal(key, value, ApplicationData.Current.LocalSettings.Values); + + public void SetRoaming(string key, object value) + => SetInternal(key, value, ApplicationData.Current.RoamingSettings.Values); + + private static T GetInternal(string key, IPropertySet collection, T defaultValue = default) { - public T Get(string key, T defaultValue = default) - => GetInternal(key, ApplicationData.Current.LocalSettings.Values, defaultValue); - - public T GetRoaming(string key, T defaultValue = default) - => GetInternal(key, ApplicationData.Current.RoamingSettings.Values, defaultValue); - - public void Set(string key, object value) - => SetInternal(key, value, ApplicationData.Current.LocalSettings.Values); - - public void SetRoaming(string key, object value) - => SetInternal(key, value, ApplicationData.Current.RoamingSettings.Values); - - private static T GetInternal(string key, IPropertySet collection, T defaultValue = default) + if (collection.TryGetValue(key, out object value)) { - if (collection.TryGetValue(key, out object value)) + var stringValue = value?.ToString(); + + if (typeof(T).IsEnum) + return (T)Enum.Parse(typeof(T), stringValue); + + if ((typeof(T) == typeof(Guid?) || typeof(T) == typeof(Guid)) && Guid.TryParse(stringValue, out Guid guidResult)) { - var stringValue = value?.ToString(); - - if (typeof(T).IsEnum) - return (T)Enum.Parse(typeof(T), stringValue); - - if ((typeof(T) == typeof(Guid?) || typeof(T) == typeof(Guid)) && Guid.TryParse(stringValue, out Guid guidResult)) - { - return (T)(object)guidResult; - } - - if (typeof(T) == typeof(TimeSpan)) - { - return (T)(object)TimeSpan.Parse(stringValue); - } - - return (T)Convert.ChangeType(stringValue, typeof(T)); + return (T)(object)guidResult; } - return defaultValue; + if (typeof(T) == typeof(TimeSpan)) + { + return (T)(object)TimeSpan.Parse(stringValue); + } + + return (T)Convert.ChangeType(stringValue, typeof(T)); } - private static void SetInternal(string key, object value, IPropertySet collection) - => collection[key] = value?.ToString(); + return defaultValue; } + + private static void SetInternal(string key, object value, IPropertySet collection) + => collection[key] = value?.ToString(); } diff --git a/Wino.Core.UWP/Services/DialogServiceBase.cs b/Wino.Core.UWP/Services/DialogServiceBase.cs index 2f8f3e92..cb569583 100644 --- a/Wino.Core.UWP/Services/DialogServiceBase.cs +++ b/Wino.Core.UWP/Services/DialogServiceBase.cs @@ -20,284 +20,283 @@ using Wino.Core.UWP.Extensions; using Wino.Dialogs; using Wino.Messaging.Client.Shell; -namespace Wino.Core.UWP.Services +namespace Wino.Core.UWP.Services; + +public class DialogServiceBase : IDialogServiceBase { - public class DialogServiceBase : IDialogServiceBase + private SemaphoreSlim _presentationSemaphore = new SemaphoreSlim(1); + + protected IThemeService ThemeService { get; } + protected IConfigurationService ConfigurationService { get; } + + protected IApplicationResourceManager ApplicationResourceManager { get; } + + public DialogServiceBase(IThemeService themeService, IConfigurationService configurationService, IApplicationResourceManager applicationResourceManager) { - private SemaphoreSlim _presentationSemaphore = new SemaphoreSlim(1); + ThemeService = themeService; + ConfigurationService = configurationService; + ApplicationResourceManager = applicationResourceManager; + } - protected IThemeService ThemeService { get; } - protected IConfigurationService ConfigurationService { get; } - - protected IApplicationResourceManager ApplicationResourceManager { get; } - - public DialogServiceBase(IThemeService themeService, IConfigurationService configurationService, IApplicationResourceManager applicationResourceManager) + public async Task ShowEditAccountDialogAsync(MailAccount account) + { + var editAccountDialog = new AccountEditDialog(account) { - ThemeService = themeService; - ConfigurationService = configurationService; - ApplicationResourceManager = applicationResourceManager; + RequestedTheme = ThemeService.RootTheme.ToWindowsElementTheme() + }; + + await HandleDialogPresentationAsync(editAccountDialog); + + return editAccountDialog.IsSaved ? editAccountDialog.Account : null; + } + + public async Task PickFilePathAsync(string saveFileName) + { + var picker = new FolderPicker() + { + SuggestedStartLocation = PickerLocationId.Desktop + }; + + picker.FileTypeFilter.Add("*"); + + var folder = await picker.PickSingleFolderAsync(); + if (folder == null) return string.Empty; + + StorageApplicationPermissions.FutureAccessList.Add(folder); + + return folder.Path; + + //var picker = new FileSavePicker + //{ + // SuggestedStartLocation = PickerLocationId.Desktop, + // SuggestedFileName = saveFileName + //}; + + //picker.FileTypeChoices.Add(Translator.FilteringOption_All, [".*"]); + + //var file = await picker.PickSaveFileAsync(); + //if (file == null) return string.Empty; + + //StorageApplicationPermissions.FutureAccessList.Add(file); + + //return file.Path; + } + + public async Task> PickFilesAsync(params object[] typeFilters) + { + var returnList = new List(); + var picker = new FileOpenPicker + { + ViewMode = PickerViewMode.Thumbnail, + SuggestedStartLocation = PickerLocationId.Desktop + }; + + foreach (var filter in typeFilters) + { + picker.FileTypeFilter.Add(filter.ToString()); } - public async Task ShowEditAccountDialogAsync(MailAccount account) + var files = await picker.PickMultipleFilesAsync(); + if (files == null) return returnList; + + foreach (var file in files) { - var editAccountDialog = new AccountEditDialog(account) - { - RequestedTheme = ThemeService.RootTheme.ToWindowsElementTheme() - }; - - await HandleDialogPresentationAsync(editAccountDialog); - - return editAccountDialog.IsSaved ? editAccountDialog.Account : null; - } - - public async Task PickFilePathAsync(string saveFileName) - { - var picker = new FolderPicker() - { - SuggestedStartLocation = PickerLocationId.Desktop - }; - - picker.FileTypeFilter.Add("*"); - - var folder = await picker.PickSingleFolderAsync(); - if (folder == null) return string.Empty; - - StorageApplicationPermissions.FutureAccessList.Add(folder); - - return folder.Path; - - //var picker = new FileSavePicker - //{ - // SuggestedStartLocation = PickerLocationId.Desktop, - // SuggestedFileName = saveFileName - //}; - - //picker.FileTypeChoices.Add(Translator.FilteringOption_All, [".*"]); - - //var file = await picker.PickSaveFileAsync(); - //if (file == null) return string.Empty; - - //StorageApplicationPermissions.FutureAccessList.Add(file); - - //return file.Path; - } - - public async Task> PickFilesAsync(params object[] typeFilters) - { - var returnList = new List(); - var picker = new FileOpenPicker - { - ViewMode = PickerViewMode.Thumbnail, - SuggestedStartLocation = PickerLocationId.Desktop - }; - - foreach (var filter in typeFilters) - { - picker.FileTypeFilter.Add(filter.ToString()); - } - - var files = await picker.PickMultipleFilesAsync(); - if (files == null) return returnList; - - foreach (var file in files) - { - StorageApplicationPermissions.FutureAccessList.Add(file); - - var sharedFile = await file.ToSharedFileAsync(); - returnList.Add(sharedFile); - } - - return returnList; - } - - private async Task PickFileAsync(params object[] typeFilters) - { - var picker = new FileOpenPicker - { - ViewMode = PickerViewMode.Thumbnail - }; - - foreach (var filter in typeFilters) - { - picker.FileTypeFilter.Add(filter.ToString()); - } - - var file = await picker.PickSingleFileAsync(); - - if (file == null) return null; - StorageApplicationPermissions.FutureAccessList.Add(file); - return file; + var sharedFile = await file.ToSharedFileAsync(); + returnList.Add(sharedFile); } - public virtual IAccountCreationDialog GetAccountCreationDialog(AccountCreationDialogResult accountCreationDialogResult) + return returnList; + } + + private async Task PickFileAsync(params object[] typeFilters) + { + var picker = new FileOpenPicker { - return new AccountCreationDialog - { - RequestedTheme = ThemeService.RootTheme.ToWindowsElementTheme() - }; - } + ViewMode = PickerViewMode.Thumbnail + }; - public async Task PickWindowsFileContentAsync(params object[] typeFilters) + foreach (var filter in typeFilters) { - var file = await PickFileAsync(typeFilters); - - if (file == null) return []; - - return await file.ToByteArrayAsync(); + picker.FileTypeFilter.Add(filter.ToString()); } - public Task ShowMessageAsync(string message, string title, WinoCustomMessageDialogIcon icon = WinoCustomMessageDialogIcon.Information) - => ShowWinoCustomMessageDialogAsync(title, message, Translator.Buttons_Close, icon); + var file = await picker.PickSingleFileAsync(); - public Task ShowConfirmationDialogAsync(string question, string title, string confirmationButtonTitle) - => ShowWinoCustomMessageDialogAsync(title, question, confirmationButtonTitle, WinoCustomMessageDialogIcon.Question, Translator.Buttons_Cancel, string.Empty); + if (file == null) return null; - public async Task ShowWinoCustomMessageDialogAsync(string title, - string description, - string approveButtonText, - WinoCustomMessageDialogIcon? icon, - string cancelButtonText = "", - string dontAskAgainConfigurationKey = "") + StorageApplicationPermissions.FutureAccessList.Add(file); + return file; + } + + public virtual IAccountCreationDialog GetAccountCreationDialog(AccountCreationDialogResult accountCreationDialogResult) + { + return new AccountCreationDialog { - // This config key has been marked as don't ask again already. - // Return immidiate result without presenting the dialog. + RequestedTheme = ThemeService.RootTheme.ToWindowsElementTheme() + }; + } - bool isDontAskEnabled = !string.IsNullOrEmpty(dontAskAgainConfigurationKey); + public async Task PickWindowsFileContentAsync(params object[] typeFilters) + { + var file = await PickFileAsync(typeFilters); - if (isDontAskEnabled && ConfigurationService.Get(dontAskAgainConfigurationKey, false)) return false; + if (file == null) return []; - var informationContainer = new CustomMessageDialogInformationContainer(title, description, icon.Value, isDontAskEnabled); + return await file.ToByteArrayAsync(); + } - var dialog = new ContentDialog - { - Style = ApplicationResourceManager.GetResource