diff --git a/App.xaml b/App.xaml new file mode 100644 index 0000000..1e4b7ba --- /dev/null +++ b/App.xaml @@ -0,0 +1,7 @@ + + + diff --git a/App.xaml.cs b/App.xaml.cs new file mode 100644 index 0000000..181d13b --- /dev/null +++ b/App.xaml.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using Windows.ApplicationModel; +using Windows.ApplicationModel.Activation; +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; +using Microsoft.Extensions.DependencyInjection; + +namespace MicaApps.Upw.Mail +{ + /// + /// 提供特定于应用程序的行为,以补充默认的应用程序类。 + /// + sealed partial class App : Application + { + /// + /// 注入依赖 + /// + public static IServiceProvider Services { get; private set; } = new ServiceCollection() + .AddSingleton() + .BuildServiceProvider(); + + + + /// + /// 初始化单一实例应用程序对象。这是执行的创作代码的第一行, + /// 已执行,逻辑上等同于 main() 或 WinMain()。 + /// + public App() + { + this.InitializeComponent(); + this.Suspending += OnSuspending; + } + + + /// + /// 在应用程序由最终用户正常启动时进行调用。 + /// 将在启动应用程序以打开特定文件等情况下使用。 + /// + /// 有关启动请求和过程的详细信息。 + protected override void OnLaunched(LaunchActivatedEventArgs e) + { + Frame rootFrame = Window.Current.Content as Frame; + + // 不要在窗口已包含内容时重复应用程序初始化, + // 只需确保窗口处于活动状态 + if (rootFrame == null) + { + // 创建要充当导航上下文的框架,并导航到第一页 + rootFrame = new Frame(); + + rootFrame.NavigationFailed += OnNavigationFailed; + + if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) + { + //TODO: 从之前挂起的应用程序加载状态 + } + + // 将框架放在当前窗口中 + Window.Current.Content = rootFrame; + } + + if (e.PrelaunchActivated == false) + { + if (rootFrame.Content == null) + { + // 当导航堆栈尚未还原时,导航到第一页, + // 并通过将所需信息作为导航参数传入来配置 + // 参数 + rootFrame.Navigate(typeof(MainPage), e.Arguments); + } + // 确保当前窗口处于活动状态 + Window.Current.Activate(); + } + } + + /// + /// 导航到特定页失败时调用 + /// + ///导航失败的框架 + ///有关导航失败的详细信息 + void OnNavigationFailed(object sender, NavigationFailedEventArgs e) + { + throw new Exception("Failed to load Page " + e.SourcePageType.FullName); + } + + /// + /// 在将要挂起应用程序执行时调用。 在不知道应用程序 + /// 无需知道应用程序会被终止还是会恢复, + /// 并让内存内容保持不变。 + /// + /// 挂起的请求的源。 + /// 有关挂起请求的详细信息。 + private void OnSuspending(object sender, SuspendingEventArgs e) + { + var deferral = e.SuspendingOperation.GetDeferral(); + //TODO: 保存应用程序状态并停止任何后台活动 + deferral.Complete(); + } + } +} diff --git a/Assets/LockScreenLogo.scale-200.png b/Assets/LockScreenLogo.scale-200.png new file mode 100644 index 0000000..735f57a Binary files /dev/null and b/Assets/LockScreenLogo.scale-200.png differ diff --git a/Assets/SplashScreen.scale-200.png b/Assets/SplashScreen.scale-200.png new file mode 100644 index 0000000..023e7f1 Binary files /dev/null and b/Assets/SplashScreen.scale-200.png differ diff --git a/Assets/Square150x150Logo.scale-200.png b/Assets/Square150x150Logo.scale-200.png new file mode 100644 index 0000000..af49fec Binary files /dev/null and b/Assets/Square150x150Logo.scale-200.png differ diff --git a/Assets/Square44x44Logo.altform-lightunplated_targetsize-256.png b/Assets/Square44x44Logo.altform-lightunplated_targetsize-256.png new file mode 100644 index 0000000..ddb5343 Binary files /dev/null and b/Assets/Square44x44Logo.altform-lightunplated_targetsize-256.png differ diff --git a/Assets/Square44x44Logo.scale-200.png b/Assets/Square44x44Logo.scale-200.png new file mode 100644 index 0000000..ce342a2 Binary files /dev/null and b/Assets/Square44x44Logo.scale-200.png differ diff --git a/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/Assets/Square44x44Logo.targetsize-24_altform-unplated.png new file mode 100644 index 0000000..f6c02ce Binary files /dev/null and b/Assets/Square44x44Logo.targetsize-24_altform-unplated.png differ diff --git a/Assets/StoreLogo.png b/Assets/StoreLogo.png new file mode 100644 index 0000000..7385b56 Binary files /dev/null and b/Assets/StoreLogo.png differ diff --git a/Assets/Wide310x150Logo.scale-200.png b/Assets/Wide310x150Logo.scale-200.png new file mode 100644 index 0000000..288995b Binary files /dev/null and b/Assets/Wide310x150Logo.scale-200.png differ diff --git a/Controls/LoginButton.xaml b/Controls/LoginButton.xaml new file mode 100644 index 0000000..bd263f3 --- /dev/null +++ b/Controls/LoginButton.xaml @@ -0,0 +1,38 @@ + diff --git a/Controls/LoginButton.xaml.cs b/Controls/LoginButton.xaml.cs new file mode 100644 index 0000000..2dc38a1 --- /dev/null +++ b/Controls/LoginButton.xaml.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; + +//https://go.microsoft.com/fwlink/?LinkId=234236 上介绍了“用户控件”项模板 + +namespace MicaApps.Upw.Mail.Controls +{ + public sealed partial class LoginButton : Button + { + public LoginButton() + { + this.InitializeComponent(); + } + + /// + /// 主标题 + /// + public string title { set=>this.textblock_title.Text = value; } + /// + /// 副标题 + /// + public string subTitle { set => this.textblock_subTitle.Text = value; } + + + + } +} diff --git a/MainPage.xaml b/MainPage.xaml new file mode 100644 index 0000000..d55f01a --- /dev/null +++ b/MainPage.xaml @@ -0,0 +1,15 @@ + + + + + + diff --git a/MainPage.xaml.cs b/MainPage.xaml.cs new file mode 100644 index 0000000..4e21eaf --- /dev/null +++ b/MainPage.xaml.cs @@ -0,0 +1,40 @@ +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using System.Threading.Tasks; +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; + +// https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x804 上介绍了“空白页”项模板 + +namespace MicaApps.Upw.Mail +{ + /// + /// 可用于自身或导航至 Frame 内部的空白页。 + /// + public sealed partial class MainPage : Page + { + public MainPage() + { + this.InitializeComponent(); + + } + + + + private void Page_Loaded(object sender, RoutedEventArgs e) + { + this.frame_main.Navigate(typeof(Pages.LoginPage)); + } + } +} diff --git a/MicaApps.Upw.Mail.csproj b/MicaApps.Upw.Mail.csproj new file mode 100644 index 0000000..b54aba7 --- /dev/null +++ b/MicaApps.Upw.Mail.csproj @@ -0,0 +1,222 @@ + + + + + Debug + x86 + {77A48790-BE44-4F0B-90FE-1AD09730BF47} + AppContainerExe + Properties + MicaApps.Upw.Mail + MicaApps.Upw.Mail + zh-CN + UAP + 10.0.19041.0 + 10.0.17763.0 + 14 + 512 + {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + true + false + + + true + bin\x86\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x86 + false + prompt + true + + + bin\x86\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x86 + false + prompt + true + true + + + true + bin\ARM\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + ARM + false + prompt + true + + + bin\ARM\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + ARM + false + prompt + true + true + + + true + bin\ARM64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + ARM64 + false + prompt + true + true + + + bin\ARM64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + ARM64 + false + prompt + true + true + + + true + bin\x64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x64 + false + prompt + true + + + bin\x64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x64 + false + prompt + true + true + + + PackageReference + + + + App.xaml + + + LoginButton.xaml + + + MainPage.xaml + + + + + + + + HomePagel.xaml + + + LoginPage.xaml + + + LoginByImapPage.xaml + + + MailPage.xaml + + + + + + + + Designer + + + + + + + + + + + + + + + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + + + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + + + 4.3.0 + + + 8.0.0 + + + 6.2.14 + + + 4.3.0 + + + + + + + 14.0 + + + + \ No newline at end of file diff --git a/MicaApps.Upw.Mail.sln b/MicaApps.Upw.Mail.sln new file mode 100644 index 0000000..8d71363 --- /dev/null +++ b/MicaApps.Upw.Mail.sln @@ -0,0 +1,79 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34330.188 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MicaApps.Upw.Mail", "MicaApps.Upw.Mail.csproj", "{77A48790-BE44-4F0B-90FE-1AD09730BF47}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Debug|Any CPU.ActiveCfg = Debug|x64 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Debug|Any CPU.Build.0 = Debug|x64 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Debug|Any CPU.Deploy.0 = Debug|x64 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Debug|ARM.ActiveCfg = Debug|ARM + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Debug|ARM.Build.0 = Debug|ARM + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Debug|ARM.Deploy.0 = Debug|ARM + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Debug|ARM64.Build.0 = Debug|ARM64 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Debug|x64.ActiveCfg = Debug|x64 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Debug|x64.Build.0 = Debug|x64 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Debug|x64.Deploy.0 = Debug|x64 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Debug|x86.ActiveCfg = Debug|x86 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Debug|x86.Build.0 = Debug|x86 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Debug|x86.Deploy.0 = Debug|x86 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Release|Any CPU.ActiveCfg = Release|x64 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Release|Any CPU.Build.0 = Release|x64 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Release|Any CPU.Deploy.0 = Release|x64 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Release|ARM.ActiveCfg = Release|ARM + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Release|ARM.Build.0 = Release|ARM + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Release|ARM.Deploy.0 = Release|ARM + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Release|ARM64.ActiveCfg = Release|ARM64 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Release|ARM64.Build.0 = Release|ARM64 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Release|ARM64.Deploy.0 = Release|ARM64 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Release|x64.ActiveCfg = Release|x64 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Release|x64.Build.0 = Release|x64 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Release|x64.Deploy.0 = Release|x64 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Release|x86.ActiveCfg = Release|x86 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Release|x86.Build.0 = Release|x86 + {77A48790-BE44-4F0B-90FE-1AD09730BF47}.Release|x86.Deploy.0 = Release|x86 + {11FED196-CDE6-4685-B094-3276C7F129F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {11FED196-CDE6-4685-B094-3276C7F129F9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {11FED196-CDE6-4685-B094-3276C7F129F9}.Debug|ARM.ActiveCfg = Debug|ARM + {11FED196-CDE6-4685-B094-3276C7F129F9}.Debug|ARM.Build.0 = Debug|ARM + {11FED196-CDE6-4685-B094-3276C7F129F9}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {11FED196-CDE6-4685-B094-3276C7F129F9}.Debug|ARM64.Build.0 = Debug|ARM64 + {11FED196-CDE6-4685-B094-3276C7F129F9}.Debug|x64.ActiveCfg = Debug|x64 + {11FED196-CDE6-4685-B094-3276C7F129F9}.Debug|x64.Build.0 = Debug|x64 + {11FED196-CDE6-4685-B094-3276C7F129F9}.Debug|x86.ActiveCfg = Debug|x86 + {11FED196-CDE6-4685-B094-3276C7F129F9}.Debug|x86.Build.0 = Debug|x86 + {11FED196-CDE6-4685-B094-3276C7F129F9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {11FED196-CDE6-4685-B094-3276C7F129F9}.Release|Any CPU.Build.0 = Release|Any CPU + {11FED196-CDE6-4685-B094-3276C7F129F9}.Release|ARM.ActiveCfg = Release|ARM + {11FED196-CDE6-4685-B094-3276C7F129F9}.Release|ARM.Build.0 = Release|ARM + {11FED196-CDE6-4685-B094-3276C7F129F9}.Release|ARM64.ActiveCfg = Release|ARM64 + {11FED196-CDE6-4685-B094-3276C7F129F9}.Release|ARM64.Build.0 = Release|ARM64 + {11FED196-CDE6-4685-B094-3276C7F129F9}.Release|x64.ActiveCfg = Release|x64 + {11FED196-CDE6-4685-B094-3276C7F129F9}.Release|x64.Build.0 = Release|x64 + {11FED196-CDE6-4685-B094-3276C7F129F9}.Release|x86.ActiveCfg = Release|x86 + {11FED196-CDE6-4685-B094-3276C7F129F9}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A29722C2-BB0B-41C4-8925-3DFE6A793CD4} + EndGlobalSection +EndGlobal diff --git a/Models/Enums/MailType.cs b/Models/Enums/MailType.cs new file mode 100644 index 0000000..b26eeca --- /dev/null +++ b/Models/Enums/MailType.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MicaApps.Upw.Mail.Models.Enums +{ + /// + /// 邮件类型 + /// + internal enum MailType + { + Receiving, Sending + } +} diff --git a/Models/ImapInfo.cs b/Models/ImapInfo.cs new file mode 100644 index 0000000..2d13dd7 --- /dev/null +++ b/Models/ImapInfo.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MailKit.Security; +using MailKit; +using MailKit.Net.Imap; +using System.Xml.Linq; +using Microsoft.Extensions.DependencyInjection; +using Windows.ApplicationModel.Resources; +using System.IO; +using System.Threading; +using Windows.Media.Protection.PlayReady; + +namespace MicaApps.Upw.Mail.Models +{ + internal class ImapInfo : ImapClient + { + //private readonly ResourceLoader resourceLoader = ResourceLoader.GetStringForReference(); + public string host { get;private set; } + public int port { get; private set; } + public SecureSocketOptions secureSocketOptions { get; set; } = SecureSocketOptions.SslOnConnect; + public ImapImplementation imapImplementation { get; set; } + public ImapInfo(string host,int port) + { + this.host = host; + this.port = port; + this.imapImplementation = new ImapImplementation + { + Name = @"MicaApps.Mail.UWP", + Version = @"1.0", + }; + } + + public async Task ConnectAsync(string username,string authorizationCode) + { + + try + { + // 连接到 IMAP 服务器 + await this.ConnectAsync(this.host, this.port, this.secureSocketOptions); + // 添加客户端身份标识 + _ = await this.IdentifyAsync(this.imapImplementation); + // 身份验证 + await this.AuthenticateAsync(username, authorizationCode); + } + catch (AuthenticationException ex) + { + throw new Exception(ex.Message); + } + catch(Exception ex) + { + throw new Exception(ex.Message); + } + } + + + + + + } +} diff --git a/Models/Letter.cs b/Models/Letter.cs new file mode 100644 index 0000000..d09cecd --- /dev/null +++ b/Models/Letter.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MimeKit; + +namespace MicaApps.Upw.Mail.Models +{ + /// + /// 专门用于储存每封信件 + /// + internal class Letter :MimeMessage + { + public string title { get => this.Subject; } + + + } +} diff --git a/Models/UserData.cs b/Models/UserData.cs new file mode 100644 index 0000000..33a17ac --- /dev/null +++ b/Models/UserData.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MicaApps.Upw.Mail.Models +{ + internal abstract class UserData + { + public string username { get; set; } = string.Empty; + + + public ObservableCollection letters { get; set; } = new ObservableCollection(); + + + public bool isEmpty { get => string.IsNullOrEmpty(username); } + + + + public abstract Task CollectLetter(); + public abstract Task LoginIn(); + + + public abstract bool IsLogin { get; } + + + } +} diff --git a/Models/UserDataByImap.cs b/Models/UserDataByImap.cs new file mode 100644 index 0000000..4a8527e --- /dev/null +++ b/Models/UserDataByImap.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MimeKit; +using MailKit.Net.Imap; +using MailKit.Security; +using Windows.UI.Xaml; +using MailKit; + +namespace MicaApps.Upw.Mail.Models +{ + /// + /// 通过Imap来获取信息 + /// + internal class UserDataByImap : UserData + { + public ImapInfo imapInfo { get; set; } + + /// + /// 授权码 + /// + public string authorizationCode { get; set; } + + public UserDataByImap(string username,string authorizationCode,ImapInfo imapInfo) + { + this.username = username; + this.authorizationCode = authorizationCode; + this.imapInfo = imapInfo; + } + + + public override async Task LoginIn() + { + await this.imapInfo.ConnectAsync(this.username,this.authorizationCode); + } + + public override async Task CollectLetter() + { + var inbox = this.imapInfo.Inbox; + await inbox.OpenAsync(FolderAccess.ReadOnly); + for (int i = 0; i < inbox.Count; i++) + { + var message = await inbox.GetMessageAsync(i); + this.letters.Add(message as Letter); + } + } + + + public override bool IsLogin { get => this.imapInfo.IsConnected; } + + } +} diff --git a/Package.appxmanifest b/Package.appxmanifest new file mode 100644 index 0000000..1a5ed77 --- /dev/null +++ b/Package.appxmanifest @@ -0,0 +1,49 @@ + + + + + + + + + + KalevaAalto.Upw.Mail + kalev + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Pages/HomePagel.xaml b/Pages/HomePagel.xaml new file mode 100644 index 0000000..6172785 --- /dev/null +++ b/Pages/HomePagel.xaml @@ -0,0 +1,20 @@ + + + + + + 收件箱 + + + + + + diff --git a/Pages/HomePagel.xaml.cs b/Pages/HomePagel.xaml.cs new file mode 100644 index 0000000..c68b38f --- /dev/null +++ b/Pages/HomePagel.xaml.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; + +// https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“空白页”项模板 + +namespace MicaApps.Upw.Mail.Pages +{ + /// + /// 可用于自身或导航至 Frame 内部的空白页。 + /// + public sealed partial class HomePagel : Page + { + public HomePagel() + { + this.InitializeComponent(); + } + + private void NavigationView_ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args) + { + // 获取点击的菜单项的 Tag + string tag = args.InvokedItemContainer.Tag.ToString(); + + // 根据 Tag 导航到相应的页面 + switch (tag) + { + case @"receive": + this.frame_main.Navigate(typeof(MailPage),tag); + break; + } + } + } +} diff --git a/Pages/Login/LoginByImapPage.xaml b/Pages/Login/LoginByImapPage.xaml new file mode 100644 index 0000000..06963da --- /dev/null +++ b/Pages/Login/LoginByImapPage.xaml @@ -0,0 +1,49 @@ + + + 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pages/Login/LoginByImapPage.xaml.cs b/Pages/Login/LoginByImapPage.xaml.cs new file mode 100644 index 0000000..f121cc4 --- /dev/null +++ b/Pages/Login/LoginByImapPage.xaml.cs @@ -0,0 +1,86 @@ +using MicaApps.Upw.Mail.Models; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using System.Text; +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; + +// https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“空白页”项模板 + +namespace MicaApps.Upw.Mail.Pages.Login +{ + /// + /// 可用于自身或导航至 Frame 内部的空白页。 + /// + public sealed partial class LoginByImapPage : Page + { + private readonly Services.StaticValues staticValues = App.Services.GetService(); + private readonly Services.LoginStatus loginStatus = App.Services.GetService(); + + public LoginByImapPage() + { + this.InitializeComponent(); + } + + private void combox_mailhost_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + Grid grid = new Grid(); + var m = grid.Margin; + } + + + private string username { get => this.textbox_username.Text + '@' + this.combox_mailhost.Text; } + private string password { get => this.textbox_password.Text; } + private string host { get=>this.textbox_host.Text; } + private int port { get => Convert.ToInt32(this.textbox_port.Text); } + + + private async void Button_Login_Click(object sender, RoutedEventArgs e) + { + + try + { + this.loginStatus.userData = new UserDataByImap( + this.username, + this.password, + new ImapInfo(this.host, this.port) + ); + + await this.loginStatus.userData.LoginIn(); + + this.Frame.Navigate(typeof(HomePagel)); + + + } + catch (Exception ex) + { + // 创建 ContentDialog + ContentDialog dialog = new ContentDialog + { + Title = "登录失败", + Content = ex.Message, + CloseButtonText = "关闭" + }; + + // 显示提示框并等待用户响应 + ContentDialogResult result = await dialog.ShowAsync(); + } + } + + private void Button_Back_Click(object sender, RoutedEventArgs e) + { + this.Frame.Navigate(typeof(LoginPage)); + } + } +} diff --git a/Pages/LoginPage.xaml b/Pages/LoginPage.xaml new file mode 100644 index 0000000..0674ae1 --- /dev/null +++ b/Pages/LoginPage.xaml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + diff --git a/Pages/LoginPage.xaml.cs b/Pages/LoginPage.xaml.cs new file mode 100644 index 0000000..ec87354 --- /dev/null +++ b/Pages/LoginPage.xaml.cs @@ -0,0 +1,80 @@ +using MicaApps.Upw.Mail.Controls; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using Windows.Devices.Enumeration; +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; + +// https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“空白页”项模板 + +namespace MicaApps.Upw.Mail.Pages +{ + /// + /// 可用于自身或导航至 Frame 内部的空白页。 + /// + public sealed partial class LoginPage : Page + { + public LoginPage() + { + this.InitializeComponent(); + } + + + /// + /// 页面加载函数 + /// + /// + /// + private void Page_Loaded(object sender, RoutedEventArgs e) + { + + } + + private void Button_Login_Click(object sender, RoutedEventArgs e) + { + if (sender is LoginButton button) + { + object tagValue = button.Tag; + + if (tagValue != null) + { + // 在这里使用按钮的 Tag 属性值 + string tagString = tagValue.ToString(); + // 其他处理逻辑... + switch (tagString) + { + case @"other": + this.Frame.Navigate(typeof(Login.LoginByImapPage)); + break; + } + } + } + } + + + private void Button_Test_Click(object sender, RoutedEventArgs e) + { +#if DEBUG + this.Frame.Navigate(typeof(HomePagel)); +#endif + } + + + + + private void NavigationView_ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args) + { + + } + } +} diff --git a/Pages/MailPage.xaml b/Pages/MailPage.xaml new file mode 100644 index 0000000..e90c2d7 --- /dev/null +++ b/Pages/MailPage.xaml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pages/MailPage.xaml.cs b/Pages/MailPage.xaml.cs new file mode 100644 index 0000000..0bbb11a --- /dev/null +++ b/Pages/MailPage.xaml.cs @@ -0,0 +1,103 @@ +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using System.Threading.Tasks; +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; + +// https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“空白页”项模板 + +namespace MicaApps.Upw.Mail.Pages +{ + /// + /// 可用于自身或导航至 Frame 内部的空白页。 + /// + public sealed partial class MailPage : Page + { + private readonly Services.LoginStatus loginStatus = App.Services.GetService(); + private string tag; + private DispatcherTimer timer; + + + public MailPage() + { + this.InitializeComponent(); + + + + // 初始化定时器 + this.timer = new DispatcherTimer(); + this.timer.Interval = TimeSpan.FromSeconds(1); // 设置定时器间隔为1秒 + this.timer.Tick += (sender, e) => + { + this.textblock_status.Text = this.loginStatus.userData != null ? this.loginStatus.userData.letters.Count().ToString() : @"未连接"; + }; + } + + + + + + + /// + /// 处理传递过来参数 + /// + protected override async void OnNavigatedTo(NavigationEventArgs e) + { + base.OnNavigatedTo(e); + + if (e.Parameter != null) + { + // 处理传递过来的参数 + this.tag = (string)e.Parameter; + // 在这里添加你的逻辑 + + } + + + if (this.loginStatus.userData != null) + { + this.listview.ItemsSource = this.loginStatus.userData.letters; + await this.loginStatus.userData.CollectLetter(); + + } + timer.Start(); + } + + + protected override void OnNavigatedFrom(NavigationEventArgs e) + { + base.OnNavigatedFrom(e); + + // 停止定时器,释放资源 + timer.Stop(); + } + + private void listview_ItemClick(object sender, ItemClickEventArgs e) + { + // 获取点击的项的数据 + Models.Letter clickedItem = e.ClickedItem as Models.Letter; + + // 处理点击事件,例如显示一个消息框 + if (clickedItem != null) + { + this.textblock_area.Text = clickedItem.TextBody; + } + else + { + this.textblock_area.Text = @"Error!"; + } + } + } +} diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..97d1f68 --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -0,0 +1,29 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("KalevaAalto.Upw.Mail")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("KalevaAalto.Upw.Mail")] +[assembly: AssemblyCopyright("Copyright © 2023")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 +//通过使用 "*",如下所示: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: ComVisible(false)] \ No newline at end of file diff --git a/Properties/Default.rd.xml b/Properties/Default.rd.xml new file mode 100644 index 0000000..769324f --- /dev/null +++ b/Properties/Default.rd.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..09ff0f9 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# KalevaAalto.Upw.Mail \ No newline at end of file diff --git a/Resources/Strings.resw b/Resources/Strings.resw new file mode 100644 index 0000000..2380118 --- /dev/null +++ b/Resources/Strings.resw @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + MicaApps.Mail.UWP + + + 1.0 + + \ No newline at end of file diff --git a/Services/LoginStatus.cs b/Services/LoginStatus.cs new file mode 100644 index 0000000..6f255d6 --- /dev/null +++ b/Services/LoginStatus.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.UI.Xaml.Media.Animation; + +namespace MicaApps.Upw.Mail.Services +{ + internal class LoginStatus + { + public Models.UserData userData { get; set; } + + public bool IsLogin { get=>this.userData != null && this.userData.IsLogin;} + + + + } +} diff --git a/Services/StaticValues.cs b/Services/StaticValues.cs new file mode 100644 index 0000000..4b51c4b --- /dev/null +++ b/Services/StaticValues.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + + +namespace MicaApps.Upw.Mail.Services +{ + internal class StaticValues + { + + + + public Dictionary imapInfos { get; } = new Dictionary + { + { @"qq.com",new Models.ImapInfo(@"imap.qq.com",993) }, + { @"163.com",new Models.ImapInfo(@"imap.163.com",993) }, + }; + + + + } +} diff --git a/Services/TestService.cs b/Services/TestService.cs new file mode 100644 index 0000000..20e3d9a --- /dev/null +++ b/Services/TestService.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Mail; +using System.Net; +using System.Text; +using System.Threading.Tasks; +using System.Threading; +using MailKit.Security; +using MailKit; +using MailKit.Net.Imap; +using Windows.UI.Xaml.Controls; + + + +namespace KalevaAalto.Upw.Base.Services +{ + public class TestService + { + + + + public void test(Action AddString) + { + string username = @"kalevaaalto@163.com"; + string password = @"RDYOIOUMYSWGAPLK"; + + using (var client = new ImapClient()) + { + client.Connect(@"imap.163.com", 993, SecureSocketOptions.SslOnConnect); + client.Authenticate(username, password); + + var clientImplementation = new ImapImplementation + { + Name = "KalevaAalto.Upw", + Version = "2.0" + }; + _ = client.Identify(clientImplementation); + + + var inbox = client.Inbox; + inbox.Open(FolderAccess.ReadOnly); + + AddString(@"Total messages: " + inbox.Count); + + for (int i = 0; i < inbox.Count; i++) + { + + + var message = inbox.GetMessage(i); + var id = message.MessageId; + AddString(@"Subject: " + message.Subject); + } + + client.Disconnect(true); + } + + + } + + + + } +}