60 Commits

Author SHA1 Message Date
Burak Kaan Köse
6db85bfa39 Some event selections 2025-07-07 21:13:53 +02:00
Burak Kaan Köse
03c9ac1e11 Local time rendering for events. 2025-07-07 21:03:07 +02:00
Burak Kaan Köse
1ee0063b62 Refactored the calendar synchronization code using AI. 2025-07-06 17:25:38 +02:00
Aleh Khantsevich
3e889d8c08 Make height of single account navigation item smaller (#702)
* Make height of navigation item 50

* fix subtle and heights

* move spacing and margins

* make 52

* fix wrong heights
2025-07-02 23:41:41 +02:00
Aleh Khantsevich
a01395aed3 fix tab navigation for compose page (#695) 2025-06-21 13:35:42 +02:00
Aleh Khantsevich
7b3459abff Text input should update property on each changem instead of lost focus (#694) 2025-06-21 01:45:21 +02:00
Aleh Khantsevich
9a88f798fc fix animations (#689) 2025-06-21 01:40:45 +02:00
Maicol Battistini
256fd1cce2 feat: Enhanced sender avatars with gravatar and favicons integration (#685)
* feat: Enhanced sender avatars with gravatar and favicons integration

* chore: Remove unused known companies thumbnails

* feat(thumbnail): add IThumbnailService and refactor usage

- Introduced a new interface `IThumbnailService` for handling thumbnail-related functionalities.
- Registered `IThumbnailService` with its implementation `ThumbnailService` in the service container.
- Updated `NotificationBuilder` to use an instance of `IThumbnailService` instead of static methods.
- Refactored `ThumbnailService` from a static class to a regular class with instance methods and variables.
- Modified `ImagePreviewControl` to utilize the new `IThumbnailService` instance.
- Completed integration of `IThumbnailService` in the application by registering it in `App.xaml.cs`.

* style: Show favicons as squares

- Changed `hintCrop` in `NotificationBuilder` to `None` for app logo display.
- Added `FaviconSquircle`, `FaviconImage`, and `isFavicon` to `ImagePreviewControl` for favicon handling.
- Updated `UpdateInformation` method to manage favicon visibility.
- Introduced `GetBitmapImageAsync` for converting Base64 to Bitmap images.
- Enhanced XAML to include `FaviconSquircle` for improved UI appearance.

* refactor thumbnail service

* Removed old code and added clear method

* added prefetch function

* Change key from host to email

* Remove redundant code

* Test event

* Fixed an issue with the thumbnail updated event.

* Fix cutted favicons

* exclude some domain from favicons

* add yandex.ru

* fix buttons in settings

* remove prefetch method

* Added thumbnails propagation to mailRenderingPage

* Revert MailItemViewModel to object

* Remove redundant code

* spaces

* await load parameter added

* fix spaces

* fix case sensativity for mail list thumbnails

* change duckdns to google

* Some cleanup.

---------

Co-authored-by: Aleh Khantsevich <aleh.khantsevich@gmail.com>
Co-authored-by: Burak Kaan Köse <bkaankose@outlook.com>
2025-06-21 01:40:25 +02:00
Burak Kaan Köse
a8cb332232 Type fix. 2025-06-20 14:34:37 +02:00
Victor
89ea2b23a2 Replaced "Dismiss" button in notification popup with "Archive" button (#664)
* replaced "Dismiss" button in notification popup with "Archive" button

fixes https://github.com/bkaankose/Wino-Mail/issues/40

* Fixed incorrect build action for the archive icon.

---------

Co-authored-by: Burak Kaan Köse <bkaankose@outlook.com>
2025-06-15 15:27:39 +02:00
Aleh Khantsevich
9b214a66c8 Added new option to hide action labels in mail rendering page (#683)
* Added option to disable labels for mail actions

* Updated spacings and section title styles in settings

* Added translations
2025-06-15 15:17:57 +02:00
Aleh Khantsevich
4c4689ec8d Flyout styles and settings animations (#682)
* Refactor and enhance settings pages and solution structure

- Added transition effects to multiple pages for enhanced UI animations.
- Moved `AboutPage` and `PersonalizationPage` to settings folder.
- Put version into settings card instead of text.

* Fixed main logo in about page and changed version styles

* revert platforms

* Remove useless imprt

* Apply this animation globally

* Added resize transition for mail rendering page

* remove entrance transition from rendering page
2025-06-15 14:54:03 +02:00
Burak Kaan Köse
c4e561dee6 dotnet format refactorings. 2025-05-18 14:06:25 +02:00
Burak Kaan Köse
69bfe5b750 Fix calendar server startup. 2025-05-03 20:21:06 +02:00
Burak Kaan Köse
137b3dc2ea Merge branch 'main' of https://github.com/bkaankose/Wino-Mail 2025-05-03 19:08:36 +02:00
Burak Kaan Köse
ea5f879181 Fixed calendar slnx build. 2025-05-03 19:08:29 +02:00
Burak Kaan Köse
25d5f34f68 Version bump 2025-05-03 19:08:22 +02:00
Dinuru Seniya
c8a6df77ac Outlook Auth Fix (#653)
Issue: Account selector dialog pops up endlessly for Outlook/Live accounts. (Stored account not being correctly identified)

Fix: Ignore case differences, add null safety and remove whitespaces when retrieving stored accounts.
2025-05-02 12:12:45 +02:00
Burak Kaan Köse
7b6ac46b6a More informational message for different UPN and address for Outlook authenticator. 2025-04-26 12:25:34 +02:00
Burak Kaan Köse
d77c648d54 New Crowdin updates (#646)
* New translations resources.json (Romanian)

* New translations resources.json (French)

* New translations resources.json (Spanish)

* New translations resources.json (Bulgarian)

* New translations resources.json (Czech)

* New translations resources.json (German)

* New translations resources.json (Greek)

* New translations resources.json (Italian)

* New translations resources.json (Dutch)

* New translations resources.json (Polish)

* New translations resources.json (Slovak)

* New translations resources.json (Ukrainian)

* New translations resources.json (Chinese Simplified)

* New translations resources.json (Portuguese, Brazilian)
2025-04-26 11:04:03 +02:00
Burak Kaan Köse
c3f47c5fa1 Check account notification preferences after the synchronization. (#647) 2025-04-26 11:02:41 +02:00
Burak Kaan Köse
f37a51b46f Remove test code. 2025-04-26 10:51:14 +02:00
Burak Kaan Köse
9feb3f35c3 Synchronizer error factory implementation (#645)
* Added sync error factories for outlook and gmail.

* Implement ObjectCannotBeDeletedHandler for OutlookSynchronizer.

* Remove debug code.

* Implement del key to delete on mail list.

* Revert debug code.
2025-04-26 10:49:55 +02:00
Burak Kaan Köse
5b44cf03ce Don't report when printing is canceled. 2025-04-21 10:31:23 +02:00
Burak Kaan Köse
86a6382463 Max 1500 mails to download per-folder on initial sync for Gmail. 2025-04-21 10:15:42 +02:00
Burak Kaan Köse
df991a3829 Bump nugets. 2025-04-21 10:15:05 +02:00
Grigory
f243c86b50 build(nuget.config): correct nuget packageSources key name (#623) 2025-04-06 11:33:30 +02:00
Grigory
b77be0a5e9 build(Wino.Server.csproj): specify RuntimeIdentifiers (#621) 2025-04-06 11:33:08 +02:00
Burak Kaan Köse
83be587c1a Make sure there are no duplicate items for providers except Gmail when creating mails. 2025-04-04 23:55:50 +02:00
Burak Kaan Köse
c6048aea80 Make sure the requests are reflected to UI during synchronization. 2025-03-19 23:37:50 +01:00
Burak Kaan Köse
13b495b0f6 Fixed the Gmail sync identifier update issue and removed the batch message download. 2025-03-19 23:22:57 +01:00
Burak Kaan Köse
ac64c35efa Fix for another sequence contains error. 2025-03-19 22:15:28 +01:00
Burak Kaan Köse
127b58601f Remove missing isuread property. 2025-03-18 00:12:31 +01:00
Burak Kaan Köse
1f795b45e9 More visible unread items. 2025-03-18 00:10:45 +01:00
Burak Kaan Köse
d26e35ee9a Ctrl + A to select all mails. 2025-03-15 17:43:57 +01:00
Burak Kaan Köse
70e69e9dac Wino Calendar slnx 2025-03-15 15:23:26 +01:00
Burak Kaan Köse
3d88f4212d Merge branch 'main' of https://github.com/bkaankose/Wino-Mail 2025-03-15 15:22:43 +01:00
Burak Kaan Köse
ad90a9c8f3 Fix: Sequence contains no elements while downloading Gmail messages. 2025-03-15 15:22:01 +01:00
Aleh Khantsevich
b43176764b Trim all whitespaces, including \t for unsubscribe links (#599) 2025-03-06 22:34:05 +01:00
Burak Kaan Köse
77f24282e0 Fix incorrect visibility. 2025-03-01 19:43:32 +01:00
Burak Kaan Köse
533f1f1102 1.10.2 release notes. 2025-03-01 19:43:21 +01:00
Burak Kaan Köse
92c5d8bd44 New translations resources.json (Turkish) (#595) 2025-03-01 17:09:54 +01:00
Burak Kaan Köse
d754ecb486 New Crowdin updates (#594)
* New translations resources.json (Romanian)

* New translations resources.json (French)

* New translations resources.json (Spanish)

* New translations resources.json (Catalan)

* New translations resources.json (Czech)

* New translations resources.json (Danish)

* New translations resources.json (German)

* New translations resources.json (Greek)

* New translations resources.json (Finnish)

* New translations resources.json (Italian)

* New translations resources.json (Japanese)

* New translations resources.json (Dutch)

* New translations resources.json (Polish)

* New translations resources.json (Russian)

* New translations resources.json (Turkish)

* New translations resources.json (Ukrainian)

* New translations resources.json (Chinese Simplified)

* New translations resources.json (Galician)

* New translations resources.json (Portuguese, Brazilian)

* New translations resources.json (Indonesian)

* New translations resources.json (Lithuanian)
2025-03-01 17:05:04 +01:00
Burak Kaan Köse
b18987a95c Added ability to edit imap server configuration. (#593) 2025-03-01 16:53:05 +01:00
EzraWard
0daec61f31 Display app name on Win10 start tiles (#591) 2025-03-01 01:17:42 +01:00
Burak Kaan Köse
8ecf301eb8 Account colors + edit account details. (#592)
* Remove account rename dialog. Implement edit account details page.

* Remove unused folder definition.

* Adressing theming issues and adding reset button. Changing the UI a bit.

* Enable auto indent in initializer. Use service from the application.

* Adding color picker to acc setup dialog. Changing UI of edit acc details page.
2025-03-01 01:17:04 +01:00
Burak Kaan Köse
6080646e89 Don't crash on contact inserts. 2025-02-28 18:21:31 +01:00
Burak Kaan Köse
970a521b66 Pre-warmup on imap synchronizer interface. 2025-02-26 23:13:17 +01:00
Burak Kaan Köse
9b5a92f942 Changing delete logic. 2025-02-26 23:13:05 +01:00
Burak Kaan Köse
c4e0f13d67 Pre warmup trigger on synchronizer creation for imaps. 2025-02-26 23:12:01 +01:00
Burak Kaan Köse
b6821746d0 Locked busy scope to handle disconnections properly. 2025-02-26 23:11:49 +01:00
Burak Kaan Köse
b98fc91a99 Refactoring ImapClientPool. Implemented no-op timer and pre-warmup clients logic. Disabled protocol log per-account. 2025-02-26 23:11:16 +01:00
Burak Kaan Köse
bd7f7b867e Making sure missing draft folder is handling during draft creation. 2025-02-26 23:10:30 +01:00
Burak Kaan Köse
32a3fea8d7 Automatically append sent messages to sent folder for iCloud and Yahoo. 2025-02-26 22:57:08 +01:00
Burak Kaan Köse
3561beab1d Revert bump graph. 2025-02-26 22:18:25 +01:00
Burak Kaan Köse
1d1fd52cae Refactoring mail collection class. 2025-02-26 19:59:20 +01:00
Burak Kaan Köse
c4ba438150 Handling of generalException and some refactorings on batch executions. 2025-02-26 19:59:11 +01:00
Burak Kaan Köse
37f0ee08b1 Bump graph API. 2025-02-26 19:22:43 +01:00
Burak Kaan Köse
240b02c94e Fix gmail mail service not enabled error. 2025-02-26 19:04:38 +01:00
Burak Kaan Köse
e8142ff3df Download messages in ascending order. 2025-02-26 11:45:23 +01:00
292 changed files with 12443 additions and 8052 deletions

View File

@@ -9,34 +9,36 @@
<PackageVersion Include="CommunityToolkit.Labs.Uwp.Controls.MarkdownTextBlock" Version="0.1.250206-build.2040" />
<PackageVersion Include="CommunityToolkit.Labs.Uwp.DependencyPropertyGenerator" Version="0.1.250206-build.2040" />
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageVersion Include="CommunityToolkit.Uwp.Animations" Version="8.2.250129-preview2" />
<PackageVersion Include="CommunityToolkit.Uwp.Behaviors" Version="8.2.250129-preview2" />
<PackageVersion Include="CommunityToolkit.Uwp.Controls.Segmented" Version="8.2.250129-preview2" />
<PackageVersion Include="CommunityToolkit.Uwp.Controls.SettingsControls" Version="8.2.250129-preview2" />
<PackageVersion Include="CommunityToolkit.Uwp.Controls.Sizers" Version="8.2.250129-preview2" />
<PackageVersion Include="CommunityToolkit.Uwp.Controls.TabbedCommandBar" Version="8.2.250129-preview2" />
<PackageVersion Include="CommunityToolkit.Uwp.Controls.TokenizingTextBox" Version="8.2.250129-preview2" />
<PackageVersion Include="CommunityToolkit.Uwp.Extensions" Version="8.2.250129-preview2" />
<PackageVersion Include="EmailValidation" Version="1.2.0" />
<PackageVersion Include="HtmlAgilityPack" Version="1.11.72" />
<PackageVersion Include="CommunityToolkit.Uwp.Animations" Version="8.2.250402" />
<PackageVersion Include="CommunityToolkit.Uwp.Behaviors" Version="8.2.250402" />
<PackageVersion Include="CommunityToolkit.Uwp.Controls.Segmented" Version="8.2.250402" />
<PackageVersion Include="CommunityToolkit.Uwp.Controls.SettingsControls" Version="8.2.250402" />
<PackageVersion Include="CommunityToolkit.Uwp.Controls.Sizers" Version="8.2.250402" />
<PackageVersion Include="CommunityToolkit.Uwp.Controls.TabbedCommandBar" Version="8.2.250402" />
<PackageVersion Include="CommunityToolkit.Uwp.Controls.TokenizingTextBox" Version="8.2.250402" />
<PackageVersion Include="CommunityToolkit.Uwp.Extensions" Version="8.2.250402" />
<PackageVersion Include="CommunityToolkit.Uwp.Controls.Primitives" Version="8.2.250129-preview2" />
<PackageVersion Include="EmailValidation" Version="1.3.0" />
<PackageVersion Include="gravatar-dotnet" Version="0.1.3" />
<PackageVersion Include="HtmlAgilityPack" Version="1.12.0" />
<PackageVersion Include="Ical.Net" Version="4.3.1" />
<PackageVersion Include="IsExternalInit" Version="1.0.3" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.12.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.2" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.2" />
<PackageVersion Include="Microsoft.Graph" Version="5.69.0" />
<PackageVersion Include="Microsoft.Identity.Client" Version="4.68.0" />
<PackageVersion Include="Microsoft.Identity.Client.Broker" Version="4.68.0" />
<PackageVersion Include="Microsoft.Identity.Client.Extensions.Msal" Version="4.68.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.13.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.4" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.4" />
<PackageVersion Include="Microsoft.Graph" Version="5.75.0" />
<PackageVersion Include="Microsoft.Identity.Client" Version="4.70.1" />
<PackageVersion Include="Microsoft.Identity.Client.Broker" Version="4.70.1" />
<PackageVersion Include="Microsoft.Identity.Client.Extensions.Msal" Version="4.70.1" />
<PackageVersion Include="Microsoft.NETCore.UniversalWindowsPlatform" Version="6.2.14" />
<PackageVersion Include="Microsoft.UI.Xaml" Version="2.8.7" />
<PackageVersion Include="Microsoft.Xaml.Behaviors.Uwp.Managed" Version="3.0.0" />
<PackageVersion Include="MimeKit" Version="4.10.0" />
<PackageVersion Include="MimeKit" Version="4.11.0" />
<PackageVersion Include="morelinq" Version="4.4.0" />
<PackageVersion Include="Nito.AsyncEx" Version="5.1.2" />
<PackageVersion Include="Nito.AsyncEx.Tasks" Version="5.1.2" />
<PackageVersion Include="NodaTime" Version="3.2.1" />
<PackageVersion Include="NodaTime" Version="3.2.2" />
<PackageVersion Include="Serilog" Version="4.2.0" />
<PackageVersion Include="Serilog.Exceptions" Version="8.4.0" />
<PackageVersion Include="Serilog.Sinks.Debug" Version="3.0.0" />
@@ -46,20 +48,20 @@
<PackageVersion Include="sqlite-net-pcl" Version="1.9.172" />
<PackageVersion Include="SqlKata" Version="4.0.1" />
<PackageVersion Include="System.Private.Uri" Version="4.3.2" />
<PackageVersion Include="System.Text.Encoding.CodePages" Version="9.0.2" />
<PackageVersion Include="System.Text.Json" Version="9.0.2" />
<PackageVersion Include="System.Text.Encoding.CodePages" Version="9.0.4" />
<PackageVersion Include="System.Text.Json" Version="9.0.4" />
<PackageVersion Include="Win2D.uwp" Version="1.28.2" />
<PackageVersion Include="H.NotifyIcon.Wpf" Version="2.2.0" />
<PackageVersion Include="H.NotifyIcon.Wpf" Version="2.3.0" />
<PackageVersion Include="CommunityToolkit.WinUI.Notifications" Version="7.1.2" />
<PackageVersion Include="Google.Apis.Auth" Version="1.69.0" />
<PackageVersion Include="Google.Apis.Calendar.v3" Version="1.69.0.3667" />
<PackageVersion Include="Google.Apis.Gmail.v1" Version="1.68.0.3427" />
<PackageVersion Include="Google.Apis.PeopleService.v1" Version="1.68.0.3359" />
<PackageVersion Include="HtmlKit" Version="1.2.0" />
<PackageVersion Include="MailKit" Version="4.10.0" />
<PackageVersion Include="TimePeriodLibrary.NET" Version="2.1.5" />
<PackageVersion Include="MailKit" Version="4.11.0" />
<PackageVersion Include="TimePeriodLibrary.NET" Version="2.1.6" />
<PackageVersion Include="System.Reactive" Version="6.0.1" />
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.2" />
<PackageVersion Include="System.Text.Encodings.Web" Version="9.0.2" />
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.4" />
<PackageVersion Include="System.Text.Encodings.Web" Version="9.0.4" />
</ItemGroup>
</Project>

View File

@@ -67,7 +67,8 @@ public class OutlookAuthenticator : BaseAuthenticator, IOutlookAuthenticator
{
await EnsureTokenCacheAttachedAsync();
var storedAccount = (await _publicClientApplication.GetAccountsAsync()).FirstOrDefault(a => a.Username == account.Address);
var storedAccount = (await _publicClientApplication.GetAccountsAsync()).FirstOrDefault(
a => string.Equals(a.Username?.Trim(), account.Address?.Trim(), StringComparison.OrdinalIgnoreCase));
if (storedAccount == null)
return await GenerateTokenInformationAsync(account);
@@ -107,7 +108,7 @@ public class OutlookAuthenticator : BaseAuthenticator, IOutlookAuthenticator
if (account?.Address != null && !account.Address.Equals(authResult.Account.Username, StringComparison.OrdinalIgnoreCase))
{
throw new AuthenticationException("Authenticated address does not match with your account address.");
throw new AuthenticationException("Authenticated address does not match with your account address. If you are signing with a Office365, it is not officially supported yet.");
}
return new TokenInformationEx(authResult.AccessToken, authResult.Account.Username);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap rescap">
<Identity
Name="58272BurakKSE.WinoCalendar"
Publisher="CN=51FBDAF3-E212-4149-89A2-A2636B3BC911"
Version="1.0.0.0" />
<Properties>
<DisplayName>Wino Calendar</DisplayName>
<PublisherDisplayName>Burak KÖSE</PublisherDisplayName>
<Logo>Images\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.14393.0" MaxVersionTested="10.0.14393.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="Wino Calendar"
Description="Wino.Calendar.Packaging"
BackgroundColor="transparent"
Square150x150Logo="Images\Square150x150Logo.png"
Square44x44Logo="Images\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Images\Wide310x150Logo.png" />
<uap:SplashScreen Image="Images\SplashScreen.png" />
</uap:VisualElements>
<Extensions>
<!-- Registration of full trust backend application. -->
<uap:Extension Category="windows.appService">
<uap:AppService Name="WinoInteropService" />
</uap:Extension>
<!-- Protocol activation: Google OAuth -->
<uap:Extension Category="windows.protocol">
<uap:Protocol Name="google.pw.oauth2">
<uap:DisplayName>Wino Google Authentication Protocol</uap:DisplayName>
</uap:Protocol>
</uap:Extension>
<!-- Protocol activation: Launch UWP app from Full Trust Process -->
<uap:Extension Category="windows.protocol">
<uap:Protocol Name="wino.calendar.launch">
<uap:DisplayName>Wino Calendara Launcher Protocol</uap:DisplayName>
</uap:Protocol>
</uap:Extension>
<!-- Startup Task -->
<uap5:Extension
Category="windows.startupTask"
Executable="Wino.Server\Wino.Server.exe"
EntryPoint="Windows.FullTrustApplication">
<uap5:StartupTask
TaskId="WinoServer"
Enabled="false"
DisplayName="Wino Mail" />
</uap5:Extension>
<desktop:Extension Category="windows.fullTrustProcess" Executable="Wino.Server\Wino.Server.exe">
<desktop:FullTrustProcess>
<desktop:ParameterGroup GroupId="WinoServer" Parameters="Calendar" />
</desktop:FullTrustProcess>
</desktop:Extension>
</Extensions>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="runFullTrust" />
<rescap:Capability Name="confirmAppClose" />
</Capabilities>
</Package>

View File

@@ -1,77 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '15.0'">
<VisualStudioVersion>15.0</VisualStudioVersion>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x86">
<Configuration>Debug</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x86">
<Configuration>Release</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|AnyCPU">
<Configuration>Debug</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|AnyCPU">
<Configuration>Release</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup>
<WapProjPath Condition="'$(WapProjPath)'==''">$(MSBuildExtensionsPath)\Microsoft\DesktopBridge\</WapProjPath>
</PropertyGroup>
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.props" />
<PropertyGroup>
<ProjectGuid>7485b18c-f5ab-4abe-ba7f-05b6623c67c8</ProjectGuid>
<TargetPlatformVersion>10.0.22621.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
<DefaultLanguage>en-US</DefaultLanguage>
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>
<NoWarn>$(NoWarn);NU1702</NoWarn>
<EntryPointProjectUniqueName>..\Wino.Calendar\Wino.Calendar.csproj</EntryPointProjectUniqueName>
<GenerateTemporaryStoreCertificate>True</GenerateTemporaryStoreCertificate>
</PropertyGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
</ItemGroup>
<ItemGroup>
<Content Include="Images\SplashScreen.scale-200.png" />
<Content Include="Images\LockScreenLogo.scale-200.png" />
<Content Include="Images\Square150x150Logo.scale-200.png" />
<Content Include="Images\Square44x44Logo.scale-200.png" />
<Content Include="Images\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Content Include="Images\StoreLogo.png" />
<Content Include="Images\Wide310x150Logo.scale-200.png" />
<None Include="Package.StoreAssociation.xml" />
</ItemGroup>
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.targets" />
<ItemGroup>
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.1742" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Wino.Calendar\Wino.Calendar.csproj" />
<ProjectReference Include="..\Wino.Server\Wino.Server.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,14 +1,16 @@
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using Wino.Calendar.ViewModels.Interfaces;
using Wino.Core.Domain;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Navigation;
using Wino.Core.ViewModels;
using Wino.Mail.ViewModels.Data;
using Wino.Messaging.UI;
using Wino.Messaging.Client.Navigation;
namespace Wino.Calendar.ViewModels;
namespace Wino.Calendar.ViewModels
{
public partial class AccountDetailsPageViewModel : CalendarBaseViewModel
{
private readonly IAccountService _accountService;
@@ -25,24 +27,11 @@ namespace Wino.Calendar.ViewModels
}
[RelayCommand]
private async Task RenameAccount()
{
if (Account == null)
return;
var updatedAccount = await CalendarDialogService.ShowEditAccountDialogAsync(Account.Account);
if (updatedAccount != null)
{
await _accountService.UpdateAccountAsync(updatedAccount);
ReportUIChange(new AccountUpdatedMessage(updatedAccount));
}
}
private void EditAccountDetails()
=> Messenger.Send(new BreadcrumbNavigationRequested(Translator.SettingsEditAccountDetails_Title, WinoPage.EditAccountDetailsPage, Account));
public override void OnNavigatedTo(NavigationMode mode, object parameters)
{
base.OnNavigatedTo(mode, parameters);
}
}
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Input;
@@ -13,8 +14,8 @@ using Wino.Core.Domain.Models.Synchronization;
using Wino.Core.ViewModels;
using Wino.Messaging.Server;
namespace Wino.Calendar.ViewModels
{
namespace Wino.Calendar.ViewModels;
public partial class AccountManagementViewModel : AccountManagementPageViewModelBase
{
private readonly IProviderService _providerService;
@@ -83,8 +84,8 @@ namespace Wino.Calendar.ViewModels
var accountCreationCancellationTokenSource = new CancellationTokenSource();
var accountCreationDialog = CalendarDialogService.GetAccountCreationDialog(accountCreationDialogResult);
accountCreationDialog.ShowDialog(accountCreationCancellationTokenSource);
accountCreationDialog.State = AccountCreationDialogState.SigningIn;
await accountCreationDialog.ShowDialogAsync(accountCreationCancellationTokenSource);
await Task.Delay(500);
// For OAuth authentications, we just generate token and assign it to the MailAccount.
@@ -141,7 +142,16 @@ namespace Wino.Calendar.ViewModels
Type = CalendarSynchronizationType.CalendarMetadata
};
var timer = new Stopwatch();
var synchronizationResponse = await WinoServerConnectionManager.GetResponseAsync<CalendarSynchronizationResult, NewCalendarSynchronizationRequested>(new NewCalendarSynchronizationRequested(synchronizationOptions, SynchronizationSource.Client));
}
timer.Stop();
Debug.WriteLine("Synchronization completed in {timer.ElapsedMilliseconds} ms");
// TODO: Properly handle synchronization errors.
accountCreationDialog.Complete(false);
}
}

View File

@@ -21,8 +21,8 @@ using Wino.Messaging.Client.Calendar;
using Wino.Messaging.Client.Navigation;
using Wino.Messaging.Server;
namespace Wino.Calendar.ViewModels
{
namespace Wino.Calendar.ViewModels;
public partial class AppShellViewModel : CalendarBaseViewModel,
IRecipient<VisibleDateRangeChangedMessage>,
IRecipient<CalendarEnableStatusChangedMessage>,
@@ -364,4 +364,3 @@ namespace Wino.Calendar.ViewModels
});
}
}
}

View File

@@ -23,8 +23,8 @@ using Wino.Core.Domain.Models.Navigation;
using Wino.Core.ViewModels;
using Wino.Messaging.Client.Calendar;
namespace Wino.Calendar.ViewModels
{
namespace Wino.Calendar.ViewModels;
public partial class CalendarPageViewModel : CalendarBaseViewModel,
IRecipient<LoadCalendarMessage>,
IRecipient<CalendarItemDeleted>,
@@ -127,6 +127,7 @@ namespace Wino.Calendar.ViewModels
private readonly ICalendarService _calendarService;
private readonly INavigationService _navigationService;
private readonly IKeyPressService _keyPressService;
private readonly ICalendarServiceEx _calendarServiceEx;
private readonly IPreferencesService _preferencesService;
// Store latest rendered options.
@@ -146,6 +147,7 @@ namespace Wino.Calendar.ViewModels
ICalendarService calendarService,
INavigationService navigationService,
IKeyPressService keyPressService,
ICalendarServiceEx calendarServiceEx,
IAccountCalendarStateService accountCalendarStateService,
IPreferencesService preferencesService)
{
@@ -155,6 +157,7 @@ namespace Wino.Calendar.ViewModels
_calendarService = calendarService;
_navigationService = navigationService;
_keyPressService = keyPressService;
_calendarServiceEx = calendarServiceEx;
_preferencesService = preferencesService;
AccountCalendarStateService.AccountCalendarSelectionStateChanged += UpdateAccountCalendarRequested;
@@ -235,23 +238,6 @@ namespace Wino.Calendar.ViewModels
[RelayCommand(AllowConcurrentExecutions = false, CanExecute = nameof(CanSaveQuickEvent))]
private async Task SaveQuickEventAsync()
{
var durationSeconds = (QuickEventEndTime - QuickEventStartTime).TotalSeconds;
var testCalendarItem = new CalendarItem
{
CalendarId = SelectedQuickEventAccountCalendar.Id,
StartDate = QuickEventStartTime,
DurationInSeconds = durationSeconds,
CreatedAt = DateTime.UtcNow,
Description = string.Empty,
Location = Location,
Title = EventName,
Id = Guid.NewGuid()
};
IsQuickEventDialogOpen = false;
await _calendarService.CreateNewCalendarItemAsync(testCalendarItem, null);
// TODO: Create the request with the synchronizer.
}
@@ -635,10 +621,13 @@ namespace Wino.Calendar.ViewModels
// Check all the events for the given date range and calendar.
// Then find the day representation for all the events returned, and add to the collection.
var events = await _calendarService.GetCalendarEventsAsync(calendarViewModel, dayRangeRenderModel).ConfigureAwait(false);
var events = await _calendarServiceEx.GetExpandedEventsInDateRangeWithExceptionsAsync(dayRangeRenderModel.Period.Start, dayRangeRenderModel.Period.End, calendarViewModel.AccountCalendar).ConfigureAwait(false);
foreach (var @event in events)
{
// TODO: Do it in the service.
@event.AssignedCalendar = calendarViewModel.AccountCalendar;
// Find the days that the event falls into.
var allDaysForEvent = dayRangeRenderModel.CalendarDays.Where(a => a.Period.OverlapsWith(@event.Period));
@@ -800,12 +789,12 @@ namespace Wino.Calendar.ViewModels
// Recurring events must be selected as a single instance.
// We need to find the day that the event is in, and then select the event.
if (!calendarItemViewModel.IsRecurringEvent)
{
return [calendarItemViewModel];
}
else
{
if (calendarItemViewModel == null) return Enumerable.Empty<CalendarItemViewModel>();
// If the calendar item is not recurring, we can just return it.
if (calendarItemViewModel.ItemType == CalendarItemType.Timed || calendarItemViewModel.ItemType == CalendarItemType.RecurringException) return new[] { calendarItemViewModel };
return DayRanges
.SelectMany(a => a.CalendarDays)
.Select(b => b.EventsCollection.GetCalendarItem(calendarItemViewModel.Id))
@@ -813,7 +802,6 @@ namespace Wino.Calendar.ViewModels
.Cast<CalendarItemViewModel>()
.Distinct();
}
}
private void UnselectCalendarItem(CalendarItemViewModel calendarItemViewModel, CalendarDayModel calendarDay = null)
{
@@ -821,6 +809,8 @@ namespace Wino.Calendar.ViewModels
var itemsToUnselect = GetCalendarItems(calendarItemViewModel, calendarDay);
if (itemsToUnselect == null) return;
foreach (var item in itemsToUnselect)
{
item.IsSelected = false;
@@ -833,6 +823,8 @@ namespace Wino.Calendar.ViewModels
var itemsToSelect = GetCalendarItems(calendarItemViewModel, calendarDay);
if (itemsToSelect == null) return;
foreach (var item in itemsToSelect)
{
item.IsSelected = true;
@@ -868,4 +860,3 @@ namespace Wino.Calendar.ViewModels
});
}
}
}

View File

@@ -8,8 +8,8 @@ using Wino.Core.Domain.Translations;
using Wino.Core.ViewModels;
using Wino.Messaging.Client.Calendar;
namespace Wino.Calendar.ViewModels
{
namespace Wino.Calendar.ViewModels;
public partial class CalendarSettingsPageViewModel : CalendarBaseViewModel
{
[ObservableProperty]
@@ -124,4 +124,3 @@ namespace Wino.Calendar.ViewModels
Messenger.Send(new CalendarSettingsUpdatedMessage());
}
}
}

View File

@@ -1,8 +1,8 @@
using Microsoft.Extensions.DependencyInjection;
using Wino.Core;
namespace Wino.Calendar.ViewModels
{
namespace Wino.Calendar.ViewModels;
public static class CalendarViewModelContainerSetup
{
public static void RegisterCalendarViewModelServices(this IServiceCollection services)
@@ -10,4 +10,3 @@ namespace Wino.Calendar.ViewModels
services.RegisterCoreServices();
}
}
}

View File

@@ -4,8 +4,8 @@ using Wino.Core.Domain.Entities.Calendar;
using Wino.Core.Domain.Entities.Shared;
using Wino.Core.Domain.Interfaces;
namespace Wino.Calendar.ViewModels.Data
{
namespace Wino.Calendar.ViewModels.Data;
public partial class AccountCalendarViewModel : ObservableObject, IAccountCalendar
{
public MailAccount Account { get; }
@@ -67,4 +67,3 @@ namespace Wino.Calendar.ViewModels.Data
}
public Guid Id { get => ((IAccountCalendar)AccountCalendar).Id; set => ((IAccountCalendar)AccountCalendar).Id = value; }
}
}

View File

@@ -1,12 +1,14 @@
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using CommunityToolkit.Mvvm.ComponentModel;
using Itenso.TimePeriod;
using Wino.Core.Domain.Entities.Calendar;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
namespace Wino.Calendar.ViewModels.Data
{
namespace Wino.Calendar.ViewModels.Data;
public partial class CalendarItemViewModel : ObservableObject, ICalendarItem, ICalendarItemViewModel
{
public CalendarItem CalendarItem { get; }
@@ -17,30 +19,74 @@ namespace Wino.Calendar.ViewModels.Data
public IAccountCalendar AssignedCalendar => CalendarItem.AssignedCalendar;
public DateTime StartDate { get => CalendarItem.StartDate; set => CalendarItem.StartDate = value; }
public DateTime StartDateTime { get => CalendarItem.StartDateTime; set => CalendarItem.StartDateTime = value; }
public DateTime EndDate => CalendarItem.EndDate;
public DateTime EndDateTime => CalendarItem.EndDateTime;
public double DurationInSeconds { get => CalendarItem.DurationInSeconds; set => CalendarItem.DurationInSeconds = value; }
/// <summary>
/// Gets the start date and time in the local time zone for display purposes.
/// </summary>
public DateTime LocalStartDateTime => ConvertToLocalTime();
/// <summary>
/// Gets the end date and time in the local time zone for display purposes.
/// </summary>
public DateTime LocalEndDateTime => ConvertToLocalTime();
public ITimePeriod Period => CalendarItem.Period;
public bool IsAllDayEvent => CalendarItem.IsAllDayEvent;
public bool IsMultiDayEvent => CalendarItem.IsMultiDayEvent;
public bool IsRecurringEvent => CalendarItem.IsRecurringEvent;
public bool IsRecurringChild => CalendarItem.IsRecurringChild;
public bool IsRecurringParent => CalendarItem.IsRecurringParent;
public bool IsRecurringEvent => !string.IsNullOrEmpty(CalendarItem.RecurrenceRules) || !string.IsNullOrEmpty(CalendarItem.RecurringEventId);
[ObservableProperty]
private bool _isSelected;
public ObservableCollection<CalendarEventAttendee> Attendees { get; } = new ObservableCollection<CalendarEventAttendee>();
public CalendarItemType ItemType => CalendarItem.ItemType;
public CalendarItemViewModel(CalendarItem calendarItem)
{
CalendarItem = calendarItem;
Debug.WriteLine($"{Title} : {ItemType}");
}
/// <summary>
/// Converts a DateTime to local time based on the provided timezone.
/// If timezone is empty or null, assumes the DateTime is in UTC.
/// </summary>
/// <param name="dateTime">The DateTime to convert</param>
/// <param name="timeZone">The timezone string. If empty/null, assumes UTC.</param>
/// <returns>DateTime converted to local time</returns>
private DateTime ConvertToLocalTime()
{
// All day events ignore time zones and are treated as local time.
if (ItemType == CalendarItemType.AllDay || ItemType == CalendarItemType.MultiDayAllDay || ItemType == CalendarItemType.RecurringAllDay)
return CalendarItem.StartDateTime;
if (string.IsNullOrEmpty(CalendarItem.TimeZone))
{
// If no timezone specified, assume it's UTC and convert to local time
return DateTime.SpecifyKind(CalendarItem.StartDateTime, DateTimeKind.Utc).ToLocalTime();
}
try
{
// Parse the timezone and convert to local time
var sourceTimeZone = TimeZoneInfo.FindSystemTimeZoneById(CalendarItem.TimeZone);
return TimeZoneInfo.ConvertTimeToUtc(CalendarItem.StartDateTime, sourceTimeZone).ToLocalTime();
}
catch (TimeZoneNotFoundException)
{
// If timezone is not found, fallback to treating as UTC
return DateTime.SpecifyKind(CalendarItem.StartDateTime, DateTimeKind.Utc).ToLocalTime();
}
catch (InvalidTimeZoneException)
{
// If timezone is invalid, fallback to treating as UTC
return DateTime.SpecifyKind(CalendarItem.StartDateTime, DateTimeKind.Utc).ToLocalTime();
}
}
public override string ToString() => CalendarItem.Title;
}
}

View File

@@ -6,8 +6,8 @@ using System.Linq;
using CommunityToolkit.Mvvm.ComponentModel;
using Wino.Core.Domain.Entities.Shared;
namespace Wino.Calendar.ViewModels.Data
{
namespace Wino.Calendar.ViewModels.Data;
public partial class GroupedAccountCalendarViewModel : ObservableObject
{
public event EventHandler CollectiveSelectionStateChanged;
@@ -143,4 +143,3 @@ namespace Wino.Calendar.ViewModels.Data
CalendarSelectionStateChanged?.Invoke(this, accountCalendarViewModel);
}
}
}

View File

@@ -12,8 +12,8 @@ using Wino.Core.Domain.Models.Navigation;
using Wino.Core.ViewModels;
using Wino.Messaging.Client.Calendar;
namespace Wino.Calendar.ViewModels
{
namespace Wino.Calendar.ViewModels;
public partial class EventDetailsPageViewModel : CalendarBaseViewModel
{
private readonly ICalendarService _calendarService;
@@ -31,7 +31,7 @@ namespace Wino.Calendar.ViewModels
[ObservableProperty]
private CalendarItemViewModel _seriesParent;
public bool CanViewSeries => CurrentEvent?.IsRecurringChild ?? false;
public bool CanViewSeries => false; //CurrentEvent?.IsRecurringChild ?? false; // TODO: Implement this properly
#endregion
@@ -67,7 +67,7 @@ namespace Wino.Calendar.ViewModels
CurrentEvent = new CalendarItemViewModel(currentEventItem);
var attendees = await _calendarService.GetAttendeesAsync(currentEventItem.EventTrackingId);
var attendees = await _calendarService.GetAttendeesAsync(currentEventItem.Id);
foreach (var item in attendees)
{
@@ -113,4 +113,3 @@ namespace Wino.Calendar.ViewModels
if (CurrentEvent == null) return;
}
}
}

View File

@@ -6,8 +6,8 @@ using System.Linq;
using Wino.Calendar.ViewModels.Data;
using Wino.Core.Domain.Entities.Shared;
namespace Wino.Calendar.ViewModels.Interfaces
{
namespace Wino.Calendar.ViewModels.Interfaces;
public interface IAccountCalendarStateService : INotifyPropertyChanged
{
ReadOnlyObservableCollection<GroupedAccountCalendarViewModel> GroupedAccountCalendars { get; }
@@ -28,4 +28,3 @@ namespace Wino.Calendar.ViewModels.Interfaces
IEnumerable<AccountCalendarViewModel> ActiveCalendars { get; }
IEnumerable<IGrouping<MailAccount, AccountCalendarViewModel>> GroupedAccountCalendarsEnumerable { get; }
}
}

View File

@@ -1,7 +1,7 @@
using Wino.Calendar.ViewModels.Data;
namespace Wino.Calendar.ViewModels.Messages
{
namespace Wino.Calendar.ViewModels.Messages;
public class CalendarItemDoubleTappedMessage
{
public CalendarItemDoubleTappedMessage(CalendarItemViewModel calendarItemViewModel)
@@ -11,4 +11,3 @@ namespace Wino.Calendar.ViewModels.Messages
public CalendarItemViewModel CalendarItemViewModel { get; }
}
}

View File

@@ -1,7 +1,7 @@
using Wino.Calendar.ViewModels.Data;
namespace Wino.Calendar.ViewModels.Messages
{
namespace Wino.Calendar.ViewModels.Messages;
public class CalendarItemRightTappedMessage
{
public CalendarItemRightTappedMessage(CalendarItemViewModel calendarItemViewModel)
@@ -11,4 +11,3 @@ namespace Wino.Calendar.ViewModels.Messages
public CalendarItemViewModel CalendarItemViewModel { get; }
}
}

View File

@@ -1,8 +1,8 @@
using Wino.Calendar.ViewModels.Data;
using Wino.Core.Domain.Models.Calendar;
namespace Wino.Calendar.ViewModels.Messages
{
namespace Wino.Calendar.ViewModels.Messages;
public class CalendarItemTappedMessage
{
public CalendarItemTappedMessage(CalendarItemViewModel calendarItemViewModel, CalendarDayModel clickedPeriod)
@@ -14,4 +14,3 @@ namespace Wino.Calendar.ViewModels.Messages
public CalendarItemViewModel CalendarItemViewModel { get; }
public CalendarDayModel ClickedPeriod { get; }
}
}

View File

@@ -1,15 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>12</LangVersion>
<Platforms>AnyCPU;x64;x86</Platforms>
<TargetFramework>net9.0</TargetFramework>
<Platforms>x86;x64;arm64</Platforms>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="TimePeriodLibrary.NET" Version="2.1.5" />
<PackageReference Include="TimePeriodLibrary.NET" />
</ItemGroup>
<ItemGroup>

View File

@@ -1,308 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.12.35424.110
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wino.Core.Domain", "Wino.Core.Domain\Wino.Core.Domain.csproj", "{814400B6-5A05-4596-B451-3A116A147DC1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wino.Core.UWP", "Wino.Core.UWP\Wino.Core.UWP.csproj", "{395F19BA-1E42-495C-9DB5-1A6F537FCCB8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wino.Core.ViewModels", "Wino.Core.ViewModels\Wino.Core.ViewModels.csproj", "{510CD96C-B3FF-4EC9-A67B-845C842E6BEC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wino.Messaging", "Wino.Messages\Wino.Messaging.csproj", "{AB588CFD-4B0C-4A1F-B711-1999E3D092D0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wino.Server", "Wino.Server\Wino.Server.csproj", "{92DA33FC-9252-40C5-BF71-67ACB0B56F2B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wino.Core", "Wino.Core\Wino.Core.csproj", "{87FFCBF4-DC17-4F09-90D6-102CF4C72BAF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wino.Calendar", "Wino.Calendar\Wino.Calendar.csproj", "{600F4979-DB7E-409D-B7DA-B60BE4C55C35}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wino.SourceGenerators", "Wino.SourceGenerators\Wino.SourceGenerators.csproj", "{8A7EB697-D722-4E0F-B20E-9FC88373ADB5}"
EndProject
Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "Wino.Calendar.Packaging", "Wino.Calendar.Packaging\Wino.Calendar.Packaging.wapproj", "{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wino.Calendar.ViewModels", "Wino.Calendar.ViewModels\Wino.Calendar.ViewModels.csproj", "{CF850F8C-5042-4376-9CBA-C8F2BB554083}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wino.Services", "Wino.Services\Wino.Services.csproj", "{BBA49030-7277-48CF-B2FE-3D01CB6B6C81}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wino.Authentication", "Wino.Authentication\Wino.Authentication.csproj", "{16A979C2-F308-464F-9B2A-0AF8ED5EDB43}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{814400B6-5A05-4596-B451-3A116A147DC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{814400B6-5A05-4596-B451-3A116A147DC1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{814400B6-5A05-4596-B451-3A116A147DC1}.Debug|ARM.ActiveCfg = Debug|Any CPU
{814400B6-5A05-4596-B451-3A116A147DC1}.Debug|ARM.Build.0 = Debug|Any CPU
{814400B6-5A05-4596-B451-3A116A147DC1}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{814400B6-5A05-4596-B451-3A116A147DC1}.Debug|ARM64.Build.0 = Debug|Any CPU
{814400B6-5A05-4596-B451-3A116A147DC1}.Debug|x64.ActiveCfg = Debug|x64
{814400B6-5A05-4596-B451-3A116A147DC1}.Debug|x64.Build.0 = Debug|x64
{814400B6-5A05-4596-B451-3A116A147DC1}.Debug|x86.ActiveCfg = Debug|x86
{814400B6-5A05-4596-B451-3A116A147DC1}.Debug|x86.Build.0 = Debug|x86
{814400B6-5A05-4596-B451-3A116A147DC1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{814400B6-5A05-4596-B451-3A116A147DC1}.Release|Any CPU.Build.0 = Release|Any CPU
{814400B6-5A05-4596-B451-3A116A147DC1}.Release|ARM.ActiveCfg = Release|Any CPU
{814400B6-5A05-4596-B451-3A116A147DC1}.Release|ARM.Build.0 = Release|Any CPU
{814400B6-5A05-4596-B451-3A116A147DC1}.Release|ARM64.ActiveCfg = Release|Any CPU
{814400B6-5A05-4596-B451-3A116A147DC1}.Release|ARM64.Build.0 = Release|Any CPU
{814400B6-5A05-4596-B451-3A116A147DC1}.Release|x64.ActiveCfg = Release|x64
{814400B6-5A05-4596-B451-3A116A147DC1}.Release|x64.Build.0 = Release|x64
{814400B6-5A05-4596-B451-3A116A147DC1}.Release|x86.ActiveCfg = Release|x86
{814400B6-5A05-4596-B451-3A116A147DC1}.Release|x86.Build.0 = Release|x86
{395F19BA-1E42-495C-9DB5-1A6F537FCCB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{395F19BA-1E42-495C-9DB5-1A6F537FCCB8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{395F19BA-1E42-495C-9DB5-1A6F537FCCB8}.Debug|ARM.ActiveCfg = Debug|Any CPU
{395F19BA-1E42-495C-9DB5-1A6F537FCCB8}.Debug|ARM.Build.0 = Debug|Any CPU
{395F19BA-1E42-495C-9DB5-1A6F537FCCB8}.Debug|ARM64.ActiveCfg = Debug|ARM64
{395F19BA-1E42-495C-9DB5-1A6F537FCCB8}.Debug|ARM64.Build.0 = Debug|ARM64
{395F19BA-1E42-495C-9DB5-1A6F537FCCB8}.Debug|x64.ActiveCfg = Debug|x64
{395F19BA-1E42-495C-9DB5-1A6F537FCCB8}.Debug|x64.Build.0 = Debug|x64
{395F19BA-1E42-495C-9DB5-1A6F537FCCB8}.Debug|x86.ActiveCfg = Debug|x86
{395F19BA-1E42-495C-9DB5-1A6F537FCCB8}.Debug|x86.Build.0 = Debug|x86
{395F19BA-1E42-495C-9DB5-1A6F537FCCB8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{395F19BA-1E42-495C-9DB5-1A6F537FCCB8}.Release|Any CPU.Build.0 = Release|Any CPU
{395F19BA-1E42-495C-9DB5-1A6F537FCCB8}.Release|ARM.ActiveCfg = Release|Any CPU
{395F19BA-1E42-495C-9DB5-1A6F537FCCB8}.Release|ARM.Build.0 = Release|Any CPU
{395F19BA-1E42-495C-9DB5-1A6F537FCCB8}.Release|ARM64.ActiveCfg = Release|ARM64
{395F19BA-1E42-495C-9DB5-1A6F537FCCB8}.Release|ARM64.Build.0 = Release|ARM64
{395F19BA-1E42-495C-9DB5-1A6F537FCCB8}.Release|x64.ActiveCfg = Release|x64
{395F19BA-1E42-495C-9DB5-1A6F537FCCB8}.Release|x64.Build.0 = Release|x64
{395F19BA-1E42-495C-9DB5-1A6F537FCCB8}.Release|x86.ActiveCfg = Release|x86
{395F19BA-1E42-495C-9DB5-1A6F537FCCB8}.Release|x86.Build.0 = Release|x86
{510CD96C-B3FF-4EC9-A67B-845C842E6BEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{510CD96C-B3FF-4EC9-A67B-845C842E6BEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{510CD96C-B3FF-4EC9-A67B-845C842E6BEC}.Debug|ARM.ActiveCfg = Debug|Any CPU
{510CD96C-B3FF-4EC9-A67B-845C842E6BEC}.Debug|ARM.Build.0 = Debug|Any CPU
{510CD96C-B3FF-4EC9-A67B-845C842E6BEC}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{510CD96C-B3FF-4EC9-A67B-845C842E6BEC}.Debug|ARM64.Build.0 = Debug|Any CPU
{510CD96C-B3FF-4EC9-A67B-845C842E6BEC}.Debug|x64.ActiveCfg = Debug|x64
{510CD96C-B3FF-4EC9-A67B-845C842E6BEC}.Debug|x64.Build.0 = Debug|x64
{510CD96C-B3FF-4EC9-A67B-845C842E6BEC}.Debug|x86.ActiveCfg = Debug|x86
{510CD96C-B3FF-4EC9-A67B-845C842E6BEC}.Debug|x86.Build.0 = Debug|x86
{510CD96C-B3FF-4EC9-A67B-845C842E6BEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{510CD96C-B3FF-4EC9-A67B-845C842E6BEC}.Release|Any CPU.Build.0 = Release|Any CPU
{510CD96C-B3FF-4EC9-A67B-845C842E6BEC}.Release|ARM.ActiveCfg = Release|Any CPU
{510CD96C-B3FF-4EC9-A67B-845C842E6BEC}.Release|ARM.Build.0 = Release|Any CPU
{510CD96C-B3FF-4EC9-A67B-845C842E6BEC}.Release|ARM64.ActiveCfg = Release|Any CPU
{510CD96C-B3FF-4EC9-A67B-845C842E6BEC}.Release|ARM64.Build.0 = Release|Any CPU
{510CD96C-B3FF-4EC9-A67B-845C842E6BEC}.Release|x64.ActiveCfg = Release|x64
{510CD96C-B3FF-4EC9-A67B-845C842E6BEC}.Release|x64.Build.0 = Release|x64
{510CD96C-B3FF-4EC9-A67B-845C842E6BEC}.Release|x86.ActiveCfg = Release|x86
{510CD96C-B3FF-4EC9-A67B-845C842E6BEC}.Release|x86.Build.0 = Release|x86
{AB588CFD-4B0C-4A1F-B711-1999E3D092D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AB588CFD-4B0C-4A1F-B711-1999E3D092D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AB588CFD-4B0C-4A1F-B711-1999E3D092D0}.Debug|ARM.ActiveCfg = Debug|Any CPU
{AB588CFD-4B0C-4A1F-B711-1999E3D092D0}.Debug|ARM.Build.0 = Debug|Any CPU
{AB588CFD-4B0C-4A1F-B711-1999E3D092D0}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{AB588CFD-4B0C-4A1F-B711-1999E3D092D0}.Debug|ARM64.Build.0 = Debug|Any CPU
{AB588CFD-4B0C-4A1F-B711-1999E3D092D0}.Debug|x64.ActiveCfg = Debug|x64
{AB588CFD-4B0C-4A1F-B711-1999E3D092D0}.Debug|x64.Build.0 = Debug|x64
{AB588CFD-4B0C-4A1F-B711-1999E3D092D0}.Debug|x86.ActiveCfg = Debug|x86
{AB588CFD-4B0C-4A1F-B711-1999E3D092D0}.Debug|x86.Build.0 = Debug|x86
{AB588CFD-4B0C-4A1F-B711-1999E3D092D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AB588CFD-4B0C-4A1F-B711-1999E3D092D0}.Release|Any CPU.Build.0 = Release|Any CPU
{AB588CFD-4B0C-4A1F-B711-1999E3D092D0}.Release|ARM.ActiveCfg = Release|Any CPU
{AB588CFD-4B0C-4A1F-B711-1999E3D092D0}.Release|ARM.Build.0 = Release|Any CPU
{AB588CFD-4B0C-4A1F-B711-1999E3D092D0}.Release|ARM64.ActiveCfg = Release|Any CPU
{AB588CFD-4B0C-4A1F-B711-1999E3D092D0}.Release|ARM64.Build.0 = Release|Any CPU
{AB588CFD-4B0C-4A1F-B711-1999E3D092D0}.Release|x64.ActiveCfg = Release|x64
{AB588CFD-4B0C-4A1F-B711-1999E3D092D0}.Release|x64.Build.0 = Release|x64
{AB588CFD-4B0C-4A1F-B711-1999E3D092D0}.Release|x86.ActiveCfg = Release|x86
{AB588CFD-4B0C-4A1F-B711-1999E3D092D0}.Release|x86.Build.0 = Release|x86
{92DA33FC-9252-40C5-BF71-67ACB0B56F2B}.Debug|Any CPU.ActiveCfg = Debug|x64
{92DA33FC-9252-40C5-BF71-67ACB0B56F2B}.Debug|Any CPU.Build.0 = Debug|x64
{92DA33FC-9252-40C5-BF71-67ACB0B56F2B}.Debug|ARM.ActiveCfg = Debug|x64
{92DA33FC-9252-40C5-BF71-67ACB0B56F2B}.Debug|ARM.Build.0 = Debug|x64
{92DA33FC-9252-40C5-BF71-67ACB0B56F2B}.Debug|ARM64.ActiveCfg = Debug|ARM64
{92DA33FC-9252-40C5-BF71-67ACB0B56F2B}.Debug|ARM64.Build.0 = Debug|ARM64
{92DA33FC-9252-40C5-BF71-67ACB0B56F2B}.Debug|x64.ActiveCfg = Debug|x64
{92DA33FC-9252-40C5-BF71-67ACB0B56F2B}.Debug|x64.Build.0 = Debug|x64
{92DA33FC-9252-40C5-BF71-67ACB0B56F2B}.Debug|x86.ActiveCfg = Debug|x86
{92DA33FC-9252-40C5-BF71-67ACB0B56F2B}.Debug|x86.Build.0 = Debug|x86
{92DA33FC-9252-40C5-BF71-67ACB0B56F2B}.Release|Any CPU.ActiveCfg = Release|x64
{92DA33FC-9252-40C5-BF71-67ACB0B56F2B}.Release|Any CPU.Build.0 = Release|x64
{92DA33FC-9252-40C5-BF71-67ACB0B56F2B}.Release|ARM.ActiveCfg = Release|x64
{92DA33FC-9252-40C5-BF71-67ACB0B56F2B}.Release|ARM.Build.0 = Release|x64
{92DA33FC-9252-40C5-BF71-67ACB0B56F2B}.Release|ARM64.ActiveCfg = Release|ARM64
{92DA33FC-9252-40C5-BF71-67ACB0B56F2B}.Release|ARM64.Build.0 = Release|ARM64
{92DA33FC-9252-40C5-BF71-67ACB0B56F2B}.Release|x64.ActiveCfg = Release|x64
{92DA33FC-9252-40C5-BF71-67ACB0B56F2B}.Release|x64.Build.0 = Release|x64
{92DA33FC-9252-40C5-BF71-67ACB0B56F2B}.Release|x86.ActiveCfg = Release|x86
{92DA33FC-9252-40C5-BF71-67ACB0B56F2B}.Release|x86.Build.0 = Release|x86
{87FFCBF4-DC17-4F09-90D6-102CF4C72BAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{87FFCBF4-DC17-4F09-90D6-102CF4C72BAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{87FFCBF4-DC17-4F09-90D6-102CF4C72BAF}.Debug|ARM.ActiveCfg = Debug|Any CPU
{87FFCBF4-DC17-4F09-90D6-102CF4C72BAF}.Debug|ARM.Build.0 = Debug|Any CPU
{87FFCBF4-DC17-4F09-90D6-102CF4C72BAF}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{87FFCBF4-DC17-4F09-90D6-102CF4C72BAF}.Debug|ARM64.Build.0 = Debug|Any CPU
{87FFCBF4-DC17-4F09-90D6-102CF4C72BAF}.Debug|x64.ActiveCfg = Debug|x64
{87FFCBF4-DC17-4F09-90D6-102CF4C72BAF}.Debug|x64.Build.0 = Debug|x64
{87FFCBF4-DC17-4F09-90D6-102CF4C72BAF}.Debug|x86.ActiveCfg = Debug|x86
{87FFCBF4-DC17-4F09-90D6-102CF4C72BAF}.Debug|x86.Build.0 = Debug|x86
{87FFCBF4-DC17-4F09-90D6-102CF4C72BAF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{87FFCBF4-DC17-4F09-90D6-102CF4C72BAF}.Release|Any CPU.Build.0 = Release|Any CPU
{87FFCBF4-DC17-4F09-90D6-102CF4C72BAF}.Release|ARM.ActiveCfg = Release|Any CPU
{87FFCBF4-DC17-4F09-90D6-102CF4C72BAF}.Release|ARM.Build.0 = Release|Any CPU
{87FFCBF4-DC17-4F09-90D6-102CF4C72BAF}.Release|ARM64.ActiveCfg = Release|Any CPU
{87FFCBF4-DC17-4F09-90D6-102CF4C72BAF}.Release|ARM64.Build.0 = Release|Any CPU
{87FFCBF4-DC17-4F09-90D6-102CF4C72BAF}.Release|x64.ActiveCfg = Release|x64
{87FFCBF4-DC17-4F09-90D6-102CF4C72BAF}.Release|x64.Build.0 = Release|x64
{87FFCBF4-DC17-4F09-90D6-102CF4C72BAF}.Release|x86.ActiveCfg = Release|x86
{87FFCBF4-DC17-4F09-90D6-102CF4C72BAF}.Release|x86.Build.0 = Release|x86
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Debug|Any CPU.ActiveCfg = Debug|x64
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Debug|Any CPU.Build.0 = Debug|x64
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Debug|Any CPU.Deploy.0 = Debug|x64
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Debug|ARM.ActiveCfg = Debug|ARM
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Debug|ARM.Build.0 = Debug|ARM
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Debug|ARM.Deploy.0 = Debug|ARM
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Debug|ARM64.ActiveCfg = Debug|ARM64
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Debug|ARM64.Build.0 = Debug|ARM64
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Debug|ARM64.Deploy.0 = Debug|ARM64
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Debug|x64.ActiveCfg = Debug|x64
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Debug|x64.Build.0 = Debug|x64
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Debug|x64.Deploy.0 = Debug|x64
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Debug|x86.ActiveCfg = Debug|x86
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Debug|x86.Build.0 = Debug|x86
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Debug|x86.Deploy.0 = Debug|x86
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Release|Any CPU.ActiveCfg = Release|x64
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Release|Any CPU.Build.0 = Release|x64
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Release|Any CPU.Deploy.0 = Release|x64
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Release|ARM.ActiveCfg = Release|ARM
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Release|ARM.Build.0 = Release|ARM
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Release|ARM.Deploy.0 = Release|ARM
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Release|ARM64.ActiveCfg = Release|ARM64
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Release|ARM64.Build.0 = Release|ARM64
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Release|ARM64.Deploy.0 = Release|ARM64
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Release|x64.ActiveCfg = Release|x64
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Release|x64.Build.0 = Release|x64
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Release|x64.Deploy.0 = Release|x64
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Release|x86.ActiveCfg = Release|x86
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Release|x86.Build.0 = Release|x86
{600F4979-DB7E-409D-B7DA-B60BE4C55C35}.Release|x86.Deploy.0 = Release|x86
{8A7EB697-D722-4E0F-B20E-9FC88373ADB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8A7EB697-D722-4E0F-B20E-9FC88373ADB5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8A7EB697-D722-4E0F-B20E-9FC88373ADB5}.Debug|ARM.ActiveCfg = Debug|Any CPU
{8A7EB697-D722-4E0F-B20E-9FC88373ADB5}.Debug|ARM.Build.0 = Debug|Any CPU
{8A7EB697-D722-4E0F-B20E-9FC88373ADB5}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{8A7EB697-D722-4E0F-B20E-9FC88373ADB5}.Debug|ARM64.Build.0 = Debug|Any CPU
{8A7EB697-D722-4E0F-B20E-9FC88373ADB5}.Debug|x64.ActiveCfg = Debug|Any CPU
{8A7EB697-D722-4E0F-B20E-9FC88373ADB5}.Debug|x64.Build.0 = Debug|Any CPU
{8A7EB697-D722-4E0F-B20E-9FC88373ADB5}.Debug|x86.ActiveCfg = Debug|Any CPU
{8A7EB697-D722-4E0F-B20E-9FC88373ADB5}.Debug|x86.Build.0 = Debug|Any CPU
{8A7EB697-D722-4E0F-B20E-9FC88373ADB5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8A7EB697-D722-4E0F-B20E-9FC88373ADB5}.Release|Any CPU.Build.0 = Release|Any CPU
{8A7EB697-D722-4E0F-B20E-9FC88373ADB5}.Release|ARM.ActiveCfg = Release|Any CPU
{8A7EB697-D722-4E0F-B20E-9FC88373ADB5}.Release|ARM.Build.0 = Release|Any CPU
{8A7EB697-D722-4E0F-B20E-9FC88373ADB5}.Release|ARM64.ActiveCfg = Release|Any CPU
{8A7EB697-D722-4E0F-B20E-9FC88373ADB5}.Release|ARM64.Build.0 = Release|Any CPU
{8A7EB697-D722-4E0F-B20E-9FC88373ADB5}.Release|x64.ActiveCfg = Release|Any CPU
{8A7EB697-D722-4E0F-B20E-9FC88373ADB5}.Release|x64.Build.0 = Release|Any CPU
{8A7EB697-D722-4E0F-B20E-9FC88373ADB5}.Release|x86.ActiveCfg = Release|Any CPU
{8A7EB697-D722-4E0F-B20E-9FC88373ADB5}.Release|x86.Build.0 = Release|Any CPU
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Debug|ARM.ActiveCfg = Debug|ARM
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Debug|ARM.Build.0 = Debug|ARM
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Debug|ARM.Deploy.0 = Debug|ARM
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Debug|ARM64.ActiveCfg = Debug|ARM64
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Debug|ARM64.Build.0 = Debug|ARM64
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Debug|ARM64.Deploy.0 = Debug|ARM64
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Debug|x64.ActiveCfg = Debug|x64
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Debug|x64.Build.0 = Debug|x64
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Debug|x64.Deploy.0 = Debug|x64
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Debug|x86.ActiveCfg = Debug|x86
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Debug|x86.Build.0 = Debug|x86
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Debug|x86.Deploy.0 = Debug|x86
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|Any CPU.Build.0 = Release|Any CPU
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|Any CPU.Deploy.0 = Release|Any CPU
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|ARM.ActiveCfg = Release|ARM
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|ARM.Build.0 = Release|ARM
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|ARM.Deploy.0 = Release|ARM
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|ARM64.ActiveCfg = Release|ARM64
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|ARM64.Build.0 = Release|ARM64
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|ARM64.Deploy.0 = Release|ARM64
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|x64.ActiveCfg = Release|x64
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|x64.Build.0 = Release|x64
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|x64.Deploy.0 = Release|x64
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|x86.ActiveCfg = Release|x86
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|x86.Build.0 = Release|x86
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|x86.Deploy.0 = Release|x86
{CF850F8C-5042-4376-9CBA-C8F2BB554083}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CF850F8C-5042-4376-9CBA-C8F2BB554083}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CF850F8C-5042-4376-9CBA-C8F2BB554083}.Debug|ARM.ActiveCfg = Debug|Any CPU
{CF850F8C-5042-4376-9CBA-C8F2BB554083}.Debug|ARM.Build.0 = Debug|Any CPU
{CF850F8C-5042-4376-9CBA-C8F2BB554083}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{CF850F8C-5042-4376-9CBA-C8F2BB554083}.Debug|ARM64.Build.0 = Debug|Any CPU
{CF850F8C-5042-4376-9CBA-C8F2BB554083}.Debug|x64.ActiveCfg = Debug|x64
{CF850F8C-5042-4376-9CBA-C8F2BB554083}.Debug|x64.Build.0 = Debug|x64
{CF850F8C-5042-4376-9CBA-C8F2BB554083}.Debug|x86.ActiveCfg = Debug|x86
{CF850F8C-5042-4376-9CBA-C8F2BB554083}.Debug|x86.Build.0 = Debug|x86
{CF850F8C-5042-4376-9CBA-C8F2BB554083}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CF850F8C-5042-4376-9CBA-C8F2BB554083}.Release|Any CPU.Build.0 = Release|Any CPU
{CF850F8C-5042-4376-9CBA-C8F2BB554083}.Release|ARM.ActiveCfg = Release|Any CPU
{CF850F8C-5042-4376-9CBA-C8F2BB554083}.Release|ARM.Build.0 = Release|Any CPU
{CF850F8C-5042-4376-9CBA-C8F2BB554083}.Release|ARM64.ActiveCfg = Release|Any CPU
{CF850F8C-5042-4376-9CBA-C8F2BB554083}.Release|ARM64.Build.0 = Release|Any CPU
{CF850F8C-5042-4376-9CBA-C8F2BB554083}.Release|x64.ActiveCfg = Release|x64
{CF850F8C-5042-4376-9CBA-C8F2BB554083}.Release|x64.Build.0 = Release|x64
{CF850F8C-5042-4376-9CBA-C8F2BB554083}.Release|x86.ActiveCfg = Release|x86
{CF850F8C-5042-4376-9CBA-C8F2BB554083}.Release|x86.Build.0 = Release|x86
{BBA49030-7277-48CF-B2FE-3D01CB6B6C81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BBA49030-7277-48CF-B2FE-3D01CB6B6C81}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BBA49030-7277-48CF-B2FE-3D01CB6B6C81}.Debug|ARM.ActiveCfg = Debug|Any CPU
{BBA49030-7277-48CF-B2FE-3D01CB6B6C81}.Debug|ARM.Build.0 = Debug|Any CPU
{BBA49030-7277-48CF-B2FE-3D01CB6B6C81}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{BBA49030-7277-48CF-B2FE-3D01CB6B6C81}.Debug|ARM64.Build.0 = Debug|Any CPU
{BBA49030-7277-48CF-B2FE-3D01CB6B6C81}.Debug|x64.ActiveCfg = Debug|Any CPU
{BBA49030-7277-48CF-B2FE-3D01CB6B6C81}.Debug|x64.Build.0 = Debug|Any CPU
{BBA49030-7277-48CF-B2FE-3D01CB6B6C81}.Debug|x86.ActiveCfg = Debug|Any CPU
{BBA49030-7277-48CF-B2FE-3D01CB6B6C81}.Debug|x86.Build.0 = Debug|Any CPU
{BBA49030-7277-48CF-B2FE-3D01CB6B6C81}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BBA49030-7277-48CF-B2FE-3D01CB6B6C81}.Release|Any CPU.Build.0 = Release|Any CPU
{BBA49030-7277-48CF-B2FE-3D01CB6B6C81}.Release|ARM.ActiveCfg = Release|Any CPU
{BBA49030-7277-48CF-B2FE-3D01CB6B6C81}.Release|ARM.Build.0 = Release|Any CPU
{BBA49030-7277-48CF-B2FE-3D01CB6B6C81}.Release|ARM64.ActiveCfg = Release|Any CPU
{BBA49030-7277-48CF-B2FE-3D01CB6B6C81}.Release|ARM64.Build.0 = Release|Any CPU
{BBA49030-7277-48CF-B2FE-3D01CB6B6C81}.Release|x64.ActiveCfg = Release|Any CPU
{BBA49030-7277-48CF-B2FE-3D01CB6B6C81}.Release|x64.Build.0 = Release|Any CPU
{BBA49030-7277-48CF-B2FE-3D01CB6B6C81}.Release|x86.ActiveCfg = Release|Any CPU
{BBA49030-7277-48CF-B2FE-3D01CB6B6C81}.Release|x86.Build.0 = Release|Any CPU
{16A979C2-F308-464F-9B2A-0AF8ED5EDB43}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{16A979C2-F308-464F-9B2A-0AF8ED5EDB43}.Debug|Any CPU.Build.0 = Debug|Any CPU
{16A979C2-F308-464F-9B2A-0AF8ED5EDB43}.Debug|ARM.ActiveCfg = Debug|Any CPU
{16A979C2-F308-464F-9B2A-0AF8ED5EDB43}.Debug|ARM.Build.0 = Debug|Any CPU
{16A979C2-F308-464F-9B2A-0AF8ED5EDB43}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{16A979C2-F308-464F-9B2A-0AF8ED5EDB43}.Debug|ARM64.Build.0 = Debug|Any CPU
{16A979C2-F308-464F-9B2A-0AF8ED5EDB43}.Debug|x64.ActiveCfg = Debug|x64
{16A979C2-F308-464F-9B2A-0AF8ED5EDB43}.Debug|x64.Build.0 = Debug|x64
{16A979C2-F308-464F-9B2A-0AF8ED5EDB43}.Debug|x86.ActiveCfg = Debug|x86
{16A979C2-F308-464F-9B2A-0AF8ED5EDB43}.Debug|x86.Build.0 = Debug|x86
{16A979C2-F308-464F-9B2A-0AF8ED5EDB43}.Release|Any CPU.ActiveCfg = Release|Any CPU
{16A979C2-F308-464F-9B2A-0AF8ED5EDB43}.Release|Any CPU.Build.0 = Release|Any CPU
{16A979C2-F308-464F-9B2A-0AF8ED5EDB43}.Release|ARM.ActiveCfg = Release|Any CPU
{16A979C2-F308-464F-9B2A-0AF8ED5EDB43}.Release|ARM.Build.0 = Release|Any CPU
{16A979C2-F308-464F-9B2A-0AF8ED5EDB43}.Release|ARM64.ActiveCfg = Release|Any CPU
{16A979C2-F308-464F-9B2A-0AF8ED5EDB43}.Release|ARM64.Build.0 = Release|Any CPU
{16A979C2-F308-464F-9B2A-0AF8ED5EDB43}.Release|x64.ActiveCfg = Release|x64
{16A979C2-F308-464F-9B2A-0AF8ED5EDB43}.Release|x64.Build.0 = Release|x64
{16A979C2-F308-464F-9B2A-0AF8ED5EDB43}.Release|x86.ActiveCfg = Release|x86
{16A979C2-F308-464F-9B2A-0AF8ED5EDB43}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -6,8 +6,8 @@ using Windows.UI.Xaml.Media.Animation;
using Wino.Activation;
using Wino.Calendar.Views;
namespace Wino.Calendar.Activation
{
namespace Wino.Calendar.Activation;
public class DefaultActivationHandler : ActivationHandler<IActivatedEventArgs>
{
protected override Task HandleInternalAsync(IActivatedEventArgs args)
@@ -21,4 +21,3 @@ namespace Wino.Calendar.Activation
protected override bool CanHandleInternal(IActivatedEventArgs args)
=> (Window.Current?.Content as Frame)?.Content == null;
}
}

View File

@@ -24,20 +24,16 @@ using Wino.Messaging.Client.Connection;
using Wino.Messaging.Server;
using Wino.Services;
namespace Wino.Calendar
{
namespace Wino.Calendar;
public sealed partial class App : WinoApplication, IRecipient<NewCalendarSynchronizationRequested>
{
public override string AppCenterKey => "dfdad6ab-95f9-44cc-9112-45ec6730c49e";
private BackgroundTaskDeferral connectionBackgroundTaskDeferral;
private BackgroundTaskDeferral toastActionBackgroundTaskDeferral;
public App()
{
InitializeComponent();
WeakReferenceMessenger.Default.Register(this);
WeakReferenceMessenger.Default.Register<NewCalendarSynchronizationRequested>(this);
}
public override IServiceProvider ConfigureServices()
@@ -161,4 +157,3 @@ namespace Wino.Calendar
}
}
}
}

View File

@@ -1,8 +1,8 @@
using System;
using Windows.Foundation;
namespace Wino.Calendar.Args
{
namespace Wino.Calendar.Args;
/// <summary>
/// When a new timeline cell is selected.
/// </summary>
@@ -38,4 +38,3 @@ namespace Wino.Calendar.Args
/// </summary>
public Size CellSize { get; }
}
}

View File

@@ -1,9 +1,8 @@
using System;
namespace Wino.Calendar.Args
{
namespace Wino.Calendar.Args;
/// <summary>
/// When selected timeline cell is unselected.
/// </summary>
public class TimelineCellUnselectedArgs : EventArgs { }
}

View File

@@ -2,9 +2,9 @@
using Windows.UI.Xaml;
using Wino.Calendar.ViewModels.Data;
namespace Wino.Calendar.Controls
{
public class CalendarItemCommandBarFlyout : CommandBarFlyout
namespace Wino.Calendar.Controls;
public partial class CalendarItemCommandBarFlyout : CommandBarFlyout
{
public static readonly DependencyProperty ItemProperty = DependencyProperty.Register(nameof(Item), typeof(CalendarItemViewModel), typeof(CalendarItemCommandBarFlyout), new PropertyMetadata(null, new PropertyChangedCallback(OnItemChanged)));
@@ -28,4 +28,3 @@ namespace Wino.Calendar.Controls
}
}
}

View File

@@ -69,7 +69,7 @@
VerticalAlignment="Top"
Orientation="Horizontal"
Spacing="6">
<controls:WinoFontIcon
<!--<controls:WinoFontIcon
FontSize="12"
Foreground="{x:Bind helpers:XamlHelpers.GetReadableTextColor(CalendarItem.AssignedCalendar.BackgroundColorHex), Mode=OneWay}"
Icon="CalendarEventRepeat"
@@ -79,7 +79,7 @@
FontSize="12"
Foreground="{x:Bind helpers:XamlHelpers.GetReadableTextColor(CalendarItem.AssignedCalendar.BackgroundColorHex), Mode=OneWay}"
Icon="CalendarEventMuiltiDay"
Visibility="{x:Bind CalendarItem.IsMultiDayEvent, Mode=OneWay}" />
Visibility="{x:Bind CalendarItem.IsMultiDayEvent, Mode=OneWay}" />-->
</StackPanel>
<VisualStateManager.VisualStateGroups>

View File

@@ -7,10 +7,11 @@ using Windows.UI.Xaml.Input;
using Wino.Calendar.ViewModels.Data;
using Wino.Calendar.ViewModels.Messages;
using Wino.Core.Domain;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Models.Calendar;
namespace Wino.Calendar.Controls
{
namespace Wino.Calendar.Controls;
public sealed partial class CalendarItemControl : UserControl
{
// Single tap has a delay to report double taps properly.
@@ -90,7 +91,9 @@ namespace Wino.Calendar.Controls
if (CalendarItem == null) return;
if (DisplayingDate == null) return;
if (CalendarItem.IsMultiDayEvent)
bool isMultiDayEvent = CalendarItem.CalendarItem.ItemType == CalendarItemType.MultiDay || CalendarItem.CalendarItem.ItemType == CalendarItemType.MultiDayAllDay;
if (isMultiDayEvent)
{
// Multi day events are divided into 3 categories:
// 1. All day events
@@ -103,14 +106,14 @@ namespace Wino.Calendar.Controls
periodRelation == PeriodRelation.EnclosingStartTouching)
{
// hour -> title
CalendarItemTitle = $"{DisplayingDate.CalendarRenderOptions.CalendarSettings.GetTimeString(CalendarItem.StartDate.TimeOfDay)} -> {CalendarItem.Title}";
CalendarItemTitle = $"{DisplayingDate.CalendarRenderOptions.CalendarSettings.GetTimeString(CalendarItem.StartDateTime.TimeOfDay)} -> {CalendarItem.Title}";
}
else if (
periodRelation == PeriodRelation.EndInside ||
periodRelation == PeriodRelation.EnclosingEndTouching)
{
// title <- hour
CalendarItemTitle = $"{CalendarItem.Title} <- {DisplayingDate.CalendarRenderOptions.CalendarSettings.GetTimeString(CalendarItem.EndDate.TimeOfDay)}";
CalendarItemTitle = $"{CalendarItem.Title} <- {DisplayingDate.CalendarRenderOptions.CalendarSettings.GetTimeString(CalendarItem.EndDateTime.TimeOfDay)}";
}
else if (periodRelation == PeriodRelation.Enclosing)
{
@@ -139,11 +142,11 @@ namespace Wino.Calendar.Controls
{
if (CalendarItem == null) return;
if (CalendarItem.IsAllDayEvent)
if (CalendarItem.CalendarItem.ItemType == CalendarItemType.AllDay)
{
VisualStateManager.GoToState(this, "AllDayEvent", true);
}
else if (CalendarItem.IsMultiDayEvent)
else if (CalendarItem.CalendarItem.ItemType == CalendarItemType.MultiDayAllDay || CalendarItem.CalendarItem.ItemType == CalendarItemType.MultiDay)
{
if (IsCustomEventArea)
{
@@ -195,4 +198,3 @@ namespace Wino.Calendar.Controls
WeakReferenceMessenger.Default.Send(new CalendarItemRightTappedMessage(CalendarItem));
}
}
}

View File

@@ -1,12 +1,12 @@
using Windows.UI.Xaml.Automation.Peers;
using Windows.UI.Xaml.Controls;
namespace Wino.Calendar.Controls
{
namespace Wino.Calendar.Controls;
/// <summary>
/// FlipView that hides the navigation buttons and exposes methods to navigate to the next and previous items with animations.
/// </summary>
public class CustomCalendarFlipView : FlipView
public partial class CustomCalendarFlipView : FlipView
{
private const string PART_PreviousButton = "PreviousButtonHorizontal";
private const string PART_NextButton = "NextButtonHorizontal";
@@ -40,4 +40,3 @@ namespace Wino.Calendar.Controls
nextPeer.Invoke();
}
}
}

View File

@@ -3,9 +3,9 @@ using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Wino.Core.Domain.Models.Calendar;
namespace Wino.Calendar.Controls
{
public class DayColumnControl : Control
namespace Wino.Calendar.Controls;
public partial class DayColumnControl : Control
{
private const string PART_HeaderDateDayText = nameof(PART_HeaderDateDayText);
private const string PART_IsTodayBorder = nameof(PART_IsTodayBorder);
@@ -75,4 +75,3 @@ namespace Wino.Calendar.Controls
UpdateLayout();
}
}
}

View File

@@ -3,9 +3,9 @@ using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Wino.Core.Domain.Enums;
namespace Wino.Calendar.Controls
{
public class DayHeaderControl : Control
namespace Wino.Calendar.Controls;
public partial class DayHeaderControl : Control
{
private const string PART_DayHeaderTextBlock = nameof(PART_DayHeaderTextBlock);
private TextBlock HeaderTextblock;
@@ -54,4 +54,3 @@ namespace Wino.Calendar.Controls
}
}
}
}

View File

@@ -10,9 +10,9 @@ using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Models.Calendar;
using Wino.Helpers;
namespace Wino.Calendar.Controls
{
public class WinoCalendarControl : Control
namespace Wino.Calendar.Controls;
public partial class WinoCalendarControl : Control
{
private const string PART_WinoFlipView = nameof(PART_WinoFlipView);
private const string PART_IdleGrid = nameof(PART_IdleGrid);
@@ -297,4 +297,3 @@ namespace Wino.Calendar.Controls
return this.FindDescendants<CalendarItemControl>().FirstOrDefault(a => a.CalendarItem == calendarItemViewModel);
}
}
}

View File

@@ -8,9 +8,9 @@ using Windows.UI.Xaml.Controls;
using Wino.Core.Domain.Collections;
using Wino.Core.Domain.Models.Calendar;
namespace Wino.Calendar.Controls
{
public class WinoCalendarFlipView : CustomCalendarFlipView
namespace Wino.Calendar.Controls;
public partial class WinoCalendarFlipView : CustomCalendarFlipView
{
public static readonly DependencyProperty IsIdleProperty = DependencyProperty.Register(nameof(IsIdle), typeof(bool), typeof(WinoCalendarFlipView), new PropertyMetadata(true));
public static readonly DependencyProperty ActiveCanvasProperty = DependencyProperty.Register(nameof(ActiveCanvas), typeof(WinoDayTimelineCanvas), typeof(WinoCalendarFlipView), new PropertyMetadata(null));
@@ -183,4 +183,3 @@ namespace Wino.Calendar.Controls
private ObservableRangeCollection<DayRangeRenderModel> GetItemsSource()
=> ItemsSource as ObservableRangeCollection<DayRangeRenderModel>;
}
}

View File

@@ -9,11 +9,12 @@ using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Wino.Calendar.Models;
using Wino.Calendar.ViewModels.Data;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
namespace Wino.Calendar.Controls
{
public class WinoCalendarPanel : Panel
namespace Wino.Calendar.Controls;
public partial class WinoCalendarPanel : Panel
{
private const double LastItemRightExtraMargin = 12d;
@@ -44,9 +45,9 @@ namespace Wino.Calendar.Controls
private void ResetMeasurements() => _measurements.Clear();
private double GetChildTopMargin(ICalendarItem calendarItemViewModel, double availableHeight)
private double GetChildTopMargin(ICalendarItemViewModel calendarItemViewModel, double availableHeight)
{
var childStart = calendarItemViewModel.StartDate;
var childStart = calendarItemViewModel.LocalStartDateTime;
if (childStart <= Period.Start)
{
@@ -68,10 +69,10 @@ namespace Wino.Calendar.Controls
private double GetChildLeftMargin(CalendarItemMeasurement calendarItemMeasurement, double availableWidth)
=> availableWidth * calendarItemMeasurement.Left;
private double GetChildHeight(ICalendarItem child)
private double GetChildHeight(ICalendarItemViewModel child)
{
// All day events are not measured.
if (child.IsAllDayEvent) return 0;
if (child.ItemType == CalendarItemType.AllDay) return 0;
double childDurationInMinutes = 0d;
double availableHeight = HourHeight * 24;
@@ -80,7 +81,7 @@ namespace Wino.Calendar.Controls
// Debug.WriteLine($"Render relation of {child.Title} ({child.Period.Start} - {child.Period.End}) is {periodRelation} with {Period.Start.Day}");
if (!child.IsMultiDayEvent)
if (child.ItemType != CalendarItemType.MultiDay || child.ItemType != CalendarItemType.MultiDayAllDay)
{
childDurationInMinutes = child.Period.Duration.TotalMinutes;
}
@@ -127,7 +128,7 @@ namespace Wino.Calendar.Controls
foreach (var control in calendarControls)
{
// We can't arrange this child.
if (!(control.Content is ICalendarItem child)) continue;
if (!(control.Content is ICalendarItemViewModel child)) continue;
bool isHorizontallyLastItem = false;
@@ -160,7 +161,7 @@ namespace Wino.Calendar.Controls
double extraRightMargin = 0;
// Multi-day events don't have any margin and their hit test is disabled.
if (!child.IsMultiDayEvent)
if (child.ItemType != CalendarItemType.MultiDay || child.ItemType != CalendarItemType.MultiDayAllDay)
{
// Max of 5% of the width or 20px max.
extraRightMargin = isHorizontallyLastItem ? Math.Max(LastItemRightExtraMargin, finalSize.Width * 5 / 100) : 0;
@@ -168,8 +169,10 @@ namespace Wino.Calendar.Controls
if (childWidth < 0) childWidth = 1;
bool isAllOrMultiDayEvent = child.ItemType == CalendarItemType.AllDay || child.ItemType == CalendarItemType.MultiDay || child.ItemType == CalendarItemType.MultiDayAllDay;
// Regular events must have 2px margin
if (!child.IsMultiDayEvent && !child.IsAllDayEvent)
if (!isAllOrMultiDayEvent)
{
childLeft += 2;
childTop += 2;
@@ -211,10 +214,12 @@ namespace Wino.Calendar.Controls
var columns = new List<List<ICalendarItem>>();
DateTime? lastEventEnding = null;
foreach (var ev in events.OrderBy(ev => ev.StartDate).ThenBy(ev => ev.EndDate))
foreach (var ev in events.OrderBy(ev => ev.StartDateTime).ThenBy(ev => ev.EndDateTime))
{
// Multi-day events are not measured.
if (ev.IsMultiDayEvent) continue;
bool isMultiDayEvent = ev.ItemType == CalendarItemType.MultiDay || ev.ItemType == CalendarItemType.MultiDayAllDay;
if (isMultiDayEvent) continue;
if (ev.Period.Start >= lastEventEnding)
{
@@ -291,4 +296,3 @@ namespace Wino.Calendar.Controls
#endregion
}
}

View File

@@ -4,9 +4,9 @@ using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Wino.Core.Domain.Enums;
namespace Wino.Calendar.Controls
{
public class WinoCalendarTypeSelectorControl : Control
namespace Wino.Calendar.Controls;
public partial class WinoCalendarTypeSelectorControl : Control
{
private const string PART_TodayButton = nameof(PART_TodayButton);
private const string PART_DayToggle = nameof(PART_DayToggle);
@@ -89,4 +89,3 @@ namespace Wino.Calendar.Controls
_yearToggle.IsChecked = SelectedType == CalendarDisplayType.Year;
}
}
}

View File

@@ -8,9 +8,9 @@ using Windows.UI.Xaml.Media;
using Wino.Core.Domain.Models.Calendar;
using Wino.Helpers;
namespace Wino.Calendar.Controls
{
public class WinoCalendarView : Control
namespace Wino.Calendar.Controls;
public partial class WinoCalendarView : Control
{
private const string PART_DayViewItemBorder = nameof(PART_DayViewItemBorder);
private const string PART_CalendarView = nameof(PART_CalendarView);
@@ -145,4 +145,3 @@ namespace Wino.Calendar.Controls
}
}
}
}

View File

@@ -10,9 +10,9 @@ using Windows.UI.Xaml.Media;
using Wino.Calendar.Args;
using Wino.Core.Domain.Models.Calendar;
namespace Wino.Calendar.Controls
{
public class WinoDayTimelineCanvas : Control, IDisposable
namespace Wino.Calendar.Controls;
public partial class WinoDayTimelineCanvas : Control, IDisposable
{
public event EventHandler<TimelineCellSelectedArgs> TimelineCellSelected;
public event EventHandler<TimelineCellUnselectedArgs> TimelineCellUnselected;
@@ -275,4 +275,3 @@ namespace Wino.Calendar.Controls
Canvas = null;
}
}
}

View File

@@ -10,8 +10,8 @@ using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Models.Calendar;
using Wino.Helpers;
namespace Wino.Calendar.Helpers
{
namespace Wino.Calendar.Helpers;
public static class CalendarXamlHelpers
{
public static CalendarItemViewModel GetFirstAllDayEvent(CalendarEventCollection collection)
@@ -22,6 +22,7 @@ namespace Wino.Calendar.Helpers
/// </summary>
public static string GetEventDetailsDateString(CalendarItemViewModel calendarItemViewModel, CalendarSettings settings)
{
// TODO: This is not correct.
if (calendarItemViewModel == null || settings == null) return string.Empty;
var start = calendarItemViewModel.Period.Start;
@@ -30,7 +31,7 @@ namespace Wino.Calendar.Helpers
string timeFormat = settings.DayHeaderDisplayType == DayHeaderDisplayType.TwelveHour ? "h:mm tt" : "HH:mm";
string dateFormat = settings.DayHeaderDisplayType == DayHeaderDisplayType.TwelveHour ? "dddd, dd MMMM h:mm tt" : "dddd, dd MMMM HH:mm";
if (calendarItemViewModel.IsMultiDayEvent)
if (calendarItemViewModel.CalendarItem.ItemType == CalendarItemType.MultiDay || calendarItemViewModel.CalendarItem.ItemType == CalendarItemType.MultiDayAllDay)
{
return $"{start.ToString($"dd MMMM ddd {timeFormat}", settings.CultureInfo)} - {end.ToString($"dd MMMM ddd {timeFormat}", settings.CultureInfo)}";
}
@@ -42,54 +43,14 @@ namespace Wino.Calendar.Helpers
public static string GetRecurrenceString(CalendarItemViewModel calendarItemViewModel)
{
if (calendarItemViewModel == null || !calendarItemViewModel.IsRecurringChild) return string.Empty;
// Parse recurrence rules
var calendarEvent = new CalendarEvent
{
Start = new CalDateTime(calendarItemViewModel.StartDate),
End = new CalDateTime(calendarItemViewModel.EndDate),
};
var recurrenceLines = Regex.Split(calendarItemViewModel.CalendarItem.Recurrence, Constants.CalendarEventRecurrenceRuleSeperator);
foreach (var line in recurrenceLines)
{
calendarEvent.RecurrenceRules.Add(new RecurrencePattern(line));
}
if (calendarEvent.RecurrenceRules == null || !calendarEvent.RecurrenceRules.Any())
{
return "No recurrence pattern.";
}
var recurrenceRule = calendarEvent.RecurrenceRules.First();
var daysOfWeek = string.Join(", ", recurrenceRule.ByDay.Select(day => day.DayOfWeek.ToString()));
string timeZone = calendarEvent.DtStart.TzId ?? "UTC";
return $"Every {daysOfWeek}, effective {calendarEvent.DtStart.Value.ToShortDateString()} " +
$"from {calendarEvent.DtStart.Value.ToShortTimeString()} to {calendarEvent.DtEnd.Value.ToShortTimeString()} " +
$"{timeZone}.";
// TODO
return string.Empty;
}
public static string GetDetailsPopupDurationString(CalendarItemViewModel calendarItemViewModel, CalendarSettings settings)
{
if (calendarItemViewModel == null || settings == null) return string.Empty;
// Single event in a day.
if (!calendarItemViewModel.IsAllDayEvent && !calendarItemViewModel.IsMultiDayEvent)
{
return $"{calendarItemViewModel.Period.Start.ToString("d", settings.CultureInfo)} {settings.GetTimeString(calendarItemViewModel.Period.Duration)}";
}
else if (calendarItemViewModel.IsMultiDayEvent)
{
return $"{calendarItemViewModel.Period.Start.ToString("d", settings.CultureInfo)} - {calendarItemViewModel.Period.End.ToString("d", settings.CultureInfo)}";
}
else
{
// All day event.
return $"{calendarItemViewModel.Period.Start.ToString("d", settings.CultureInfo)} ({Translator.CalendarItemAllDay})";
}
// TODO
return string.Empty;
}
public static PopupPlacementMode GetDesiredPlacementModeForEventsDetailsPopup(
@@ -98,10 +59,13 @@ namespace Wino.Calendar.Helpers
{
if (calendarItemViewModel == null) return PopupPlacementMode.Auto;
bool isAllDayOrMultiDay = calendarItemViewModel.CalendarItem.ItemType == CalendarItemType.MultiDay ||
calendarItemViewModel.CalendarItem.ItemType == CalendarItemType.AllDay ||
calendarItemViewModel.CalendarItem.ItemType == CalendarItemType.MultiDayAllDay;
// All and/or multi day events always go to the top of the screen.
if (calendarItemViewModel.IsAllDayEvent || calendarItemViewModel.IsMultiDayEvent) return PopupPlacementMode.Bottom;
if (isAllDayOrMultiDay) return PopupPlacementMode.Bottom;
return XamlHelpers.GetPlaccementModeForCalendarType(calendarDisplayType);
}
}
}

View File

@@ -15,8 +15,8 @@ using Windows.UI.Xaml.Navigation;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace Wino.Calendar
{
namespace Wino.Calendar;
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
@@ -27,4 +27,3 @@ namespace Wino.Calendar
this.InitializeComponent();
}
}
}

View File

@@ -1,5 +1,5 @@
namespace Wino.Calendar.Models
{
namespace Wino.Calendar.Models;
public struct CalendarItemMeasurement
{
// Where to start?
@@ -14,4 +14,3 @@
Right = right;
}
}
}

View File

@@ -8,6 +8,11 @@
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
IgnorableNamespaces="uap mp">
<Identity
Name="58272BurakKSE.WinoCalendar"
Publisher="CN=51FBDAF3-E212-4149-89A2-A2636B3BC911"
Version="1.0.15.0" />
<!-- Publisher Cache Folders -->
<Extensions>
<Extension Category="windows.publisherCacheFolders">
@@ -17,11 +22,6 @@
</Extension>
</Extensions>
<Identity
Name="58272BurakKSE.WinoCalendar"
Publisher="CN=51FBDAF3-E212-4149-89A2-A2636B3BC911"
Version="1.0.15.0" />
<mp:PhoneIdentity PhoneProductId="f047b7dd-96ec-4d54-a862-9321e271e449" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>

View File

@@ -1,29 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Wino.Calendar")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Wino.Calendar")]
[assembly: AssemblyCopyright("Copyright © 2023")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: ComVisible(false)]

View File

@@ -1,44 +0,0 @@
<!--
This file contains Runtime Directives used by .NET Native. The defaults here are suitable for most
developers. However, you can modify these parameters to modify the behavior of the .NET Native
optimizer.
Runtime Directives are documented at https://go.microsoft.com/fwlink/?LinkID=391919
To fully enable reflection for App1.MyClass and all of its public/private members
<Type Name="App1.MyClass" Dynamic="Required All"/>
To enable dynamic creation of the specific instantiation of AppClass<T> over System.Int32
<TypeInstantiation Name="App1.AppClass" Arguments="System.Int32" Activate="Required Public" />
Using the Namespace directive to apply reflection policy to all the types in a particular namespace
<Namespace Name="DataClasses.ViewModels" Serialize="All" />
-->
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
<!--
An Assembly element with Name="*Application*" applies to all assemblies in
the application package. The asterisks are not wildcards.
-->
<Assembly Name="*Application*" Dynamic="Required All" />
<!-- Reduce memory footprint when building with Microsoft.Graph -->
<Assembly Name="Microsoft.Graph" Serialize="Excluded" />
<Assembly Name="Microsoft.Kiota.Abstractions" Dynamic="Public" />
<Assembly Name="Microsoft.Kiota.Authentication.Azure" Dynamic="Public" />
<Assembly Name="Microsoft.Kiota.Http.HttpClientLibrary" Dynamic="Public" />
<Assembly Name="Microsoft.Kiota.Serialization.Form" Dynamic="Public" />
<Assembly Name="Microsoft.Kiota.Serialization.Json" Dynamic="Public" />
<Assembly Name="Microsoft.Kiota.Serialization.Multipart" Dynamic="Public" />
<!-- Add your application specific runtime directives here. -->
<Type Name="Windows.Foundation.TypedEventHandler{Microsoft.UI.Xaml.Controls.NavigationView,Microsoft.UI.Xaml.Controls.NavigationViewItemInvokedEventArgs}" MarshalObject="Public" />
<Type Name="Microsoft.UI.Xaml.Controls.NavigationView">
<Event Name="ItemInvoked" Dynamic="Required"/>
</Type>
</Application>
</Directives>

View File

@@ -0,0 +1,7 @@
{
"profiles": {
"Wino.Calendar": {
"commandName": "MsixPackage"
}
}
}

View File

@@ -2,9 +2,9 @@
using Windows.UI.Xaml.Controls;
using Wino.Calendar.ViewModels.Data;
namespace Wino.Calendar.Selectors
{
public class CustomAreaCalendarItemSelector : DataTemplateSelector
namespace Wino.Calendar.Selectors;
public partial class CustomAreaCalendarItemSelector : DataTemplateSelector
{
public DataTemplate AllDayTemplate { get; set; }
public DataTemplate MultiDayTemplate { get; set; }
@@ -13,10 +13,10 @@ namespace Wino.Calendar.Selectors
{
if (item is CalendarItemViewModel calendarItemViewModel)
{
return calendarItemViewModel.IsMultiDayEvent ? MultiDayTemplate : AllDayTemplate;
return calendarItemViewModel.CalendarItem.ItemType == Core.Domain.Enums.CalendarItemType.MultiDay ||
calendarItemViewModel.CalendarItem.ItemType == Core.Domain.Enums.CalendarItemType.MultiDayAllDay ? MultiDayTemplate : AllDayTemplate;
}
return base.SelectTemplateCore(item, container);
}
}
}

View File

@@ -2,9 +2,9 @@
using Windows.UI.Xaml.Controls;
using Wino.Core.Domain.Enums;
namespace Wino.Calendar.Selectors
{
public class WinoCalendarItemTemplateSelector : DataTemplateSelector
namespace Wino.Calendar.Selectors;
public partial class WinoCalendarItemTemplateSelector : DataTemplateSelector
{
public CalendarDisplayType DisplayType { get; set; }
@@ -31,4 +31,3 @@ namespace Wino.Calendar.Selectors
return base.SelectTemplateCore(item, container);
}
}
}

View File

@@ -7,8 +7,8 @@ using Wino.Calendar.ViewModels.Data;
using Wino.Calendar.ViewModels.Interfaces;
using Wino.Core.Domain.Entities.Shared;
namespace Wino.Calendar.Services
{
namespace Wino.Calendar.Services;
/// <summary>
/// Encapsulated state manager for collectively managing the state of account calendars.
/// Callers must react to the events to update their state only from this service.
@@ -19,7 +19,7 @@ namespace Wino.Calendar.Services
public event EventHandler<AccountCalendarViewModel> AccountCalendarSelectionStateChanged;
[ObservableProperty]
private ReadOnlyObservableCollection<GroupedAccountCalendarViewModel> groupedAccountCalendars;
public partial ReadOnlyObservableCollection<GroupedAccountCalendarViewModel> GroupedAccountCalendars { get; set; }
private ObservableCollection<GroupedAccountCalendarViewModel> _internalGroupedAccountCalendars = new ObservableCollection<GroupedAccountCalendarViewModel>();
@@ -111,4 +111,3 @@ namespace Wino.Calendar.Services
}
}
}
}

View File

@@ -2,8 +2,8 @@
using Wino.Core.Domain.Interfaces;
using Wino.Core.UWP.Services;
namespace Wino.Calendar.Services
{
namespace Wino.Calendar.Services;
public class DialogService : DialogServiceBase, ICalendarDialogService
{
public DialogService(IThemeService themeService,
@@ -12,4 +12,3 @@ namespace Wino.Calendar.Services
{
}
}
}

View File

@@ -10,8 +10,8 @@ using Wino.Core.Domain.Models.Navigation;
using Wino.Core.UWP.Services;
using Wino.Views;
namespace Wino.Calendar.Services
{
namespace Wino.Calendar.Services;
public class NavigationService : NavigationServiceBase, INavigationService
{
public Type GetPageType(WinoPage winoPage)
@@ -60,4 +60,3 @@ namespace Wino.Calendar.Services
return false;
}
}
}

View File

@@ -4,8 +4,8 @@ using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Accounts;
namespace Wino.Calendar.Services
{
namespace Wino.Calendar.Services;
public class ProviderService : IProviderService
{
public IProviderDetail GetProviderDetail(MailProviderType type)
@@ -33,4 +33,3 @@ namespace Wino.Calendar.Services
return providerList;
}
}
}

View File

@@ -4,8 +4,8 @@ using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Settings;
namespace Wino.Calendar.Services
{
namespace Wino.Calendar.Services;
public class SettingsBuilderService : ISettingsBuilderService
{
public List<SettingOption> GetSettingItems()
@@ -18,4 +18,3 @@ namespace Wino.Calendar.Services
new SettingOption(Translator.SettingsAbout_Title, Translator.SettingsAbout_Description, WinoPage.AboutPage,"F1 M 9.375 18.75 C 8.509114 18.75 7.677409 18.639322 6.879883 18.417969 C 6.082356 18.196615 5.335286 17.882486 4.638672 17.475586 C 3.942057 17.068686 3.308919 16.580404 2.739258 16.010742 C 2.169596 15.441081 1.681315 14.807943 1.274414 14.111328 C 0.867513 13.414714 0.553385 12.667644 0.332031 11.870117 C 0.110677 11.072592 0 10.240886 0 9.375 C 0 8.509115 0.110677 7.677409 0.332031 6.879883 C 0.553385 6.082357 0.867513 5.335287 1.274414 4.638672 C 1.681315 3.942059 2.169596 3.30892 2.739258 2.739258 C 3.308919 2.169598 3.942057 1.681316 4.638672 1.274414 C 5.335286 0.867514 6.082356 0.553387 6.879883 0.332031 C 7.677409 0.110678 8.509114 0 9.375 0 C 10.240885 0 11.072591 0.110678 11.870117 0.332031 C 12.667643 0.553387 13.414713 0.867514 14.111328 1.274414 C 14.807942 1.681316 15.44108 2.169598 16.010742 2.739258 C 16.580402 3.30892 17.068684 3.942059 17.475586 4.638672 C 17.882486 5.335287 18.196613 6.082357 18.417969 6.879883 C 18.639322 7.677409 18.75 8.509115 18.75 9.375 C 18.75 10.240886 18.639322 11.072592 18.417969 11.870117 C 18.196613 12.667644 17.882486 13.414714 17.475586 14.111328 C 17.068684 14.807943 16.580402 15.441081 16.010742 16.010742 C 15.44108 16.580404 14.807942 17.068686 14.111328 17.475586 C 13.414713 17.882486 12.667643 18.196615 11.870117 18.417969 C 11.072591 18.639322 10.240885 18.75 9.375 18.75 Z M 9.375 1.25 C 8.626302 1.25 7.906901 1.347656 7.216797 1.542969 C 6.526692 1.738281 5.880533 2.011719 5.27832 2.363281 C 4.676106 2.714844 4.127604 3.138021 3.632812 3.632812 C 3.138021 4.127604 2.714844 4.676107 2.363281 5.27832 C 2.011719 5.880534 1.738281 6.52832 1.542969 7.22168 C 1.347656 7.915039 1.25 8.632812 1.25 9.375 C 1.25 10.117188 1.347656 10.834961 1.542969 11.52832 C 1.738281 12.22168 2.011719 12.869467 2.363281 13.47168 C 2.714844 14.073894 3.138021 14.622396 3.632812 15.117188 C 4.127604 15.611979 4.676106 16.035156 5.27832 16.386719 C 5.880533 16.738281 6.526692 17.011719 7.216797 17.207031 C 7.906901 17.402344 8.626302 17.5 9.375 17.5 C 10.117188 17.5 10.834961 17.402344 11.52832 17.207031 C 12.221679 17.011719 12.869465 16.738281 13.47168 16.386719 C 14.073893 16.035156 14.622396 15.611979 15.117188 15.117188 C 15.611979 14.622396 16.035156 14.073894 16.386719 13.47168 C 16.738281 12.869467 17.011719 12.223308 17.207031 11.533203 C 17.402344 10.8431 17.5 10.123698 17.5 9.375 C 17.5 8.632812 17.402344 7.915039 17.207031 7.22168 C 17.011719 6.52832 16.738281 5.880534 16.386719 5.27832 C 16.035156 4.676107 15.611979 4.127604 15.117188 3.632812 C 14.622396 3.138021 14.073893 2.714844 13.47168 2.363281 C 12.869465 2.011719 12.221679 1.738281 11.52832 1.542969 C 10.834961 1.347656 10.117188 1.25 9.375 1.25 Z M 8.75 7.5 L 10 7.5 L 10 13.75 L 8.75 13.75 Z M 8.75 5 L 10 5 L 10 6.25 L 8.75 6.25 Z "),
};
}
}

View File

@@ -1,7 +1,7 @@
using Windows.UI.Xaml;
namespace Wino.Calendar.Styles
{
namespace Wino.Calendar.Styles;
public sealed partial class WinoCalendarResources : ResourceDictionary
{
public WinoCalendarResources()
@@ -9,4 +9,3 @@ namespace Wino.Calendar.Styles
this.InitializeComponent();
}
}
}

View File

@@ -1,7 +1,6 @@
using Wino.Calendar.ViewModels;
using Wino.Core.UWP;
namespace Wino.Calendar.Views.Abstract
{
namespace Wino.Calendar.Views.Abstract;
public abstract class AccountDetailsPageAbstract : BasePage<AccountDetailsPageViewModel> { }
}

View File

@@ -1,7 +1,6 @@
using Wino.Calendar.ViewModels;
using Wino.Core.UWP;
namespace Wino.Calendar.Views.Abstract
{
public class AccountManagementPageAbstract : BasePage<AccountManagementViewModel> { }
}
namespace Wino.Calendar.Views.Abstract;
public partial class AccountManagementPageAbstract : BasePage<AccountManagementViewModel> { }

View File

@@ -1,7 +1,6 @@
using Wino.Calendar.ViewModels;
using Wino.Core.UWP;
namespace Wino.Calendar.Views.Abstract
{
namespace Wino.Calendar.Views.Abstract;
public abstract class AppShellAbstract : BasePage<AppShellViewModel> { }
}

View File

@@ -1,7 +1,6 @@
using Wino.Calendar.ViewModels;
using Wino.Core.UWP;
namespace Wino.Calendar.Views.Abstract
{
namespace Wino.Calendar.Views.Abstract;
public abstract class CalendarPageAbstract : BasePage<CalendarPageViewModel> { }
}

View File

@@ -1,7 +1,6 @@
using Wino.Calendar.ViewModels;
using Wino.Core.UWP;
namespace Wino.Calendar.Views.Abstract
{
namespace Wino.Calendar.Views.Abstract;
public abstract class CalendarSettingsPageAbstract : BasePage<CalendarSettingsPageViewModel> { }
}

View File

@@ -1,7 +1,6 @@
using Wino.Calendar.ViewModels;
using Wino.Core.UWP;
namespace Wino.Calendar.Views.Abstract
{
namespace Wino.Calendar.Views.Abstract;
public abstract class EventDetailsPageAbstract : BasePage<EventDetailsPageViewModel> { }
}

View File

@@ -1,7 +1,6 @@
using Wino.Core.UWP;
using Wino.Core.ViewModels;
namespace Wino.Calendar.Views.Abstract
{
public class PersonalizationPageAbstract : BasePage<PersonalizationPageViewModel> { }
}
namespace Wino.Calendar.Views.Abstract;
public partial class PersonalizationPageAbstract : BasePage<PersonalizationPageViewModel> { }

View File

@@ -1,7 +1,7 @@
using Wino.Calendar.Views.Abstract;
namespace Wino.Calendar.Views.Account
{
namespace Wino.Calendar.Views.Account;
public sealed partial class AccountManagementPage : AccountManagementPageAbstract
{
public AccountManagementPage()
@@ -9,4 +9,3 @@ namespace Wino.Calendar.Views.Account
InitializeComponent();
}
}
}

View File

@@ -89,6 +89,7 @@
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
BorderBrush="Transparent"
IsTabStop="False"
PlaceholderText="Search" />
<StackPanel

View File

@@ -5,8 +5,8 @@ using Wino.Calendar.Views.Abstract;
using Wino.Core.UWP;
using Wino.Messaging.Client.Calendar;
namespace Wino.Calendar.Views
{
namespace Wino.Calendar.Views;
public sealed partial class AppShell : AppShellAbstract,
IRecipient<CalendarDisplayTypeChangedMessage>
{
@@ -51,4 +51,3 @@ namespace Wino.Calendar.Views
private void AppBarBackButtonClicked(Core.UWP.Controls.WinoAppTitleBar sender, RoutedEventArgs args)
=> ViewModel.NavigationService.GoBack();
}
}

View File

@@ -9,8 +9,8 @@ using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Models.Calendar;
using Wino.Messaging.Client.Calendar;
namespace Wino.Calendar.Views
{
namespace Wino.Calendar.Views;
public sealed partial class CalendarPage : CalendarPageAbstract,
IRecipient<ScrollToDateMessage>,
IRecipient<ScrollToHourMessage>,
@@ -158,4 +158,3 @@ namespace Wino.Calendar.Views
ViewModel.DisplayDetailsCalendarItemViewModel = null;
}
}
}

View File

@@ -256,7 +256,7 @@
<PersonPicture
Width="40"
Height="40"
DisplayName="{x:Bind Name}" />
DisplayName="{x:Bind DisplayName}" />
<!-- TODO: Organizer -->
<Grid Grid.Column="1">
@@ -265,7 +265,7 @@
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock FontWeight="SemiBold" Text="{x:Bind Name}" />
<TextBlock FontWeight="SemiBold" Text="{x:Bind DisplayName}" />
<TextBlock
Grid.Row="1"
FontSize="13"

View File

@@ -1,8 +1,8 @@
using Wino.Calendar.Views.Abstract;
namespace Wino.Calendar.Views
{
namespace Wino.Calendar.Views;
public sealed partial class EventDetailsPage : EventDetailsPageAbstract
{
public EventDetailsPage()
@@ -10,4 +10,3 @@ namespace Wino.Calendar.Views
this.InitializeComponent();
}
}
}

View File

@@ -20,7 +20,7 @@
<controls:SettingsCard.HeaderIcon>
<PathIcon Data="F1 M 10 0.625 C 10 0.45573 10.061849 0.309246 10.185547 0.185547 C 10.309244 0.06185 10.455729 0 10.625 0 L 15.625 0 C 15.79427 0 15.940754 0.06185 16.064453 0.185547 C 16.18815 0.309246 16.25 0.45573 16.25 0.625 C 16.25 0.794271 16.18815 0.940756 16.064453 1.064453 C 15.940754 1.188152 15.79427 1.25 15.625 1.25 L 13.75 1.25 L 13.75 18.75 L 15.625 18.75 C 15.79427 18.75 15.940754 18.81185 16.064453 18.935547 C 16.18815 19.059244 16.25 19.205729 16.25 19.375 C 16.25 19.544271 16.18815 19.690756 16.064453 19.814453 C 15.940754 19.93815 15.79427 20 15.625 20 L 10.625 20 C 10.455729 20 10.309244 19.93815 10.185547 19.814453 C 10.061849 19.690756 10 19.544271 10 19.375 C 10 19.205729 10.061849 19.059244 10.185547 18.935547 C 10.309244 18.81185 10.455729 18.75 10.625 18.75 L 12.5 18.75 L 12.5 1.25 L 10.625 1.25 C 10.455729 1.25 10.309244 1.188152 10.185547 1.064453 C 10.061849 0.940756 10 0.794271 10 0.625 Z M 0 6.25 C 0 5.735678 0.097656 5.250651 0.292969 4.794922 C 0.488281 4.339193 0.756836 3.94043 1.098633 3.598633 C 1.44043 3.256836 1.837565 2.988281 2.290039 2.792969 C 2.742513 2.597656 3.229167 2.5 3.75 2.5 L 11.25 2.5 L 11.25 3.75 L 3.75 3.75 C 3.404948 3.75 3.081055 3.815105 2.77832 3.945312 C 2.475586 4.075521 2.210286 4.254558 1.982422 4.482422 C 1.754557 4.710287 1.575521 4.975587 1.445312 5.27832 C 1.315104 5.581056 1.25 5.904949 1.25 6.25 L 1.25 13.75 C 1.25 14.095053 1.315104 14.418945 1.445312 14.72168 C 1.575521 15.024414 1.754557 15.289714 1.982422 15.517578 C 2.210286 15.745443 2.475586 15.924479 2.77832 16.054688 C 3.081055 16.184896 3.404948 16.25 3.75 16.25 L 11.25 16.25 L 11.25 17.5 L 3.75 17.5 C 3.229167 17.5 2.742513 17.402344 2.290039 17.207031 C 1.837565 17.011719 1.44043 16.743164 1.098633 16.401367 C 0.756836 16.05957 0.488281 15.662436 0.292969 15.209961 C 0.097656 14.757487 0 14.270834 0 13.75 Z M 15 3.75 L 15 2.5 L 16.25 2.5 C 16.764322 2.5 17.249348 2.597656 17.705078 2.792969 C 18.160807 2.988281 18.55957 3.256836 18.901367 3.598633 C 19.243164 3.94043 19.511719 4.339193 19.707031 4.794922 C 19.902344 5.250651 20 5.735678 20 6.25 L 20 13.75 C 20 14.270834 19.902344 14.757487 19.707031 15.209961 C 19.511719 15.662436 19.243164 16.05957 18.901367 16.401367 C 18.55957 16.743164 18.160807 17.011719 17.705078 17.207031 C 17.249348 17.402344 16.764322 17.5 16.25 17.5 L 15 17.5 L 15 16.25 L 16.25 16.25 C 16.595051 16.25 16.918945 16.184896 17.22168 16.054688 C 17.524414 15.924479 17.789713 15.745443 18.017578 15.517578 C 18.245441 15.289714 18.424479 15.024414 18.554688 14.72168 C 18.684895 14.418945 18.75 14.095053 18.75 13.75 L 18.75 6.25 C 18.75 5.904949 18.684895 5.581056 18.554688 5.27832 C 18.424479 4.975587 18.245441 4.710287 18.017578 4.482422 C 17.789713 4.254558 17.524414 4.075521 17.22168 3.945312 C 16.918945 3.815105 16.595051 3.75 16.25 3.75 Z M 7.441406 5.361328 C 7.389323 5.250651 7.312825 5.162761 7.211914 5.097656 C 7.111002 5.032553 6.998697 5.000001 6.875 5 C 6.751302 5.000001 6.638997 5.032553 6.538086 5.097656 C 6.437174 5.162761 6.360677 5.250651 6.308594 5.361328 L 2.871094 12.861328 C 2.799479 13.017578 2.792969 13.177084 2.851562 13.339844 C 2.910156 13.502604 3.017578 13.619792 3.173828 13.691406 C 3.330078 13.763021 3.489583 13.769531 3.652344 13.710938 C 3.815104 13.652344 3.932292 13.544922 4.003906 13.388672 L 4.84375 11.5625 L 8.896484 11.5625 L 8.90625 11.5625 L 9.746094 13.388672 C 9.817708 13.544922 9.934896 13.652344 10.097656 13.710938 C 10.260416 13.769531 10.419922 13.763021 10.576172 13.691406 C 10.732422 13.619792 10.839844 13.502604 10.898438 13.339844 C 10.957031 13.177084 10.950521 13.017578 10.878906 12.861328 Z M 5.410156 10.3125 L 6.875 7.128906 L 8.339844 10.3125 Z " />
</controls:SettingsCard.HeaderIcon>
<Button Command="{x:Bind ViewModel.RenameAccountCommand}" Content="{x:Bind domain:Translator.FolderOperation_Rename}" />
<Button Command="{x:Bind ViewModel.EditAccountDetailsCommand}" Content="{x:Bind domain:Translator.FolderOperation_Rename}" />
</controls:SettingsCard>
<!-- TODO -->

View File

@@ -1,7 +1,7 @@
using Wino.Calendar.Views.Abstract;
namespace Wino.Calendar.Views.Settings
{
namespace Wino.Calendar.Views.Settings;
public sealed partial class AccountDetailsPage : AccountDetailsPageAbstract
{
public AccountDetailsPage()
@@ -9,4 +9,3 @@ namespace Wino.Calendar.Views.Settings
this.InitializeComponent();
}
}
}

View File

@@ -1,8 +1,8 @@
using Wino.Calendar.Views.Abstract;
namespace Wino.Calendar.Views.Settings
{
namespace Wino.Calendar.Views.Settings;
public sealed partial class CalendarSettingsPage : CalendarSettingsPageAbstract
{
public CalendarSettingsPage()
@@ -10,4 +10,3 @@ namespace Wino.Calendar.Views.Settings
InitializeComponent();
}
}
}

View File

@@ -1,7 +1,7 @@
using Wino.Calendar.Views.Abstract;
namespace Wino.Calendar.Views.Settings
{
namespace Wino.Calendar.Views.Settings;
public sealed partial class PersonalizationPage : PersonalizationPageAbstract
{
public PersonalizationPage()
@@ -9,4 +9,3 @@ namespace Wino.Calendar.Views.Settings
this.InitializeComponent();
}
}
}

View File

@@ -1,184 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<LangVersion>8.0</LangVersion>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
<!-- UWP WAM Authentication on Xbox needs this. -->
<UseDotNetNativeSharedAssemblyFrameworkPackage>false</UseDotNetNativeSharedAssemblyFrameworkPackage>
<PackageCertificateThumbprint>
</PackageCertificateThumbprint>
<PackageCertificateKeyFile>Wino.Mail_TemporaryKey.pfx</PackageCertificateKeyFile>
<GenerateAppInstallerFile>False</GenerateAppInstallerFile>
<AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm>
<AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>
<AppxSymbolPackageEnabled>False</AppxSymbolPackageEnabled>
<GenerateTestArtifacts>True</GenerateTestArtifacts>
<AppxBundle>Always</AppxBundle>
<AppxBundlePlatforms>x64</AppxBundlePlatforms>
<HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks>
</PropertyGroup>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{600F4979-DB7E-409D-B7DA-B60BE4C55C35}</ProjectGuid>
<OutputType>AppContainerExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Wino.Calendar</RootNamespace>
<AssemblyName>Wino.Calendar</AssemblyName>
<OutputType>WinExe</OutputType>
<TargetFramework>net9.0-windows10.0.26100.0</TargetFramework>
<TargetPlatformMinVersion>10.0.18362.0</TargetPlatformMinVersion>
<UseUwp>true</UseUwp>
<Platforms>x86;x64;arm64</Platforms>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
<DefaultLanguage>en-US</DefaultLanguage>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion Condition=" '$(TargetPlatformVersion)' == '' ">10.0.22621.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WindowsXamlEnableOverview>true</WindowsXamlEnableOverview>
<!--<PublishAot>true</PublishAot>-->
<PublishProfile>win-$(Platform).pubxml</PublishProfile>
<DisableRuntimeMarshalling>true</DisableRuntimeMarshalling>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<GenerateAppInstallerFile>True</GenerateAppInstallerFile>
<AppxPackageSigningEnabled>True</AppxPackageSigningEnabled>
<GenerateTemporaryStoreCertificate>True</GenerateTemporaryStoreCertificate>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\ARM64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>ARM64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM64'">
<OutputPath>bin\ARM64\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>ARM64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<!-- .NET Native Shit -->
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
<UseDotNetNativeSharedAssemblyFrameworkPackage>false</UseDotNetNativeSharedAssemblyFrameworkPackage>
<Use64BitCompiler>true</Use64BitCompiler>
<OutOfProcPDB>true</OutOfProcPDB>
<AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm>
</PropertyGroup>
<ItemGroup>
<Compile Include="Activation\DefaultActivationHandler.cs" />
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="Args\TimelineCellSelectedArgs.cs" />
<Compile Include="Args\TimelineCellUnselectedArgs.cs" />
<Compile Include="Controls\CalendarItemCommandBarFlyout.cs" />
<Compile Include="Controls\CalendarItemControl.xaml.cs">
<DependentUpon>CalendarItemControl.xaml</DependentUpon>
</Compile>
<Compile Include="Controls\CustomCalendarFlipView.cs" />
<Compile Include="Controls\DayColumnControl.cs" />
<Compile Include="Controls\DayHeaderControl.cs" />
<Compile Include="Controls\WinoCalendarControl.cs" />
<Compile Include="Controls\WinoCalendarFlipView.cs" />
<Compile Include="Controls\WinoCalendarPanel.cs" />
<Compile Include="Controls\WinoCalendarTypeSelectorControl.cs" />
<Compile Include="Controls\WinoCalendarView.cs" />
<Compile Include="Controls\WinoDayTimelineCanvas.cs" />
<Compile Include="Helpers\CalendarXamlHelpers.cs" />
<Compile Include="MainPage.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon>
</Compile>
<Compile Include="Models\CalendarItemMeasurement.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Selectors\CustomAreaCalendarItemSelector.cs" />
<Compile Include="Selectors\WinoCalendarItemTemplateSelector.cs" />
<Compile Include="Services\AccountCalendarStateService.cs" />
<Compile Include="Services\CalendarAuthenticatorConfig.cs" />
<Compile Include="Services\DialogService.cs" />
<Compile Include="Services\NavigationService.cs" />
<Compile Include="Services\ProviderService.cs" />
<Compile Include="Services\SettingsBuilderService.cs" />
<Compile Include="Styles\WinoCalendarResources.xaml.cs" />
<Compile Include="Views\Abstract\AccountDetailsPageAbstract.cs" />
<Compile Include="Views\Abstract\AccountManagementPageAbstract.cs" />
<Compile Include="Views\Abstract\AppShellAbstract.cs" />
<Compile Include="Views\Abstract\CalendarPageAbstract.cs" />
<Compile Include="Views\Abstract\CalendarSettingsPageAbstract.cs" />
<Compile Include="Views\Abstract\EventDetailsPageAbstract.cs" />
<Compile Include="Views\Abstract\PersonalizationPageAbstract.cs" />
<Compile Include="Views\Account\AccountManagementPage.xaml.cs">
<DependentUpon>AccountManagementPage.xaml</DependentUpon>
</Compile>
<Compile Include="Views\AppShell.xaml.cs">
<DependentUpon>AppShell.xaml</DependentUpon>
</Compile>
<Compile Include="Views\CalendarPage.xaml.cs">
<DependentUpon>CalendarPage.xaml</DependentUpon>
</Compile>
<Compile Include="Views\EventDetailsPage.xaml.cs">
<DependentUpon>EventDetailsPage.xaml</DependentUpon>
</Compile>
<Compile Include="Views\Settings\AccountDetailsPage.xaml.cs">
<DependentUpon>AccountDetailsPage.xaml</DependentUpon>
</Compile>
<Compile Include="Views\Settings\CalendarSettingsPage.xaml.cs">
<DependentUpon>CalendarSettingsPage.xaml</DependentUpon>
</Compile>
<Compile Include="Views\Settings\PersonalizationPage.xaml.cs">
<DependentUpon>PersonalizationPage.xaml</DependentUpon>
</Compile>
<Compile Remove="BundleArtifacts\**" />
<EmbeddedResource Remove="BundleArtifacts\**" />
<None Remove="BundleArtifacts\**" />
<Page Remove="BundleArtifacts\**" />
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
<PRIResource Remove="BundleArtifacts\**" />
</ItemGroup>
<ItemGroup>
<None Include="Package.StoreAssociation.xml" />
<Content Include="Assets\LargeTile.scale-100.png" />
@@ -226,7 +73,6 @@
<Content Include="Assets\Wide310x150Logo.scale-125.png" />
<Content Include="Assets\Wide310x150Logo.scale-150.png" />
<Content Include="Assets\Wide310x150Logo.scale-400.png" />
<Content Include="Properties\Default.rd.xml" />
<Content Include="Assets\LockScreenLogo.scale-200.png" />
<Content Include="Assets\SplashScreen.scale-200.png" />
<Content Include="Assets\Square150x150Logo.scale-200.png" />
@@ -235,120 +81,18 @@
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="Controls\CalendarItemControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="MainPage.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Styles\CalendarThemeResources.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Styles\DayHeaderControl.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Styles\WinoCalendarResources.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Styles\WinoCalendarTypeSelectorControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Styles\WinoCalendarView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Styles\WinoDayTimelineCanvas.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\Account\AccountManagementPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\AppShell.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\CalendarPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\EventDetailsPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\Settings\AccountDetailsPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\Settings\CalendarSettingsPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\Settings\PersonalizationPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<PackageReference Include="CommunityToolkit.Uwp.Controls.Primitives" />
<PackageReference Include="Microsoft.Identity.Client" />
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform" />
<PackageReference Include="Win2D.uwp" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="CommunityToolkit.Uwp.Controls.Primitives">
<Version>8.1.240916</Version>
</PackageReference>
<PackageReference Include="Microsoft.Identity.Client">
<Version>4.66.2</Version>
</PackageReference>
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
<Version>6.2.14</Version>
</PackageReference>
<PackageReference Include="Win2D.uwp">
<Version>1.28.1</Version>
</PackageReference>
<ProjectReference Include="..\Wino.Authentication\Wino.Authentication.csproj" />
<ProjectReference Include="..\Wino.Calendar.ViewModels\Wino.Calendar.ViewModels.csproj" />
<ProjectReference Include="..\Wino.Core.Domain\Wino.Core.Domain.csproj" />
<ProjectReference Include="..\Wino.Core.UWP\Wino.Core.UWP.csproj" />
<ProjectReference Include="..\Wino.Core.ViewModels\Wino.Core.ViewModels.csproj" />
<ProjectReference Include="..\Wino.Messages\Wino.Messaging.csproj" />
<ProjectReference Include="..\Wino.Services\Wino.Services.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Wino.Calendar.ViewModels\Wino.Calendar.ViewModels.csproj">
<Project>{039affa8-c1cc-4e3b-8a31-6814d7557f74}</Project>
<Name>Wino.Calendar.ViewModels</Name>
</ProjectReference>
<ProjectReference Include="..\Wino.Core.Domain\Wino.Core.Domain.csproj">
<Project>{cf3312e5-5da0-4867-9945-49ea7598af1f}</Project>
<Name>Wino.Core.Domain</Name>
</ProjectReference>
<ProjectReference Include="..\Wino.Core.UWP\Wino.Core.UWP.csproj">
<Project>{395f19ba-1e42-495c-9db5-1a6f537fccb8}</Project>
<Name>Wino.Core.UWP</Name>
</ProjectReference>
<ProjectReference Include="..\Wino.Core.ViewModels\Wino.Core.ViewModels.csproj">
<Project>{53723ae8-7e7e-4d54-adab-0a6033255cc8}</Project>
<Name>Wino.Core.ViewModels</Name>
</ProjectReference>
<ProjectReference Include="..\Wino.Messages\Wino.Messaging.csproj">
<Project>{0c307d7e-256f-448c-8265-5622a812fbcc}</Project>
<Name>Wino.Messaging</Name>
</ProjectReference>
<ProjectReference Include="..\Wino.Services\Wino.Services.csproj">
<Project>{bba49030-7277-48cf-b2fe-3d01cb6b6c81}</Project>
<Name>Wino.Services</Name>
</ProjectReference>
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -80,11 +80,11 @@ public class CalendarEventCollection
// Multi-day events go to both.
// Anything else goes to regular.
if (calendarItem.IsAllDayEvent)
if (calendarItem.ItemType == Enums.CalendarItemType.AllDay || calendarItem.ItemType == Enums.CalendarItemType.MultiDayAllDay || calendarItem.ItemType == Enums.CalendarItemType.RecurringAllDay)
{
return [_internalAllDayEvents];
}
else if (calendarItem.IsMultiDayEvent)
else if (calendarItem.ItemType == Enums.CalendarItemType.MultiDay || calendarItem.ItemType == Enums.CalendarItemType.MultiDayAllDay)
{
return [_internalRegularEvents, _internalAllDayEvents];
}

View File

@@ -8,8 +8,6 @@ public static class Constants
public const string WinoLocalDraftHeader = "X-Wino-Draft-Id";
public const string LocalDraftStartPrefix = "localDraft_";
public const string CalendarEventRecurrenceRuleSeperator = "___";
public const string ToastMailUniqueIdKey = nameof(ToastMailUniqueIdKey);
public const string ToastActionKey = nameof(ToastActionKey);

View File

@@ -7,12 +7,40 @@ namespace Wino.Core.Domain.Entities.Calendar;
public class AccountCalendar : IAccountCalendar
{
[PrimaryKey]
public Guid Id { get; set; }
public Guid Id { get; set; } = Guid.NewGuid();
[NotNull]
public string RemoteCalendarId { get; set; } = string.Empty;
[NotNull]
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; }
[NotNull]
public string Name { get; set; } = string.Empty;
public string? Description { get; set; }
public string? Location { get; set; }
public string? TimeZone { get; set; }
public string? AccessRole { get; set; }
public bool IsPrimary { get; set; } = false;
public string? BackgroundColor { get; set; }
public string? ForegroundColor { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime LastModified { get; set; }
public DateTime? LastSyncTime { get; set; }
public string? SynchronizationDeltaToken { get; set; }
public bool IsDeleted { get; set; } = false;
public bool IsExtended { get; set; } = true;
/// <summary>
@@ -20,5 +48,4 @@ public class AccountCalendar : IAccountCalendar
/// </summary>
public string TextColorHex { get; set; }
public string BackgroundColorHex { get; set; }
public string TimeZone { get; set; }
}

View File

@@ -8,12 +8,29 @@ namespace Wino.Core.Domain.Entities.Calendar;
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; }
public Guid Id { get; set; } = Guid.NewGuid();
[NotNull]
public Guid EventId { get; set; }
[NotNull]
public string Email { get; set; } = string.Empty;
public string? DisplayName { get; set; }
public AttendeeResponseStatus ResponseStatus { get; set; } = AttendeeResponseStatus.NeedsAction;
public bool IsOptional { get; set; } = false;
public bool IsOrganizer { get; set; } = false;
public bool IsSelf { get; set; } = false;
public string? Comment { get; set; }
public int? AdditionalGuests { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime LastModified { get; set; }
}

View File

@@ -3,6 +3,7 @@ using System.Diagnostics;
using Itenso.TimePeriod;
using SQLite;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Helpers;
using Wino.Core.Domain.Interfaces;
namespace Wino.Core.Domain.Entities.Calendar;
@@ -11,169 +12,81 @@ namespace Wino.Core.Domain.Entities.Calendar;
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 Guid Id { get; set; } = Guid.NewGuid();
public DateTime StartDate { get; set; }
[NotNull]
public string RemoteEventId { get; set; } = string.Empty;
public DateTime EndDate
{
get
{
return StartDate.AddSeconds(DurationInSeconds);
}
}
[NotNull]
public Guid CalendarId { get; set; }
public TimeSpan StartDateOffset { get; set; }
public TimeSpan EndDateOffset { get; set; }
[Ignore]
public IAccountCalendar AssignedCalendar { get; set; }
[NotNull]
public string Title { get; set; } = string.Empty;
public string? Description { get; set; }
public string? Location { get; set; }
public string? HtmlLink { get; set; }
public DateTime StartDateTime { get; set; }
public DateTime EndDateTime { get; set; }
private ITimePeriod _period;
public ITimePeriod Period
{
get
{
_period ??= new TimeRange(StartDate, EndDate);
_period ??= new TimeRange(StartDateTime, EndDateTime);
return _period;
}
}
/// <summary>
/// Events that starts at midnight and ends at midnight are considered all-day events.
/// </summary>
public bool IsAllDayEvent
{
get
{
return
StartDate.TimeOfDay == TimeSpan.Zero &&
EndDate.TimeOfDay == TimeSpan.Zero;
}
}
public bool IsAllDay { get; set; }
public string? TimeZone { get; set; }
public string? RecurrenceRules { get; set; }
public string? Status { get; set; }
public string? OrganizerDisplayName { get; set; }
public string? OrganizerEmail { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime LastModified { get; set; }
public bool IsDeleted { get; set; }
public string? RecurringEventId { get; set; }
public string? OriginalStartTime { get; set; }
/// <summary>
/// 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.
/// The type of calendar item (Timed, AllDay, MultiDay, etc.)
/// </summary>
public bool IsRecurringChild
{
get
{
return RecurringCalendarItemId != null;
}
}
public CalendarItemType ItemType { get; set; }
/// <summary>
/// Events that are either an exceptional instance of a recurring event or occurrences.
/// Automatically determines and sets the ItemType based on event properties
/// </summary>
public bool IsRecurringEvent => IsRecurringChild || IsRecurringParent;
public void DetermineItemType()
{
var hasRecurrence = !string.IsNullOrEmpty(RecurrenceRules);
var isCancelled = Status?.ToLowerInvariant() == "cancelled" || IsDeleted;
/// <summary>
/// Events that are the master event definition of recurrence events.
/// </summary>
public bool IsRecurringParent
{
get
{
return !string.IsNullOrEmpty(Recurrence) && RecurringCalendarItemId == null;
}
}
/// <summary>
/// Events that are not all-day events and last more than one day are considered multi-day events.
/// </summary>
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; }
/// <summary>
/// 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.
/// </summary>
public Guid? RecurringCalendarItemId { get; set; }
/// <summary>
/// Indicates read-only events. Default is false.
/// </summary>
public bool IsLocked { get; set; }
/// <summary>
/// Hidden events must not be displayed to the user.
/// This usually happens when a child instance of recurring parent is cancelled after creation.
/// </summary>
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; }
/// <summary>
/// Whether this item does not really exist in the database or not.
/// These are used to display occurrence instances of parent recurring events.
/// </summary>
[Ignore]
public bool IsOccurrence { get; set; }
/// <summary>
/// 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.
/// </summary>
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
};
ItemType = CalendarItemTypeHelper.DetermineItemType(
StartDateTime,
EndDateTime,
IsAllDay,
hasRecurrence,
isCancelled,
Status);
}
}

