@capawesome/capacitor-mail-composer 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CapawesomeCapacitorMailComposer.podspec +17 -0
- package/LICENSE +21 -0
- package/Package.swift +28 -0
- package/README.md +208 -0
- package/android/build.gradle +58 -0
- package/android/src/main/AndroidManifest.xml +8 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/mailcomposer/MailComposer.java +120 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/mailcomposer/MailComposerPlugin.java +101 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/mailcomposer/classes/CustomException.java +20 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/mailcomposer/classes/CustomExceptions.java +9 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/mailcomposer/classes/options/ComposeMailOptions.java +86 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/mailcomposer/classes/results/CanComposeMailResult.java +22 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/mailcomposer/classes/results/ComposeMailResult.java +23 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/mailcomposer/interfaces/Callback.java +5 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/mailcomposer/interfaces/NonEmptyResultCallback.java +7 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/mailcomposer/interfaces/Result.java +7 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/dist/docs.json +261 -0
- package/dist/esm/definitions.d.ts +133 -0
- package/dist/esm/definitions.js +19 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +8 -0
- package/dist/esm/web.js +35 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +68 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +71 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Plugin/Classes/Options/ComposeMailOptions.swift +22 -0
- package/ios/Plugin/Classes/Results/CanComposeMailResult.swift +16 -0
- package/ios/Plugin/Classes/Results/ComposeMailResult.swift +16 -0
- package/ios/Plugin/Enums/CustomError.swift +31 -0
- package/ios/Plugin/Info.plist +24 -0
- package/ios/Plugin/MailComposer.swift +88 -0
- package/ios/Plugin/MailComposerPlugin.swift +62 -0
- package/ios/Plugin/Protocols/Result.swift +5 -0
- package/package.json +91 -0
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
var capacitorMailComposer = (function (exports, core) {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @since 0.1.0
|
|
6
|
+
*/
|
|
7
|
+
exports.ErrorCode = void 0;
|
|
8
|
+
(function (ErrorCode) {
|
|
9
|
+
/**
|
|
10
|
+
* An attachment could not be found at the provided path.
|
|
11
|
+
*
|
|
12
|
+
* @since 0.1.0
|
|
13
|
+
*/
|
|
14
|
+
ErrorCode["AttachmentNotFound"] = "ATTACHMENT_NOT_FOUND";
|
|
15
|
+
/**
|
|
16
|
+
* The email could not be composed.
|
|
17
|
+
*
|
|
18
|
+
* @since 0.1.0
|
|
19
|
+
*/
|
|
20
|
+
ErrorCode["ComposeFailed"] = "COMPOSE_FAILED";
|
|
21
|
+
})(exports.ErrorCode || (exports.ErrorCode = {}));
|
|
22
|
+
|
|
23
|
+
const MailComposer = core.registerPlugin('MailComposer', {
|
|
24
|
+
web: () => Promise.resolve().then(function () { return web; }).then(m => new m.MailComposerWeb()),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
class MailComposerWeb extends core.WebPlugin {
|
|
28
|
+
async canComposeMail() {
|
|
29
|
+
return { canCompose: true };
|
|
30
|
+
}
|
|
31
|
+
async composeMail(options) {
|
|
32
|
+
if (options.attachments && options.attachments.length > 0) {
|
|
33
|
+
throw new Error(MailComposerWeb.errorAttachmentsNotSupported);
|
|
34
|
+
}
|
|
35
|
+
const url = this.createMailtoUrl(options);
|
|
36
|
+
window.open(url, '_self');
|
|
37
|
+
return { status: 'unknown' };
|
|
38
|
+
}
|
|
39
|
+
createMailtoUrl(options) {
|
|
40
|
+
var _a;
|
|
41
|
+
const to = ((_a = options.to) !== null && _a !== void 0 ? _a : []).join(',');
|
|
42
|
+
const params = new URLSearchParams();
|
|
43
|
+
if (options.cc && options.cc.length > 0) {
|
|
44
|
+
params.set('cc', options.cc.join(','));
|
|
45
|
+
}
|
|
46
|
+
if (options.bcc && options.bcc.length > 0) {
|
|
47
|
+
params.set('bcc', options.bcc.join(','));
|
|
48
|
+
}
|
|
49
|
+
if (options.subject) {
|
|
50
|
+
params.set('subject', options.subject);
|
|
51
|
+
}
|
|
52
|
+
if (options.body) {
|
|
53
|
+
params.set('body', options.body);
|
|
54
|
+
}
|
|
55
|
+
const query = params.toString();
|
|
56
|
+
return `mailto:${encodeURIComponent(to)}${query ? `?${query}` : ''}`;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
MailComposerWeb.errorAttachmentsNotSupported = 'Attachments are not supported on the web.';
|
|
60
|
+
|
|
61
|
+
var web = /*#__PURE__*/Object.freeze({
|
|
62
|
+
__proto__: null,
|
|
63
|
+
MailComposerWeb: MailComposerWeb
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
exports.MailComposer = MailComposer;
|
|
67
|
+
|
|
68
|
+
return exports;
|
|
69
|
+
|
|
70
|
+
})({}, capacitorExports);
|
|
71
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["esm/definitions.js","esm/index.js","esm/web.js"],"sourcesContent":["/**\n * @since 0.1.0\n */\nexport var ErrorCode;\n(function (ErrorCode) {\n /**\n * An attachment could not be found at the provided path.\n *\n * @since 0.1.0\n */\n ErrorCode[\"AttachmentNotFound\"] = \"ATTACHMENT_NOT_FOUND\";\n /**\n * The email could not be composed.\n *\n * @since 0.1.0\n */\n ErrorCode[\"ComposeFailed\"] = \"COMPOSE_FAILED\";\n})(ErrorCode || (ErrorCode = {}));\n//# sourceMappingURL=definitions.js.map","import { registerPlugin } from '@capacitor/core';\nconst MailComposer = registerPlugin('MailComposer', {\n web: () => import('./web').then(m => new m.MailComposerWeb()),\n});\nexport * from './definitions';\nexport { MailComposer };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class MailComposerWeb extends WebPlugin {\n async canComposeMail() {\n return { canCompose: true };\n }\n async composeMail(options) {\n if (options.attachments && options.attachments.length > 0) {\n throw new Error(MailComposerWeb.errorAttachmentsNotSupported);\n }\n const url = this.createMailtoUrl(options);\n window.open(url, '_self');\n return { status: 'unknown' };\n }\n createMailtoUrl(options) {\n var _a;\n const to = ((_a = options.to) !== null && _a !== void 0 ? _a : []).join(',');\n const params = new URLSearchParams();\n if (options.cc && options.cc.length > 0) {\n params.set('cc', options.cc.join(','));\n }\n if (options.bcc && options.bcc.length > 0) {\n params.set('bcc', options.bcc.join(','));\n }\n if (options.subject) {\n params.set('subject', options.subject);\n }\n if (options.body) {\n params.set('body', options.body);\n }\n const query = params.toString();\n return `mailto:${encodeURIComponent(to)}${query ? `?${query}` : ''}`;\n }\n}\nMailComposerWeb.errorAttachmentsNotSupported = 'Attachments are not supported on the web.';\n//# sourceMappingURL=web.js.map"],"names":["ErrorCode","registerPlugin","WebPlugin"],"mappings":";;;IAAA;IACA;IACA;AACWA;IACX,CAAC,UAAU,SAAS,EAAE;IACtB;IACA;IACA;IACA;IACA;IACA,IAAI,SAAS,CAAC,oBAAoB,CAAC,GAAG,sBAAsB;IAC5D;IACA;IACA;IACA;IACA;IACA,IAAI,SAAS,CAAC,eAAe,CAAC,GAAG,gBAAgB;IACjD,CAAC,EAAEA,iBAAS,KAAKA,iBAAS,GAAG,EAAE,CAAC,CAAC;;AChB5B,UAAC,YAAY,GAAGC,mBAAc,CAAC,cAAc,EAAE;IACpD,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,eAAe,EAAE,CAAC;IACjE,CAAC;;ICFM,MAAM,eAAe,SAASC,cAAS,CAAC;IAC/C,IAAI,MAAM,cAAc,GAAG;IAC3B,QAAQ,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE;IACnC,IAAI;IACJ,IAAI,MAAM,WAAW,CAAC,OAAO,EAAE;IAC/B,QAAQ,IAAI,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE;IACnE,YAAY,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,4BAA4B,CAAC;IACzE,QAAQ;IACR,QAAQ,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC;IACjD,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC;IACjC,QAAQ,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE;IACpC,IAAI;IACJ,IAAI,eAAe,CAAC,OAAO,EAAE;IAC7B,QAAQ,IAAI,EAAE;IACd,QAAQ,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,MAAM,IAAI,IAAI,EAAE,KAAK,MAAM,GAAG,EAAE,GAAG,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC;IACpF,QAAQ,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE;IAC5C,QAAQ,IAAI,OAAO,CAAC,EAAE,IAAI,OAAO,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE;IACjD,YAAY,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClD,QAAQ;IACR,QAAQ,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE;IACnD,YAAY,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpD,QAAQ;IACR,QAAQ,IAAI,OAAO,CAAC,OAAO,EAAE;IAC7B,YAAY,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC;IAClD,QAAQ;IACR,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE;IAC1B,YAAY,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC;IAC5C,QAAQ;IACR,QAAQ,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE;IACvC,QAAQ,OAAO,CAAC,OAAO,EAAE,kBAAkB,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC5E,IAAI;IACJ;IACA,eAAe,CAAC,4BAA4B,GAAG,2CAA2C;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Capacitor
|
|
3
|
+
|
|
4
|
+
@objc public class ComposeMailOptions: NSObject {
|
|
5
|
+
let attachments: [String]
|
|
6
|
+
let bccRecipients: [String]
|
|
7
|
+
let body: String?
|
|
8
|
+
let ccRecipients: [String]
|
|
9
|
+
let isHtml: Bool
|
|
10
|
+
let subject: String?
|
|
11
|
+
let toRecipients: [String]
|
|
12
|
+
|
|
13
|
+
init(_ call: CAPPluginCall) {
|
|
14
|
+
self.toRecipients = call.getArray("to", String.self) ?? []
|
|
15
|
+
self.ccRecipients = call.getArray("cc", String.self) ?? []
|
|
16
|
+
self.bccRecipients = call.getArray("bcc", String.self) ?? []
|
|
17
|
+
self.subject = call.getString("subject")
|
|
18
|
+
self.body = call.getString("body")
|
|
19
|
+
self.isHtml = call.getBool("isHtml", false)
|
|
20
|
+
self.attachments = call.getArray("attachments", String.self) ?? []
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Capacitor
|
|
3
|
+
|
|
4
|
+
@objc public class CanComposeMailResult: NSObject, Result {
|
|
5
|
+
let canCompose: Bool
|
|
6
|
+
|
|
7
|
+
init(canCompose: Bool) {
|
|
8
|
+
self.canCompose = canCompose
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
@objc public func toJSObject() -> AnyObject {
|
|
12
|
+
var result = JSObject()
|
|
13
|
+
result["canCompose"] = canCompose
|
|
14
|
+
return result as AnyObject
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Capacitor
|
|
3
|
+
|
|
4
|
+
@objc public class ComposeMailResult: NSObject, Result {
|
|
5
|
+
let status: String
|
|
6
|
+
|
|
7
|
+
init(status: String) {
|
|
8
|
+
self.status = status
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
@objc public func toJSObject() -> AnyObject {
|
|
12
|
+
var result = JSObject()
|
|
13
|
+
result["status"] = status
|
|
14
|
+
return result as AnyObject
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
enum CustomError: Error {
|
|
4
|
+
case attachmentNotFound
|
|
5
|
+
case composeFailed
|
|
6
|
+
case mailServicesUnavailable
|
|
7
|
+
|
|
8
|
+
var code: String? {
|
|
9
|
+
switch self {
|
|
10
|
+
case .attachmentNotFound:
|
|
11
|
+
return "ATTACHMENT_NOT_FOUND"
|
|
12
|
+
case .composeFailed:
|
|
13
|
+
return "COMPOSE_FAILED"
|
|
14
|
+
case .mailServicesUnavailable:
|
|
15
|
+
return nil
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
extension CustomError: LocalizedError {
|
|
21
|
+
public var errorDescription: String? {
|
|
22
|
+
switch self {
|
|
23
|
+
case .attachmentNotFound:
|
|
24
|
+
return NSLocalizedString("An attachment could not be found at the provided path.", comment: "attachmentNotFound")
|
|
25
|
+
case .composeFailed:
|
|
26
|
+
return NSLocalizedString("The email could not be composed.", comment: "composeFailed")
|
|
27
|
+
case .mailServicesUnavailable:
|
|
28
|
+
return NSLocalizedString("No mail account is configured on this device.", comment: "mailServicesUnavailable")
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>CFBundleDevelopmentRegion</key>
|
|
6
|
+
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
|
7
|
+
<key>CFBundleExecutable</key>
|
|
8
|
+
<string>$(EXECUTABLE_NAME)</string>
|
|
9
|
+
<key>CFBundleIdentifier</key>
|
|
10
|
+
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
|
11
|
+
<key>CFBundleInfoDictionaryVersion</key>
|
|
12
|
+
<string>6.0</string>
|
|
13
|
+
<key>CFBundleName</key>
|
|
14
|
+
<string>$(PRODUCT_NAME)</string>
|
|
15
|
+
<key>CFBundlePackageType</key>
|
|
16
|
+
<string>FMWK</string>
|
|
17
|
+
<key>CFBundleShortVersionString</key>
|
|
18
|
+
<string>1.0</string>
|
|
19
|
+
<key>CFBundleVersion</key>
|
|
20
|
+
<string>$(CURRENT_PROJECT_VERSION)</string>
|
|
21
|
+
<key>NSPrincipalClass</key>
|
|
22
|
+
<string></string>
|
|
23
|
+
</dict>
|
|
24
|
+
</plist>
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Capacitor
|
|
3
|
+
import MessageUI
|
|
4
|
+
import UniformTypeIdentifiers
|
|
5
|
+
|
|
6
|
+
@objc public class MailComposer: NSObject {
|
|
7
|
+
private let plugin: MailComposerPlugin
|
|
8
|
+
private var composeCompletion: ((ComposeMailResult?, Error?) -> Void)?
|
|
9
|
+
|
|
10
|
+
init(plugin: MailComposerPlugin) {
|
|
11
|
+
self.plugin = plugin
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
@objc public func canComposeMail(completion: @escaping (CanComposeMailResult?, Error?) -> Void) {
|
|
15
|
+
let result = CanComposeMailResult(canCompose: MFMailComposeViewController.canSendMail())
|
|
16
|
+
completion(result, nil)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@objc public func composeMail(_ options: ComposeMailOptions, completion: @escaping (ComposeMailResult?, Error?) -> Void) {
|
|
20
|
+
DispatchQueue.main.async {
|
|
21
|
+
guard MFMailComposeViewController.canSendMail() else {
|
|
22
|
+
completion(nil, CustomError.mailServicesUnavailable)
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
let controller = MFMailComposeViewController()
|
|
26
|
+
controller.mailComposeDelegate = self
|
|
27
|
+
controller.setToRecipients(options.toRecipients)
|
|
28
|
+
controller.setCcRecipients(options.ccRecipients)
|
|
29
|
+
controller.setBccRecipients(options.bccRecipients)
|
|
30
|
+
if let subject = options.subject {
|
|
31
|
+
controller.setSubject(subject)
|
|
32
|
+
}
|
|
33
|
+
if let body = options.body {
|
|
34
|
+
controller.setMessageBody(body, isHTML: options.isHtml)
|
|
35
|
+
}
|
|
36
|
+
for attachment in options.attachments {
|
|
37
|
+
let url = Self.createFileUrl(from: attachment)
|
|
38
|
+
guard let data = try? Data(contentsOf: url) else {
|
|
39
|
+
completion(nil, CustomError.attachmentNotFound)
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
controller.addAttachmentData(data, mimeType: Self.mimeType(for: url), fileName: url.lastPathComponent)
|
|
43
|
+
}
|
|
44
|
+
self.composeCompletion = completion
|
|
45
|
+
self.plugin.bridge?.viewController?.present(controller, animated: true)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
private static func createFileUrl(from path: String) -> URL {
|
|
50
|
+
if path.hasPrefix("file://") {
|
|
51
|
+
return URL(string: path) ?? URL(fileURLWithPath: path)
|
|
52
|
+
}
|
|
53
|
+
return URL(fileURLWithPath: path)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private static func mapResult(_ result: MFMailComposeResult) -> String {
|
|
57
|
+
switch result {
|
|
58
|
+
case .sent:
|
|
59
|
+
return "sent"
|
|
60
|
+
case .saved:
|
|
61
|
+
return "saved"
|
|
62
|
+
case .cancelled:
|
|
63
|
+
return "canceled"
|
|
64
|
+
default:
|
|
65
|
+
return "unknown"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private static func mimeType(for url: URL) -> String {
|
|
70
|
+
if let type = UTType(filenameExtension: url.pathExtension), let mimeType = type.preferredMIMEType {
|
|
71
|
+
return mimeType
|
|
72
|
+
}
|
|
73
|
+
return "application/octet-stream"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
extension MailComposer: MFMailComposeViewControllerDelegate {
|
|
78
|
+
public func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
|
|
79
|
+
controller.dismiss(animated: true)
|
|
80
|
+
let completion = composeCompletion
|
|
81
|
+
composeCompletion = nil
|
|
82
|
+
if result == .failed {
|
|
83
|
+
completion?(nil, CustomError.composeFailed)
|
|
84
|
+
return
|
|
85
|
+
}
|
|
86
|
+
completion?(ComposeMailResult(status: Self.mapResult(result)), nil)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Capacitor
|
|
3
|
+
|
|
4
|
+
@objc(MailComposerPlugin)
|
|
5
|
+
public class MailComposerPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
6
|
+
public let identifier = "MailComposerPlugin"
|
|
7
|
+
public let jsName = "MailComposer"
|
|
8
|
+
public let pluginMethods: [CAPPluginMethod] = [
|
|
9
|
+
CAPPluginMethod(name: "canComposeMail", returnType: CAPPluginReturnPromise),
|
|
10
|
+
CAPPluginMethod(name: "composeMail", returnType: CAPPluginReturnPromise)
|
|
11
|
+
]
|
|
12
|
+
public static let tag = "MailComposerPlugin"
|
|
13
|
+
|
|
14
|
+
private var implementation: MailComposer?
|
|
15
|
+
|
|
16
|
+
override public func load() {
|
|
17
|
+
self.implementation = MailComposer(plugin: self)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@objc func canComposeMail(_ call: CAPPluginCall) {
|
|
21
|
+
implementation?.canComposeMail { result, error in
|
|
22
|
+
if let error = error {
|
|
23
|
+
self.rejectCall(call, error)
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
self.resolveCall(call, result)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@objc func composeMail(_ call: CAPPluginCall) {
|
|
31
|
+
let options = ComposeMailOptions(call)
|
|
32
|
+
implementation?.composeMail(options) { result, error in
|
|
33
|
+
if let error = error {
|
|
34
|
+
if case CustomError.mailServicesUnavailable = error {
|
|
35
|
+
self.rejectCallAsUnavailable(call)
|
|
36
|
+
} else {
|
|
37
|
+
self.rejectCall(call, error)
|
|
38
|
+
}
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
self.resolveCall(call, result)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
private func rejectCall(_ call: CAPPluginCall, _ error: Error) {
|
|
46
|
+
CAPLog.print("[", MailComposerPlugin.tag, "] ", error)
|
|
47
|
+
let code = (error as? CustomError)?.code
|
|
48
|
+
call.reject(error.localizedDescription, code)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private func rejectCallAsUnavailable(_ call: CAPPluginCall) {
|
|
52
|
+
call.unavailable("This method is not available on this platform.")
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
private func resolveCall(_ call: CAPPluginCall, _ result: Result?) {
|
|
56
|
+
if let result = result?.toJSObject() as? JSObject {
|
|
57
|
+
call.resolve(result)
|
|
58
|
+
} else {
|
|
59
|
+
call.resolve()
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@capawesome/capacitor-mail-composer",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Capacitor plugin to open the native email composer.",
|
|
5
|
+
"main": "dist/plugin.cjs.js",
|
|
6
|
+
"module": "dist/esm/index.js",
|
|
7
|
+
"types": "dist/esm/index.d.ts",
|
|
8
|
+
"unpkg": "dist/plugin.js",
|
|
9
|
+
"files": [
|
|
10
|
+
"android/src/main/",
|
|
11
|
+
"android/build.gradle",
|
|
12
|
+
"dist/",
|
|
13
|
+
"ios/Plugin/",
|
|
14
|
+
"CapawesomeCapacitorMailComposer.podspec",
|
|
15
|
+
"Package.swift"
|
|
16
|
+
],
|
|
17
|
+
"author": "Robin Genz <mail@robingenz.dev>",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/capawesome-team/capacitor-plugins.git"
|
|
22
|
+
},
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/capawesome-team/capacitor-plugins/issues"
|
|
25
|
+
},
|
|
26
|
+
"funding": [
|
|
27
|
+
{
|
|
28
|
+
"type": "github",
|
|
29
|
+
"url": "https://github.com/sponsors/capawesome-team/"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"type": "opencollective",
|
|
33
|
+
"url": "https://opencollective.com/capawesome"
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"homepage": "https://capawesome.io/docs/plugins/mail-composer/",
|
|
37
|
+
"keywords": [
|
|
38
|
+
"capacitor",
|
|
39
|
+
"plugin",
|
|
40
|
+
"native"
|
|
41
|
+
],
|
|
42
|
+
"scripts": {
|
|
43
|
+
"verify": "npm run verify:ios && npm run verify:android && npm run verify:web",
|
|
44
|
+
"verify:ios": "cd ios && pod install && xcodebuild -workspace Plugin.xcworkspace -scheme Plugin -destination generic/platform=iOS && cd ..",
|
|
45
|
+
"verify:android": "cd android && ./gradlew clean build test && cd ..",
|
|
46
|
+
"verify:web": "npm run build",
|
|
47
|
+
"lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
|
|
48
|
+
"fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
|
|
49
|
+
"eslint": "eslint . --ext ts",
|
|
50
|
+
"prettier": "prettier \"**/*.{css,html,ts,js,java}\"",
|
|
51
|
+
"swiftlint": "node-swiftlint",
|
|
52
|
+
"docgen": "docgen --api MailComposerPlugin --output-readme README.md --output-json dist/docs.json",
|
|
53
|
+
"build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.mjs",
|
|
54
|
+
"clean": "rimraf ./dist",
|
|
55
|
+
"watch": "tsc --watch",
|
|
56
|
+
"ios:pod:install": "cd ios && pod install --repo-update && cd ..",
|
|
57
|
+
"ios:spm:install": "cd ios && swift package resolve && cd ..",
|
|
58
|
+
"prepublishOnly": "npm run build"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@capacitor/android": "8.0.0",
|
|
62
|
+
"@capacitor/cli": "8.0.0",
|
|
63
|
+
"@capacitor/core": "8.0.0",
|
|
64
|
+
"@capacitor/docgen": "0.3.1",
|
|
65
|
+
"@capacitor/ios": "8.0.0",
|
|
66
|
+
"@ionic/eslint-config": "0.4.0",
|
|
67
|
+
"eslint": "8.57.0",
|
|
68
|
+
"prettier-plugin-java": "2.6.7",
|
|
69
|
+
"rimraf": "6.1.2",
|
|
70
|
+
"rollup": "4.53.3",
|
|
71
|
+
"swiftlint": "2.0.0",
|
|
72
|
+
"typescript": "5.9.3"
|
|
73
|
+
},
|
|
74
|
+
"peerDependencies": {
|
|
75
|
+
"@capacitor/core": ">=8.0.0"
|
|
76
|
+
},
|
|
77
|
+
"eslintConfig": {
|
|
78
|
+
"extends": "@ionic/eslint-config/recommended"
|
|
79
|
+
},
|
|
80
|
+
"capacitor": {
|
|
81
|
+
"ios": {
|
|
82
|
+
"src": "ios"
|
|
83
|
+
},
|
|
84
|
+
"android": {
|
|
85
|
+
"src": "android"
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
"publishConfig": {
|
|
89
|
+
"access": "public"
|
|
90
|
+
}
|
|
91
|
+
}
|