Compare commits
425 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b64cc44531 | ||
|
|
1b51982551 | ||
|
|
10c94efa57 | ||
|
|
c84316e974 | ||
|
|
7e4d1fbf49 | ||
|
|
31c7c8b46f | ||
|
|
8cdb6646c4 | ||
|
|
43a51e5f2f | ||
|
|
d0b54ea44b | ||
|
|
c8fce82dc1 | ||
|
|
3ffccaa7e5 | ||
|
|
3f7e7a1474 | ||
|
|
d30c15464b | ||
|
|
2a1f748469 | ||
|
|
74b429b1bf | ||
|
|
7afe1b517c | ||
|
|
fcdcf5692f | ||
|
|
735baa67ed | ||
|
|
ac00caf83e | ||
|
|
2ccda353e9 | ||
|
|
4257ca54b7 | ||
|
|
20dd2ef98d | ||
|
|
8be52c9ddd | ||
|
|
3bea6619fa | ||
|
|
0e5fb11c52 | ||
|
|
fc47f7701d | ||
|
|
3e4ccf8de4 | ||
|
|
8abb3c709b | ||
|
|
5263900620 | ||
|
|
54ee9e5072 | ||
|
|
20f4857405 | ||
|
|
55110dd39d | ||
|
|
07d8111df9 | ||
|
|
a701b97f1e | ||
|
|
b025537d62 | ||
|
|
e68bc2de65 | ||
|
|
d0b1c93382 | ||
|
|
a08fa9eabf | ||
|
|
65ef130bda | ||
|
|
32471a71e5 | ||
|
|
ca80f01907 | ||
|
|
b1fae57922 | ||
|
|
dea01dda2d | ||
|
|
9777619259 | ||
|
|
6db0f84f8f | ||
|
|
84e382fcc5 | ||
|
|
eceed1b934 | ||
|
|
e7b5cd74a4 | ||
|
|
a98930791c | ||
|
|
67b0389097 | ||
|
|
ff30595fb4 | ||
|
|
d272b62c45 | ||
|
|
c1973023d0 | ||
|
|
ef4689619e | ||
|
|
9ed297a49d | ||
|
|
9950729080 | ||
|
|
36eec9d061 | ||
|
|
fd3a977009 | ||
|
|
ff88832cca | ||
|
|
d69b72b77d | ||
|
|
d9bd9e996b | ||
|
|
f45580be70 | ||
|
|
0fbeb11304 | ||
|
|
6a70c13b57 | ||
|
|
f797520e56 | ||
|
|
d060db3c96 | ||
|
|
298344c2ab | ||
|
|
53dbeadabb | ||
|
|
93087d7aa7 | ||
|
|
c304517fc2 | ||
|
|
af13e034c3 | ||
|
|
e6b9d59160 | ||
|
|
bd9cbe30c5 | ||
|
|
f627226da9 | ||
|
|
bab3272970 | ||
|
|
003085db7e | ||
|
|
8f98bd37c7 | ||
|
|
6971ef1ede | ||
|
|
0baac3dc49 | ||
|
|
16feb8602d | ||
|
|
d623129d56 | ||
|
|
9cc4c33bb1 | ||
|
|
c087b40d4a | ||
|
|
a82e074bd4 | ||
|
|
3365c099bb | ||
|
|
d8705de26f | ||
|
|
3af181e736 | ||
|
|
ba6c01b7c6 | ||
|
|
7a7cdcb041 | ||
|
|
09e52bf199 | ||
|
|
a8c39a1587 | ||
|
|
68536d6c34 | ||
|
|
f57c27e755 | ||
|
|
9a97a27c8a | ||
|
|
07bb90dda9 | ||
|
|
3bb156f4da | ||
|
|
e13e0efcc6 | ||
|
|
3ae0a94159 | ||
|
|
eec67ec7dc | ||
|
|
cf51853eec | ||
|
|
67838b28a4 | ||
|
|
bf68e3b7d5 | ||
|
|
91ed0bb8bd | ||
|
|
55fe791c2a | ||
|
|
747efac2ec | ||
|
|
a87df2e9f6 | ||
|
|
2e4a664744 | ||
|
|
579a22ea45 | ||
|
|
abff850427 | ||
|
|
f1154058ba | ||
|
|
cf9f308b7f | ||
|
|
1791df236c | ||
|
|
7211f94f08 | ||
|
|
7b0343c87f | ||
|
|
b80f0276b4 | ||
|
|
8f66fcbb00 | ||
|
|
fe449ee1f3 | ||
|
|
34d6d95186 | ||
|
|
05ddc0660a | ||
|
|
c6047a8428 | ||
|
|
bc4838578e | ||
|
|
548996405a | ||
|
|
a9a5f0bd14 | ||
|
|
ec05ff6123 | ||
|
|
10c7ab421b | ||
|
|
a8a5cc53ea | ||
|
|
8fe48ca438 | ||
|
|
cbd5a515a9 | ||
|
|
5912adff93 | ||
|
|
983bc21448 | ||
|
|
6d08368462 | ||
|
|
cde7bb3524 | ||
|
|
133dc91561 | ||
|
|
f408f59beb | ||
|
|
8763bf11ab | ||
|
|
99592a52be | ||
|
|
25a8a52573 | ||
|
|
5901344459 | ||
|
|
b07ae4bc42 | ||
|
|
0d9e61480a | ||
|
|
baaea96b1d | ||
|
|
e156cb5c2e | ||
|
|
ff77b2b3dc | ||
|
|
4dc225184d | ||
|
|
49a0266224 | ||
|
|
7a62d96b91 | ||
|
|
641454fa14 | ||
|
|
cf2f0ec936 | ||
|
|
76375c9471 | ||
|
|
0894c56c19 | ||
|
|
7de89ffe57 | ||
|
|
e0c01343a8 | ||
|
|
48ed4f971c | ||
|
|
9e8c8a019e | ||
|
|
96f4ca2cc9 | ||
|
|
fad59604f9 | ||
|
|
ac0e8da0ba | ||
|
|
fc5c3fd73e | ||
|
|
536fbb23a1 | ||
|
|
ac01006398 | ||
|
|
ade8654cc4 | ||
|
|
8e03f26fb5 | ||
|
|
dab51bef7b | ||
|
|
bea7fb5fe5 | ||
|
|
d6b3240506 | ||
|
|
19e53d8bc8 | ||
|
|
5923d72803 | ||
|
|
8cde976358 | ||
|
|
256a5b50ac | ||
|
|
8b236f68f4 | ||
|
|
c18f6d3978 | ||
|
|
e65733754c | ||
|
|
4505630896 | ||
|
|
044804143f | ||
|
|
1e9d7c9b93 | ||
|
|
573fe3cad3 | ||
|
|
cd3880c85c | ||
|
|
02cd8ed7ae | ||
|
|
3d69f96b96 | ||
|
|
963a15abe7 | ||
|
|
40542f0461 | ||
|
|
bfc2af71a4 | ||
|
|
35142bb61d | ||
|
|
39626e0df9 | ||
|
|
ca40730600 | ||
|
|
4158e196d6 | ||
|
|
1516e800dd | ||
|
|
0b96f69a1d | ||
|
|
bb418e51d4 | ||
|
|
5fb23ab8bf | ||
|
|
117b01c48b | ||
|
|
18719815a3 | ||
|
|
f795595107 | ||
|
|
be3f9465eb | ||
|
|
c598daab9b | ||
|
|
438b25672f | ||
|
|
1e12ddd8e2 | ||
|
|
dccf55d57a | ||
|
|
3397845ccc | ||
|
|
82ae13ba3e | ||
|
|
8c830761f3 | ||
|
|
ad5c134887 | ||
|
|
150bf124a9 | ||
|
|
1c96c0ccbf | ||
|
|
cf8ad3d697 | ||
|
|
5b723ec954 | ||
|
|
633c708c33 | ||
|
|
e4784108f7 | ||
|
|
b4103a4edb | ||
|
|
cfdd32708a | ||
|
|
8e97c1e9e8 | ||
|
|
e009bebfaf | ||
|
|
d3d190989d | ||
|
|
1b36b52019 | ||
|
|
e526e96e2d | ||
|
|
1659d74938 | ||
|
|
f7161dc39b | ||
|
|
d8ea41e4dd | ||
|
|
fe0a03db2f | ||
|
|
49afed7751 | ||
|
|
a788b1706b | ||
|
|
d57fd20ca2 | ||
|
|
5ecc1b09c8 | ||
|
|
f1dfc9666b | ||
|
|
b503584431 | ||
|
|
0dfe1c8e3a | ||
|
|
c5630d90ec | ||
|
|
f8973a3cf7 | ||
|
|
228be8376f | ||
|
|
3fee3b0224 | ||
|
|
b4e705b347 | ||
|
|
51e59bebfc | ||
|
|
a56ac31f4b | ||
|
|
af05f081d2 | ||
|
|
b97d79d261 | ||
|
|
d227e6339f | ||
|
|
74c503fea0 | ||
|
|
ed8b0c4d3c | ||
|
|
cbb17e92f0 | ||
|
|
f9d64cf777 | ||
|
|
7fdd6d19cf | ||
|
|
60ca252b63 | ||
|
|
2027837c18 | ||
|
|
67904568b1 | ||
|
|
afbc559a47 | ||
|
|
67c312642c | ||
|
|
89eb007e43 | ||
|
|
88c3f3204b | ||
|
|
052ab98cd3 | ||
|
|
cd01c0e31b | ||
|
|
c3d3228f65 | ||
|
|
f04647192f | ||
|
|
c00f0c9f52 | ||
|
|
690e04c377 | ||
|
|
545880dcce | ||
|
|
fedf5d2203 | ||
|
|
5242e55826 | ||
|
|
1bf86e73a7 | ||
|
|
c3fe72f561 | ||
|
|
b54555a4f7 | ||
|
|
4c080360a7 | ||
|
|
fdea15eef4 | ||
|
|
5a4dd97abe | ||
|
|
e47e3d936b | ||
|
|
0e9fd4373e | ||
|
|
69a10c754a | ||
|
|
a8ba965c0d | ||
|
|
847aed3519 | ||
|
|
fed9345bea | ||
|
|
d71b6d0ab0 | ||
|
|
40e5521fbf | ||
|
|
c7781d2e75 | ||
|
|
0ccf67000c | ||
|
|
f4e81aca9d | ||
|
|
2d654cf759 | ||
|
|
0b728162ae | ||
|
|
f52b426652 | ||
|
|
ad0528d763 | ||
|
|
263adcf2b5 | ||
|
|
b201e274f1 | ||
|
|
c1a6a73b7d | ||
|
|
ed4764cc70 | ||
|
|
8d84b3adbc | ||
|
|
35db674c88 | ||
|
|
3e1850a713 | ||
|
|
8c625c0ecd | ||
|
|
bf1de8e7a4 | ||
|
|
8c2dca3770 | ||
|
|
23adbddfb7 | ||
|
|
b1b6b64e68 | ||
|
|
0c7909df09 | ||
|
|
641bfd8c06 | ||
|
|
52140c3208 | ||
|
|
1baa9173cb | ||
|
|
26749c2116 | ||
|
|
a1ecb9ad39 | ||
|
|
b398fde24e | ||
|
|
a5767b60fb | ||
|
|
ef196c384c | ||
|
|
920def7446 | ||
|
|
bec98dcaa2 | ||
|
|
747be07322 | ||
|
|
c1fc6f0bce | ||
|
|
851c42e630 | ||
|
|
4e5a4a9c17 | ||
|
|
df19d500de | ||
|
|
4fd4c9802e | ||
|
|
23d0eeab16 | ||
|
|
b66557f3be | ||
|
|
580586cab3 | ||
|
|
9a97ef1dad | ||
|
|
b4f7503d85 | ||
|
|
b89406a89a | ||
|
|
932cdae22e | ||
|
|
34ef86cfff | ||
|
|
023bace2a9 | ||
|
|
467b63cffb | ||
|
|
49ffb0fa68 | ||
|
|
04984dea98 | ||
|
|
78e9a768b4 | ||
|
|
401f877388 | ||
|
|
b3ba1aa3b9 | ||
|
|
ae76aebe24 | ||
|
|
b5e1bf2867 | ||
|
|
fb3a0da54f | ||
|
|
7d197f405d | ||
|
|
bc7af3a68b | ||
|
|
120e79229a | ||
|
|
f0e4bbcda9 | ||
|
|
57e31c1dfb | ||
|
|
8f2f414f5e | ||
|
|
879f91693e | ||
|
|
0c504b52e4 | ||
|
|
bbaa5f9fa8 | ||
|
|
2a9f7fde28 | ||
|
|
0ec7c87851 | ||
|
|
cf515abc4c | ||
|
|
99cab08ab7 | ||
|
|
e60d40ee9c | ||
|
|
c90fa68f16 | ||
|
|
61ae86e927 | ||
|
|
86c995906c | ||
|
|
a77b88aaf6 | ||
|
|
0d288f3206 | ||
|
|
d9d6244931 | ||
|
|
4d984f0524 | ||
|
|
b456b0143b | ||
|
|
3ebcfd5598 | ||
|
|
745ea3509e | ||
|
|
8f5d4e5bc2 | ||
|
|
acd7d3bbac | ||
|
|
f3bd6598e7 | ||
|
|
ce48fdc445 | ||
|
|
5aea223c14 | ||
|
|
1f59d3179c | ||
|
|
1f6e1db695 | ||
|
|
5b46c372ab | ||
|
|
f143d3e1c2 | ||
|
|
c7639309ef | ||
|
|
b788531e47 | ||
|
|
00fa2ca804 | ||
|
|
74cdf09ebc | ||
|
|
80ec12740a | ||
|
|
a0002ff97b | ||
|
|
2cb0db02e3 | ||
|
|
bed8d71f7e | ||
|
|
668b385a10 | ||
|
|
d96df469a4 | ||
|
|
8edbe1aa2c | ||
|
|
99ece9a61a | ||
|
|
4b5253dd6b | ||
|
|
5e10294a16 | ||
|
|
226d2069d9 | ||
|
|
8d1365b712 | ||
|
|
45624d905e | ||
|
|
a5d9c931ca | ||
|
|
f0db2b2f6e | ||
|
|
cde5913ace | ||
|
|
ceea9fc501 | ||
|
|
eb678b4533 | ||
|
|
dcbe8bb3dc | ||
|
|
555310a4ca | ||
|
|
3a57358f58 | ||
|
|
9982ba2fec | ||
|
|
11b652f851 | ||
|
|
380950a615 | ||
|
|
e8b07738a5 | ||
|
|
9d1163e73e | ||
|
|
e2f0c73bab | ||
|
|
183873afff | ||
|
|
b356475741 | ||
|
|
279bae115a | ||
|
|
82bb5a96ad | ||
|
|
a4e9ffcc99 | ||
|
|
1c25427c5c | ||
|
|
2ec22eb6cd | ||
|
|
2ff508607d | ||
|
|
69a34c65f7 | ||
|
|
f34c1520a4 | ||
|
|
f3fa8eec50 | ||
|
|
9baa9b1dd6 | ||
|
|
c1c1af1ded | ||
|
|
4a8c1b7de4 | ||
|
|
1f35165919 | ||
|
|
2e85508426 | ||
|
|
631b218057 | ||
|
|
e8cfc88d83 | ||
|
|
78502a0cd0 | ||
|
|
2bcb6a146b | ||
|
|
ae474b5e5b | ||
|
|
babed18af0 | ||
|
|
3fa7e3e36d | ||
|
|
45587d5f15 | ||
|
|
e98f6997ca | ||
|
|
21d1b71653 | ||
|
|
afd7b5650f | ||
|
|
a0687d555a | ||
|
|
f543953389 | ||
|
|
2c4c7586b7 | ||
|
|
e92921a6cc | ||
|
|
0322bcd047 | ||
|
|
26c914be96 | ||
|
|
75863faf58 | ||
|
|
99b3ec4ce3 | ||
|
|
d97ffd863b |
@@ -25,6 +25,7 @@ I'm a big fan of Windows Mail & Calendars due to its simplicity. Personally, I f
|
||||
- API integration for Outlook and Gmail
|
||||
- IMAP/SMTP support for custom mail servers
|
||||
- Send, receive, mark as (read,important,spam etc), move mails.
|
||||
- Linked/Merged Accounts
|
||||
- Toast notifications with background sync.
|
||||
- Instant startup performance
|
||||
- Offline use / search.
|
||||
@@ -43,7 +44,7 @@ Download latest version of Wino Mail from Microsoft Store for free.
|
||||
|
||||
## Beta Releases
|
||||
|
||||
Stable releases will always be distributed on Microsoft Store. However, beta releases will be distributed in [GitHub Releases](https://github.com/bkaankose/Wino-Mail/releases). Please keep in mind that beta releases might not be for daily use, only for testing purposes and recommended for experienced users or developers.
|
||||
Stable releases will always be distributed on Microsoft Store. However, beta releases will be distributed in [GitHub Releases](https://github.com/bkaankose/Wino-Mail/releases). Please keep in mind that beta releases might not be for daily use, only for testing purposes and recommended for experienced users or developers. Beta releases are also managed manually. Therefore, code in the repository might be ahead of the released Beta version at the moment. Make sure to compare versions before tryout out the Beta version.
|
||||
|
||||
These releases are distributed as side-loaded packages. To install them, download the **.msixbundle** file in GitHub releases and [follow the steps explained here.](https://learn.microsoft.com/en-us/windows/application-management/sideload-apps-in-windows)
|
||||
|
||||
@@ -52,10 +53,6 @@ These releases are distributed as side-loaded packages. To install them, downloa
|
||||
|
||||
Check out the [contribution guidelines](/CONTRIBUTING.md) before diving into the source code or opening an issue. There are multiple ways to contribute and all of them are explained in detail there.
|
||||
|
||||
#### Attention
|
||||
|
||||
Sources here **does not belong to the Store version of Wino Mail. It belongs to beta release as of April 17 2024.** I've been working on a big patch for couple months already and the code here includes those changes, but these changes are not yet released to Microsoft Store. Therefore, if you'd like to contribute, please validate the bug before in beta version and start working on it. I will delete this text from here once this big patch goes alive in the Store, so everything will be aligned then.
|
||||
|
||||
## Donate
|
||||
|
||||
Your donations will motivate me more to work on Wino in my spare time and cover the expenses to keep [project's website](https://www.winomail.app/) alive.
|
||||
|
||||
42
Settings.XamlStyler
Normal file
42
Settings.XamlStyler
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"AttributesTolerance": 2,
|
||||
"KeepFirstAttributeOnSameLine": false,
|
||||
"MaxAttributeCharactersPerLine": 0,
|
||||
"MaxAttributesPerLine": 1,
|
||||
"NewlineExemptionElements": "RadialGradientBrush, GradientStop, LinearGradientBrush, ScaleTransform, SkewTransform, RotateTransform, TranslateTransform, Trigger, Condition, Setter",
|
||||
"SeparateByGroups": false,
|
||||
"AttributeIndentation": 0,
|
||||
"AttributeIndentationStyle": 1,
|
||||
"RemoveDesignTimeReferences": false,
|
||||
"IgnoreDesignTimeReferencePrefix": false,
|
||||
"EnableAttributeReordering": true,
|
||||
"AttributeOrderingRuleGroups": [
|
||||
"x:Class",
|
||||
"xmlns, xmlns:x",
|
||||
"xmlns:*",
|
||||
"x:Key, Key, x:Name, Name, x:Uid, Uid, Title",
|
||||
"Grid.Row, Grid.RowSpan, Grid.Column, Grid.ColumnSpan, Canvas.Left, Canvas.Top, Canvas.Right, Canvas.Bottom",
|
||||
"Width, Height, MinWidth, MinHeight, MaxWidth, MaxHeight",
|
||||
"Margin, Padding, HorizontalAlignment, VerticalAlignment, HorizontalContentAlignment, VerticalContentAlignment, Panel.ZIndex",
|
||||
"*:*, *",
|
||||
"PageSource, PageIndex, Offset, Color, TargetName, Property, Value, StartPoint, EndPoint",
|
||||
"mc:Ignorable, d:IsDataSource, d:LayoutOverrides, d:IsStaticText",
|
||||
"Storyboard.*, From, To, Duration"
|
||||
],
|
||||
"FirstLineAttributes": "",
|
||||
"OrderAttributesByName": true,
|
||||
"PutEndingBracketOnNewLine": false,
|
||||
"RemoveEndingTagOfEmptyElement": true,
|
||||
"SpaceBeforeClosingSlash": true,
|
||||
"RootElementLineBreakRule": 0,
|
||||
"ReorderVSM": 2,
|
||||
"ReorderGridChildren": false,
|
||||
"ReorderCanvasChildren": false,
|
||||
"ReorderSetters": 0,
|
||||
"FormatMarkupExtension": true,
|
||||
"NoNewLineMarkupExtensions": "x:Bind, Binding",
|
||||
"ThicknessSeparator": 2,
|
||||
"ThicknessAttributes": "Margin, Padding, BorderThickness, ThumbnailClipMargin",
|
||||
"FormatOnSave": true,
|
||||
"CommentPadding": 2,
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
using Microsoft.Toolkit.Uwp.Notifications;
|
||||
using Windows.ApplicationModel;
|
||||
using Windows.ApplicationModel.Background;
|
||||
using Wino.Core.Domain;
|
||||
|
||||
namespace Wino.BackgroundTasks
|
||||
{
|
||||
@@ -23,8 +22,9 @@ namespace Wino.BackgroundTasks
|
||||
|
||||
var versionText = string.Format("{0}.{1}.{2}.{3}", version.Major, version.Minor, version.Build, version.Revision);
|
||||
|
||||
builder.AddText(Translator.Notifications_WinoUpdatedTitle);
|
||||
builder.AddText(string.Format(Translator.Notifications_WinoUpdatedMessage, versionText));
|
||||
// TODO: Handle with Translator, but it's not initialized here yet.
|
||||
builder.AddText("Wino Mail is updated!");
|
||||
builder.AddText(string.Format("New version {0} is ready.", versionText));
|
||||
|
||||
builder.Show();
|
||||
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Serilog;
|
||||
using Windows.ApplicationModel.Background;
|
||||
using Windows.Storage;
|
||||
using Wino.Core;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Services;
|
||||
using Wino.Core.UWP;
|
||||
using Wino.Services;
|
||||
|
||||
namespace Wino.BackgroundTasks
|
||||
{
|
||||
public sealed class SessionConnectedTask : IBackgroundTask
|
||||
{
|
||||
public async void Run(IBackgroundTaskInstance taskInstance)
|
||||
{
|
||||
var def = taskInstance.GetDeferral();
|
||||
|
||||
try
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
|
||||
services.RegisterCoreServices();
|
||||
services.RegisterCoreUWPServices();
|
||||
|
||||
var providere = services.BuildServiceProvider();
|
||||
|
||||
var backgroundTaskService = providere.GetService<IBackgroundSynchronizer>();
|
||||
var dbService = providere.GetService<IDatabaseService>();
|
||||
var logInitializer = providere.GetService<ILogInitializer>();
|
||||
|
||||
logInitializer.SetupLogger(ApplicationData.Current.LocalFolder.Path);
|
||||
|
||||
await dbService.InitializeAsync();
|
||||
await backgroundTaskService.RunBackgroundSynchronizationAsync(Core.Domain.Enums.BackgroundSynchronizationReason.SessionConnected);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Background synchronization failed from background task.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
def.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,25 +18,6 @@
|
||||
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<AllowCrossPlatformRetargeting>false</AllowCrossPlatformRetargeting>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -57,26 +38,6 @@
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\ARM\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<OutputPath>bin\ARM\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM64'">
|
||||
<PlatformTarget>ARM64</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -123,7 +84,6 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="AppUpdatedTask.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SessionConnectedTask.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
public const string WinoLocalDraftHeader = "X-Wino-Draft-Id";
|
||||
public const string LocalDraftStartPrefix = "localDraft_";
|
||||
|
||||
public const string ToastMailItemIdKey = nameof(ToastMailItemIdKey);
|
||||
public const string ToastMailUniqueIdKey = nameof(ToastMailUniqueIdKey);
|
||||
public const string ToastActionKey = nameof(ToastActionKey);
|
||||
|
||||
public const string ClientLogFile = "Client_.log";
|
||||
public const string ServerLogFile = "Server_.log";
|
||||
public const string LogArchiveFileName = "WinoLogs.zip";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using SQLite;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using SQLite;
|
||||
|
||||
namespace Wino.Core.Domain.Entities
|
||||
{
|
||||
@@ -9,23 +9,41 @@ namespace Wino.Core.Domain.Entities
|
||||
/// These values will be inserted during MIME fetch.
|
||||
/// </summary>
|
||||
|
||||
|
||||
// TODO: This can easily evolve to Contact store, just like People app in Windows 10/11.
|
||||
// Do it.
|
||||
public class AddressInformation : IEquatable<AddressInformation>
|
||||
public class AccountContact : IEquatable<AccountContact>
|
||||
{
|
||||
/// <summary>
|
||||
/// E-mail address of the contact.
|
||||
/// </summary>
|
||||
[PrimaryKey]
|
||||
public string Address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Display name of the contact.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Base64 encoded profile image of the contact.
|
||||
/// </summary>
|
||||
public string Base64ContactPicture { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// All registered accounts have their contacts registered as root.
|
||||
/// Root contacts must not be overridden by any configuration.
|
||||
/// They are created on account creation.
|
||||
/// </summary>
|
||||
public bool IsRootContact { get; set; }
|
||||
|
||||
public string DisplayName => Address == Name ? Address : $"{Name} <{Address}>";
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return Equals(obj as AddressInformation);
|
||||
return Equals(obj as AccountContact);
|
||||
}
|
||||
|
||||
public bool Equals(AddressInformation other)
|
||||
public bool Equals(AccountContact other)
|
||||
{
|
||||
return !(other is null) &&
|
||||
Address == other.Address &&
|
||||
@@ -40,12 +58,12 @@ namespace Wino.Core.Domain.Entities
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
public static bool operator ==(AddressInformation left, AddressInformation right)
|
||||
public static bool operator ==(AccountContact left, AccountContact right)
|
||||
{
|
||||
return EqualityComparer<AddressInformation>.Default.Equals(left, right);
|
||||
return EqualityComparer<AccountContact>.Default.Equals(left, right);
|
||||
}
|
||||
|
||||
public static bool operator !=(AddressInformation left, AddressInformation right)
|
||||
public static bool operator !=(AccountContact left, AccountContact right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
@@ -8,6 +8,10 @@ namespace Wino.Core.Domain.Entities
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string HtmlBody { get; set; }
|
||||
|
||||
public Guid MailAccountId { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,10 @@ namespace Wino.Core.Domain.Entities
|
||||
|
||||
public Guid AccountId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This field is ignored. DisplayName is stored in MailAccount as SenderName from now.
|
||||
/// </summary>
|
||||
[Ignore]
|
||||
public string DisplayName { get; set; }
|
||||
public string Address { get; set; }
|
||||
public string IncomingServer { get; set; }
|
||||
@@ -39,11 +43,11 @@ namespace Wino.Core.Domain.Entities
|
||||
|
||||
public string ProxyServer { get; set; }
|
||||
public string ProxyServerPort { get; set; }
|
||||
|
||||
[Obsolete("As 1.7.0")]
|
||||
public bool IncomingRequiresSSL { get; set; }
|
||||
|
||||
[Obsolete("As 1.7.0")]
|
||||
public bool OutgoingRequresSSL { get; set; }
|
||||
/// <summary>
|
||||
/// Number of concurrent clients that can connect to the server.
|
||||
/// Default is 5.
|
||||
/// </summary>
|
||||
public int MaxConcurrentClients { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Wino.Core.Domain.Entities
|
||||
/// IMAP is populated by user on setup dialog.
|
||||
/// </summary>
|
||||
|
||||
public string ProfileName { get; set; }
|
||||
public string SenderName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Account e-mail address.
|
||||
@@ -40,10 +40,19 @@ namespace Wino.Core.Domain.Entities
|
||||
public string SynchronizationDeltaIdentifier { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the signature to be used for this account.
|
||||
/// Null if no signature should be used.
|
||||
/// TODO: Gets or sets the custom account identifier color in hex.
|
||||
/// </summary>
|
||||
public Guid? SignatureId { get; set; }
|
||||
public string AccountColorHex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Base64 encoded profile picture of the account.
|
||||
/// </summary>
|
||||
public string Base64ProfilePictureData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the listing order of the account in the accounts list.
|
||||
/// </summary>
|
||||
public int Order { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the account has any reason for an interactive user action to fix continue operating.
|
||||
@@ -74,5 +83,15 @@ namespace Wino.Core.Domain.Entities
|
||||
/// </summary>
|
||||
[Ignore]
|
||||
public MailAccountPreferences Preferences { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the account can perform ProfileInformation sync type.
|
||||
/// </summary>
|
||||
public bool IsProfileInfoSyncSupported => ProviderType == MailProviderType.Outlook || ProviderType == MailProviderType.Office365 || ProviderType == MailProviderType.Gmail;
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the account can perform AliasInformation sync type.
|
||||
/// </summary>
|
||||
public bool IsAliasSyncSupported => ProviderType == MailProviderType.Gmail;
|
||||
}
|
||||
}
|
||||
|
||||
56
Wino.Core.Domain/Entities/MailAccountAlias.cs
Normal file
56
Wino.Core.Domain/Entities/MailAccountAlias.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using SQLite;
|
||||
|
||||
namespace Wino.Core.Domain.Entities
|
||||
{
|
||||
public class RemoteAccountAlias
|
||||
{
|
||||
/// <summary>
|
||||
/// Display address of the alias.
|
||||
/// </summary>
|
||||
public string AliasAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Address to be included in Reply-To header when alias is used for sending messages.
|
||||
/// </summary>
|
||||
public string ReplyToAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this alias is the primary alias for the account.
|
||||
/// </summary>
|
||||
public bool IsPrimary { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the alias is verified by the server.
|
||||
/// Only Gmail aliases are verified for now.
|
||||
/// Non-verified alias messages might be rejected by SMTP server.
|
||||
/// </summary>
|
||||
public bool IsVerified { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this alias is the root alias for the account.
|
||||
/// Root alias means the first alias that was created for the account.
|
||||
/// It can't be deleted or changed.
|
||||
/// </summary>
|
||||
public bool IsRootAlias { get; set; }
|
||||
}
|
||||
|
||||
public class MailAccountAlias : RemoteAccountAlias
|
||||
{
|
||||
/// <summary>
|
||||
/// Unique Id for the alias.
|
||||
/// </summary>
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Account id that this alias is attached to.
|
||||
/// </summary>
|
||||
public Guid AccountId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Root aliases can't be deleted.
|
||||
/// </summary>
|
||||
public bool CanDelete => !IsRootAlias;
|
||||
}
|
||||
}
|
||||
@@ -25,15 +25,25 @@ namespace Wino.Core.Domain.Entities
|
||||
/// </summary>
|
||||
public bool IsNotificationsEnabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the custom account identifier color in hex.
|
||||
/// </summary>
|
||||
public string AccountColorHex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the account has Focused inbox support.
|
||||
/// Null if the account provider type doesn't support Focused inbox.
|
||||
/// </summary>
|
||||
public bool? IsFocusedInboxEnabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether signature should be appended automatically.
|
||||
/// </summary>
|
||||
public bool IsSignatureEnabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets signature for new messages. Null if signature is not needed.
|
||||
/// </summary>
|
||||
public Guid? SignatureIdForNewMessages { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets signature for following messages. Null if signature is not needed.
|
||||
/// </summary>
|
||||
public Guid? SignatureIdForFollowingMessages { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using SQLite;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
@@ -107,6 +108,12 @@ namespace Wino.Core.Domain.Entities
|
||||
/// </summary>
|
||||
public string DraftId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this mail is only created locally.
|
||||
/// </summary>
|
||||
[Ignore]
|
||||
public bool IsLocalDraft => !string.IsNullOrEmpty(DraftId) && DraftId.StartsWith(Constants.LocalDraftStartPrefix);
|
||||
|
||||
/// <summary>
|
||||
/// Whether this copy is draft or not.
|
||||
/// </summary>
|
||||
@@ -135,6 +142,15 @@ namespace Wino.Core.Domain.Entities
|
||||
[Ignore]
|
||||
public MailAccount AssignedAccount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Contact information of the sender if exists.
|
||||
/// Warning: This field is not populated by queries.
|
||||
/// Services or View Models are responsible for populating this field.
|
||||
/// </summary>
|
||||
[Ignore]
|
||||
public AccountContact SenderContact { get; set; }
|
||||
|
||||
public IEnumerable<Guid> GetContainingIds() => [UniqueId];
|
||||
public override string ToString() => $"{Subject} <-> {Id}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,6 +67,9 @@ namespace Wino.Core.Domain.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
public static MailItemFolder CreateMoreFolder() => new MailItemFolder() { IsSticky = true, SpecialFolderType = SpecialFolderType.More, FolderName = Translator.MoreFolderNameOverride };
|
||||
public static MailItemFolder CreateCategoriesFolder() => new MailItemFolder() { IsSticky = true, SpecialFolderType = SpecialFolderType.Category, FolderName = Translator.CategoriesFolderNameOverride };
|
||||
|
||||
public override string ToString() => FolderName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,10 @@ namespace Wino.Core.Domain.Entities
|
||||
|
||||
public Guid AccountId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Unique object storage for authenticators if needed.
|
||||
/// </summary>
|
||||
public string UniqueId { get; set; }
|
||||
public string Address { get; set; }
|
||||
|
||||
public void RefreshTokens(TokenInformationBase tokenInformationBase)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
ManuelSetupWaiting,
|
||||
TestingConnection,
|
||||
AutoDiscoverySetup,
|
||||
AutoDiscoveryInProgress
|
||||
AutoDiscoveryInProgress,
|
||||
FetchingProfileInformation
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
Czech,
|
||||
Chinese,
|
||||
Spanish,
|
||||
French
|
||||
French,
|
||||
Indonesian,
|
||||
Greek,
|
||||
PortugeseBrazil,
|
||||
Italian
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
public enum EditorToolbarSectionType
|
||||
{
|
||||
None,
|
||||
Format,
|
||||
Insert,
|
||||
Draw,
|
||||
Options
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
All,
|
||||
Unread,
|
||||
Flagged,
|
||||
Mentions
|
||||
Mentions,
|
||||
Files
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,10 @@
|
||||
ChangeFlag,
|
||||
AlwaysMoveTo,
|
||||
MoveToFocused,
|
||||
RenameFolder
|
||||
Archive,
|
||||
RenameFolder,
|
||||
EmptyFolder,
|
||||
MarkFolderRead,
|
||||
}
|
||||
|
||||
// UI requests
|
||||
@@ -44,6 +47,7 @@
|
||||
DarkEditor,
|
||||
LightEditor,
|
||||
Print,
|
||||
DiscardLocalDraft,
|
||||
Navigate // For toast activation
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
public enum MenuPaneMode
|
||||
{
|
||||
Visible,
|
||||
Hidden
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
public enum ReaderFont
|
||||
{
|
||||
Arial,
|
||||
TimesNewRoman,
|
||||
Verdana,
|
||||
Tahoma,
|
||||
CourierNew,
|
||||
Georgia,
|
||||
TrebuchetMS,
|
||||
Calibri,
|
||||
Helvetica
|
||||
}
|
||||
}
|
||||
12
Wino.Core.Domain/Enums/ServerBackgroundMode.cs
Normal file
12
Wino.Core.Domain/Enums/ServerBackgroundMode.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// What should happen to server app when the client is terminated.
|
||||
/// </summary>
|
||||
public enum ServerBackgroundMode
|
||||
{
|
||||
MinimizedTray, // Still runs, tray icon is visible.
|
||||
Invisible, // Still runs, tray icon is invisible.
|
||||
Terminate // Server is terminated as Wino terminates.
|
||||
}
|
||||
}
|
||||
11
Wino.Core.Domain/Enums/StartupBehaviorResult.cs
Normal file
11
Wino.Core.Domain/Enums/StartupBehaviorResult.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
public enum StartupBehaviorResult
|
||||
{
|
||||
Enabled,
|
||||
Disabled,
|
||||
DisabledByUser,
|
||||
DisabledByPolicy,
|
||||
Fatal
|
||||
}
|
||||
}
|
||||
12
Wino.Core.Domain/Enums/SynchronizationSource.cs
Normal file
12
Wino.Core.Domain/Enums/SynchronizationSource.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumeration for the source of synchronization.
|
||||
/// Right now it can either be from the client or the server.
|
||||
/// </summary>
|
||||
public enum SynchronizationSource
|
||||
{
|
||||
Client,
|
||||
Server
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,10 @@
|
||||
{
|
||||
FoldersOnly, // Only synchronize folder metadata.
|
||||
ExecuteRequests, // Run the queued requests, and then synchronize if needed.
|
||||
Inbox, // Only Inbox
|
||||
Inbox, // Only Inbox, Sent and Draft folders.
|
||||
Custom, // Only sync folders that are specified in the options.
|
||||
Full, // Synchronize everything
|
||||
Full, // Synchronize all folders. This won't update profile or alias information.
|
||||
UpdateProfile, // Only update profile information
|
||||
Alias, // Only update alias information
|
||||
}
|
||||
}
|
||||
|
||||
10
Wino.Core.Domain/Enums/WinoCustomMessageDialogIcon.cs
Normal file
10
Wino.Core.Domain/Enums/WinoCustomMessageDialogIcon.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
public enum WinoCustomMessageDialogIcon
|
||||
{
|
||||
Information,
|
||||
Warning,
|
||||
Error,
|
||||
Question
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,10 @@
|
||||
PersonalizationPage,
|
||||
MessageListPage,
|
||||
MailListPage,
|
||||
ReadingPanePage,
|
||||
SettingOptionsPage
|
||||
ReadComposePanePage,
|
||||
LanguageTimePage,
|
||||
AppPreferencesPage,
|
||||
SettingOptionsPage,
|
||||
AliasManagementPage
|
||||
}
|
||||
}
|
||||
|
||||
11
Wino.Core.Domain/Enums/WinoServerConnectionStatus.cs
Normal file
11
Wino.Core.Domain/Enums/WinoServerConnectionStatus.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
public enum WinoServerConnectionStatus
|
||||
{
|
||||
None,
|
||||
Connecting,
|
||||
Connected,
|
||||
Disconnected,
|
||||
Failed
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// An exception thrown when the background task execution policies are denied for some reason.
|
||||
/// </summary>
|
||||
public class BackgroundTaskExecutionRequestDeniedException : Exception { }
|
||||
}
|
||||
@@ -4,8 +4,11 @@ namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
public class ImapClientPoolException : Exception
|
||||
{
|
||||
public ImapClientPoolException(Exception innerException) : base(Translator.Exception_ImapClientPoolFailed, innerException)
|
||||
public ImapClientPoolException(Exception innerException, string protocolLog) : base(Translator.Exception_ImapClientPoolFailed, innerException)
|
||||
{
|
||||
ProtocolLog = protocolLog;
|
||||
}
|
||||
|
||||
public string ProtocolLog { get; }
|
||||
}
|
||||
}
|
||||
|
||||
21
Wino.Core.Domain/Exceptions/ImapConnectionFailedPackage.cs
Normal file
21
Wino.Core.Domain/Exceptions/ImapConnectionFailedPackage.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using Wino.Core.Domain.Models.AutoDiscovery;
|
||||
|
||||
namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
public class ImapConnectionFailedPackage
|
||||
{
|
||||
public ImapConnectionFailedPackage(Exception error, string protocolLog, AutoDiscoverySettings settings)
|
||||
{
|
||||
Error = error;
|
||||
ProtocolLog = protocolLog;
|
||||
Settings = settings;
|
||||
}
|
||||
|
||||
public AutoDiscoverySettings Settings { get; }
|
||||
public Exception Error { get; }
|
||||
public string ProtocolLog { get; }
|
||||
|
||||
public string GetErrorMessage() => Error.InnerException == null ? Error.Message : Error.InnerException.Message;
|
||||
}
|
||||
}
|
||||
7
Wino.Core.Domain/Exceptions/MissingAliasException.cs
Normal file
7
Wino.Core.Domain/Exceptions/MissingAliasException.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
public class MissingAliasException : System.Exception
|
||||
{
|
||||
public MissingAliasException() : base(Translator.Exception_MissingAlias) { }
|
||||
}
|
||||
}
|
||||
12
Wino.Core.Domain/Exceptions/WinoServerException.cs
Normal file
12
Wino.Core.Domain/Exceptions/WinoServerException.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// All server crash types. Wino Server ideally should not throw anything else than this Exception type.
|
||||
/// </summary>
|
||||
public class WinoServerException : Exception
|
||||
{
|
||||
public WinoServerException(string message) : base(message) { }
|
||||
}
|
||||
}
|
||||
20
Wino.Core.Domain/Extensions/MimeExtensions.cs
Normal file
20
Wino.Core.Domain/Extensions/MimeExtensions.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
|
||||
namespace Wino.Core.Domain.Extensions
|
||||
{
|
||||
public static class MimeExtensions
|
||||
{
|
||||
public static string GetBase64MimeMessage(this MimeKit.MimeMessage message)
|
||||
{
|
||||
using System.IO.MemoryStream memoryStream = new();
|
||||
message.WriteTo(MimeKit.FormatOptions.Default, memoryStream);
|
||||
byte[] buffer = memoryStream.GetBuffer();
|
||||
int count = (int)memoryStream.Length;
|
||||
|
||||
return Convert.ToBase64String(buffer);
|
||||
}
|
||||
|
||||
public static MimeKit.MimeMessage GetMimeMessageFromBase64(this string base64)
|
||||
=> MimeKit.MimeMessage.Load(new System.IO.MemoryStream(Convert.FromBase64String(base64)));
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,17 @@ namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
public interface IAccountMenuItem : IMenuItem
|
||||
{
|
||||
bool IsEnabled { get; set; }
|
||||
double SynchronizationProgress { get; set; }
|
||||
int UnreadItemCount { get; set; }
|
||||
IEnumerable<MailAccount> HoldingAccounts { get; }
|
||||
void UpdateAccount(MailAccount account);
|
||||
}
|
||||
|
||||
public interface IMergedAccountMenuItem : IAccountMenuItem
|
||||
{
|
||||
int MergedAccountCount { get; }
|
||||
|
||||
MergedInbox Parameter { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,5 +13,26 @@ namespace Wino.Core.Domain.Interfaces
|
||||
/// Name representation of the view model that will be used to identify the startup entity on launch.
|
||||
/// </summary>
|
||||
string StartupEntityTitle { get; }
|
||||
|
||||
/// <summary>
|
||||
/// E-mail addresses that this account holds.
|
||||
/// </summary>
|
||||
|
||||
string StartupEntityAddresses { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Represents the account order in the accounts list.
|
||||
/// </summary>
|
||||
int Order { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Provider details of the account.
|
||||
/// </summary>
|
||||
IProviderDetail ProviderDetail { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// How many accounts this provider has.
|
||||
/// </summary>
|
||||
int HoldingAccountCount { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Wino.Core.Domain.Entities;
|
||||
using Wino.Core.Domain.Models.Accounts;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
@@ -68,12 +69,91 @@ namespace Wino.Core.Domain.Interfaces
|
||||
/// <returns>Current account synchronization modifier.</returns>
|
||||
Task<string> UpdateSynchronizationIdentifierAsync(Guid accountId, string newIdentifier);
|
||||
|
||||
/// <summary>
|
||||
/// Renames the merged inbox with the given id.
|
||||
/// </summary>
|
||||
/// <param name="mergedInboxId">Merged Inbox id</param>
|
||||
/// <param name="newName">New name for the merged/linked inbox.</param>
|
||||
Task RenameMergedAccountAsync(Guid mergedInboxId, string newName);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new merged inbox with the given accounts.
|
||||
/// </summary>
|
||||
/// <param name="mergedInbox">Merged inbox properties.</param>
|
||||
/// <param name="accountsToMerge">List of accounts to merge together.</param>
|
||||
Task CreateMergeAccountsAsync(MergedInbox mergedInbox, IEnumerable<MailAccount> accountsToMerge);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the merged inbox with the given id with the new linked accounts.
|
||||
/// </summary>
|
||||
/// <param name="mergedInboxId">Updating merged inbox id.</param>
|
||||
/// <param name="linkedAccountIds">List of linked account ids.</param>
|
||||
Task UpdateMergedInboxAsync(Guid mergedInboxId, IEnumerable<Guid> linkedAccountIds);
|
||||
|
||||
/// <summary>
|
||||
/// Destroys the merged inbox with the given id.
|
||||
/// </summary>
|
||||
/// <param name="mergedInboxId">Merged inbox id to destroy.</param>
|
||||
Task UnlinkMergedInboxAsync(Guid mergedInboxId);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the account listing orders.
|
||||
/// </summary>
|
||||
/// <param name="accountIdOrderPair">AccountId-OrderNumber pair for all accounts.</param>
|
||||
Task UpdateAccountOrdersAsync(Dictionary<Guid, int> accountIdOrderPair);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the account aliases.
|
||||
/// </summary>
|
||||
/// <param name="accountId">Account id.</param>
|
||||
/// <returns>A list of MailAccountAlias that has e-mail aliases.</returns>
|
||||
Task<List<MailAccountAlias>> GetAccountAliasesAsync(Guid accountId);
|
||||
|
||||
/// <summary>
|
||||
/// Updated account's aliases.
|
||||
/// </summary>
|
||||
/// <param name="accountId">Account id to update aliases for.</param>
|
||||
/// <param name="aliases">Full list of updated aliases.</param>
|
||||
/// <returns></returns>
|
||||
Task UpdateAccountAliasesAsync(Guid accountId, List<MailAccountAlias> aliases);
|
||||
|
||||
/// <summary>
|
||||
/// Delete account alias.
|
||||
/// </summary>
|
||||
/// <param name="aliasId">Alias to remove.</param>
|
||||
Task DeleteAccountAliasAsync(Guid aliasId);
|
||||
|
||||
/// <summary>
|
||||
/// Updated profile information of the account.
|
||||
/// </summary>
|
||||
/// <param name="accountId">Account id to update info for.</param>
|
||||
/// <param name="profileInformation">Info data.</param>
|
||||
/// <returns></returns>
|
||||
Task UpdateProfileInformationAsync(Guid accountId, ProfileInformation profileInformation);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a root + primary alias for the account.
|
||||
/// This is only called when the account is created.
|
||||
/// </summary>
|
||||
/// <param name="accountId">Account id.</param>
|
||||
/// <param name="address">Address to create root primary alias from.</param>
|
||||
Task CreateRootAliasAsync(Guid accountId, string address);
|
||||
|
||||
/// <summary>
|
||||
/// Will compare local-remote aliases and update the local ones or add/delete new ones.
|
||||
/// </summary>
|
||||
/// <param name="remoteAccountAliases">Remotely fetched basic alias info from synchronizer.</param>
|
||||
/// <param name="account">Account to update remote aliases for..</param>
|
||||
Task UpdateRemoteAliasInformationAsync(MailAccount account, List<RemoteAccountAlias> remoteAccountAliases);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the primary account alias for the given account id.
|
||||
/// Used when creating draft messages.
|
||||
/// </summary>
|
||||
/// <param name="accountId">Account id.</param>
|
||||
/// <returns>Primary alias for the account.</returns>
|
||||
Task<MailAccountAlias> GetPrimaryAccountAliasAsync(Guid accountId);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
public interface IAppInitializerService
|
||||
{
|
||||
string GetApplicationDataFolder();
|
||||
|
||||
Task MigrateAsync();
|
||||
}
|
||||
}
|
||||
21
Wino.Core.Domain/Interfaces/IApplicationConfiguration.cs
Normal file
21
Wino.Core.Domain/Interfaces/IApplicationConfiguration.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Singleton object that holds the application data folder path and the publisher shared folder path.
|
||||
/// Load the values before calling any service.
|
||||
/// App data folder is used for storing files.
|
||||
/// Pubhlisher cache folder is only used for database file so other apps can access it in the same package by same publisher.
|
||||
/// </summary>
|
||||
public interface IApplicationConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// Application data folder.
|
||||
/// </summary>
|
||||
string ApplicationDataFolderPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Publisher shared folder path.
|
||||
/// </summary>
|
||||
string PublisherSharedFolderPath { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks;
|
||||
using Wino.Core.Domain.Entities;
|
||||
using Wino.Core.Domain.Enums;
|
||||
|
||||
@@ -23,28 +22,12 @@ namespace Wino.Core.Domain.Interfaces
|
||||
|
||||
/// <summary>
|
||||
/// Initial creation of token. Requires user interaction.
|
||||
/// This will save token into database, but still returns for account creation
|
||||
/// This will cache the token but still returns for account creation
|
||||
/// since account address is required.
|
||||
/// </summary>
|
||||
/// <param name="expectedAccountAddress">Token cache might ask for regeneration of token for specific
|
||||
/// account address. If one is provided and re-generation native token doesn't belong to this address
|
||||
/// token saving to database won't happen.</param>
|
||||
/// <returns>Freshly created TokenInformation..</returns>
|
||||
Task<TokenInformation> GenerateTokenAsync(MailAccount account, bool saveToken);
|
||||
|
||||
/// <summary>
|
||||
/// Required for external authorization on launched browser to continue.
|
||||
/// Used for Gmail.
|
||||
/// </summary>
|
||||
/// <param name="authorizationResponseUri">Response's redirect uri.</param>
|
||||
void ContinueAuthorization(Uri authorizationResponseUri);
|
||||
|
||||
/// <summary>
|
||||
/// For external browser required authentications.
|
||||
/// Canceling Gmail authentication dialog etc.
|
||||
/// </summary>
|
||||
void CancelAuthorization();
|
||||
|
||||
/// <summary>
|
||||
/// ClientId in case of needed for authorization/authentication.
|
||||
/// </summary>
|
||||
|
||||
6
Wino.Core.Domain/Interfaces/IAuthenticatorTypes.cs
Normal file
6
Wino.Core.Domain/Interfaces/IAuthenticatorTypes.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
public interface IOutlookAuthenticator : IAuthenticator { }
|
||||
public interface IGmailAuthenticator : IAuthenticator { }
|
||||
public interface IImapAuthenticator : IAuthenticator { }
|
||||
}
|
||||
@@ -5,15 +5,14 @@ namespace Wino.Core.Domain.Interfaces
|
||||
public interface IBackgroundTaskService
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages background task registrations, requests access if needed, checks the statusses of them etc.
|
||||
/// </summary>
|
||||
/// <exception cref="BackgroundTaskExecutionRequestDeniedException">If the access request is denied for some reason.</exception>
|
||||
/// <exception cref="BackgroundTaskRegistrationFailedException">If one of the requires background tasks are failed during registration.</exception>
|
||||
Task HandleBackgroundTaskRegistrations();
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters all existing background tasks. Useful for migrations.
|
||||
/// Unregisters all background tasks once.
|
||||
/// This is used to clean up the background tasks when the app is updated.
|
||||
/// </summary>
|
||||
void UnregisterAllBackgroundTask();
|
||||
|
||||
/// <summary>
|
||||
/// Registers required background tasks.
|
||||
/// </summary>
|
||||
Task RegisterBackgroundTasksAsync();
|
||||
}
|
||||
}
|
||||
|
||||
62
Wino.Core.Domain/Interfaces/IBaseSynchronizer.cs
Normal file
62
Wino.Core.Domain/Interfaces/IBaseSynchronizer.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MailKit;
|
||||
using Wino.Core.Domain.Entities;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Models.Accounts;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
using Wino.Core.Domain.Models.Synchronization;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
public interface IBaseSynchronizer
|
||||
{
|
||||
/// <summary>
|
||||
/// Account that is assigned for this synchronizer.
|
||||
/// </summary>
|
||||
MailAccount Account { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Synchronizer state.
|
||||
/// </summary>
|
||||
AccountSynchronizerState State { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Queues a single request to be executed in the next synchronization.
|
||||
/// </summary>
|
||||
/// <param name="request">Request to queue.</param>
|
||||
void QueueRequest(IRequestBase request);
|
||||
|
||||
/// <summary>
|
||||
/// TODO
|
||||
/// </summary>
|
||||
/// <returns>Whether active synchronization is stopped or not.</returns>
|
||||
bool CancelActiveSynchronization();
|
||||
|
||||
/// <summary>
|
||||
/// Performs a full synchronization with the server with given options.
|
||||
/// This will also prepares batch requests for execution.
|
||||
/// Requests are executed in the order they are queued and happens before the synchronization.
|
||||
/// Result of the execution queue is processed during the synchronization.
|
||||
/// </summary>
|
||||
/// <param name="options">Options for synchronization.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>Result summary of synchronization.</returns>
|
||||
Task<SynchronizationResult> SynchronizeAsync(SynchronizationOptions options, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Synchronizes profile information with the server.
|
||||
/// Sender name and Profile picture are updated.
|
||||
/// </summary>
|
||||
/// <returns>Profile information model that holds the values.</returns>
|
||||
Task<ProfileInformation> GetProfileInformationAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Downloads a single MIME message from the server and saves it to disk.
|
||||
/// </summary>
|
||||
/// <param name="mailItem">Mail item to download from server.</param>
|
||||
/// <param name="transferProgress">Optional progress reporting for download operation.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
Task DownloadMissingMimeMessageAsync(IMailItem mailItem, ITransferProgress transferProgress, CancellationToken cancellationToken = default);
|
||||
}
|
||||
}
|
||||
8
Wino.Core.Domain/Interfaces/IClientMessage.cs
Normal file
8
Wino.Core.Domain/Interfaces/IClientMessage.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// All messages that Client sends to Server and awaits a response in return.
|
||||
/// For example; triggering a new synchronization request.
|
||||
/// </summary>
|
||||
public interface IClientMessage;
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
public interface IConfirmationDialog
|
||||
{
|
||||
Task<bool> ShowDialogAsync(string title, string message, string approveButtonTitle);
|
||||
}
|
||||
}
|
||||
9
Wino.Core.Domain/Interfaces/ICreateAccountAliasDialog.cs
Normal file
9
Wino.Core.Domain/Interfaces/ICreateAccountAliasDialog.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using Wino.Core.Domain.Entities;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
public interface ICreateAccountAliasDialog
|
||||
{
|
||||
public MailAccountAlias CreatedAccountAlias { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -15,5 +15,11 @@ namespace Wino.Core.Domain.Interfaces
|
||||
/// Displays preparing folders page.
|
||||
/// </summary>
|
||||
void ShowPreparingFolders();
|
||||
|
||||
/// <summary>
|
||||
/// Updates account properties for the welcome imap setup dialog and starts the setup.
|
||||
/// </summary>
|
||||
/// <param name="account">Account properties.</param>
|
||||
void StartImapConnectionSetup(MailAccount account);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Threading.Tasks;
|
||||
using Wino.Core.Domain.Entities;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Models.Accounts;
|
||||
using Wino.Core.Domain.Models.Folders;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
@@ -13,11 +15,10 @@ namespace Wino.Core.Domain.Interfaces
|
||||
Task<byte[]> PickWindowsFileContentAsync(params object[] typeFilters);
|
||||
Task<bool> ShowConfirmationDialogAsync(string question, string title, string confirmationButtonTitle);
|
||||
Task<bool> ShowHardDeleteConfirmationAsync();
|
||||
Task<IStoreRatingDialog> ShowRatingDialogAsync();
|
||||
Task HandleSystemFolderConfigurationDialogAsync(Guid accountId, IFolderService folderService);
|
||||
Task<bool> ShowCustomThemeBuilderDialogAsync();
|
||||
|
||||
Task ShowMessageAsync(string message, string title);
|
||||
Task ShowMessageAsync(string message, string title, WinoCustomMessageDialogIcon icon);
|
||||
void InfoBarMessage(string title, string message, InfoBarMessageType messageType);
|
||||
void InfoBarMessage(string title, string message, InfoBarMessageType messageType, string actionButtonText, Action action);
|
||||
|
||||
@@ -25,12 +26,19 @@ namespace Wino.Core.Domain.Interfaces
|
||||
|
||||
// Custom dialogs
|
||||
Task<IMailItemFolder> ShowMoveMailFolderDialogAsync(List<IMailItemFolder> availableFolders);
|
||||
Task<Tuple<string, MailProviderType>> ShowNewAccountMailProviderDialogAsync(List<IProviderDetail> availableProviders);
|
||||
Task<AccountCreationDialogResult> ShowNewAccountMailProviderDialogAsync(List<IProviderDetail> availableProviders);
|
||||
IAccountCreationDialog GetAccountCreationDialog(MailProviderType type);
|
||||
Task<string> ShowTextInputDialogAsync(string currentInput, string dialogTitle, string dialogDescription);
|
||||
Task<string> ShowTextInputDialogAsync(string currentInput, string dialogTitle, string dialogDescription, string primaryButtonText);
|
||||
Task<MailAccount> ShowEditAccountDialogAsync(MailAccount account);
|
||||
Task<MailAccount> ShowAccountPickerDialogAsync(List<MailAccount> availableAccounts);
|
||||
|
||||
/// <summary>
|
||||
/// Displays a dialog to the user for reordering accounts.
|
||||
/// </summary>
|
||||
/// <param name="availableAccounts">Available accounts in order.</param>
|
||||
/// <returns>Result model that has dict of AccountId-AccountOrder.</returns>
|
||||
Task ShowAccountReorderDialogAsync(ObservableCollection<IAccountProviderDetailViewModel> availableAccounts);
|
||||
|
||||
/// <summary>
|
||||
/// Presents a dialog to the user for selecting folder.
|
||||
/// </summary>
|
||||
@@ -38,5 +46,23 @@ namespace Wino.Core.Domain.Interfaces
|
||||
/// <param name="reason">The reason behind the picking operation
|
||||
/// <returns>Selected folder structure. Null if none.</returns>
|
||||
Task<IMailItemFolder> PickFolderAsync(Guid accountId, PickFolderReason reason, IFolderService folderService);
|
||||
|
||||
/// <summary>
|
||||
/// Presents a dialog to the user for signature creation/modification.
|
||||
/// </summary>
|
||||
/// <returns>Signature information. Null if canceled.</returns>
|
||||
Task<AccountSignature> ShowSignatureEditorDialog(AccountSignature signatureModel = null);
|
||||
|
||||
/// <summary>
|
||||
/// Presents a dialog to the user for account alias creation/modification.
|
||||
/// </summary>
|
||||
/// <returns>Created alias model if not canceled.</returns>
|
||||
Task<ICreateAccountAliasDialog> ShowCreateAccountAliasDialogAsync();
|
||||
Task<bool> ShowWinoCustomMessageDialogAsync(string title,
|
||||
string description,
|
||||
string approveButtonText,
|
||||
WinoCustomMessageDialogIcon? icon,
|
||||
string cancelButtonText = "",
|
||||
string dontAskAgainConfigurationKey = "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,5 +8,13 @@ namespace Wino.Core.Domain.Interfaces
|
||||
Task<string> CopyFileAsync(string sourceFilePath, string destinationFolderPath);
|
||||
Task<Stream> GetFileStreamAsync(string folderPath, string fileName);
|
||||
Task<string> GetFileContentByApplicationUriAsync(string resourcePath);
|
||||
|
||||
/// <summary>
|
||||
/// Zips all existing logs and saves to picked destination folder.
|
||||
/// </summary>
|
||||
/// <param name="logsFolder">Folder path where logs are stored.</param>
|
||||
/// <param name="destinationFolder">Target path to save the archive file.</param>
|
||||
/// <returns>True if zip is created with at least one item, false if logs are not found.</returns>
|
||||
Task<bool> SaveLogsToFolderAsync(string logsFolder, string destinationFolder);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace Wino.Core.Domain.Interfaces
|
||||
public interface IFolderMenuItem : IBaseFolderMenuItem
|
||||
{
|
||||
MailAccount ParentAccount { get; }
|
||||
void UpdateParentAccounnt(MailAccount account);
|
||||
}
|
||||
|
||||
public interface IMergedAccountFolderMenuItem : IBaseFolderMenuItem { }
|
||||
@@ -19,6 +20,7 @@ namespace Wino.Core.Domain.Interfaces
|
||||
int UnreadItemCount { get; set; }
|
||||
SpecialFolderType SpecialFolderType { get; }
|
||||
IEnumerable<IMailItemFolder> HandlingFolders { get; }
|
||||
IEnumerable<IMenuItem> SubMenuItems { get; }
|
||||
bool IsMoveTarget { get; }
|
||||
bool IsSticky { get; }
|
||||
bool IsSystemFolder { get; }
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Wino.Core.Domain.Entities;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Models.Accounts;
|
||||
using Wino.Core.Domain.Models.Folders;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
using Wino.Core.Domain.Models.Synchronization;
|
||||
@@ -15,13 +16,10 @@ namespace Wino.Core.Domain.Interfaces
|
||||
Task<MailItemFolder> GetFolderAsync(Guid folderId);
|
||||
Task<MailItemFolder> GetFolderAsync(Guid accountId, string remoteFolderId);
|
||||
Task<List<MailItemFolder>> GetFoldersAsync(Guid accountId);
|
||||
Task<List<MailItemFolder>> GetUnreadUpdateFoldersAsync(Guid accountId);
|
||||
Task SetSpecialFolderAsync(Guid folderId, SpecialFolderType type);
|
||||
Task<MailItemFolder> GetSpecialFolderByAccountIdAsync(Guid accountId, SpecialFolderType type);
|
||||
Task<int> GetCurrentItemCountForFolder(Guid folderId);
|
||||
Task<int> GetFolderNotificationBadgeAsync(Guid folderId);
|
||||
Task ChangeStickyStatusAsync(Guid folderId, bool isSticky);
|
||||
Task UpdateCustomServerMailListAsync(Guid accountId, List<MailItemFolder> folders);
|
||||
|
||||
Task<MailAccount> UpdateSystemFolderConfigurationAsync(Guid accountId, SystemFolderConfiguration configuration);
|
||||
Task ChangeFolderSynchronizationStateAsync(Guid folderId, bool isSynchronizationEnabled);
|
||||
@@ -39,25 +37,6 @@ namespace Wino.Core.Domain.Interfaces
|
||||
/// </summary>
|
||||
Task<List<MailFolderPairMetadata>> GetMailFolderPairMetadatasAsync(string mailCopyId);
|
||||
|
||||
// v2
|
||||
|
||||
/// <summary>
|
||||
/// Performs bulk update for the given folders.
|
||||
/// Used in Gmail.
|
||||
/// </summary>
|
||||
/// <param name="accountId">Account that folders belong to.</param>
|
||||
/// <param name="allFolders">Folders to update.</param>
|
||||
Task BulkUpdateFolderStructureAsync(Guid accountId, List<MailItemFolder> allFolders);
|
||||
|
||||
/// <summary>
|
||||
/// Updates Folder's delta synchronization identifier.
|
||||
/// Only used in Outlook since it does per-folder sync.
|
||||
/// </summary>
|
||||
/// <param name="folderId">Folder id</param>
|
||||
/// <param name="synchronizationIdentifier">New synchronization identifier.</param>
|
||||
/// <returns>New identifier if success.</returns>
|
||||
Task<string> UpdateFolderDeltaSynchronizationIdentifierAsync(Guid folderId, string synchronizationIdentifier);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the folder for the given account by remote folder id.
|
||||
/// </summary>
|
||||
@@ -87,6 +66,29 @@ namespace Wino.Core.Domain.Interfaces
|
||||
/// <returns>True if Inbox exists, False if not.</returns>
|
||||
Task<bool> IsInboxAvailableForAccountAsync(Guid accountId);
|
||||
|
||||
Task TestAsync();
|
||||
/// <summary>
|
||||
/// Updates folder's LastSynchronizedDate to now.
|
||||
/// </summary>
|
||||
/// <param name="folderId">Folder to update.</param>
|
||||
Task UpdateFolderLastSyncDateAsync(Guid folderId);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the given folder.
|
||||
/// </summary>
|
||||
/// <param name="folder">Folder to update.</param>
|
||||
Task UpdateFolderAsync(MailItemFolder folder);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the active folder menu items for the given account for UI.
|
||||
/// </summary>
|
||||
/// <param name="accountMenuItem">Account to get folder menu items for.</param>
|
||||
Task<IEnumerable<IMenuItem>> GetAccountFoldersForDisplayAsync(IAccountMenuItem accountMenuItem);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of unread item counts for the given account ids.
|
||||
/// Every folder that is marked as show unread badge is included.
|
||||
/// </summary>
|
||||
/// <param name="accountIds">Account ids to get unread folder counts for.</param>
|
||||
Task<List<UnreadItemCountResult>> GetUnreadItemCountResultsAsync(IEnumerable<Guid> accountIds);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
using System.Collections.Generic;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Models.Reader;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Service to access available fonts.
|
||||
/// </summary>
|
||||
public interface IFontService
|
||||
{
|
||||
List<ReaderFontModel> GetReaderFonts();
|
||||
ReaderFontModel GetCurrentReaderFont();
|
||||
int GetCurrentReaderFontSize();
|
||||
|
||||
void ChangeReaderFont(ReaderFont font);
|
||||
void ChangeReaderFontSize(int size);
|
||||
/// <summary>
|
||||
/// Get available fonts. Default + installed system fonts.
|
||||
/// Fonts initialized only once. To refresh fonts, restart the application.
|
||||
/// </summary>
|
||||
List<string> GetFonts();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
using System.Collections.Specialized;
|
||||
using Wino.Core.Domain.Models.Launch;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
namespace Wino.Core.Domain.Interfaces;
|
||||
|
||||
public interface ILaunchProtocolService
|
||||
{
|
||||
public interface ILaunchProtocolService
|
||||
{
|
||||
object LaunchParameter { get; set; }
|
||||
NameValueCollection MailtoParameters { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Used to handle toasts.
|
||||
/// </summary>
|
||||
object LaunchParameter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Used to handle mailto links.
|
||||
/// </summary>
|
||||
MailToUri MailToUri { get; set; }
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{
|
||||
public interface ILogInitializer
|
||||
{
|
||||
void SetupLogger(string logFolderPath);
|
||||
void SetupLogger(string fullLogFilePath);
|
||||
|
||||
void RefreshLoggingLevel();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MimeKit;
|
||||
using Wino.Core.Domain.Entities;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
|
||||
@@ -11,12 +11,7 @@ namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
Task<MailCopy> GetSingleMailItemAsync(string mailCopyId, string remoteFolderId);
|
||||
Task<MailCopy> GetSingleMailItemAsync(Guid uniqueMailId);
|
||||
Task<MailCopy> CreateDraftAsync(MailAccount composerAccount, MimeMessage generatedReplyMime, MimeMessage replyingMimeMessage = null, IMailItem replyingMailItem = null);
|
||||
Task<List<IMailItem>> FetchMailsAsync(MailListInitializationOptions options);
|
||||
|
||||
Task<List<string>> GetMailIdsByFolderIdAsync(Guid folderId);
|
||||
|
||||
// v2
|
||||
Task<List<IMailItem>> FetchMailsAsync(MailListInitializationOptions options, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes all mail copies for all folders.
|
||||
@@ -48,15 +43,12 @@ namespace Wino.Core.Domain.Interfaces
|
||||
|
||||
/// <summary>
|
||||
/// Maps new mail item with the existing local draft copy.
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="newMailCopyId"></param>
|
||||
/// <param name="newDraftId"></param>
|
||||
/// <param name="newThreadId"></param>
|
||||
/// <returns></returns>
|
||||
Task MapLocalDraftAsync(string newMailCopyId, string newDraftId, string newThreadId);
|
||||
|
||||
Task<MimeMessage> CreateDraftMimeMessageAsync(Guid accountId, DraftCreationOptions options);
|
||||
Task UpdateMailAsync(MailCopy mailCopy);
|
||||
|
||||
/// <summary>
|
||||
@@ -77,5 +69,43 @@ namespace Wino.Core.Domain.Interfaces
|
||||
/// <param name="uniqueMailId">Unique id of the mail item.</param>
|
||||
/// <returns>Account that mail belongs to.</returns>
|
||||
Task<MailAccount> GetMailAccountByUniqueIdAsync(Guid uniqueMailId);
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether the given mail copy id exists in the database.
|
||||
/// Safely used for Outlook to prevent downloading the same mail twice.
|
||||
/// For Gmail, it should be avoided since one mail may belong to multiple folders.
|
||||
/// </summary>
|
||||
/// <param name="mailCopyId">Native mail id of the message.</param>
|
||||
Task<bool> IsMailExistsAsync(string mailCopyId);
|
||||
|
||||
/// <summary>
|
||||
/// Returns all mails for given folder id.
|
||||
/// </summary>
|
||||
/// <param name="folderId">Folder id to get mails for</param>
|
||||
Task<List<MailCopy>> GetMailsByFolderIdAsync(Guid folderId);
|
||||
|
||||
/// <summary>
|
||||
/// Returns all unread mails for given folder id.
|
||||
/// </summary>
|
||||
/// <param name="folderId">Folder id to get unread mails for.</param>
|
||||
Task<List<MailCopy>> GetUnreadMailsByFolderIdAsync(Guid folderId);
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether the mail exists in the folder.
|
||||
/// When deciding Create or Update existing mail, we need to check if the mail exists in the folder.
|
||||
/// </summary>
|
||||
/// <param name="mailCopyId">MailCopy id</param>
|
||||
/// <param name="folderId">Folder's local id.</param>
|
||||
/// <returns>Whether mail exists in the folder or not.</returns>
|
||||
Task<bool> IsMailExistsAsync(string mailCopyId, Guid folderId);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a draft MailCopy and MimeMessage based on the given options.
|
||||
/// For forward/reply it would include the referenced message.
|
||||
/// </summary>
|
||||
/// <param name="accountId">AccountId which should have new draft.</param>
|
||||
/// <param name="draftCreationOptions">Options like new email/forward/draft.</param>
|
||||
/// <returns>Draft MailCopy and Draft MimeMessage as base64.</returns>
|
||||
Task<(MailCopy draftMailCopy, string draftBase64MimeMessage)> CreateDraftAsync(Guid accountId, DraftCreationOptions draftCreationOptions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,9 +8,23 @@ namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
string GetWebAuthenticationBrokerUri();
|
||||
Task<string> GetMimeMessageStoragePath();
|
||||
Task<string> GetQuillEditorBundlePathAsync();
|
||||
Task<string> GetEditorBundlePathAsync();
|
||||
Task LaunchFileAsync(string filePath);
|
||||
Task LaunchUriAsync(Uri uri);
|
||||
|
||||
/// <summary>
|
||||
/// Launches the default browser with the specified uri and waits for protocol activation to finish.
|
||||
/// </summary>
|
||||
/// <param name="authenticator"></param>
|
||||
/// <returns>Response callback from the browser.</returns>
|
||||
Task<Uri> GetAuthorizationResponseUriAsync(IAuthenticator authenticator, string authorizationUri);
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes GetAuthorizationResponseUriAsync for current IAuthenticator.
|
||||
/// </summary>
|
||||
/// <param name="authorizationResponseUri"></param>
|
||||
void ContinueAuthorization(Uri authorizationResponseUri);
|
||||
|
||||
bool IsAppRunning();
|
||||
|
||||
string GetFullAppVersion();
|
||||
@@ -21,5 +35,11 @@ namespace Wino.Core.Domain.Interfaces
|
||||
/// Some cryptographic shit is needed for requesting Google authentication in UWP.
|
||||
/// </summary>
|
||||
GoogleAuthorizationRequest GetGoogleAuthorizationRequest();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the function that returns a pointer for main window hwnd for UWP.
|
||||
/// This is used to display WAM broker dialog on running UWP app called by a windowless server code.
|
||||
/// </summary>
|
||||
Func<IntPtr> GetCoreWindowHwnd { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,15 +122,25 @@ namespace Wino.Core.Domain.Interfaces
|
||||
AppLanguage CurrentLanguage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Setting: Display font for the mail reader. Not composer.
|
||||
/// Setting: Display font for the mail reader.
|
||||
/// </summary>
|
||||
ReaderFont ReaderFont { get; set; }
|
||||
string ReaderFont { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Setting: Font size for the mail reader. Not composer.
|
||||
/// Setting: Font size for the mail reader.
|
||||
/// </summary>
|
||||
int ReaderFontSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Setting: Display font for the mail composer.
|
||||
/// </summary>
|
||||
string ComposerFont { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Setting: Font size for the mail composer.
|
||||
/// </summary>
|
||||
int ComposerFontSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Setting: Whether the navigation pane is opened on the last session or not.
|
||||
/// </summary>
|
||||
@@ -140,5 +150,10 @@ namespace Wino.Core.Domain.Interfaces
|
||||
/// Setting: Whether the next item should be automatically selected once the current item is moved or removed.
|
||||
/// </summary>
|
||||
bool AutoSelectNextItem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Setting: Gets or sets what should happen to server app when the client is terminated.
|
||||
/// </summary>
|
||||
ServerBackgroundMode ServerTerminationBehavior { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Wino.Core.Domain.Interfaces
|
||||
TRequest NativeRequest { get; }
|
||||
}
|
||||
|
||||
public interface IRequestBase
|
||||
public interface IRequestBase : IClientMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// Synchronizer option to perform.
|
||||
@@ -40,6 +40,15 @@ namespace Wino.Core.Domain.Interfaces
|
||||
/// Reverts the UI changes applied by <see cref="ApplyUIChanges"/> if the request fails.
|
||||
/// </summary>
|
||||
void RevertUIChanges();
|
||||
|
||||
/// <summary>
|
||||
/// Whether synchronizations should be delayed after executing this request.
|
||||
/// Specially Outlook sometimes don't report changes back immidiately after sending the API request.
|
||||
/// This results following synchronization to miss the changes.
|
||||
/// We add small delay for the following synchronization after executing current requests to overcome this issue.
|
||||
/// Default is false.
|
||||
/// </summary>
|
||||
int ResynchronizationDelay { get; }
|
||||
}
|
||||
|
||||
public interface IRequest : IRequestBase
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Wino.Core.Domain.Entities;
|
||||
|
||||
@@ -7,27 +8,40 @@ namespace Wino.Core.Domain.Interfaces
|
||||
public interface ISignatureService
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the assigned account signature for the account.
|
||||
/// Get one signature by Id.
|
||||
/// </summary>
|
||||
/// <param name="accountId"></param>
|
||||
/// <returns></returns>
|
||||
Task<AccountSignature> GetAccountSignatureAsync(Guid accountId);
|
||||
/// <param name="signatureId">Signature Id.</param>
|
||||
Task<AccountSignature> GetSignatureAsync(Guid signatureId);
|
||||
|
||||
/// <summary>
|
||||
/// Creates the initial signature for new created accounts.
|
||||
/// Returns all signatures for specified account.
|
||||
/// </summary>
|
||||
/// <param name="accountId"></param>
|
||||
/// <returns></returns>
|
||||
/// <param name="accountId">Account id</param>
|
||||
Task<List<AccountSignature>> GetSignaturesAsync(Guid accountId);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new signature for the account.
|
||||
/// </summary>
|
||||
/// <param name="signature">Signature that should be created. It should contain ID and account to which it belongs.</param>
|
||||
Task<AccountSignature> CreateSignatureAsync(AccountSignature signature);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a default Wino signature for the account.
|
||||
/// Needed only for initial account setup.
|
||||
/// </summary>
|
||||
/// <param name="accountId">Account Id.</param>
|
||||
Task<AccountSignature> CreateDefaultSignatureAsync(Guid accountId);
|
||||
|
||||
/// <summary>
|
||||
/// Updates account's existing signature with the given HTML signature.
|
||||
/// Updates existing signature.
|
||||
/// </summary>
|
||||
Task<AccountSignature> UpdateAccountSignatureAsync(Guid accountId, string htmlBody);
|
||||
/// <param name="signature">Signature that should be updated. It should contain ID and account to which it belongs.</param>
|
||||
Task<AccountSignature> UpdateSignatureAsync(AccountSignature signature);
|
||||
|
||||
/// <summary>
|
||||
/// Disabled signature for the account and deletes existing signature.
|
||||
/// Deletes existing signature.
|
||||
/// </summary>
|
||||
Task DeleteAccountSignatureAssignment(Guid accountId);
|
||||
/// <param name="signature">Signature that should be deleted.</param>
|
||||
Task<AccountSignature> DeleteSignatureAsync(AccountSignature signature);
|
||||
}
|
||||
}
|
||||
|
||||
20
Wino.Core.Domain/Interfaces/IStartupBehaviorService.cs
Normal file
20
Wino.Core.Domain/Interfaces/IStartupBehaviorService.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System.Threading.Tasks;
|
||||
using Wino.Core.Domain.Enums;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
public interface IStartupBehaviorService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets whether Wino Server is set to launch on startup or not.
|
||||
/// </summary>
|
||||
Task<StartupBehaviorResult> GetCurrentStartupBehaviorAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Enables/disables the current startup behavior for Wino Server.
|
||||
/// </summary>
|
||||
/// <param name="isEnabled">Whether to launch enabled or disabled.</param>
|
||||
/// <returns>True if operation success, false if not.</returns>
|
||||
Task<StartupBehaviorResult> ToggleStartupBehavior(bool isEnabled);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
public interface IStoreRatingDialog
|
||||
{
|
||||
bool DontAskAgain { get; }
|
||||
bool RateWinoClicked { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface for reporting progress of the synchronization.
|
||||
/// Gmail does not support reporting folder progress.
|
||||
/// For others, account progress is calculated based on the number of folders.
|
||||
/// </summary>
|
||||
public interface ISynchronizationProgress
|
||||
{
|
||||
/// <summary>
|
||||
/// Reports account synchronization progress.
|
||||
/// </summary>
|
||||
/// <param name="accountId">Account id for the report.</param>
|
||||
/// <param name="progress">Value. This is always between 0 - 100</param>
|
||||
void AccountProgressUpdated(Guid accountId, int progress);
|
||||
}
|
||||
}
|
||||
11
Wino.Core.Domain/Interfaces/ISynchronizerFactory.cs
Normal file
11
Wino.Core.Domain/Interfaces/ISynchronizerFactory.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
public interface ISynchronizerFactory
|
||||
{
|
||||
Task<IBaseSynchronizer> GetAccountSynchronizerAsync(Guid accountId);
|
||||
Task InitializeAsync();
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,11 @@ namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
public interface IThreadingStrategy
|
||||
{
|
||||
/// <summary>
|
||||
/// Attach thread mails to the list.
|
||||
/// </summary>
|
||||
/// <param name="items">Original mails.</param>
|
||||
/// <returns>Original mails with thread mails.</returns>
|
||||
Task<List<IMailItem>> ThreadItemsAsync(List<MailCopy> items);
|
||||
bool ShouldThreadWithItem(IMailItem originalItem, IMailItem targetItem);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Wino.Core.Domain.Models.Requests
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for all messages to report UI changes from synchronizers to UI.
|
||||
@@ -6,5 +6,6 @@
|
||||
/// They are sent either from processor or view models to signal some other
|
||||
/// parts of the application.
|
||||
/// </summary>
|
||||
|
||||
public interface IUIMessage;
|
||||
}
|
||||
15
Wino.Core.Domain/Interfaces/IUnsubscriptionService.cs
Normal file
15
Wino.Core.Domain/Interfaces/IUnsubscriptionService.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System.Threading.Tasks;
|
||||
using Wino.Core.Domain.Models.Reader;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
public interface IUnsubscriptionService
|
||||
{
|
||||
/// <summary>
|
||||
/// Unsubscribes from the subscription using one-click method.
|
||||
/// </summary>
|
||||
/// <param name="info">Unsubscribtion information.</param>
|
||||
/// <returns>Whether the unsubscription is succeeded or not.</returns>
|
||||
Task<bool> OneClickUnsubscribeAsync(UnsubscribeInfo info);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Threading.Tasks;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Models.Folders;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
|
||||
@@ -17,7 +16,7 @@ namespace Wino.Core.Domain.Interfaces
|
||||
/// Queues new draft creation request for synchronizer.
|
||||
/// </summary>
|
||||
/// <param name="draftPreperationRequest">A class that holds the parameters for creating a draft.</param>
|
||||
Task ExecuteAsync(DraftPreperationRequest draftPreperationRequest);
|
||||
Task ExecuteAsync(DraftPreparationRequest draftPreperationRequest);
|
||||
|
||||
/// <summary>
|
||||
/// Queues a new request for synchronizer to send a draft.
|
||||
@@ -28,8 +27,7 @@ namespace Wino.Core.Domain.Interfaces
|
||||
/// <summary>
|
||||
/// Prepares requires IRequest collection for folder actions and executes them via proper synchronizers.
|
||||
/// </summary>
|
||||
/// <param name="operation">Folder operation to execute.</param>
|
||||
/// <param name="folderStructure">Target folder</param>
|
||||
Task ExecuteAsync(FolderOperation operation, IMailItemFolder folderStructure);
|
||||
/// <param name="folderOperationPreperationRequest">Folder prep request.</param>
|
||||
Task ExecuteAsync(FolderOperationPreperationRequest folderOperationPreperationRequest);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Models.Folders;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
using Wino.Core.Domain.Models.Requests;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
public interface IWinoRequestProcessor
|
||||
{
|
||||
Task<IRequest> PrepareFolderRequestAsync(FolderOperation operation, IMailItemFolder mailItemFolder);
|
||||
/// <summary>
|
||||
/// Prepares proper folder action requests for synchronizers to execute.
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns>Base request that synchronizer can execute.</returns>
|
||||
Task<IRequestBase> PrepareFolderRequestAsync(FolderOperationPreperationRequest request);
|
||||
|
||||
/// <summary>
|
||||
/// Prepares proper Wino requests for synchronizers to execute categorized by AccountId and FolderId.
|
||||
@@ -17,6 +20,7 @@ namespace Wino.Core.Domain.Interfaces
|
||||
/// <param name="operation">User action</param>
|
||||
/// <param name="mailCopyIds">Selected mails.</param>
|
||||
/// <exception cref="UnavailableSpecialFolderException">When required folder target is not available for account.</exception>
|
||||
/// <returns>Base request that synchronizer can execute.</returns>
|
||||
Task<List<IRequest>> PrepareRequestsAsync(MailOperationPreperationRequest request);
|
||||
}
|
||||
}
|
||||
|
||||
61
Wino.Core.Domain/Interfaces/IWinoServerConnectionManager.cs
Normal file
61
Wino.Core.Domain/Interfaces/IWinoServerConnectionManager.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Models.Server;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
public interface IWinoServerConnectionManager
|
||||
{
|
||||
/// <summary>
|
||||
/// When the connection status changes, this event will be triggered.
|
||||
/// </summary>
|
||||
event EventHandler<WinoServerConnectionStatus> StatusChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the connection status.
|
||||
/// </summary>
|
||||
WinoServerConnectionStatus Status { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Launches Full Trust process (Wino Server) and awaits connection completion.
|
||||
/// If connection is not established in 10 seconds, it will return false.
|
||||
/// If the server process is already running, it'll connect to existing one.
|
||||
/// If the server process is not running, it'll be launched and connection establishment is awaited.
|
||||
/// </summary>
|
||||
/// <returns>Whether connection is established or not.</returns>
|
||||
Task<bool> ConnectAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Queues a new user request to be processed by Wino Server.
|
||||
/// Healthy connection must present before calling this method.
|
||||
/// </summary>
|
||||
/// <param name="request">Request to queue for synchronizer in the server.</param>
|
||||
/// <param name="accountId">Account id to queueu request for.</param>
|
||||
Task QueueRequestAsync(IRequestBase request, Guid accountId);
|
||||
|
||||
/// <summary>
|
||||
/// Returns response from server for the given request.
|
||||
/// </summary>
|
||||
/// <typeparam name="TResponse">Response type.</typeparam>
|
||||
/// <typeparam name="TRequestType">Request type.</typeparam>
|
||||
/// <param name="clientMessage">Request type.</param>
|
||||
/// <returns>Response received from the server for the given TResponse type.</returns>
|
||||
Task<WinoServerResponse<TResponse>> GetResponseAsync<TResponse, TRequestType>(TRequestType clientMessage) where TRequestType : IClientMessage;
|
||||
|
||||
/// <summary>
|
||||
/// Handle for connecting to the server.
|
||||
/// If the server is already running, it'll connect to existing one.
|
||||
/// Callers can await this handle to wait for connection establishment.
|
||||
/// </summary>
|
||||
TaskCompletionSource<bool> ConnectingHandle { get; }
|
||||
}
|
||||
|
||||
public interface IWinoServerConnectionManager<TAppServiceConnection> : IWinoServerConnectionManager, IInitializeAsync
|
||||
{
|
||||
/// <summary>
|
||||
/// Existing connection handle to the server of TAppServiceConnection type.
|
||||
/// </summary>
|
||||
TAppServiceConnection Connection { get; set; }
|
||||
}
|
||||
}
|
||||
11
Wino.Core.Domain/Interfaces/IWinoSynchronizerFactory.cs
Normal file
11
Wino.Core.Domain/Interfaces/IWinoSynchronizerFactory.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using Wino.Core.Domain.Entities;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
public interface IWinoSynchronizerFactory : IInitializeAsync
|
||||
{
|
||||
IBaseSynchronizer GetAccountSynchronizer(Guid accountId);
|
||||
IBaseSynchronizer CreateNewSynchronizer(MailAccount account);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
using Wino.Core.Domain.Enums;
|
||||
|
||||
namespace Wino.Core.Domain.Models.Accounts
|
||||
{
|
||||
public record AccountCreationDialogResult(MailProviderType ProviderType, string AccountName, string AccountColorHex = "");
|
||||
}
|
||||
9
Wino.Core.Domain/Models/Accounts/ProfileInformation.cs
Normal file
9
Wino.Core.Domain/Models/Accounts/ProfileInformation.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Wino.Core.Domain.Models.Accounts
|
||||
{
|
||||
/// <summary>
|
||||
/// Encapsulates the profile information of an account.
|
||||
/// </summary>
|
||||
/// <param name="SenderName">Display sender name for the account.</param>
|
||||
/// <param name="Base64ProfilePictureData">Base 64 encoded profile picture data of the account. Thumbnail size.</param>
|
||||
public record ProfileInformation(string SenderName, string Base64ProfilePictureData);
|
||||
}
|
||||
13
Wino.Core.Domain/Models/Accounts/UnreadItemCountResult.cs
Normal file
13
Wino.Core.Domain/Models/Accounts/UnreadItemCountResult.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using Wino.Core.Domain.Enums;
|
||||
|
||||
namespace Wino.Core.Domain.Models.Accounts
|
||||
{
|
||||
public class UnreadItemCountResult
|
||||
{
|
||||
public Guid FolderId { get; set; }
|
||||
public Guid AccountId { get; set; }
|
||||
public SpecialFolderType SpecialFolderType { get; set; }
|
||||
public int UnreadItemCount { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@ namespace Wino.Core.Domain.Models.Authorization
|
||||
ClientId = clientId;
|
||||
|
||||
// Creates the OAuth 2.0 authorization request.
|
||||
return string.Format("{0}?response_type=code&scope=https://mail.google.com/ https://www.googleapis.com/auth/gmail.labels&redirect_uri={1}&client_id={2}&state={3}&code_challenge={4}&code_challenge_method={5}",
|
||||
return string.Format("{0}?response_type=code&scope=https://mail.google.com/ https://www.googleapis.com/auth/gmail.labels https://www.googleapis.com/auth/userinfo.profile&redirect_uri={1}&client_id={2}&state={3}&code_challenge={4}&code_challenge_method={5}",
|
||||
authorizationEndpoint,
|
||||
Uri.EscapeDataString(RedirectUri),
|
||||
ClientId,
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Wino.Core.Domain.Models.AutoDiscovery
|
||||
{
|
||||
public class AutoDiscoveryConnectionTestFailedPackage
|
||||
{
|
||||
public AutoDiscoveryConnectionTestFailedPackage(AutoDiscoverySettings settings, Exception error)
|
||||
{
|
||||
Settings = settings ?? throw new ArgumentNullException(nameof(settings));
|
||||
Error = error ?? throw new ArgumentNullException(nameof(error));
|
||||
}
|
||||
|
||||
public AutoDiscoveryConnectionTestFailedPackage(Exception error)
|
||||
{
|
||||
Error = error ?? throw new ArgumentNullException(nameof(error));
|
||||
}
|
||||
|
||||
public AutoDiscoverySettings Settings { get; set; }
|
||||
public Exception Error { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,22 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Wino.Core.Domain.Models.AutoDiscovery
|
||||
{
|
||||
public class AutoDiscoveryProviderSetting
|
||||
{
|
||||
[JsonProperty("protocol")]
|
||||
[JsonPropertyName("protocol")]
|
||||
public string Protocol { get; set; }
|
||||
|
||||
[JsonProperty("address")]
|
||||
[JsonPropertyName("address")]
|
||||
public string Address { get; set; }
|
||||
|
||||
[JsonProperty("port")]
|
||||
[JsonPropertyName("port")]
|
||||
public int Port { get; set; }
|
||||
|
||||
[JsonProperty("secure")]
|
||||
[JsonPropertyName("secure")]
|
||||
public string Secure { get; set; }
|
||||
|
||||
[JsonProperty("username")]
|
||||
[JsonPropertyName("username")]
|
||||
public string Username { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Wino.Core.Domain.Entities;
|
||||
|
||||
namespace Wino.Core.Domain.Models.AutoDiscovery
|
||||
{
|
||||
public class AutoDiscoverySettings
|
||||
{
|
||||
[JsonProperty("domain")]
|
||||
[JsonPropertyName("domain")]
|
||||
public string Domain { get; set; }
|
||||
|
||||
[JsonProperty("password")]
|
||||
[JsonPropertyName("password")]
|
||||
public string Password { get; set; }
|
||||
|
||||
[JsonProperty("settings")]
|
||||
[JsonPropertyName("settings")]
|
||||
public List<AutoDiscoveryProviderSetting> Settings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -30,9 +30,6 @@ namespace Wino.Core.Domain.Models.AutoDiscovery
|
||||
|
||||
if (imapSettings == null || smtpSettings == null) return null;
|
||||
|
||||
bool imapRequiresSSL = imapSettings.Secure == "SSL";
|
||||
bool smtpRequiresSSL = smtpSettings.Secure == "SSL";
|
||||
|
||||
string imapUrl = imapSettings.Address;
|
||||
string smtpUrl = smtpSettings.Address;
|
||||
|
||||
@@ -49,15 +46,18 @@ namespace Wino.Core.Domain.Models.AutoDiscovery
|
||||
Address = UserMinimalSettings.Email,
|
||||
IncomingServerPassword = UserMinimalSettings.Password,
|
||||
OutgoingServerPassword = UserMinimalSettings.Password,
|
||||
IncomingRequiresSSL = imapRequiresSSL,
|
||||
OutgoingRequresSSL = smtpRequiresSSL,
|
||||
IncomingAuthenticationMethod = Enums.ImapAuthenticationMethod.Auto,
|
||||
OutgoingAuthenticationMethod = Enums.ImapAuthenticationMethod.Auto,
|
||||
OutgoingServerSocketOption = Enums.ImapConnectionSecurity.Auto,
|
||||
IncomingServerSocketOption = Enums.ImapConnectionSecurity.Auto,
|
||||
IncomingServer = imapUrl,
|
||||
OutgoingServer = smtpUrl,
|
||||
IncomingServerPort = imapPort.ToString(),
|
||||
OutgoingServerPort = smtpPort.ToString(),
|
||||
IncomingServerType = Enums.CustomIncomingServerType.IMAP4,
|
||||
IncomingServerUsername = imapUsername,
|
||||
OutgoingServerUsername = smtpUsername
|
||||
OutgoingServerUsername = smtpUsername,
|
||||
MaxConcurrentClients = 5
|
||||
};
|
||||
|
||||
return serverInfo;
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
using Wino.Core.Domain.Entities;
|
||||
using Wino.Core.Domain.Enums;
|
||||
|
||||
namespace Wino.Core.Domain.Models.Folders
|
||||
{
|
||||
/// <summary>
|
||||
/// Encapsulates a request to prepare a folder operation like Rename, Delete, etc.
|
||||
/// </summary>
|
||||
/// <param name="Action">Folder operation.</param>
|
||||
/// <param name="Folder">Target folder.</param>
|
||||
public record FolderOperationPreperationRequest(FolderOperation Action, MailItemFolder Folder) { }
|
||||
}
|
||||
76
Wino.Core.Domain/Models/Launch/MailToUri.cs
Normal file
76
Wino.Core.Domain/Models/Launch/MailToUri.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
|
||||
namespace Wino.Core.Domain.Models.Launch;
|
||||
|
||||
public class MailToUri
|
||||
{
|
||||
public string Subject { get; private set; }
|
||||
public string Body { get; private set; }
|
||||
public List<string> To { get; } = [];
|
||||
public List<string> Cc { get; } = [];
|
||||
public List<string> Bcc { get; } = [];
|
||||
public Dictionary<string, string> OtherParameters { get; } = [];
|
||||
|
||||
public MailToUri(string mailToUrl)
|
||||
{
|
||||
ParseMailToUrl(mailToUrl);
|
||||
}
|
||||
|
||||
private void ParseMailToUrl(string mailToUrl)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(mailToUrl))
|
||||
throw new ArgumentException("mailtoUrl cannot be null or empty.", nameof(mailToUrl));
|
||||
|
||||
if (!mailToUrl.StartsWith("mailto:", StringComparison.OrdinalIgnoreCase))
|
||||
throw new ArgumentException("URL must start with 'mailto:'.", nameof(mailToUrl));
|
||||
|
||||
var mailToWithoutScheme = mailToUrl.Substring(7); // Remove "mailto:"
|
||||
var components = mailToWithoutScheme.Split('?');
|
||||
if (!string.IsNullOrEmpty(components[0]))
|
||||
{
|
||||
To.AddRange(components[0].Split(',').Select(email => HttpUtility.UrlDecode(email).Trim()));
|
||||
}
|
||||
|
||||
if (components.Length <= 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var parameters = components[1].Split('&');
|
||||
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
var keyValue = parameter.Split('=');
|
||||
if (keyValue.Length != 2)
|
||||
continue;
|
||||
|
||||
var key = keyValue[0].ToLowerInvariant();
|
||||
var value = HttpUtility.UrlDecode(keyValue[1]);
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case "to":
|
||||
To.AddRange(value.Split(',').Select(email => email.Trim()));
|
||||
break;
|
||||
case "subject":
|
||||
Subject = value;
|
||||
break;
|
||||
case "body":
|
||||
Body = value;
|
||||
break;
|
||||
case "cc":
|
||||
Cc.AddRange(value.Split(',').Select(email => email.Trim()));
|
||||
break;
|
||||
case "bcc":
|
||||
Bcc.AddRange(value.Split(',').Select(email => email.Trim()));
|
||||
break;
|
||||
default:
|
||||
OtherParameters[key] = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +1,27 @@
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using MimeKit;
|
||||
using MimeKit;
|
||||
using Wino.Core.Domain.Entities;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Models.Launch;
|
||||
|
||||
namespace Wino.Core.Domain.Models.MailItem
|
||||
namespace Wino.Core.Domain.Models.MailItem;
|
||||
|
||||
public class DraftCreationOptions
|
||||
{
|
||||
public class DraftCreationOptions
|
||||
{
|
||||
public MimeMessage ReferenceMimeMessage { get; set; }
|
||||
public MailCopy ReferenceMailCopy { get; set; }
|
||||
public DraftCreationReason Reason { get; set; }
|
||||
public DraftCreationReason Reason { get; set; }
|
||||
|
||||
#region Mailto Protocol Related Stuff
|
||||
/// <summary>
|
||||
/// Used for forward/reply
|
||||
/// </summary>
|
||||
public ReferencedMessage ReferencedMessage { get; set; }
|
||||
|
||||
public const string MailtoSubjectParameterKey = "subject";
|
||||
public const string MailtoBodyParameterKey = "body";
|
||||
public const string MailtoToParameterKey = "mailto";
|
||||
public const string MailtoCCParameterKey = "cc";
|
||||
public const string MailtoBCCParameterKey = "bcc";
|
||||
|
||||
public NameValueCollection MailtoParameters { get; set; }
|
||||
|
||||
private bool IsMailtoParameterExists(string parameterKey)
|
||||
=> MailtoParameters != null
|
||||
&& MailtoParameters.AllKeys.Contains(parameterKey);
|
||||
|
||||
public bool TryGetMailtoValue(string key, out string value)
|
||||
{
|
||||
bool valueExists = IsMailtoParameterExists(key);
|
||||
|
||||
value = valueExists ? MailtoParameters[key] : string.Empty;
|
||||
|
||||
return valueExists;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/// <summary>
|
||||
/// Used to create mails from Mailto links
|
||||
/// </summary>
|
||||
public MailToUri MailToUri { get; set; }
|
||||
}
|
||||
|
||||
public class ReferencedMessage
|
||||
{
|
||||
public MailCopy MailCopy { get; set; }
|
||||
public MimeMessage MimeMessage { get; set; }
|
||||
}
|
||||
|
||||
55
Wino.Core.Domain/Models/MailItem/DraftPreparationRequest.cs
Normal file
55
Wino.Core.Domain/Models/MailItem/DraftPreparationRequest.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
using MimeKit;
|
||||
using Wino.Core.Domain.Entities;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Extensions;
|
||||
|
||||
namespace Wino.Core.Domain.Models.MailItem;
|
||||
|
||||
public class DraftPreparationRequest
|
||||
{
|
||||
public DraftPreparationRequest(MailAccount account,
|
||||
MailCopy createdLocalDraftCopy,
|
||||
string base64EncodedMimeMessage,
|
||||
DraftCreationReason reason,
|
||||
MailCopy referenceMailCopy = null)
|
||||
{
|
||||
Account = account ?? throw new ArgumentNullException(nameof(account));
|
||||
|
||||
CreatedLocalDraftCopy = createdLocalDraftCopy ?? throw new ArgumentNullException(nameof(createdLocalDraftCopy));
|
||||
ReferenceMailCopy = referenceMailCopy;
|
||||
|
||||
// MimeMessage is not serializable with System.Text.Json. Convert to base64 string.
|
||||
// This is additional work when deserialization needed, but not much to do atm.
|
||||
|
||||
Base64LocalDraftMimeMessage = base64EncodedMimeMessage;
|
||||
Reason = reason;
|
||||
}
|
||||
|
||||
[JsonConstructor]
|
||||
private DraftPreparationRequest() { }
|
||||
|
||||
public MailCopy CreatedLocalDraftCopy { get; set; }
|
||||
|
||||
public MailCopy ReferenceMailCopy { get; set; }
|
||||
|
||||
public string Base64LocalDraftMimeMessage { get; set; }
|
||||
public DraftCreationReason Reason { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
private MimeMessage createdLocalDraftMimeMessage;
|
||||
|
||||
[JsonIgnore]
|
||||
public MimeMessage CreatedLocalDraftMimeMessage
|
||||
{
|
||||
get
|
||||
{
|
||||
createdLocalDraftMimeMessage ??= Base64LocalDraftMimeMessage.GetMimeMessageFromBase64();
|
||||
|
||||
return createdLocalDraftMimeMessage;
|
||||
}
|
||||
}
|
||||
|
||||
public MailAccount Account { get; set; }
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using MimeKit;
|
||||
using Wino.Core.Domain.Entities;
|
||||
|
||||
namespace Wino.Core.Domain.Models.MailItem
|
||||
{
|
||||
public class DraftPreperationRequest : DraftCreationOptions
|
||||
{
|
||||
public DraftPreperationRequest(MailAccount account, MailCopy createdLocalDraftCopy, MimeMessage createdLocalDraftMimeMessage)
|
||||
{
|
||||
Account = account ?? throw new ArgumentNullException(nameof(account));
|
||||
|
||||
CreatedLocalDraftCopy = createdLocalDraftCopy ?? throw new ArgumentNullException(nameof(createdLocalDraftCopy));
|
||||
CreatedLocalDraftMimeMessage = createdLocalDraftMimeMessage ?? throw new ArgumentNullException(nameof(createdLocalDraftMimeMessage));
|
||||
}
|
||||
|
||||
public MailCopy CreatedLocalDraftCopy { get; set; }
|
||||
public MimeMessage CreatedLocalDraftMimeMessage { get; set; }
|
||||
public MailAccount Account { get; }
|
||||
}
|
||||
}
|
||||
15
Wino.Core.Domain/Models/MailItem/IMailHashContainer.cs
Normal file
15
Wino.Core.Domain/Models/MailItem/IMailHashContainer.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wino.Core.Domain.Models.MailItem
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface that returns the UniqueId store for IMailItem.
|
||||
/// For threads, it may be multiple items.
|
||||
/// For single mails, it'll always be one item.
|
||||
/// </summary>
|
||||
public interface IMailHashContainer
|
||||
{
|
||||
IEnumerable<Guid> GetContainingIds();
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ namespace Wino.Core.Domain.Models.MailItem
|
||||
/// <summary>
|
||||
/// Interface of simplest representation of a MailCopy.
|
||||
/// </summary>
|
||||
public interface IMailItem
|
||||
public interface IMailItem : IMailHashContainer
|
||||
{
|
||||
Guid UniqueId { get; }
|
||||
string Id { get; }
|
||||
@@ -29,5 +29,6 @@ namespace Wino.Core.Domain.Models.MailItem
|
||||
|
||||
MailItemFolder AssignedFolder { get; }
|
||||
MailAccount AssignedAccount { get; }
|
||||
AccountContact SenderContact { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,61 +9,31 @@ namespace Wino.Core.Domain.Models.MailItem
|
||||
/// <summary>
|
||||
/// Encapsulates the options for preparing requests to execute mail operations for mail items like Move, Delete, MarkAsRead, etc.
|
||||
/// </summary>
|
||||
public class MailOperationPreperationRequest
|
||||
/// <param name="Action"> Action to execute. </param>
|
||||
/// <param name="MailItems"> Mail copies execute the action on. </param>
|
||||
/// <param name="ToggleExecution"> Whether the operation can be reverted if needed.
|
||||
/// eg. MarkAsRead on already read item will set the action to MarkAsUnread.
|
||||
/// This is used in hover actions for example. </param>
|
||||
/// <param name="IgnoreHardDeleteProtection"> Whether hard delete protection should be ignored.
|
||||
/// Discard draft requests for example should ignore hard delete protection. </param>
|
||||
/// <param name="MoveTargetFolder"> Moving folder for the Move operation.
|
||||
/// If null and the action is Move, the user will be prompted to select a folder. </param>
|
||||
public record MailOperationPreperationRequest(MailOperation Action, IEnumerable<MailCopy> MailItems, bool ToggleExecution, bool IgnoreHardDeleteProtection, IMailItemFolder MoveTargetFolder)
|
||||
{
|
||||
public MailOperationPreperationRequest(MailOperation action,
|
||||
IEnumerable<MailCopy> mailItems,
|
||||
bool toggleExecution = false,
|
||||
IMailItemFolder moveTargetFolder = null,
|
||||
bool ignoreHardDeleteProtection = false)
|
||||
bool ignoreHardDeleteProtection = false) : this(action, mailItems ?? throw new ArgumentNullException(nameof(mailItems)), toggleExecution, ignoreHardDeleteProtection, moveTargetFolder)
|
||||
{
|
||||
Action = action;
|
||||
MailItems = mailItems ?? throw new ArgumentNullException(nameof(mailItems));
|
||||
ToggleExecution = toggleExecution;
|
||||
MoveTargetFolder = moveTargetFolder;
|
||||
IgnoreHardDeleteProtection = ignoreHardDeleteProtection;
|
||||
}
|
||||
|
||||
public MailOperationPreperationRequest(MailOperation action,
|
||||
MailCopy singleMailItem,
|
||||
bool toggleExecution = false,
|
||||
IMailItemFolder moveTargetFolder = null,
|
||||
bool ignoreHardDeleteProtection = false)
|
||||
bool ignoreHardDeleteProtection = false) : this(action, new List<MailCopy>() { singleMailItem }, toggleExecution, ignoreHardDeleteProtection, moveTargetFolder)
|
||||
{
|
||||
Action = action;
|
||||
MailItems = new List<MailCopy>() { singleMailItem };
|
||||
ToggleExecution = toggleExecution;
|
||||
MoveTargetFolder = moveTargetFolder;
|
||||
IgnoreHardDeleteProtection = ignoreHardDeleteProtection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Action to execute.
|
||||
/// </summary>
|
||||
public MailOperation Action { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Mail copies execute the action on.
|
||||
/// </summary>
|
||||
public IEnumerable<MailCopy> MailItems { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the operation can be reverted if needed.
|
||||
/// eg. MarkAsRead on already read item will set the action to MarkAsUnread.
|
||||
/// This is used in hover actions for example.
|
||||
/// </summary>
|
||||
public bool ToggleExecution { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether hard delete protection should be ignored.
|
||||
/// Discard draft requests for example should ignore hard delete protection.
|
||||
/// </summary>
|
||||
public bool IgnoreHardDeleteProtection { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Moving folder for the Move operation.
|
||||
/// If null and the action is Move, the user will be prompted to select a folder.
|
||||
/// </summary>
|
||||
public IMailItemFolder MoveTargetFolder { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,21 @@
|
||||
using MimeKit;
|
||||
using System.Text.Json.Serialization;
|
||||
using MimeKit;
|
||||
using Wino.Core.Domain.Entities;
|
||||
using Wino.Core.Domain.Extensions;
|
||||
|
||||
namespace Wino.Core.Domain.Models.MailItem
|
||||
{
|
||||
public record SendDraftPreparationRequest(MailCopy MailItem, MimeMessage Mime, MailItemFolder DraftFolder, MailItemFolder SentFolder, MailAccountPreferences AccountPreferences);
|
||||
public record SendDraftPreparationRequest(MailCopy MailItem,
|
||||
MailAccountAlias SendingAlias,
|
||||
MailItemFolder SentFolder,
|
||||
MailItemFolder DraftFolder,
|
||||
MailAccountPreferences AccountPreferences,
|
||||
string Base64MimeMessage)
|
||||
{
|
||||
[JsonIgnore]
|
||||
private MimeMessage mime;
|
||||
|
||||
[JsonIgnore]
|
||||
public MimeMessage Mime => mime ??= Base64MimeMessage.GetMimeMessageFromBase64();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Wino.Core.Domain.Entities;
|
||||
@@ -40,6 +41,8 @@ namespace Wino.Core.Domain.Models.MailItem
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<Guid> GetContainingIds() => ThreadItems?.Select(a => a.UniqueId) ?? default;
|
||||
|
||||
#region IMailItem
|
||||
|
||||
public Guid UniqueId => LatestMailItem?.UniqueId ?? Guid.Empty;
|
||||
@@ -82,6 +85,8 @@ namespace Wino.Core.Domain.Models.MailItem
|
||||
|
||||
public Guid FileId => LatestMailItem?.FileId ?? Guid.Empty;
|
||||
|
||||
public AccountContact SenderContact => LatestMailItem?.SenderContact;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using System;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
|
||||
namespace Wino.Core.Domain.Models.Requests
|
||||
namespace Wino.Core.Domain.Models.MailItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a single rule for toggling user actions if needed.
|
||||
@@ -3,6 +3,6 @@
|
||||
public enum NavigationTransitionType
|
||||
{
|
||||
None, // Supress
|
||||
DrillIn,
|
||||
DrillIn
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
namespace Wino.Core.Domain.Models.Personalization
|
||||
{
|
||||
public record MailListPaneLengthPreferences(string Title, double Length);
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
using Wino.Core.Domain.Enums;
|
||||
|
||||
namespace Wino.Core.Domain.Models.Reader
|
||||
{
|
||||
public class EditorToolbarSection
|
||||
{
|
||||
public EditorToolbarSectionType SectionType { get; set; }
|
||||
public string Title
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (SectionType)
|
||||
{
|
||||
case EditorToolbarSectionType.None:
|
||||
return Translator.EditorToolbarOption_None;
|
||||
case EditorToolbarSectionType.Format:
|
||||
return Translator.EditorToolbarOption_Format;
|
||||
case EditorToolbarSectionType.Insert:
|
||||
return Translator.EditorToolbarOption_Insert;
|
||||
case EditorToolbarSectionType.Draw:
|
||||
return Translator.EditorToolbarOption_Draw;
|
||||
case EditorToolbarSectionType.Options:
|
||||
return Translator.EditorToolbarOption_Options;
|
||||
default:
|
||||
return "Unknown Editor Option";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Wino.Core.Domain/Models/Reader/ImageInfo.cs
Normal file
12
Wino.Core.Domain/Models/Reader/ImageInfo.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Wino.Core.Domain.Models.Reader;
|
||||
|
||||
public class ImageInfo
|
||||
{
|
||||
[JsonPropertyName("data")]
|
||||
public string Data { get; set; }
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
@@ -11,10 +11,9 @@ namespace Wino.Core.Domain.Models.Reader
|
||||
{
|
||||
public string RenderHtml { get; }
|
||||
public MailRenderingOptions MailRenderingOptions { get; }
|
||||
public List<MimePart> Attachments { get; set; } = new List<MimePart>();
|
||||
public List<MimePart> Attachments { get; set; } = [];
|
||||
|
||||
public string UnsubscribeLink { get; set; }
|
||||
public bool CanUnsubscribe => !string.IsNullOrEmpty(UnsubscribeLink);
|
||||
public UnsubscribeInfo UnsubscribeInfo { get; set; }
|
||||
|
||||
public MailRenderModel(string renderHtml, MailRenderingOptions mailRenderingOptions = null)
|
||||
{
|
||||
@@ -22,4 +21,12 @@ namespace Wino.Core.Domain.Models.Reader
|
||||
MailRenderingOptions = mailRenderingOptions;
|
||||
}
|
||||
}
|
||||
|
||||
public class UnsubscribeInfo
|
||||
{
|
||||
public string HttpLink { get; set; }
|
||||
public string MailToLink { get; set; }
|
||||
public bool IsOneClick { get; set; }
|
||||
public bool CanUnsubscribe => HttpLink != null || MailToLink != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
using Wino.Core.Domain.Enums;
|
||||
|
||||
namespace Wino.Core.Domain.Models.Reader
|
||||
{
|
||||
public record ReaderFontModel(ReaderFont Font, string FontFamilyName);
|
||||
}
|
||||
16
Wino.Core.Domain/Models/Reader/WebViewMessage.cs
Normal file
16
Wino.Core.Domain/Models/Reader/WebViewMessage.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Wino.Core.Domain.Models.Reader
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to pass messages from the webview to the app.
|
||||
/// </summary>
|
||||
public class WebViewMessage
|
||||
{
|
||||
[JsonPropertyName("type")]
|
||||
public string Type { get; set; }
|
||||
|
||||
[JsonPropertyName("value")]
|
||||
public string Value { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -11,17 +11,24 @@ namespace Wino.Core.Domain.Models.Requests
|
||||
public abstract IBatchChangeRequest CreateBatch(IEnumerable<IRequest> requests);
|
||||
public abstract void ApplyUIChanges();
|
||||
public abstract void RevertUIChanges();
|
||||
|
||||
public virtual int ResynchronizationDelay => 0;
|
||||
}
|
||||
|
||||
public abstract record FolderRequestBase(MailItemFolder Folder, MailSynchronizerOperation Operation) : IFolderRequest
|
||||
{
|
||||
public abstract void ApplyUIChanges();
|
||||
public abstract void RevertUIChanges();
|
||||
|
||||
public virtual int ResynchronizationDelay => 0;
|
||||
}
|
||||
|
||||
public abstract record BatchRequestBase(IEnumerable<IRequest> Items, MailSynchronizerOperation Operation) : IBatchChangeRequest
|
||||
{
|
||||
public abstract void ApplyUIChanges();
|
||||
public abstract void RevertUIChanges();
|
||||
|
||||
public virtual int ResynchronizationDelay => 0;
|
||||
public virtual bool ExecuteSerialBatch => false;
|
||||
}
|
||||
}
|
||||
|
||||
15
Wino.Core.Domain/Models/Requests/ServerRequestPackage.cs
Normal file
15
Wino.Core.Domain/Models/Requests/ServerRequestPackage.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
|
||||
namespace Wino.Core.Domain.Models.Requests
|
||||
{
|
||||
/// <summary>
|
||||
/// Encapsulates request to queue and account for synchronizer.
|
||||
/// </summary>
|
||||
/// <param name="AccountId">Which account to execute this request for.</param>
|
||||
/// <param name="Request">Prepared request for the server.</param>
|
||||
public record ServerRequestPackage(Guid AccountId, IRequestBase Request) : IClientMessage
|
||||
{
|
||||
public override string ToString() => $"Server Package: {Request.GetType().Name}";
|
||||
}
|
||||
}
|
||||
40
Wino.Core.Domain/Models/Server/WinoServerResponse.cs
Normal file
40
Wino.Core.Domain/Models/Server/WinoServerResponse.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using Wino.Core.Domain.Exceptions;
|
||||
|
||||
namespace Wino.Core.Domain.Models.Server
|
||||
{
|
||||
/// <summary>
|
||||
/// Encapsulates responses from the Wino server.
|
||||
/// Exceptions are stored separately in the Message and StackTrace properties due to serialization issues.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the expected response.</typeparam>
|
||||
public class WinoServerResponse<T>
|
||||
{
|
||||
public bool IsSuccess { get; set; }
|
||||
public string Message { get; set; }
|
||||
public T Data { get; set; }
|
||||
|
||||
public static WinoServerResponse<T> CreateSuccessResponse(T data)
|
||||
{
|
||||
return new WinoServerResponse<T>
|
||||
{
|
||||
IsSuccess = true,
|
||||
Data = data
|
||||
};
|
||||
}
|
||||
|
||||
public static WinoServerResponse<T> CreateErrorResponse(string message)
|
||||
{
|
||||
return new WinoServerResponse<T>
|
||||
{
|
||||
IsSuccess = false,
|
||||
Message = message
|
||||
};
|
||||
}
|
||||
|
||||
public void ThrowIfFailed()
|
||||
{
|
||||
if (!IsSuccess)
|
||||
throw new WinoServerException(Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user