View File

@@ -0,0 +1,14 @@
using System;
using SQLite;
namespace Wino.Core.Domain.Entities.Shared;
public class Thumbnail
{
[PrimaryKey]
public string Domain { get; set; }
public string Gravatar { get; set; }
public string Favicon { get; set; }
public DateTime LastUpdated { get; set; }
}

View File

@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wino.Core.Domain.Enums;
/// <summary>
/// Represents the response status of an attendee to a calendar event
/// </summary>
public enum AttendeeResponseStatus
{
/// <summary>
/// The attendee has not responded to the invitation
/// </summary>
NeedsAction = 0,
/// <summary>
/// The attendee has accepted the invitation
/// </summary>
Accepted = 1,
/// <summary>
/// The attendee has declined the invitation
/// </summary>
Declined = 2,
/// <summary>
/// The attendee has tentatively accepted the invitation
/// </summary>
Tentative = 3
}

View File

@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wino.Core.Domain.Enums;
public enum CalendarItemType
{
/// <summary>
/// A standard timed event with specific start and end times on the same day
/// </summary>
Timed = 0,
/// <summary>
/// An all-day event that spans exactly one day
/// </summary>
AllDay = 1,
/// <summary>
/// A multi-day event that spans more than one day but has specific times
/// </summary>
MultiDay = 2,
/// <summary>
/// A multi-day all-day event (e.g., vacation, conference spanning multiple days)
/// </summary>
MultiDayAllDay = 3,
/// <summary>
/// A recurring event with a defined pattern (daily, weekly, monthly, yearly)
/// </summary>
Recurring = 4,
/// <summary>
/// A recurring all-day event (e.g., annual holiday, weekly all-day event)
/// </summary>
RecurringAllDay = 5,
/// <summary>
/// A single instance of a recurring event that has been modified
/// </summary>
RecurringException = 6,
/// <summary>
/// An event that extends beyond midnight but is not multi-day (e.g., 11 PM to 2 AM)
/// </summary>
CrossMidnight = 7,
}

