Skip to content
This repository has been archived by the owner on May 15, 2024. It is now read-only.

Commit

Permalink
GH-27: Master based email (#105)
Browse files Browse the repository at this point in the history
* email API initial commit
UWP OK

* Email Sample and Device Tests

* API according to comments

* Android Composing finished

* Update the Email API

* Update the tests - removed the emil tests as this will leave the current app

* Update the tests - removed the emil tests as this will leave the current app

* Add base for email attachments

* Removing attachments as this is not as simple as one might expect...

* Removing usless email tests

* Return fast

* Update Email.uwp.cs

* Added the empty email docs

* Warnings instead of messages for missing docs as this is serious

* This should be private

* Updated existing docs to match their APIs

* Added the email docs

* Updated the samples description

* Fix test email address
  • Loading branch information
mattleibow authored and Redth committed Apr 4, 2018
1 parent 877d135 commit 4a110c7
Show file tree
Hide file tree
Showing 30 changed files with 688 additions and 46 deletions.
9 changes: 9 additions & 0 deletions Caboodle.Tests/Email_Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Microsoft.Caboodle;
using Xunit;

namespace Caboodle.Tests
{
public class Email_Tests
{
}
}
4 changes: 2 additions & 2 deletions Caboodle/Caboodle.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
<DebugType>pdbonly</DebugType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="mdoc" Version="5.6.0" PrivateAssets="All" />
<PackageReference Include="MSBuild.Sdk.Extras" Version="1.2.0" PrivateAssets="All" />
<PackageReference Include="mdoc" Version="5.6.1" PrivateAssets="All" />
<PackageReference Include="MSBuild.Sdk.Extras" Version="1.2.2" PrivateAssets="All" />
<Compile Include="**\*.shared.cs" />
<Compile Include="**\*.shared.*.cs" />
</ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion Caboodle/DeviceInfo/DeviceInfo.ios.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static void StopScreenMetricsListeners()
observer = null;
}