View File

@@ -25,7 +25,7 @@ public enum WinoPage
AppPreferencesPage,
SettingOptionsPage,
AliasManagementPage,
EditAccountDetailsPage,
// Calendar
CalendarPage,
CalendarSettingsPage,

View File

@@ -20,7 +20,7 @@ public class ImapClientPoolException : Exception
ProtocolLog = protocolLog;
}
public ImapClientPoolException(Exception innerException, string protocolLog) : base(Translator.Exception_ImapClientPoolFailed, innerException)
public ImapClientPoolException(Exception innerException, string protocolLog) : base(innerException.Message, innerException)
{
ProtocolLog = protocolLog;
}

View File

@@ -0,0 +1,143 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Wino.Core.Domain.Enums;
namespace Wino.Core.Domain.Helpers;
/// <summary>
/// Helper class for CalendarItemType operations
/// </summary>
public static class CalendarItemTypeHelper
{
/// <summary>
/// Determines the calendar item type based on event properties
/// </summary>
/// <param name="startDateTime">Event start date/time</param>
/// <param name="endDateTime">Event end date/time</param>
/// <param name="isAllDay">Whether the event is marked as all-day</param>
/// <param name="isRecurring">Whether the event has recurrence rules</param>
/// <param name="isCancelled">Whether the event is cancelled</param>
/// <param name="status">Event status</param>
/// <returns>The appropriate CalendarItemType</returns>
public static CalendarItemType DetermineItemType(
DateTime startDateTime,
DateTime endDateTime,
bool isAllDay,
bool isRecurring = false,
bool isCancelled = false,
string? status = null)
{
// Handle recurring events
if (isRecurring)
{
return isAllDay ? CalendarItemType.RecurringAllDay : CalendarItemType.Recurring;
}
// Handle all-day events
if (isAllDay)
{
var daySpan = (endDateTime.Date - startDateTime.Date).Days;
return daySpan > 1 ? CalendarItemType.MultiDayAllDay : CalendarItemType.AllDay;
}
// Handle timed events
var duration = endDateTime - startDateTime;
// Multi-day timed events
if (duration.TotalDays >= 1)
{
return CalendarItemType.MultiDay;
}
// Cross midnight events (same calendar day but extends past midnight)
if (startDateTime.Date != endDateTime.Date && duration.TotalHours <= 24)
{
return CalendarItemType.CrossMidnight;
}
// Standard timed events
return CalendarItemType.Timed;
}
/// <summary>
/// Gets a human-readable description of the calendar item type
/// </summary>
/// <param name="itemType">The calendar item type</param>
/// <returns>Description string</returns>
public static string GetDescription(CalendarItemType itemType)
{
return itemType switch
{
CalendarItemType.Timed => "Timed Event",
CalendarItemType.AllDay => "All-Day Event",
CalendarItemType.MultiDay => "Multi-Day Event",
CalendarItemType.MultiDayAllDay => "Multi-Day All-Day Event",
CalendarItemType.Recurring => "Recurring Event",
CalendarItemType.RecurringAllDay => "Recurring All-Day Event",
CalendarItemType.RecurringException => "Modified Recurring Event",
CalendarItemType.CrossMidnight => "Cross-Midnight Event",
_ => "Unknown Event Type"
};
}
/// <summary>
/// Checks if the event type represents an all-day event
/// </summary>
/// <param name="itemType">The calendar item type</param>
/// <returns>True if it's an all-day event type</returns>
public static bool IsAllDayType(CalendarItemType itemType)
{
return itemType == CalendarItemType.AllDay ||
itemType == CalendarItemType.MultiDayAllDay ||
itemType == CalendarItemType.RecurringAllDay;
}
/// <summary>
/// Checks if the event type represents a recurring event
/// </summary>
/// <param name="itemType">The calendar item type</param>
/// <returns>True if it's a recurring event type</returns>
public static bool IsRecurringType(CalendarItemType itemType)
{
return itemType == CalendarItemType.Recurring ||
itemType == CalendarItemType.RecurringAllDay ||
itemType == CalendarItemType.RecurringException;
}
/// <summary>
/// Checks if the event type represents a multi-day event
/// </summary>
/// <param name="itemType">The calendar item type</param>
/// <returns>True if it's a multi-day event type</returns>
public static bool IsMultiDayType(CalendarItemType itemType)
{
return itemType == CalendarItemType.MultiDay ||
itemType == CalendarItemType.MultiDayAllDay;
}
/// <summary>
/// Gets the priority level for sorting events (lower number = higher priority)
/// </summary>
/// <param name="itemType">The calendar item type</param>
/// <returns>Priority number for sorting</returns>
public static int GetSortPriority(CalendarItemType itemType)
{
return itemType switch
{
CalendarItemType.AllDay => 2,
CalendarItemType.MultiDayAllDay => 3,
CalendarItemType.Timed => 4,
CalendarItemType.CrossMidnight => 5,
CalendarItemType.MultiDay => 6,
CalendarItemType.Recurring => 7,
CalendarItemType.RecurringAllDay => 8,
CalendarItemType.RecurringException => 9,
_ => 99
};
}
}

View File

@@ -62,15 +62,6 @@ public interface IAccountService
/// <param name="accountId">Account id to remove from</param>
Task ClearAccountAttentionAsync(Guid accountId);
/// <summary>
/// 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.
/// </summary>
/// <param name="newIdentifier">Identifier to update</param>
/// <returns>Current account synchronization modifier.</returns>
Task<string> UpdateSynchronizationIdentifierAsync(Guid accountId, string newIdentifier);
/// <summary>
/// Renames the merged inbox with the given id.
/// </summary>
@@ -164,4 +155,19 @@ public interface IAccountService
/// <param name="accountId">Account id.</param>
/// <param name="AccountCacheResetReason">Reason for the cache reset.</param>
Task DeleteAccountMailCacheAsync(Guid accountId, AccountCacheResetReason accountCacheResetReason);
/// <summary>
/// Updates the synchronization identifier for a specific account asynchronously.
/// </summary>
/// <param name="accountId">Identifies the account for which the synchronization identifier is being updated.</param>
/// <param name="syncIdentifier">Represents the new synchronization identifier to be set for the specified account.</param>
Task<string> UpdateSyncIdentifierRawAsync(Guid accountId, string syncIdentifier);
/// <summary>
/// Gets whether the notifications are enabled for the given account id.
/// </summary>
/// <param name="accountId">Account id.</param>
/// <returns>Whether the notifications should be created after sync or not.</returns>
Task<bool> IsNotificationsEnabled(Guid accountId);
}