private static void OnScreenMetricsChanaged(NSNotification obj)
static void OnScreenMetricsChanaged(NSNotification obj)
{
var metrics = GetScreenMetrics();
OnScreenMetricsChanaged(metrics);
Expand Down
66 changes: 66 additions & 0 deletions Caboodle/Email/Email.android.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using System.Threading.Tasks;
using Android.Content;
using Android.OS;
using Android.Text;

namespace Microsoft.Caboodle
{
public static partial class Email
{
static readonly EmailMessage testEmail =
new EmailMessage("Testing Caboodle", "This is a test email.", "caboodle@example.org");

internal static bool IsComposeSupported
=> Platform.IsIntentSupported(CreateIntent(testEmail));

static Task PlatformComposeAsync(EmailMessage message)
{
var intent = CreateIntent(message)
.SetFlags(ActivityFlags.ClearTop)
.SetFlags(ActivityFlags.NewTask);

Platform.CurrentContext.StartActivity(intent);

return Task.FromResult(true);
}

static Intent CreateIntent(EmailMessage message)
{
var intent = new Intent(Intent.ActionSend);
intent.SetType("message/rfc822");

if (!string.IsNullOrEmpty(message?.Body))
{
if (message?.BodyFormat == EmailBodyFormat.Html)
{
ISpanned html;
if (Platform.HasApiLevel(BuildVersionCodes.N))
{
html = Html.FromHtml(message.Body, FromHtmlOptions.ModeLegacy);
}
else
{
#pragma warning disable CS0618 // Type or member is obsolete
html = Html.FromHtml(message.Body);
#pragma warning restore CS0618 // Type or member is obsolete
}
intent.PutExtra(Intent.ExtraText, html);
}
else
{
intent.PutExtra(Intent.ExtraText, message.Body);
}
}
if (!string.IsNullOrEmpty(message?.Subject))
intent.PutExtra(Intent.ExtraSubject, message.Subject);
if (message.To?.Count > 0)
intent.PutExtra(Intent.ExtraEmail, message.To.ToArray());
if (message.Cc?.Count > 0)
intent.PutExtra(Intent.ExtraCc, message.Cc.ToArray());
if (message.Bcc?.Count > 0)
intent.PutExtra(Intent.ExtraBcc, message.Bcc.ToArray());

return intent;
}
}
}
41 changes: 41 additions & 0 deletions Caboodle/Email/Email.ios.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System.Threading.Tasks;
using MessageUI;

namespace Microsoft.Caboodle
{
public static partial class Email
{
internal static bool IsComposeSupported
=> MFMailComposeViewController.CanSendMail;

static Task PlatformComposeAsync(EmailMessage message)
{
// do this first so we can throw as early as possible
var parentController = Platform.GetCurrentViewController();

// create the controller
var controller = new MFMailComposeViewController();
if (!string.IsNullOrEmpty(message?.Body))
controller.SetMessageBody(message.Body, message?.BodyFormat == EmailBodyFormat.Html);
if (!string.IsNullOrEmpty(message?.Subject))
controller.SetSubject(message.Subject);
if (message?.To.Count > 0)
controller.SetToRecipients(message.To.ToArray());
if (message?.Cc.Count > 0)
controller.SetCcRecipients(message.Cc.ToArray());
if (message?.Bcc.Count > 0)
controller.SetBccRecipients(message.Bcc.ToArray());

// show the controller
var tcs = new TaskCompletionSource<bool>();
controller.Finished += (sender, e) =>
{
controller.DismissViewController(true, null);
tcs.SetResult(e.Result == MFMailComposeResult.Sent);
};
parentController.PresentViewController(controller, true, null);

return tcs.Task;
}
}
}
12 changes: 12 additions & 0 deletions Caboodle/Email/Email.netstandard.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Threading.Tasks;

namespace Microsoft.Caboodle
{
public static partial class Email
{
internal static bool IsComposeSupported => false;

static Task PlatformComposeAsync(EmailMessage message) =>
throw new NotImplementedInReferenceAssemblyException();
}
}
53 changes: 53 additions & 0 deletions Caboodle/Email/Email.shared.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Microsoft.Caboodle
{
public static partial class Email
{
public static Task ComposeAsync()
=> ComposeAsync(null);

public static Task ComposeAsync(string subject, string body, params string[] to)
=> ComposeAsync(new EmailMessage(subject, body, to));

public static Task ComposeAsync(EmailMessage message)
{
if (!IsComposeSupported)
throw new FeatureNotSupportedException();

return PlatformComposeAsync(message);
}
}

public class EmailMessage
{
public EmailMessage()
{
}

public EmailMessage(string subject, string body, params string[] to)
{
To = to?.ToList() ?? new List<string>();
}

public string Subject { get; set; }

public string Body { get; set; }

public EmailBodyFormat BodyFormat { get; set; }

public List<string> To { get; set; } = new List<string>();

public List<string> Cc { get; set; } = new List<string>();

public List<string> Bcc { get; set; } = new List<string>();
}

public enum EmailBodyFormat
{
PlainText,
Html
}
}
44 changes: 44 additions & 0 deletions Caboodle/Email/Email.uwp.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.ApplicationModel.Email;
using Windows.Foundation.Metadata;

using NativeEmailMessage = Windows.ApplicationModel.Email.EmailMessage;

namespace Microsoft.Caboodle
{
public static partial class Email
{
internal static bool IsComposeSupported
=> ApiInformation.IsTypePresent("Windows.ApplicationModel.Email.EmailManager");

static async Task PlatformComposeAsync(EmailMessage message)
{
if (message != null && message.BodyFormat != EmailBodyFormat.PlainText)
throw new FeatureNotSupportedException("UWP can only compose plain text email messages.");

var nativeMessage = new NativeEmailMessage();
if (!string.IsNullOrEmpty(message?.Body))
nativeMessage.Body = message.Body;
if (!string.IsNullOrEmpty(message?.Subject))
nativeMessage.Subject = message.Subject;
Sync(message?.To, nativeMessage.To);
Sync(message?.Cc, nativeMessage.CC);
Sync(message?.Bcc, nativeMessage.Bcc);

await EmailManager.ShowComposeNewEmailAsync(nativeMessage);
}

static void Sync(List<string> recipients, IList<EmailRecipient> nativeRecipients)
{
if (recipients == null)
return;

foreach (var recipient in recipients)
{
nativeRecipients.Add(new EmailRecipient(recipient));
}
}
}
}
3 changes: 1 addition & 2 deletions Caboodle/PhoneDialer/PhoneDialer.netstandard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
{
public static partial class PhoneDialer
{
internal static bool IsSupported =>
throw new NotImplementedInReferenceAssemblyException();
internal static bool IsSupported => false;

public static void Open(string number) =>
throw new NotImplementedInReferenceAssemblyException();
Expand Down
7 changes: 2 additions & 5 deletions Caboodle/Sms/Sms.android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,11 @@ namespace Microsoft.Caboodle
{
public static partial class Sms
{
static bool IsComposeSupported
internal static bool IsComposeSupported
=> Platform.IsIntentSupported(CreateIntent("0000000000"));

public static Task ComposeAsync(SmsMessage message)
static Task PlatformComposeAsync(SmsMessage message)
{
if (!IsComposeSupported)
throw new FeatureNotSupportedException();

var intent = CreateIntent(message)
.SetFlags(ActivityFlags.ClearTop)
.SetFlags(ActivityFlags.NewTask);
Expand Down
7 changes: 2 additions & 5 deletions Caboodle/Sms/Sms.ios.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,11 @@ namespace Microsoft.Caboodle
{
public static partial class Sms
{
static bool IsComposeSupported
internal static bool IsComposeSupported
=> MFMessageComposeViewController.CanSendText;

public static Task ComposeAsync(SmsMessage message)
static Task PlatformComposeAsync(SmsMessage message)
{
if (!IsComposeSupported)
throw new FeatureNotSupportedException();

// do this first so we can throw as early as possible
var controller = Platform.GetCurrentViewController();

Expand Down
4 changes: 3 additions & 1 deletion Caboodle/Sms/Sms.netstandard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ namespace Microsoft.Caboodle
{
public static partial class Sms
{
public static Task ComposeAsync(SmsMessage message)
internal static bool IsComposeSupported => false;

static Task PlatformComposeAsync(SmsMessage message)
=> throw new NotImplementedInReferenceAssemblyException();
}
}
8 changes: 8 additions & 0 deletions Caboodle/Sms/Sms.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ public static partial class Sms
{
public static Task ComposeAsync()
=> ComposeAsync(null);

public static Task ComposeAsync(SmsMessage message)
{
if (!IsComposeSupported)
throw new FeatureNotSupportedException();

return PlatformComposeAsync(message);
}
}

public class SmsMessage
Expand Down
7 changes: 2 additions & 5 deletions Caboodle/Sms/Sms.uwp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@ namespace Microsoft.Caboodle
{
public static partial class Sms
{
static bool IsComposeSupported
internal static bool IsComposeSupported
=> ApiInformation.IsTypePresent("Windows.ApplicationModel.Chat.ChatMessageManager");

public static Task ComposeAsync(SmsMessage message)
static Task PlatformComposeAsync(SmsMessage message)
{
if (!IsComposeSupported)
throw new FeatureNotSupportedException();

var chat = new ChatMessage();
if (!string.IsNullOrWhiteSpace(message?.Body))
chat.Body = message.Body;
Expand Down
2 changes: 1 addition & 1 deletion Caboodle/mdoc.targets
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@
var typename = xdoc.Root.Attribute("FullName").Value;
var member = node.Attribute("MemberName").Value;
var memberType = node.Element("MemberType").Value.ToLower();
Log.LogMessage(MessageImportance.High, "Missing docs for {2} '{0}.{1}'.", typename, member, memberType);
Log.LogWarning("Missing docs for {2} '{0}.{1}'.", typename, member, memberType);
}
// write
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)Compass_Tests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Connectivity_Tests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Email_Tests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Battery_Tests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Clipboard_Tests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)DeviceInfo_Tests.cs" />
Expand Down
12 changes: 12 additions & 0 deletions DeviceTests/Caboodle.DeviceTests.Shared/Email_Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Caboodle;
using Xunit;

namespace Caboodle.DeviceTests
{
public class Email_Tests
{
}
}

0 comments on commit 4a110c7

Please sign in to comment.