View File

@@ -1,5 +1,6 @@
using System;
using Itenso.TimePeriod;
using Wino.Core.Domain.Enums;
namespace Wino.Core.Domain.Interfaces;
@@ -8,15 +9,8 @@ public interface ICalendarItem
string Title { get; }
Guid Id { get; }
IAccountCalendar AssignedCalendar { get; }
DateTime StartDate { get; set; }
DateTime EndDate { get; }
double DurationInSeconds { get; set; }
DateTime StartDateTime { get; set; }
DateTime EndDateTime { get; }
ITimePeriod Period { get; }
bool IsAllDayEvent { get; }
bool IsMultiDayEvent { get; }
bool IsRecurringChild { get; }
bool IsRecurringParent { get; }
bool IsRecurringEvent { get; }
CalendarItemType ItemType { get; }
}

View File

@@ -1,9 +1,13 @@
namespace Wino.Core.Domain.Interfaces;
using System;
namespace Wino.Core.Domain.Interfaces;
/// <summary>
/// Temporarily to enforce CalendarItemViewModel. Used in CalendarEventCollection.
/// </summary>
public interface ICalendarItemViewModel
public interface ICalendarItemViewModel : ICalendarItem
{
bool IsSelected { get; set; }
DateTime LocalStartDateTime { get; }
DateTime LocalEndDateTime { get; }
}

View File

@@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Wino.Core.Domain.Entities.Calendar;
using Wino.Core.Domain.Enums;
namespace Wino.Core.Domain.Interfaces;
public interface ICalendarServiceEx
{
Task<int> ClearAllCalendarEventAttendeesAsync();
Task<int> ClearAllCalendarsAsync();
Task<int> ClearAllDataAsync();
Task<int> ClearAllEventsAsync();
Task<int> DeleteCalendarAsync(string remoteCalendarId);
Task<int> DeleteCalendarEventAttendeesForEventAsync(Guid eventId);
Task<int> DeleteEventAsync(string remoteEventId);
Task<List<CalendarEventAttendee>> GetAllCalendarEventAttendeesAsync();
Task<List<AccountCalendar>> GetAllCalendarsAsync();
Task<List<CalendarItem>> GetAllDayEventsAsync();
Task<List<CalendarItem>> GetAllEventsAsync();
Task<List<CalendarItem>> GetAllEventsIncludingDeletedAsync();
Task<List<CalendarItem>> GetAllRecurringEventsByTypeAsync();
Task<AccountCalendar> GetCalendarByRemoteIdAsync(string remoteCalendarId);
Task<Dictionary<AttendeeResponseStatus, int>> GetCalendarEventAttendeeResponseCountsAsync(Guid eventId);
Task<List<CalendarEventAttendee>> GetCalendarEventAttendeesForEventAsync(Guid eventId);
Task<List<CalendarEventAttendee>> GetCalendarEventAttendeesForEventByRemoteIdAsync(string remoteEventId);
Task<string> GetCalendarSyncTokenAsync(string calendarId);
Task<CalendarItem> GetEventByRemoteIdAsync(string remoteEventId);
Task<List<CalendarItem>> GetEventsByItemTypeAsync(CalendarItemType itemType);
Task<List<CalendarItem>> GetEventsByItemTypesAsync(params CalendarItemType[] itemTypes);
Task<List<CalendarItem>> GetEventsByremoteCalendarIdAsync(string remoteCalendarId);
Task<List<CalendarItem>> GetEventsForCalendarAsync(Guid calendarId);
Task<List<CalendarItem>> GetEventsInDateRangeAsync(DateTime startDate, DateTime endDate);
Task<List<CalendarItem>> GetEventsSinceLastSyncAsync(DateTime? lastSyncTime);
Task<Dictionary<CalendarItemType, int>> GetEventStatsByItemTypeAsync();
Task<List<CalendarItem>> GetExpandedEventsInDateRangeAsync(DateTime startDate, DateTime endDate);
Task<List<CalendarItem>> GetExpandedEventsInDateRangeWithExceptionsAsync(DateTime startDate, DateTime endDate, AccountCalendar calendar);
Task<DateTime?> GetLastSyncTimeAsync(string calendarId);
Task<List<CalendarItem>> GetMultiDayEventsAsync();
Task<List<CalendarItem>> GetRecurringEventsAsync();
Task<int> HardDeleteEventAsync(string remoteEventId);
Task<int> InsertCalendarAsync(AccountCalendar calendar);
Task<int> InsertCalendarEventAttendeeAsync(CalendarEventAttendee calendareventattendee);
Task<int> InsertEventAsync(CalendarItem calendarItem);
Task<int> MarkEventAsDeletedAsync(string remoteEventId, string remoteCalendarId);
Task<int> SyncAttendeesForEventAsync(Guid eventId, List<CalendarEventAttendee> attendees);
Task<int> SyncCalendarEventAttendeesForEventAsync(Guid eventId, List<CalendarEventAttendee> calendareventattendees);
Task<int> UpdateAllEventItemTypesAsync();
Task<int> UpdateCalendarAsync(AccountCalendar calendar);
Task<int> UpdateCalendarEventAttendeeAsync(CalendarEventAttendee calendareventattendee);
Task<int> UpdateCalendarSyncTokenAsync(string calendarId, string syncToken);
Task<int> UpdateEventAsync(CalendarItem calendarItem);
Task<int> UpsertCalendarAsync(AccountCalendar calendar);
Task<int> UpsertEventAsync(CalendarItem calendarItem);
}

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Wino.Core.Domain.Entities.Shared;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Models.Accounts;
using Wino.Core.Domain.Models.Common;
@@ -17,7 +16,6 @@ public interface IDialogServiceBase
void InfoBarMessage(string title, string message, InfoBarMessageType messageType);
void InfoBarMessage(string title, string message, InfoBarMessageType messageType, string actionButtonText, Action action);
void ShowNotSupportedMessage();
Task<MailAccount> ShowEditAccountDialogAsync(MailAccount account);
Task<string> ShowTextInputDialogAsync(string currentInput, string dialogTitle, string dialogDescription, string primaryButtonText);
Task<bool> ShowWinoCustomMessageDialogAsync(string title,
string description,

View File

@@ -13,4 +13,5 @@ public interface IImapSynchronizer
Task<List<NewMailItemPackage>> CreateNewMailPackagesAsync(ImapMessageCreationPackage message, MailItemFolder assignedFolder, CancellationToken cancellationToken = default);
Task StartIdleClientAsync();
Task StopIdleClientAsync();
Task PreWarmClientPoolAsync();
}

View File

@@ -1,11 +1,12 @@
using System;
using System.ComponentModel;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Models.Calendar;
using Wino.Core.Domain.Models.Reader;
namespace Wino.Core.Domain.Interfaces;
public interface IPreferencesService
public interface IPreferencesService: INotifyPropertyChanged
{
/// <summary>
/// When any of the preferences are changed.
@@ -188,6 +189,21 @@ public interface IPreferencesService
/// </summary>
bool IsMailListActionBarEnabled { get; set; }
/// <summary>
/// Setting: Whether the mail rendering page will show the action labels
/// </summary>
bool IsShowActionLabelsEnabled { get; set; }
/// <summary>
/// Setting: Enable/disable Gravatar for sender avatars.
/// </summary>
bool IsGravatarEnabled { get; set; }
/// <summary>
/// Setting: Enable/disable Favicon for sender avatars.
/// </summary>
bool IsFaviconEnabled { get; set; }
#endregion
#region Calendar

View File

@@ -14,7 +14,7 @@ public interface IThemeService : IInitializeAsync
Task<List<AppThemeBase>> GetAvailableThemesAsync();
Task<CustomThemeMetadata> CreateNewCustomThemeAsync(string themeName, string accentColor, byte[] wallpaperData);
Task<List<CustomThemeMetadata>> GetCurrentCustomThemesAsync();
List<string> GetAvailableAccountColors();
Task ApplyCustomThemeAsync(bool isInitializing);
// Settings

View File

@@ -0,0 +1,20 @@
using System.Threading.Tasks;
namespace Wino.Core.Domain.Interfaces;
public interface IThumbnailService
{
/// <summary>
/// Clears the thumbnail cache.
/// </summary>
Task ClearCache();
/// <summary>
/// Gets thumbnail
/// </summary>
/// <param name="email">Address for thumbnail</param>
/// <param name="awaitLoad">Force to wait for thumbnail loading.
/// Should be used in non-UI threads or where delay is acceptable
/// </param>
ValueTask<string> GetThumbnailAsync(string email, bool awaitLoad = false);
}

View File

@@ -56,6 +56,12 @@ public partial class AccountMenuItem : MenuItemBase<MailAccount, MenuItemBase<IM
set => SetProperty(Parameter.Base64ProfilePictureData, value, Parameter, (u, n) => u.Base64ProfilePictureData = n);
}
public string AccountColorHex
{
get => Parameter.AccountColorHex;
set => SetProperty(Parameter.AccountColorHex, value, Parameter, (u, n) => u.AccountColorHex = n);
}
public IEnumerable<MailAccount> HoldingAccounts => new List<MailAccount> { Parameter };
public AccountMenuItem(MailAccount account, IMenuItem parent = null) : base(account, account.Id, parent)
@@ -66,9 +72,11 @@ public partial class AccountMenuItem : MenuItemBase<MailAccount, MenuItemBase<IM
public void UpdateAccount(MailAccount account)
{
Parameter = account;
AccountName = account.Name;
AttentionReason = account.AttentionReason;
Base64ProfilePicture = account.Base64ProfilePictureData;
OnPropertyChanged(nameof(AccountName));
OnPropertyChanged(nameof(Base64ProfilePicture));
OnPropertyChanged(nameof(AccountColorHex));
OnPropertyChanged(nameof(IsAttentionRequired));
if (SubMenuItems == null) return;

View File

@@ -2,4 +2,4 @@
namespace Wino.Core.Domain.Models.Accounts;
public record AccountCreationDialogResult(MailProviderType ProviderType, string AccountName, SpecialImapProviderDetails SpecialImapProviderDetails);
public record AccountCreationDialogResult(MailProviderType ProviderType, string AccountName, SpecialImapProviderDetails SpecialImapProviderDetails, string AccountColorHex);

View File

@@ -0,0 +1,695 @@
{
"AccountAlias_Column_Alias": "Псевдоним",
"AccountAlias_Column_IsPrimaryAlias": "Основен",
"AccountAlias_Column_Verified": "Потвърден",
"AccountAlias_Disclaimer_FirstLine": "Wino може да импортира псевдоними само за вашите акаунти в Gmail.",
"AccountAlias_Disclaimer_SecondLine": "Ако искате да използвате псевдоними за акаунта си в Outlook или IMAP, добавете ги сами.",
"AccountCacheReset_Title": "Нулиране на кеша на акаунта",
"AccountCacheReset_Message": "Този акаунт изисква пълна ресинхронизация, за да продължи да работи. Моля, изчакайте, докато Wino ресинхронизира съобщенията ви...",
"AccountContactNameYou": "Вие",
"AccountCreationDialog_Completed": "всичко е готово",
"AccountCreationDialog_FetchingEvents": "Извличане на събитията от календара.",
"AccountCreationDialog_FetchingProfileInformation": "Извличане на данните за профила.",
"AccountCreationDialog_GoogleAuthHelpClipboardText_Row0": "Ако браузърът ви не се е стартирал автоматично, за да завърши удостоверяването:",
"AccountCreationDialog_GoogleAuthHelpClipboardText_Row1": "1) Щракнете върху бутона по-долу, за да копирате адреса за удостоверяване",
"AccountCreationDialog_GoogleAuthHelpClipboardText_Row2": "2) Стартирайте уеб браузъра си (Edge, Chrome, Firefox и др.)",
"AccountCreationDialog_GoogleAuthHelpClipboardText_Row3": "3) Поставете копирания адрес и отидете на уебсайта, за да завършите удостоверяването ръчно.",
"AccountCreationDialog_Initializing": "инициализиране",
"AccountCreationDialog_PreparingFolders": "В момента получаваме информация за папките.",
"AccountCreationDialog_SigninIn": "Информацията за акаунта се запазва.",
"AccountEditDialog_Message": "Име на акаунта",
"AccountEditDialog_Title": "Редактиране на акаунта",
"AccountPickerDialog_Title": "Изберете акаунт",
"AccountSettingsDialog_AccountName": "Име на подателя",
"AccountSettingsDialog_AccountNamePlaceholder": "напр. Иван Иванов",
"AccountDetailsPage_Title": "Информация за акаунта",
"AccountDetailsPage_Description": "Променете името на акаунта в Wino и задайте желаното име на изпращача.",
"AccountDetailsPage_ColorPicker_Title": "Цвят на акаунта",
"AccountDetailsPage_ColorPicker_Description": "Задайте цвят на акаунта, за да оцветите символа му в списъка.",
"AddHyperlink": "Добавяне",
"AppCloseBackgroundSynchronizationWarningTitle": "Синхронизация на заден план",
"AppCloseStartupLaunchDisabledWarningMessageFirstLine": "Приложението не е настроено да се стартира при стартиране на Windows.",
"AppCloseStartupLaunchDisabledWarningMessageSecondLine": "Това ще доведе до пропускане на известия при рестартиране на компютъра.",
"AppCloseStartupLaunchDisabledWarningMessageThirdLine": "Искате ли да отидете на страницата с настройки на приложението, за да я активирате?",
"AppCloseTerminateBehaviorWarningMessageFirstLine": "Прекратявате Wino Mail и поведението му при затваряне на приложението е настроено на „Прекратяване“.",
"AppCloseTerminateBehaviorWarningMessageSecondLine": "Това ще спре всички фонови синхронизации и известия.",
"AppCloseTerminateBehaviorWarningMessageThirdLine": "Искате ли да отидете в Предпочитания за приложението, за да настроите Wino Mail да работи минимизиран или във фонов режим?",
"AutoDiscoveryProgressMessage": "Търсене на настройки на пощата...",
"BasicIMAPSetupDialog_AdvancedConfiguration": "Разширено конфигуриране",
"BasicIMAPSetupDialog_CredentialLocalMessage": "Вашите идентификационни данни се съхраняват само локално на вашия компютър.",
"BasicIMAPSetupDialog_Description": "Някои акаунти изискват допълнителни стъпки за влизане",
"BasicIMAPSetupDialog_DisplayName": "Показвано име",
"BasicIMAPSetupDialog_DisplayNamePlaceholder": "напр. Иван Иванов",
"BasicIMAPSetupDialog_LearnMore": "Научете повече",
"BasicIMAPSetupDialog_MailAddress": "Адрес на имейл",
"BasicIMAPSetupDialog_MailAddressPlaceholder": "ivanivanov@mail.com",
"BasicIMAPSetupDialog_Password": "Парола",
"BasicIMAPSetupDialog_Title": "IMAP акаунт",
"Busy": "Зает",
"Buttons_AddAccount": "Добавяне на акаунт",
"Buttons_AddNewAlias": "Добавяне на нов псевдоним",
"Buttons_Allow": "Позволяване",
"Buttons_ApplyTheme": "Прилагане на темата",
"Buttons_Browse": "Преглед",
"Buttons_Cancel": "Отказ",
"Buttons_Close": "Затваряне",
"Buttons_Copy": "Копиране",
"Buttons_Create": "Създаване",
"Buttons_CreateAccount": "Създаване на акаунт",
"Buttons_Delete": "Изтриване",
"Buttons_Deny": "Отказване",
"Buttons_Discard": "Отхвърляне",
"Buttons_Edit": "Редактиране",
"Buttons_EnableImageRendering": "Активиране",
"Buttons_Multiselect": "Избор на няколко",
"Buttons_No": "Не",
"Buttons_Open": "Отваряне",
"Buttons_Purchase": "Купете",
"Buttons_RateWino": "Оценете Wino",
"Buttons_Reset": "Нулиране",
"Buttons_Save": "Запазване",
"Buttons_SaveConfiguration": "Запазване на конфигурацията",
"Buttons_Send": "Изпращане",
"Buttons_Share": "Споделяне",
"Buttons_SignIn": "Вход",
"Buttons_Sync": "Синхронизиране",
"Buttons_SyncAliases": "Синхронизиране на псевдонимите",
"Buttons_TryAgain": "Нов опит",
"Buttons_Yes": "Да",
"CalendarAllDayEventSummary": "целодневни събития",
"CalendarDisplayOptions_Color": "Цвят",
"CalendarDisplayOptions_Expand": "Разширяване",
"CalendarItem_DetailsPopup_JoinOnline": "Присъединяване онлайн",
"CalendarItem_DetailsPopup_ViewEventButton": "Преглед на събитието",
"CalendarItem_DetailsPopup_ViewSeriesButton": "Преглед на сериите",
"CalendarItemAllDay": "цял ден",
"CategoriesFolderNameOverride": "Категории",
"Center": "Център",
"ClipboardTextCopied_Message": "{0} е копирано в клипборда.",
"ClipboardTextCopied_Title": "Копирано",
"ClipboardTextCopyFailed_Message": "Неуспешно копиране на {0} в клипборда.",
"ComingSoon": "Очаквайте скоро...",
"ComposerAttachmentsDragDropAttach_Message": "Прикачване",
"ComposerAttachmentsDropZone_Message": "Пуснете файловете си тук",
"ComposerFrom": "От: ",
"ComposerImagesDropZone_Message": "Пуснете изображенията си тук",
"ComposerSubject": "Тема: ",
"ComposerTo": "До: ",
"ComposerToPlaceholder": "натиснете Enter, за да въведете адреси",
"CreateAccountAliasDialog_AliasAddress": "Адрес",
"CreateAccountAliasDialog_AliasAddressPlaceholder": "напр. support@mydomain.com",
"CreateAccountAliasDialog_Description": "Уверете се, че вашият изходящ сървър позволява изпращането на имейли от този псевдоним.",
"CreateAccountAliasDialog_ReplyToAddress": "Адрес за отговор",
"CreateAccountAliasDialog_ReplyToAddressPlaceholder": "admin@mydomain.com",
"CreateAccountAliasDialog_Title": "Създаване на псевдоним на акаунта",
"CustomThemeBuilder_AccentColorDescription": "Задайте персонализиран цвят на акцента, ако желаете. Ако не изберете цвят, ще се използва акцентиращият цвят на Windows.",
"CustomThemeBuilder_AccentColorTitle": "Акцентиращ цвят",
"CustomThemeBuilder_PickColor": "Избор",
"CustomThemeBuilder_ThemeNameDescription": "Уникално име за вашата персонализирана тема.",
"CustomThemeBuilder_ThemeNameTitle": "Име на темата",
"CustomThemeBuilder_Title": "Изграждане на персонализирана тема",
"CustomThemeBuilder_WallpaperDescription": "Задаване на персонализиран тапет за Wino",
"CustomThemeBuilder_WallpaperTitle": "Задаване на персонализиран тапет",
"Dialog_DontAskAgain": "Не питайте отново",
"DialogMessage_AccountLimitMessage": "Достигнали сте лимита за създаване на акаунти.\nИскате ли да закупите добавката „Неограничен акаунт“, за да продължите?",
"DialogMessage_AccountLimitTitle": "Достигнат е лимита на акаунтите",
"DialogMessage_AliasCreatedMessage": "Новият псевдоним е създаден успешно.",
"DialogMessage_AliasCreatedTitle": "Създаден е нов псевдоним",
"DialogMessage_AliasExistsMessage": "Този псевдоним вече се използва.",
"DialogMessage_AliasExistsTitle": "Съществуващ псевдоним",
"DialogMessage_AliasNotSelectedMessage": "Трябва да изберете псевдоним, преди да изпратите съобщение.",
"DialogMessage_AliasNotSelectedTitle": "Липсващ псевдоним",
"DialogMessage_CantDeleteRootAliasMessage": "Основният псевдоним не може да бъде изтрит. Това е основната ви самоличност, свързана с настройката на профила ви.",
"DialogMessage_CantDeleteRootAliasTitle": "Не може да се изтрие псевдонимът",
"DialogMessage_CleanupFolderMessage": "Искате ли да изтриете окончателно всички писма в тази папка?",
"DialogMessage_CleanupFolderTitle": "Почистване на папката",
"DialogMessage_ComposerMissingRecipientMessage": "Съобщението няма получател.",
"DialogMessage_ComposerValidationFailedTitle": "Валидирането е неуспешно",
"DialogMessage_CreateLinkedAccountMessage": "Дайте име на тази нова връзка. Акаунтите ще бъдат обединени под това име.",
"DialogMessage_CreateLinkedAccountTitle": "Име на връзката с акаунта",
"DialogMessage_DeleteAccountConfirmationMessage": "Изтриване на {0}?",
"DialogMessage_DeleteAccountConfirmationTitle": "Всички данни, свързани с този акаунт, ще бъдат изтрити от диска за постоянно.",
"DialogMessage_DiscardDraftConfirmationMessage": "Тази чернова ще бъде отхвърлена. Искате ли да продължите?",
"DialogMessage_DiscardDraftConfirmationTitle": "Отхвърляне на черновата",
"DialogMessage_EmptySubjectConfirmation": "Липсваща тема",
"DialogMessage_EmptySubjectConfirmationMessage": "Съобщението няма тема. Искате ли да продължите?",
"DialogMessage_EnableStartupLaunchDeniedMessage": "Можете да активирате автоматично стартиране от Настройки -> Предпочитания за приложението.",
"DialogMessage_EnableStartupLaunchMessage": "Позволете на Wino Mail да се стартира автоматично минимизиран при стартиране на Windows, за да не пропускате никакви известия.\n\nИскате ли да разрешите автоматичното стартиране?",
"DialogMessage_EnableStartupLaunchTitle": "Активиране на автоматичното стартиране",
"DialogMessage_HardDeleteConfirmationMessage": "Окончателно изтриване",
"DialogMessage_HardDeleteConfirmationTitle": "Съобщението/ята ще бъдат изтрити за постоянно. Искате ли да продължите?",
"DialogMessage_InvalidAliasMessage": "Този псевдоним не е валиден. Уверете се, че всички адреси от псевдонима са валидни имейл адреси.",
"DialogMessage_InvalidAliasTitle": "Невалиден псевдоним",
"DialogMessage_NoAccountsForCreateMailMessage": "Нямате акаунти, от които да създадете съобщение.",
"DialogMessage_NoAccountsForCreateMailTitle": "Липсва акаунт",
"DialogMessage_PrintingFailedMessage": "Неуспешно отпечатване на този имейл. Резултат: {0}",
"DialogMessage_PrintingFailedTitle": "Неуспешно",
"DialogMessage_PrintingSuccessMessage": "Имейлът се изпраща към принтера.",
"DialogMessage_PrintingSuccessTitle": "Успешно",
"DialogMessage_RenameFolderMessage": "Въведете ново име за тази папка",
"DialogMessage_RenameFolderTitle": "Преименуване на папката",
"DialogMessage_RenameLinkedAccountsMessage": "Въведете ново име за свързания акаунт",
"DialogMessage_RenameLinkedAccountsTitle": "Преименуване на свързания акаунт",
"DialogMessage_UnlinkAccountsConfirmationMessage": "Тази операция няма да доведе до изтриване на акаунтите ви, а само до прекъсване на връзката към споделените папки. Искате ли да продължите?",
"DialogMessage_UnlinkAccountsConfirmationTitle": "Премахване на връзката между акаунтите",
"DialogMessage_UnsubscribeConfirmationGoToWebsiteConfirmButton": "Към уебсайта",
"DialogMessage_UnsubscribeConfirmationGoToWebsiteMessage": "За да спрете да получавате съобщения от {0}, отидете на техния уебсайт, за да се отпишете.",
"DialogMessage_UnsubscribeConfirmationMailtoMessage": "Искате ли да спрете да получавате съобщения от {0}? Wino ще се откаже от абонамента вместо вас, като изпрати имейл от вашия имейл акаунт до {1}.",
"DialogMessage_UnsubscribeConfirmationOneClickMessage": "Искате ли да спрете да получавате съобщения от {0}?",
"DialogMessage_UnsubscribeConfirmationTitle": "Отписване",
"DiscordChannelDisclaimerMessage": "Wino няма собствен сървър в Discord, но специалният канал 'wino-mail' се хоства на сървъра „Developer Sanctuary“.\nЗа да получавате актуализации за Wino, моля, присъединете се към сървъра Developer Sanctuary и следвайте канала „wino-mail“ в „Community Projects“.\n\nЩе бъдете пренасочени към URL адреса на сървъра, тъй като Discord не поддържа покани за канали.",
"DiscordChannelDisclaimerTitle": "Важна информация за Discord",
"Draft": "Чернова",
"DragMoveToFolderCaption": "Преместване в {0}",
"EditorToolbarOption_Draw": "Рисуване",
"EditorToolbarOption_Format": "Форматиране",
"EditorToolbarOption_Insert": "Вмъкване",
"EditorToolbarOption_None": "Няма",
"EditorToolbarOption_Options": "Опции",
"EditorTooltip_WebViewEditor": "Използване на редактор в уеб изглед",
"ElementTheme_Dark": "Тъмен режим",
"ElementTheme_Default": "Използване на системната настройка",
"ElementTheme_Light": "Светъл режим",
"Emoji": "Емотикони",
"Error_FailedToSetupSystemFolders_Title": "Неуспешна настройка на системните папки",
"Exception_AuthenticationCanceled": "Удостоверяването е отменено",
"Exception_CustomThemeExists": "Тази тема вече съществува.",
"Exception_CustomThemeMissingName": "Трябва да посочите име.",
"Exception_CustomThemeMissingWallpaper": "Трябва да предоставите персонализирано фоново изображение.",
"Exception_FailedToSynchronizeAliases": "Неуспешно синхронизиране на псевдонимите",
"Exception_FailedToSynchronizeFolders": "Неуспешно синхронизиране на папките",
"Exception_FailedToSynchronizeProfileInformation": "Неуспешно синхронизиране на информацията за профила",
"Exception_GoogleAuthCallbackNull": "Callback uri е празенl при активиране.",
"Exception_GoogleAuthCorruptedCode": "Повреден отговор за упълномощаване.",
"Exception_GoogleAuthError": "Грешка при оторизацията на OAuth: {0}",
"Exception_GoogleAuthInvalidResponse": "Получена заявка с невалидно състояние ({0})",
"Exception_GoogleAuthorizationCodeExchangeFailed": "Обменът на код за упълномощаване е неуспешен.",
"Exception_ImapAutoDiscoveryFailed": "Не могат да се намерят настройките на пощенската кутия.",
"Exception_ImapClientPoolFailed": "IMAP Client Pool се провали.",
"Exception_InboxNotAvailable": "Не може да се настроят папките на акаунта.",
"Exception_InvalidSystemFolderConfiguration": "Конфигурацията на системната папка не е валидна. Проверете конфигурацията и опитайте отново.",
"Exception_InvalidMultiAccountMoveTarget": "Не можете да премествате няколко елемента, които принадлежат на различни акаунти, в свързан акаунт.",
"Exception_MailProcessing": "Тази поща все още се обработва. Моля, опитайте отново след няколко секунди.",
"Exception_MissingAlias": "За този акаунт не съществува първичен псевдоним. Създаването на чернова е неуспешно.",
"Exception_NullAssignedAccount": "Присвоеният акаунт е нулев",
"Exception_NullAssignedFolder": "Присвоената папка е нулева",
"Exception_SynchronizerFailureHTTP": "Обработката на отговора е неуспешна с грешка HTTP код {0}",
"Exception_TokenGenerationFailed": "Неуспешно генериране на токен",
"Exception_TokenInfoRetrivalFailed": "Не се получи информация за токена.",
"Exception_UnknowErrorDuringAuthentication": "Възникна неизвестна грешка по време на удостоверяването",
"Exception_UnsupportedAction": "Действието {0} не е внедрено в процесора за обработка на заявки",
"Exception_UnsupportedProvider": "Този доставчик не се поддържа.",
"Exception_UnsupportedSynchronizerOperation": "Тази операция не се поддържа за {0}",
"Exception_UserCancelSystemFolderSetupDialog": "Диалогът за конфигуриране на системната папка е отменен от потребителя.",
"Exception_WinoServerException": "Сървърът на Wino е неуспешен.",
"Files": "Файлове",
"FilteringOption_All": "Всички",
"FilteringOption_Files": "Съдържа файлове",
"FilteringOption_Flagged": "Отбелязани",
"FilteringOption_Unread": "Непрочетени",
"Focused": "На фокус",
"FolderOperation_CreateSubFolder": "Създаване на подпапка",
"FolderOperation_Delete": "Изтриване",
"FolderOperation_DontSync": "Да не се синхронизира тази папка",
"FolderOperation_Empty": "Изпразване на тази папка",
"FolderOperation_MarkAllAsRead": "Маркиране на всички като прочетени",
"FolderOperation_Move": "Преместване",
"FolderOperation_None": "Няма",
"FolderOperation_Pin": "Фиксиране",
"FolderOperation_Rename": "Преименуване",
"FolderOperation_Unpin": "Освобождаване",
"GeneralTitle_Error": "Грешка",
"GeneralTitle_Info": "Информация",
"GeneralTitle_Warning": "Внимание",
"GmailServiceDisabled_Title": "Грешка в Gmail",
"GmailServiceDisabled_Message": "Вашият акаунт в Google Workspace изглежда е деактивиран за услугата Gmail. Моля, свържете се с вашия администратор, за да активира услугата Gmail за вашия акаунт.",
"GmailArchiveFolderNameOverride": "Архив",
"HoverActionOption_Archive": "Архивиране",
"HoverActionOption_Delete": "Изтриване",
"HoverActionOption_MoveJunk": "Преместване в Нежелани",
"HoverActionOption_ToggleFlag": "Отбелязване / Без отбелязване",
"HoverActionOption_ToggleRead": "Прочетено / Непрочетено",
"ImageRenderingDisabled": "Показването на изображения е деактивирано за това съобщение.",
"ImapAdvancedSetupDialog_AuthenticationMethod": "Метод за удостоверяване",
"ImapAdvancedSetupDialog_ConnectionSecurity": "Сигурност на връзката",
"IMAPAdvancedSetupDialog_ValidationAuthMethodRequired": "Изисква се метод за удостоверяване",
"IMAPAdvancedSetupDialog_ValidationConnectionSecurityRequired": "Изисква се тип сигурност на връзката",
"IMAPAdvancedSetupDialog_ValidationDisplayNameRequired": "Изисква се показвано име",
"IMAPAdvancedSetupDialog_ValidationEmailInvalid": "Моля, въведете валиден имейл адрес",
"IMAPAdvancedSetupDialog_ValidationEmailRequired": "Изисква се имейл адрес",
"IMAPAdvancedSetupDialog_ValidationErrorTitle": "Моля, проверете следното:",
"IMAPAdvancedSetupDialog_ValidationIncomingPortInvalid": "Входящият порт трябва да е между 1-65535",
"IMAPAdvancedSetupDialog_ValidationIncomingPortRequired": "Изисква се порт на входящия сървър",
"IMAPAdvancedSetupDialog_ValidationIncomingServerRequired": "Изисква се адрес на входящия сървър",
"IMAPAdvancedSetupDialog_ValidationOutgoingPasswordRequired": "Изисква се парола на изходящия сървър",
"IMAPAdvancedSetupDialog_ValidationOutgoingPortInvalid": "Изходящият порт трябва да е между 1-65535",
"IMAPAdvancedSetupDialog_ValidationOutgoingPortRequired": "Изисква се порт на изходящия сървър",
"IMAPAdvancedSetupDialog_ValidationOutgoingServerRequired": "Изисква се адрес на изходящия сървър",
"IMAPAdvancedSetupDialog_ValidationOutgoingUsernameRequired": "Изисква се потребителско име на изходящия сървър",
"IMAPAdvancedSetupDialog_ValidationPasswordRequired": "Изисква се парола",
"IMAPAdvancedSetupDialog_ValidationUsernameRequired": "Изисква се потребителско име",
"ImapAuthenticationMethod_Auto": "Автоматично",
"ImapAuthenticationMethod_CramMD5": "CRAM-MD5",
"ImapAuthenticationMethod_DigestMD5": "DIGEST-MD5",
"ImapAuthenticationMethod_EncryptedPassword": "Криптирана парола",
"ImapAuthenticationMethod_None": "Без удостоверяване",
"ImapAuthenticationMethod_Ntlm": "NTLM",
"ImapAuthenticationMethod_Plain": "Нормална парола",
"ImapConnectionSecurity_Auto": "Автоматично",
"ImapConnectionSecurity_None": "Няма",
"ImapConnectionSecurity_SslTls": "SSL/TLS",
"ImapConnectionSecurity_StartTls": "STARTTLS",
"IMAPSetupDialog_AccountType": "Тип на акаунта",
"IMAPSetupDialog_ValidationSuccess_Title": "Успешно",
"IMAPSetupDialog_ValidationSuccess_Message": "Успешно валидиране",
"IMAPSetupDialog_ValidationFailed_Title": "Неуспешно валидиране на IMAP сървъра.",
"IMAPSetupDialog_CertificateAllowanceRequired_Row0": "Този сървър изисква установяване на защитена SSL връзка, за да продължи. Моля, потвърдете данните за сертификата по-долу.",
"IMAPSetupDialog_CertificateAllowanceRequired_Row1": "Разрешете защитената връзка, за да продължите да настройвате акаунта си.",
"IMAPSetupDialog_CertificateDenied": "Потребителят не е разрешил защитената връзка със сертификата.",
"IMAPSetupDialog_CertificateIssuer": "Издател",
"IMAPSetupDialog_CertificateSubject": "Тема",
"IMAPSetupDialog_CertificateValidFrom": "Валиден от",
"IMAPSetupDialog_CertificateValidTo": "Валиден до",
"IMAPSetupDialog_CertificateView": "Преглед на сертификата",
"IMAPSetupDialog_ConnectionFailedMessage": "Връзката с IMAP е неуспешна.",
"IMAPSetupDialog_ConnectionFailedTitle": "Връзката е неуспешна",
"IMAPSetupDialog_DisplayName": "Показвано име",
"IMAPSetupDialog_DisplayNamePlaceholder": "напр. Иван Иванов",
"IMAPSetupDialog_IncomingMailServer": "Сървър за входяща поща",
"IMAPSetupDialog_IncomingMailServerPort": "Порт",
"IMAPSetupDialog_IMAPSettings": "Настройки на IMAP сървъра",
"IMAPSetupDialog_SMTPSettings": "Настройки на SMTP сървъра",
"IMAPSetupDialog_MailAddress": "Имейл адрес",
"IMAPSetupDialog_MailAddressPlaceholder": "nyakoy@primer.com",
"IMAPSetupDialog_OutgoingMailServer": "Сървър за изходяща поща (SMTP)",
"IMAPSetupDialog_OutgoingMailServerPassword": "Парола на изходящия сървър",
"IMAPSetupDialog_OutgoingMailServerPort": "Порт",
"IMAPSetupDialog_OutgoingMailServerRequireAuthentication": "Изходящият сървър изисква удостоверяване",
"IMAPSetupDialog_OutgoingMailServerUsername": "Потребителско име на изходящия сървър",
"IMAPSetupDialog_Password": "Парола",
"IMAPSetupDialog_RequireSSLForIncomingMail": "Изисква SSL за входящата поща",
"IMAPSetupDialog_RequireSSLForOutgoingMail": "Изисква SSL за изходящата поща",
"IMAPSetupDialog_Title": "Разширено конфигуриране на IMAP",
"IMAPSetupDialog_Username": "Потребител",
"IMAPSetupDialog_UsernamePlaceholder": "ivanivanov, ivanivanov@primer.com, domain/ivanivanov",
"IMAPSetupDialog_UseSameConfig": "Използване на същото потребителско име и парола за изпращане на имейли",
"Info_AccountCreatedMessage": "{0} е създаден",
"Info_AccountCreatedTitle": "Създаване на акаунт",
"Info_AccountCreationFailedTitle": "Неуспешно създаване на акаунт",
"Info_AccountDeletedMessage": "{0} е изтрит успешно.",
"Info_AccountDeletedTitle": "Акаунтът е изтрит",
"Info_AccountIssueFixFailedTitle": "Неуспешно",
"Info_AccountIssueFixSuccessMessage": "Отстранени са всички проблеми с акаунтите.",
"Info_AccountIssueFixSuccessTitle": "Успешно",
"Info_AttachmentOpenFailedMessage": "Не може да се отвори този прикачен файл.",
"Info_AttachmentOpenFailedTitle": "Неуспешно",
"Info_AttachmentSaveFailedMessage": "Не може да се запази този прикачен файл.",
"Info_AttachmentSaveFailedTitle": "Неуспешно",
"Info_AttachmentSaveSuccessMessage": "Прикаченият файл е запазен.",
"Info_AttachmentSaveSuccessTitle": "Запазен прикачен файл",
"Info_BackgroundExecutionDeniedMessage": "Изпълнението на приложението на заден план е отказано. Това може да повлияе на синхронизацията на заден план и известията в реално време.",
"Info_BackgroundExecutionDeniedTitle": "Отказано изпълнение на задан план",
"Info_BackgroundExecutionUnknownErrorMessage": "Възникна неизвестно изключение при регистриране на синхронизатора на заден план.",
"Info_BackgroundExecutionUnknownErrorTitle": "Неуспешно изпълнение на заден план",
"Info_CantDeletePrimaryAliasMessage": "Основният псевдоним не може да бъде изтрит. Моля, променете псевдонима си, преди да изтриете този",
"Info_ComposerMissingMIMEMessage": "MIME файлът не можа да се намери. Синхронизирането може да помогне.",
"Info_ComposerMissingMIMETitle": "Неуспешно",
"Info_ContactExistsMessage": "Този контакт вече е в списъка с получатели.",
"Info_ContactExistsTitle": "Контактът съществува",
"Info_DraftFolderMissingMessage": "За този акаунт липсва папка Чернови. Моля, проверете настройките на акаунта си.",
"Info_DraftFolderMissingTitle": "Липсва папка Чернови",
"Info_FailedToOpenFileMessage": "Файлът може да бъде премахнат от диска.",
"Info_FailedToOpenFileTitle": "Неуспешно стартиране на файла.",
"Info_FileLaunchFailedTitle": "Неуспешно стартиране на файла",
"Info_InvalidAddressMessage": "„{0}“ не е валиден имейл адрес.",
"Info_InvalidAddressTitle": "Невалиден адрес",
"Info_InvalidMoveTargetMessage": "Не можете да преместите избраните писма в тази папка.",
"Info_InvalidMoveTargetTitle": "Невалидна цел за преместване",
"Info_LogsNotFoundMessage": "Няма дневници за споделяне.",
"Info_LogsNotFoundTitle": "Дневниците не са намерени",
"Info_LogsSavedMessage": "{0} се запазва в избраната папка.",
"Info_LogsSavedTitle": "Запазено",
"Info_MailListSizeResetSuccessMessage": "Размерът на пощенския списък е нулиран.",
"Info_MailRenderingFailedMessage": "Тази поща е повредена или не може да бъде отворена.\n{0}",
"Info_MailRenderingFailedTitle": "Неуспешно визуализиране",
"Info_MessageCorruptedMessage": "Това съобщение е повредено.",
"Info_MessageCorruptedTitle": "Грешка",
"Info_MissingFolderMessage": "{0} не съществува за този акаунт.",
"Info_MissingFolderTitle": "Липсваща папка",
"Info_PDFSaveFailedTitle": "Неуспешно записване на PDF файл",
"Info_PDFSaveSuccessMessage": "PDF файлът е записан в {0}",
"Info_PDFSaveSuccessTitle": "Успешно",
"Info_PurchaseExistsMessage": "Изглежда, че този продукт вече е бил закупен преди.",
"Info_PurchaseExistsTitle": "Съществуващ продукт",
"Info_PurchaseThankYouMessage": "Благодарим ви",
"Info_PurchaseThankYouTitle": "Покупката е успешна",
"Info_RequestCreationFailedTitle": "Неуспешно създаване на заявки",
"Info_ReviewNetworkErrorMessage": "Имаше мрежов проблем с прегледа ви.",
"Info_ReviewNetworkErrorTitle": "Мрежов проблем",
"Info_ReviewNewMessage": "Оценяваме всички отзиви. Благодарим ви за прегледа!",
"Info_ReviewSuccessTitle": "Благодарим ви",
"Info_ReviewUnknownErrorMessage": "Имаше неизвестен проблем с прегледа ви. ({0})",
"Info_ReviewUnknownErrorTitle": "Неизвестна грешка",
"Info_ReviewUpdatedMessage": "Благодарим ви за актуализирания преглед.",
"Info_SignatureDisabledMessage": "Деактивиран подпис за този акаунт",
"Info_SignatureDisabledTitle": "Успешно",
"Info_SignatureSavedMessage": "Новият подпис се запазва",
"Info_SignatureSavedTitle": "Успешно",
"Info_SyncCanceledMessage": "Отменено",
"Info_SyncCanceledTitle": "Синхронизиране",
"Info_SyncFailedTitle": "Неуспешна синхронизация",
"Info_UnsubscribeErrorMessage": "Неуспешно отписване",
"Info_UnsubscribeLinkInvalidMessage": "Тази връзка за отписване е невалидна. Неуспешно отписване от списъка.",
"Info_UnsubscribeLinkInvalidTitle": "Невалиден Uri за отписване",
"Info_UnsubscribeSuccessMessage": "Успешно се отписахте от {0}.",
"Info_UnsupportedFunctionalityDescription": "Тази функционалност все още не е реализирана.",
"Info_UnsupportedFunctionalityTitle": "Не се поддържа",
"InfoBarAction_Enable": "Активиране",
"InfoBarMessage_SynchronizationDisabledFolder": "Синхронизирането на тази папка е деактивирано.",
"InfoBarTitle_SynchronizationDisabledFolder": "Изключена папка",
"Justify": "Двустранно",
"Left": "Ляво",
"Link": "Връзка",
"LinkedAccountsCreatePolicyMessage": "Трябва да имате поне 2 акаунта, за да създадете връзка.\nВръзката ще бъде премахната при запазване.",
"LinkedAccountsTitle": "Свързани акаунти",
"MailItemNoSubject": "Без тема",
"MailOperation_AlwaysMoveFocused": "Винаги да се преместват в На фокус",
"MailOperation_AlwaysMoveOther": "Винаги да се преместват в Други",
"MailOperation_Archive": "Архивиране",
"MailOperation_ClearFlag": "Без отбелязване",
"MailOperation_DarkEditor": "Тъмна",
"MailOperation_Delete": "Изтриване",
"MailOperation_ExportPDF": "Експортиране в PDF",
"MailOperation_Find": "Намиране",
"MailOperation_Forward": "Препращане",
"MailOperation_Ignore": "Игнориране",
"MailOperation_LightEditor": "Светла",
"MailOperation_MarkAsJunk": "Маркиране като нежелано",
"MailOperation_MarkAsRead": "Маркиране като прочетено",
"MailOperation_MarkAsUnread": "Маркиране като непрочетено",
"MailOperation_MarkNotJunk": "Не е нежелано",
"MailOperation_Move": "Преместване",
"MailOperation_MoveFocused": "Преместване в На фокус",
"MailOperation_MoveJunk": "Преместване в Нежелани",
"MailOperation_MoveOther": "Преместване в Други",
"MailOperation_Navigate": "Отиване",
"MailOperation_Print": "Отпечатване",
"MailOperation_Reply": "Отговор",
"MailOperation_ReplyAll": "Отговор на всички",
"MailOperation_SaveAs": "Запазване като",
"MailOperation_SetFlag": "Отбелязване",
"MailOperation_Unarchive": "Разархивиране",
"MailOperation_ViewMessageSource": "Преглед на изходния код",
"MailOperation_Zoom": "Мащаб",
"MailsSelected": "{0} избран(и) елемент(и)",
"MarkFlagUnflag": "Отбелязано/Без отбелязване",
"MarkReadUnread": "Маркиране като прочетено/непрочетено",
"MenuManageAccounts": "Управление на акаунтите",
"MenuMergedAccountItemAccountsSuffix": " акаунти",
"MenuNewMail": "Нов имейл",
"MenuRate": "Оценете Wino",
"MenuSettings": "Настройки",
"MergedAccountCommonFolderArchive": "Архив",
"MergedAccountCommonFolderDraft": "Чернова",
"MergedAccountCommonFolderInbox": "Входящи",
"MergedAccountCommonFolderJunk": "Нежелани",
"MergedAccountCommonFolderSent": "Изпратени",
"MergedAccountCommonFolderTrash": "Изтрити",
"MergedAccountsAvailableAccountsTitle": "Налични акаунти",
"MessageSourceDialog_Title": "Източник на съобщението",
"More": "Още",
"MoreFolderNameOverride": "Още",
"MoveMailDialog_InvalidFolderMessage": "{0} не е валидна папка за тази поща.",
"MoveMailDialog_Title": "Изберете папка",
"NewAccountDialog_AccountName": "Име на акаунта",
"NewAccountDialog_AccountNameDefaultValue": "Личен",
"NewAccountDialog_AccountNamePlaceholder": "напр. Лична поща",
"NewAccountDialog_Title": "Добавяне на нов акаунт",
"NoMailSelected": "Не е избрано съобщение",
"NoMessageCrieteria": "Няма съобщения, които да отговарят на критериите ви за търсене",
"NoMessageEmptyFolder": "Тази папка е празна",
"Notifications_MultipleNotificationsMessage": "Имате {0} нови съобщения.",
"Notifications_MultipleNotificationsTitle": "Нов имейл",
"Notifications_WinoUpdatedMessage": "Вижте новата версия {0}",
"Notifications_WinoUpdatedTitle": "Wino Mail е актуализиран.",
"OnlineSearchFailed_Message": "Неуспешно търсене\n{0}\n\nПоказване на офлайн имейли.",
"OnlineSearchTry_Line1": "Не можете да намерите това, което търсите?",
"OnlineSearchTry_Line2": "Опитайте онлайн търсене.",
"Other": "Друго",
"PaneLengthOption_Default": "По подразбиране",
"PaneLengthOption_ExtraLarge": "Много голям",
"PaneLengthOption_Large": "Голям",
"PaneLengthOption_Medium": "Среден",
"PaneLengthOption_Micro": "Много малък",
"PaneLengthOption_Small": "Малък",
"Photos": "Снимки",
"PreparingFoldersMessage": "Подготовка на папките",
"ProtocolLogAvailable_Message": "Протоколните дневници са достъпни за диагностика.",
"ProviderDetail_Gmail_Description": "Акаунт в Google",
"ProviderDetail_iCloud_Description": "Акаунт в Apple iCloud",
"ProviderDetail_iCloud_Title": "iCloud",
"ProviderDetail_IMAP_Description": "Потребителски IMAP/SMTP сървър",
"ProviderDetail_IMAP_Title": "IMAP сървър",
"ProviderDetail_Yahoo_Description": "Акаунт в Yahoo",
"ProviderDetail_Yahoo_Title": "Yahoo Mail",
"QuickEventDialog_EventName": "Име на събитието",
"QuickEventDialog_IsAllDay": "Цял ден",
"QuickEventDialog_Location": "Местоположение",
"QuickEventDialog_RemindMe": "Напомнете ми",
"QuickEventDialogMoreDetailsButtonText": "Повече подробности",
"Reader_SaveAllAttachmentButtonText": "Запазване на всички прикачени файлове",
"Results": "Резултати",
"Right": "Дясно",
"SearchBarPlaceholder": "Търсене",
"SearchingIn": "Търсене в",
"SearchPivotName": "Резултати",
"SettingConfigureSpecialFolders_Button": "Конфигуриране",
"SettingsEditAccountDetails_IMAPConfiguration_Title": "Конфигурация на IMAP/SMTP",
"SettingsEditAccountDetails_IMAPConfiguration_Description": "Променете настройките на входящия/изходящия сървър.",
"SettingsAbout_Description": "Научете повече за Wino.",
"SettingsAbout_Title": "За приложението",
"SettingsAboutGithub_Description": "Към хранилището на GitHub за проследяване на проблеми.",
"SettingsAboutGithub_Title": "GitHub",
"SettingsAboutVersion": "Версия ",
"SettingsAboutWinoDescription": "Лек пощенски клиент за семейства устройства с Windows.",
"SettingsAccentColor_Description": "Промяна на цвета на акцента в приложението",
"SettingsAccentColor_Title": "Цвят на акцента",
"SettingsAccentColor_UseWindowsAccentColor": "Използване на акцентния цвят на Windows",
"SettingsAccountManagementAppendMessage_Description": "Създаване на копие на съобщението в папка „Изпратени“ след изпращане на черновата. Включете това, ако не виждате писмата си след изпращането им в папка „Изпратени“.",
"SettingsAccountManagementAppendMessage_Title": "Добавяне на съобщенията в папка „Изпратени“",
"SettingsAccountName_Description": "Промяна на името на акаунта.",
"SettingsAccountName_Title": "Име на акаунта",
"SettingsApplicationTheme_Description": "Персонализирайте Wino с различни потребителски теми за приложението, които ви харесват.",
"SettingsApplicationTheme_Title": "Тема на приложението",
"SettingsAppPreferences_CloseBehavior_Description": "Какво да се случи, когато затворите приложението?",
"SettingsAppPreferences_CloseBehavior_Title": "Поведение при затваряне на приложението",
"SettingsAppPreferences_Description": "Общи настройки / предпочитания за Wino Mail.",
"SettingsAppPreferences_SearchMode_Description": "Задайте дали Wino да проверява първо получените писма при търсене или да попита вашия пощенски сървър онлайн. Местното търсене винаги е по-бързо и винаги можете да направите онлайн търсене, ако вашата поща не е в резултатите.",
"SettingsAppPreferences_SearchMode_Local": "Локално",
"SettingsAppPreferences_SearchMode_Online": "Онлайн",
"SettingsAppPreferences_SearchMode_Title": "Режим на търсене по подразбиране",
"SettingsAppPreferences_ServerBackgroundingMode_Invisible_Description": "Wino Mail ще продължи да работи на заден план. Ще бъдете уведомявани за пристигането на нови имейли.",
"SettingsAppPreferences_ServerBackgroundingMode_Invisible_Title": "Работа на заден план",
"SettingsAppPreferences_ServerBackgroundingMode_MinimizeTray_Description": "Wino Mail ще продължи да работи в системната област. Можете да го стартирате, като щракнете върху иконата. Ще бъдете уведомявани при пристигането на нови имейли.",
"SettingsAppPreferences_ServerBackgroundingMode_MinimizeTray_Title": "Минимизиране в системната област",
"SettingsAppPreferences_ServerBackgroundingMode_Terminate_Description": "Wino Mail няма да продължи да работи никъде. Няма да бъдете уведомявани за пристигането на нови имейли. Стартирайте отново Wino Mail, за да продължите синхронизирането на пощата.",
"SettingsAppPreferences_ServerBackgroundingMode_Terminate_Title": "Прекратяване",
"SettingsAppPreferences_StartupBehavior_Description": "Позволете на Wino Mail да се стартира минимизиран при стартиране на Windows. Винаги разрешавайте да получава известия.",
"SettingsAppPreferences_StartupBehavior_Disable": "Деактивиране",
"SettingsAppPreferences_StartupBehavior_Disabled": "Wino Mail няма да се стартира при стартиране на Windows. Това ще доведе до пропускане на известия при рестартиране на компютъра.",
"SettingsAppPreferences_StartupBehavior_DisabledByPolicy": "Вашият администратор или групови политики са забранили стартирането на приложения при начално стартиране. Поради това Wino Mail не може да бъде настроен да се стартира при стартиране на Windows.",
"SettingsAppPreferences_StartupBehavior_DisabledByUser": "Моля, отидете в Мениджър на задачите -> раздел Автоматично стартиращи се приложения, за да разрешите на Wino Mail да се стартира при стартиране на Windows.",
"SettingsAppPreferences_StartupBehavior_Enable": "Активиране",
"SettingsAppPreferences_StartupBehavior_Enabled": "Wino Mail е настроен успешно да се стартира на заден план при стартиране на Windows.",
"SettingsAppPreferences_StartupBehavior_FatalError": "Възникна фатална грешка при промяна на режима на стартиране на Wino Mail.",
"SettingsAppPreferences_StartupBehavior_Title": "Стартиране в минимизиран вид при стартиране на Windows",
"SettingsAppPreferences_Title": "Предпочитания за приложението",
"SettingsAutoSelectNextItem_Description": "Избиране на следващия елемент, след като изтриете или преместите имейл.",
"SettingsAutoSelectNextItem_Title": "Автоматично избиране на следващия елемент",
"SettingsAvailableThemes_Description": "Изберете тема от собствената колекция на Wino по ваш вкус или приложете свои собствени теми.",
"SettingsAvailableThemes_Title": "Налични теми",
"SettingsCalendarSettings_Description": "Променете първия ден от седмицата, височината на часовата клетка и други...",
"SettingsCalendarSettings_Title": "Настройки на календара",
"SettingsComposer_Title": "Съставяне",
"SettingsComposerFont_Title": "Шрифт по подразбиране за съставяне",
"SettingsComposerFontFamily_Description": "Промяна на шрифтовото семейство и размера на шрифта по подразбиране за съставяне на имейли.",
"SettingsConfigureSpecialFolders_Description": "Задаване на папки със специални функции. Папки като Архив, Входящи и Чернови са от съществено значение за правилното функциониране на Wino.",
"SettingsConfigureSpecialFolders_Title": "Конфигуриране на системните папки",
"SettingsCustomTheme_Description": "Създайте своя собствена тема с персонализиран тапет и цвят на акцента.",
"SettingsCustomTheme_Title": "Потребителска тема",
"SettingsDeleteAccount_Description": "Изтриване на всички имейли и идентификационни данни, свързани с този акаунт.",
"SettingsDeleteAccount_Title": "Изтриване на този акаунт",
"SettingsDeleteProtection_Description": "Трябва ли Wino да ви пита за потвърждение всеки път, когато се опитвате да изтриете окончателно имейл с клавишите Shift + Del?",
"SettingsDeleteProtection_Title": "Защита от окончателно изтриване",
"SettingsDiagnostics_Description": "За разработчици",
"SettingsDiagnostics_DiagnosticId_Description": "Споделете този идентификационен номер с разработчиците, когато ви помолят, за да получите помощ за проблемите, с които се сблъсквате в Wino Mail.",
"SettingsDiagnostics_DiagnosticId_Title": "Идентификатор за диагностика",
"SettingsDiagnostics_Title": "Диагностика",
"SettingsDiscord_Description": "Получавайте редовно актуализации за разработката, включвайте се в обсъждания на пътната карта и предоставяйте обратна връзка.",
"SettingsDiscord_Title": "Канал в Discord",
"SettingsEditLinkedInbox_Description": "Добавяне/премахване на акаунти, преименуване или прекъсване на връзката между акаунтите.",
"SettingsEditLinkedInbox_Title": "Редактиране на свързаната входяща поща",
"SettingsElementTheme_Description": "Избор на тема на Windows за Wino",
"SettingsElementTheme_Title": "Цветови режим",
"SettingsElementThemeSelectionDisabled": "Изборът на цветови режим е забранен, когато е избрана тема на приложението, различна от тази по подразбиране.",
"SettingsEnableHoverActions_Title": "Активиране на действията при поставяне на курсора",
"SettingsEnableIMAPLogs_Description": "Активирайте тази опция, за да предоставите подробна информация за проблемите със свързаността на IMAP, които сте имали по време на настройката на IMAP сървъра.",
"SettingsEnableIMAPLogs_Title": "Активиране на дневниците на IMAP протокола",
"SettingsEnableLogs_Description": "Може да ми трябват дневниците за сривове, за да диагностицирам проблемите, които сте открили в GitHub. Нито един от дневниците няма да разкрие публично вашите идентификационни данни или чувствителна информация.",
"SettingsEnableLogs_Title": "Активиране на дневниците",
"SettingsEnableSignature": "Активиране на подписа",
"SettingsExpandOnStartup_Description": "Задайте дали Wino да разгръща папките на този акаунт при стартиране.",
"SettingsExpandOnStartup_Title": "Разгръщане на менюто при стартиране",
"SettingsExternalContent_Description": "Управление на настройките за външно съдържание при визуализиране на имейли.",
"SettingsExternalContent_Title": "Външно съдържание",
"SettingsFocusedInbox_Description": "Задайте дали входящата поща да бъде разделена на две като На фокус - Други.",
"SettingsFocusedInbox_Title": "Входящи на фокус",
"SettingsFolderMenuStyle_Description": "Промяна на това дали папките на акаунта трябва да са вложени в менюто на акаунта или не. Изключете тази опция, ако ви харесва старата система на менютата в Поща на Windows",
"SettingsFolderMenuStyle_Title": "Създаване на вложени папки",
"SettingsFolderOptions_Description": "Промяна настройките на отделните папки, като например разрешаване/забрана на синхронизацията или показване/скриване на значката за непрочетените.",
"SettingsFolderOptions_Title": "Конфигурация на папките",
"SettingsFolderSync_Description": "Активиране или деактивиране синхронизирането на определени папки.",
"SettingsFolderSync_Title": "Синхронизиране на папките",
"SettingsFontFamily_Title": "Семейство шрифтове",
"SettingsFontPreview_Title": "Преглед",
"SettingsFontSize_Title": "Размер на шрифта",
"SettingsHoverActionCenter": "Централно действие",
"SettingsHoverActionLeft": "Ляво действие",
"SettingsHoverActionRight": "Дясно действие",
"SettingsHoverActions_Description": "Изберете 3 действия, които да се показват при преминаване с курсора над имейлите.",
"SettingsHoverActions_Title": "Действия при преминаване с мишката",
"SettingsLanguage_Description": "Промяна на езика за показване на Wino.",
"SettingsLanguage_Title": "Език на показване",
"SettingsLanguageTime_Description": "Език на показване на Wino, предпочитан формат на часа.",
"SettingsLanguageTime_Title": "Език и формат на часа",
"SettingsLinkAccounts_Description": "Сливане на няколко акаунта в един. Виждайте имейлите заедно в една входяща кутия.",
"SettingsLinkAccounts_Title": "Създаване на свързани акаунти",
"SettingsLinkedAccountsSave_Description": "Промяна на текущото свързване с новите акаунти.",
"SettingsLinkedAccountsSave_Title": "Запазване на промените",
"SettingsLoadImages_Title": "Автоматично зареждане на изображенията",
"SettingsLoadPlaintextLinks_Title": "Конвертиране на обикновените текстови връзки в такива, върху които може да се клика",
"SettingsLoadStyles_Title": "Автоматично зареждане на стиловете",
"SettingsMailListActionBar_Description": "Скриване/показване на лентата за действия в горната част на списъка със съобщения.",
"SettingsMailListActionBar_Title": "Показване на действията в списъка с имейлите",
"SettingsMailSpacing_Description": "Настройте отстоянието между имейлите.",
"SettingsMailSpacing_Title": "Интервал между имейлите",
"SettingsManageAccountSettings_Description": "Известия, подписи, синхронизация и други настройки за всеки акаунт.",
"SettingsManageAccountSettings_Title": "Управление на настройките на акаунта",
"SettingsManageAliases_Description": "Вижте псевдонимите на имейлите, назначени за този акаунт, актуализирайте ги или ги изтрийте.",
"SettingsManageAliases_Title": "Псевдоними",
"SettingsEditAccountDetails_Title": "Редактиране на данните на акаунта",
"SettingsEditAccountDetails_Description": "Променете името на акаунта, името на подателя и задайте нов цвят, ако желаете.",
"SettingsManageLink_Description": "Преместете елементите, за да добавите нова връзка или да премахнете съществуваща връзка.",
"SettingsManageLink_Title": "Управление на връзката",
"SettingsMarkAsRead_Description": "Променете какво трябва да се случи с избрания елемент.",
"SettingsMarkAsRead_DontChange": "Да не се маркира автоматично елемента като прочетен",
"SettingsMarkAsRead_SecondsToWait": "Секунди за изчакване: ",
"SettingsMarkAsRead_Timer": "При преглед в прозореца за четене",
"SettingsMarkAsRead_Title": "Маркиране на елемента като прочетен",
"SettingsMarkAsRead_WhenSelected": "Когато е избран",
"SettingsMessageList_Description": "Променете начина на организиране на съобщенията в списъка с имейли.",
"SettingsMessageList_Title": "Списък със съобщения",
"SettingsNoAccountSetupMessage": "Все още не сте настроили никакви акаунти.",
"SettingsNotifications_Description": "Включване или изключване на известията за този акаунт.",
"SettingsNotifications_Title": "Известия",
"SettingsNotificationsAndTaskbar_Description": "Променете дали да се показват известия и значка в лентата на задачите за този акаунт.",
"SettingsNotificationsAndTaskbar_Title": "Известия и лента на задачите",
"SettingsOptions_Title": "Настройки",
"SettingsPaneLengthReset_Description": "Възстановете първоначалния размер на списъка с имейли, ако имате проблеми с него.",
"SettingsPaneLengthReset_Title": "Възстановяване размера на списъка с имейли",
"SettingsPaypal_Description": "Покажете много повече любов ❤️ Всички дарения са добре дошли.",
"SettingsPaypal_Title": "Дарете чрез PayPal",
"SettingsPersonalization_Description": "Променете външния вид на Wino, както ви харесва.",
"SettingsPersonalization_Title": "Персонализация",
"SettingsPersonalizationMailDisplayCompactMode": "Компактен режим",
"SettingsPersonalizationMailDisplayMediumMode": "Среден режим",
"SettingsPersonalizationMailDisplaySpaciousMode": "Просторен режим",
"SettingsPrefer24HourClock_Description": "Часовете на получената поща ще се показват в 24-часов формат вместо в 12-часов (AM/PM)",
"SettingsPrefer24HourClock_Title": "Показване на часовете в 24-часов формат",
"SettingsPrivacyPolicy_Description": "Прегледайте политиката за поверителност.",
"SettingsPrivacyPolicy_Title": "Политика за поверителност",
"SettingsReadComposePane_Description": "Шрифтове, външно съдържание.",
"SettingsReadComposePane_Title": "Четене и съставяне",
"SettingsReader_Title": "Четене",
"SettingsReaderFont_Title": "Шрифт по подразбиране за четене",
"SettingsReaderFontFamily_Description": "Променете шрифтовото семейство и размера на шрифта по подразбиране за четене на имейли.",
"SettingsRenameMergeAccount_Description": "Променете показваното име на свързаните акаунти.",
"SettingsRenameMergeAccount_Title": "Преименуване",
"SettingsReorderAccounts_Description": "Променете реда на акаунтите в списъка с акаунти.",
"SettingsReorderAccounts_Title": "Пренареждане на акаунтите",
"SettingsSemanticZoom_Description": "Това ще ви позволи да кликнете върху заглавията в списъка със съобщения и да преминете към определена дата",
"SettingsSemanticZoom_Title": "Семантично увеличение за заглавия с дати",
"SettingsShowPreviewText_Description": "Скриване/показване на текста за визуализация.",
"SettingsShowPreviewText_Title": "Показване визуализация на текста",
"SettingsShowSenderPictures_Description": "Скриване/показване на миниатюрите на снимките на изпращача.",
"SettingsShowSenderPictures_Title": "Показване на аватарите на подателите",
"SettingsSignature_AddCustomSignature_Button": "Добавяне на подпис",
"SettingsSignature_AddCustomSignature_Title": "Добавяне на персонализиран подпис",
"SettingsSignature_DeleteSignature_Title": "Изтриване на подписа",
"SettingsSignature_Description": "Управление на подписите на акаунтите",
"SettingsSignature_EditSignature_Title": "Редактиране на подписа",
"SettingsSignature_ForFollowingMessages_Title": "За отговори/препратки",
"SettingsSignature_ForNewMessages_Title": "За нови съобщения",
"SettingsSignature_NoneSignatureName": "Няма",
"SettingsSignature_SignatureDefaults": "Параметри на подписа по подразбиране",
"SettingsSignature_Signatures": "Подписи",
"SettingsSignature_Title": "Подпис",
"SettingsStartupItem_Description": "Основен елемент от акаунта за зареждане на Входящи при стартиране.",
"SettingsStartupItem_Title": "Елемент за стартиране",
"SettingsStore_Description": "Покажете малко любов ❤️",
"SettingsStore_Title": "Оценете ни в магазина",
"SettingsTaskbarBadge_Description": "Показване броя на непрочетените писма в иконата в лентата на задачите.",
"SettingsTaskbarBadge_Title": "Значка на лентата на задачите",
"SettingsThreads_Description": "Организиране на съобщенията в разговори.",
"SettingsThreads_Title": "Групиране в разговори",
"SettingsUnlinkAccounts_Description": "Премахване на връзката между акаунтите. Това няма да доведе до изтриване на акаунтите ви.",
"SettingsUnlinkAccounts_Title": "Премахване на връзката между акаунтите",
"SignatureDeleteDialog_Message": "Наистина ли искате да изтриете подписа „{0}“?",
"SignatureDeleteDialog_Title": "Изтриване на подписа",
"SignatureEditorDialog_SignatureName_Placeholder": "Име на вашия подпис",
"SignatureEditorDialog_SignatureName_TitleEdit": "Текущо име на подписа: {0}",
"SignatureEditorDialog_SignatureName_TitleNew": "Име на подписа",
"SignatureEditorDialog_Title": "Редактор на подписи",
"SortingOption_Date": "по дата",
"SortingOption_Name": "по име",
"StoreRatingDialog_MessageFirstLine": "Всички отзиви се оценяват и ще направят Wino много по-добър в бъдеще. Искате ли да оцените Wino в Microsoft Store?",
"StoreRatingDialog_MessageSecondLine": "Искате ли да оцените Wino Mail в Microsoft Store?",
"StoreRatingDialog_Title": "Wino ви харесва?",
"SynchronizationFolderReport_Failed": "неуспешна синхронизация",
"SynchronizationFolderReport_Success": "актуални",
"SystemFolderConfigDialog_ArchiveFolderDescription": "Архивираните съобщения ще бъдат преместени тук.",
"SystemFolderConfigDialog_ArchiveFolderHeader": "Папка Архив",
"SystemFolderConfigDialog_DeletedFolderDescription": "Изтритите съобщения ще бъдат преместени тук.",
"SystemFolderConfigDialog_DeletedFolderHeader": "Изтрита папка",
"SystemFolderConfigDialog_DraftFolderDescription": "Новите писма/отговори ще бъдат създавани тук.",
"SystemFolderConfigDialog_DraftFolderHeader": "Папка Чернови",
"SystemFolderConfigDialog_JunkFolderDescription": "Всички спам/нежелани имейли ще бъдат тук.",
"SystemFolderConfigDialog_JunkFolderHeader": "Папка за нежелана поща/спам",
"SystemFolderConfigDialog_MessageFirstLine": "Този IMAP сървър не поддържа разширението SPECIAL-USE, поради което Wino не може да настрои правилно системните папки.",
"SystemFolderConfigDialog_MessageSecondLine": "Моля, изберете подходящите папки за конкретни функционалности.",
"SystemFolderConfigDialog_SentFolderDescription": "Папка, в която ще се съхраняват изпратените съобщения.",
"SystemFolderConfigDialog_SentFolderHeader": "Папка Изпратени",
"SystemFolderConfigDialog_Title": "Конфигуриране на системните папки",
"SystemFolderConfigDialogValidation_DuplicateSystemFolders": "Някои от системните папки се използват повече от веднъж в конфигурацията.",
"SystemFolderConfigDialogValidation_InboxSelected": "Не можете да присвоите папка Входящи към друга системна папка.",
"SystemFolderConfigSetupSuccess_Message": "Системните папки са успешно конфигурирани.",
"SystemFolderConfigSetupSuccess_Title": "Настройка на системните папки",
"TestingImapConnectionMessage": "Тестване на връзката със сървъра...",
"TitleBarServerDisconnectedButton_Description": "Wino е изключен от мрежата. Щракнете върху Повторно свързване, за да възстановите връзката.",
"TitleBarServerDisconnectedButton_Title": "няма връзка",
"TitleBarServerReconnectButton_Title": "повторно свързване",
"TitleBarServerReconnectingButton_Title": "свързване",
"Today": "Днес",
"UnknownAddress": "неизвестен адрес",
"UnknownDateHeader": "Неизвестна дата",
"UnknownGroupAddress": "неизвестен адрес на пощенската група",
"UnknownSender": "Неизвестен подател",
"Unsubscribe": "Отписване",
"ViewContactDetails": "Вижте подробностите",
"WinoUpgradeDescription": "Wino предлага 3 безплатни акаунта за начало. Ако имате нужда от повече от 3 акаунта, моля, надстройте",
"WinoUpgradeMessage": "Надграждане до неограничен брой акаунти",
"WinoUpgradeRemainingAccountsMessage": "Използвани са {0} от {1} безплатни акаунта.",
"Yesterday": "Вчера"
}

View File

@@ -22,6 +22,10 @@
"AccountPickerDialog_Title": "Pick an account",
"AccountSettingsDialog_AccountName": "Sender Display Name",
"AccountSettingsDialog_AccountNamePlaceholder": "eg. John Doe",
"AccountDetailsPage_Title": "Account info",
"AccountDetailsPage_Description": "Change the name of the account in Wino and set desired sender name.",
"AccountDetailsPage_ColorPicker_Title": "Account color",
"AccountDetailsPage_ColorPicker_Description": "Assign a new account color to colorize its symbol in the list.",
"AddHyperlink": "Add",
"AppCloseBackgroundSynchronizationWarningTitle": "Background Synchronization",
"AppCloseStartupLaunchDisabledWarningMessageFirstLine": "Application has not been set to launch on Windows startup.",
@@ -256,6 +260,9 @@
"ImapConnectionSecurity_SslTls": "SSL/TLS",
"ImapConnectionSecurity_StartTls": "STARTTLS",
"IMAPSetupDialog_AccountType": "Account type",
"IMAPSetupDialog_ValidationSuccess_Title": "Success",
"IMAPSetupDialog_ValidationSuccess_Message": "Validation successful",
"IMAPSetupDialog_ValidationFailed_Title": "IMAP Server validation failed.",
"IMAPSetupDialog_CertificateAllowanceRequired_Row0": "This server is requesting a SSL handshake to continue. Please confirm the certificate details below.",
"IMAPSetupDialog_CertificateAllowanceRequired_Row1": "Allow the handshake to continue setting up your account.",
"IMAPSetupDialog_CertificateDenied": "User didn't authorize the handshake with the certificate.",
@@ -270,6 +277,8 @@
"IMAPSetupDialog_DisplayNamePlaceholder": "eg. John Doe",
"IMAPSetupDialog_IncomingMailServer": "Incoming mail server",
"IMAPSetupDialog_IncomingMailServerPort": "Port",
"IMAPSetupDialog_IMAPSettings": "IMAP Server Settings",
"IMAPSetupDialog_SMTPSettings": "SMTP Server Settings",
"IMAPSetupDialog_MailAddress": "Email address",
"IMAPSetupDialog_MailAddressPlaceholder": "someone@example.com",
"IMAPSetupDialog_OutgoingMailServer": "Outgoing (SMTP) mail server",
@@ -455,6 +464,8 @@
"SearchingIn": "Searching in",
"SearchPivotName": "Results",
"SettingConfigureSpecialFolders_Button": "Configure",
"SettingsEditAccountDetails_IMAPConfiguration_Title": "IMAP/SMTP Configuration",
"SettingsEditAccountDetails_IMAPConfiguration_Description": "Change your incoming/outgoing server settings.",
"SettingsAbout_Description": "Learn more about Wino.",
"SettingsAbout_Title": "About",
"SettingsAboutGithub_Description": "Go to issue tracker GitHub repository.",
@@ -566,6 +577,8 @@
"SettingsManageAccountSettings_Title": "Manage Account Settings",
"SettingsManageAliases_Description": "See e-mail aliases assigned for this account, update or delete them.",
"SettingsManageAliases_Title": "Aliases",
"SettingsEditAccountDetails_Title": "Edit Account Details",
"SettingsEditAccountDetails_Description": "Change account name, sender name and assign a new color if you like.",
"SettingsManageLink_Description": "Move items to add new link or remove existing link.",
"SettingsManageLink_Title": "Manage Link",
"SettingsMarkAsRead_Description": "Change what should happen to the selected item.",

Some files were not shown because too many files have changed in this diff Show More