eddyverbruggen / nativescript-email Goto Github PK
View Code? Open in Web Editor NEW:envelope: NativeScript plugin for opening draft e-mails
License: MIT License
:envelope: NativeScript plugin for opening draft e-mails
License: MIT License
Hi there!
Wanted to know whether your plugin will still be working fine if I add the flag of 'markingMode' set to 'none' in package.json file, as mentioned in one of the blogs of NativeScript release?
Here is the link of the blog where the reference is made for the same: https://www.nativescript.org/blog/announcing-the-release-of-nativescript-3.2
Looking forward to an early reply. Thank you!
I get the following error when trying to compose an email from a modal view. (I made sure that compose works in other places and I check if its available)
Attempt to present <MFMailComposeViewController: 0x11200f200> on <r: 0x10651dae0> whose view is not in the window hierarchy!
This is probably related to the way the UIViewController is obtained here https://github.com/EddyVerbruggen/nativescript-email/blob/master/email.ios.js#L49
On Android I get this exception in the system logs, even though all paramters are correct. The email activity is started nevertheless, so this is not critical, but I think it should be taken care of anyway.
58:17.421 4014 4014 D ViewRootImpl: ViewPostImeInputStage processPointer 1
12-22 10:58:17.511 4014 4014 W Bundle : Key android.intent.extra.TEXT expected ArrayList<CharSequence> but value was a android.text.SpannableStringBuilder. The default value <null> was returned.
12-22 10:58:17.531 4014 4014 E art : invalid stream - problem with parameter iterator in /data/app/ro.bvb.arenaxt.next-1/base.apk for method void com.tns.gen.android.view.View_OnClickListener.onClick(android.view.View)
12-22 10:58:17.551 4014 4014 W Bundle : Attempt to cast generated internal exception:
12-22 10:58:17.551 4014 4014 W Bundle : java.lang.ClassCastException: android.text.SpannableStringBuilder cannot be cast to java.util.ArrayList
12-22 10:58:17.551 4014 4014 W Bundle : at android.os.BaseBundle.getCharSequenceArrayList(BaseBundle.java:1067)
12-22 10:58:17.551 4014 4014 W Bundle : at android.os.Bundle.getCharSequenceArrayList(Bundle.java:922)
12-22 10:58:17.551 4014 4014 W Bundle : at android.content.Intent.getCharSequenceArrayListExtra(Intent.java:6295)
12-22 10:58:17.551 4014 4014 W Bundle : at android.content.Intent.migrateExtraStreamToClipData(Intent.java:9179)
12-22 10:58:17.551 4014 4014 W Bundle : at android.content.Intent.migrateExtraStreamToClipData(Intent.java:9142)
12-22 10:58:17.551 4014 4014 W Bundle : at android.app.Instrumentation.execStartActivity(Instrumentation.java:1533)
12-22 10:58:17.551 4014 4014 W Bundle : at android.app.ContextImpl.startActivity(ContextImpl.java:739)
12-22 10:58:17.551 4014 4014 W Bundle : at android.app.ContextImpl.startActivity(ContextImpl.java:721)
12-22 10:58:17.551 4014 4014 W Bundle : at android.content.ContextWrapper.startActivity(ContextWrapper.java:345)
12-22 10:58:17.551 4014 4014 W Bundle : at com.tns.Runtime.callJSMethodNative(Native Method)
12-22 10:58:17.551 4014 4014 W Bundle : at com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1022)
12-22 10:58:17.551 4014 4014 W Bundle : at com.tns.Runtime.callJSMethodImpl(Runtime.java:907)
12-22 10:58:17.551 4014 4014 W Bundle : at com.tns.Runtime.callJSMethod(Runtime.java:895)
12-22 10:58:17.551 4014 4014 W Bundle : at com.tns.Runtime.callJSMethod(Runtime.java:879)
12-22 10:58:17.551 4014 4014 W Bundle : at com.tns.Runtime.callJSMethod(Runtime.java:871)
12-22 10:58:17.551 4014 4014 W Bundle : at com.tns.gen.android.view.View_OnClickListener.onClick(android.view.View$OnClickListener.java)
12-22 10:58:17.551 4014 4014 W Bundle : at android.view.View.performClick(View.java:5702)
12-22 10:58:17.551 4014 4014 W Bundle : at android.widget.TextView.performClick(TextView.java:10888)
12-22 10:58:17.551 4014 4014 W Bundle : at android.view.View$PerformClick.run(View.java:22541)
12-22 10:58:17.551 4014 4014 W Bundle : at android.os.Handler.handleCallback(Handler.java:739)
12-22 10:58:17.551 4014 4014 W Bundle : at android.os.Handler.dispatchMessage(Handler.java:95)
12-22 10:58:17.551 4014 4014 W Bundle : at android.os.Looper.loop(Looper.java:158)
12-22 10:58:17.551 4014 4014 W Bundle : at android.app.ActivityThread.main(ActivityThread.java:7229)
12-22 10:58:17.551 4014 4014 W Bundle : at java.lang.reflect.Method.invoke(Native Method)
12-22 10:58:17.551 4014 4014 W Bundle : at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
12-22 10:58:17.551 4014 4014 W Bundle : at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
This is how I use the plugin:
email.available().then((available) => {
if (available) {
email.compose({
subject: "undisclosed",
to: ['[email protected]'],
cc: [],
bcc: [],
attachments: [],
appPickerTitle: "Email",
body: `
<br><br><br>-------------------------------
<br>OS: ${device.os} ${device.osVersion} ${device.language}
<br>Device: ${device.manufacturer} ${device.model}
`
});
} else {
this.translate.get("feedback_not_ready").subscribe(txt => {
toast.makeText(txt, toast.duration.long).show();
});
}
}).catch(() => {
this.translate.get("feedback_error").subscribe(txt => {
toast.makeText(txt, toast.duration.long).show();
});
});
Note: I've tried with and without the empty cc/bcc/attachments parameters. Same error.
I've got:
emailModule.available().then( function( bAvailable: boolean ) { console.log( "email available=" + bAvailable ); } );
Returns false on an iOS device - even though email clients and accounts are enabled - specifically GMail.
I don't think the build-in iOS email client has an account attached.
Is that a problem?
I made the necessary steps written on this site (https://www.npmjs.com/package/nativescript-email
) to implement nativescript-email.
I imported it:
import * as email from "nativescript-email";
And the in the code I wanted to test it:
email.available((avail: boolean) => {
console.log("Email available? " + avail);
})
The code is in TypeScript, I work with angular. If I do 'npm start' it does no compile and get the following error message:
ERROR in ./src/app/generate-doc/generate-doc.component.ts
Module not found: Error: Can't resolve 'nativescript-email'
When trying to open the email window from within a modal window we are getting an error and no email window. Our app is using a TabView
as bootstrap component. From the tabview component a modal is opened showing a login page. From this page we have a button which calls the email.compose
method. The error we get is:
Warning: Attempt to present <MFMailComposeViewController: 0x103cfc400> on <UITabBarControllerImpl: 0x103caac00> whose view is not in the window hierarchy!
It looks like there is a clash betwee the window that opens the login-modal and the email-window.
If we call the exact same code from outside a modal window (inside one of the tabview pages) the code works as expected.
We are on:
Hi @EddyVerbruggen. I think this is a similar issue to the local notifications plugin. On iOS10 (Xcode 8) I get this: CONSOLE LOG file:///app/tns_modules/nativescript-email/email.js:10:18: Error in email.available: TypeError: UIDevice.currentDevice is not a function. (In 'UIDevice.currentDevice()', 'UIDevice.currentDevice' is an instance of UIDevice)
Being able to attach files (e.g. images) would be awesome!
Hi,
Looks like when we have the attachments it fails with the following message (undefined is not a object (evaluating 'path.indexOf'). After researching I found that the code uses 'for in' loop which loops through properties. Changing the loop to 'for(var a = 0; a < arg.attachments; a++) might work better.
Thanks
JS: Error in email.compose: Error: android.content.ActivityNotFoundException: No
Activity found to handle Intent { act=android.intent.action.SENDTO typ=text/pla
in flg=0x10000000 (has extras) }
JS: android.app.Instrumentation.checkStartActivityResult(Instrumentation.jav
a:1861)
JS: android.app.Instrumentation.execStartActivity(Instrumentation.java:1534)
JS: android.app.ContextImpl.startActivity(ContextImpl.java:1658)
JS: android.app.ContextImpl.startActivity(ContextImpl.java:1640)
JS: android.content.ContextWrapper.startActivity(ContextWrapper.java:338)
JS: com.tns.Runtime.callJSMethodNative(Native Method)
JS: com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1043)
JS: com.tns.Runtime.callJSMethodImpl(Runtime.java:925)
JS: com.tns.Runtime.callJSMethod(Runtime.java:912)
JS: com.tns.Runtime.callJSMethod(Runtime.java:896)
JS: com.tns.Runtime.callJSMethod(Runtime.java:888)
JS: com.tns.gen.android.view.GestureDetector_SimpleOnGestureListener_frnal_t
s_helpers_l58_c38__TapAndDoubleTapGestureListenerImpl.onSingleTapUp(GestureDetec
tor_SimpleOnGestureListener_frnal_ts_helpers_l58_c38__TapAndDoubleTapGestureList
enerImpl.java:12)
JS: android.view.GestureDetector.onTouchEvent(GestureDetector.java:604)
JS: android.support.v4.view.GestureDetectorCompat$GestureDetectorCompatImplJ
ellybeanMr2.onTouchEvent(GestureDetectorCompat.java:479)
JS: android.support.v4.view.GestureDetectorCompat.onTouchEvent(GestureDetect
orCompat.java:542)
JS: com.tns.Runtime.callJSMethodNative(Native Method)
JS: com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1043)
JS: com.tns.Runtime.callJSMethodImpl(Runtime.java:925)
JS: com.tns.Runtime.callJSMethod(Runtime.java:912)
JS: com.tns.Runtime.callJSMethod(Runtime.java:896)
JS: com.tns.Runtime.callJSMethod(Runtime.java:888)
JS: com.tns.gen.java.lang.Object_frnal_ts_helpers_l58_c38__TouchListenerImpl
.onTouch(Object_frnal_ts_helpers_l58_c38__TouchListenerImpl.java:13)
JS: android.view.View.dispatchTouchEvent(View.java:9128)
JS: android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2680
)
JS: android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2351)
JS: android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2691
)
JS: android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2366)
JS: android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2691
)
JS: android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2366)
JS: android.widget.ScrollView.dispatchTouchEvent(ScrollView.java:614)
JS: android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2691
)
JS: android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2366)
JS: android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2691
)
JS: android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2366)
JS: android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2691
)
JS: android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2366)
JS: android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2691
)
JS: android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2366)
JS: android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2691
)
JS: android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2366)
JS: com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouc
hEvent(PhoneWindow.java:2743)
JS: com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(Pho
neWindow.java:1836)
JS: android.app.Activity.dispatchTouchEvent(Activity.java:3009)
JS: com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEven
t(PhoneWindow.java:2704)
JS: android.view.View.dispatchPointerEvent(View.java:9344)
JS: android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(View
RootImpl.java:5042)
JS: android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.j
ava:4880)
JS: android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4337)
JS: android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4
390)
JS: android.view.ViewRootImpl$InputStage.f
JS: orward(ViewRootImpl.java:4356)
JS: android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4482
)
JS: android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4364)
JS: android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4539)
JS: android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4337)
JS: android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4
390)
JS: android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4356)
JS: android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4364)
JS: android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4337)
JS: android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6938)
JS: android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6811)
JS: android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6782)
JS: android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRoot
Impl.java:7028)
JS: android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.ja
va:185)
JS: android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native M
ethod)
JS: android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventRece
iver.java:176)
JS: android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:6999)
JS: android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.j
ava:7051)
JS: android.view.Choreographer$CallbackRecord.run(Choreographer.java:777)
JS: android.view.Choreographer.doCallbacks(Choreographer.java:590)
JS: android.view.Choreographer.doFrame(Choreographer.java:558)
JS: android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.j
ava:763)
JS: android.os.Handler.handleCallback(Handler.java:739)
JS: android.os.Handler.dispatchMessage(Handler.java:95)
JS: android.os.Looper.loop(Looper.java:145)
JS: android.app.ActivityThread.main(ActivityThread.java:6946)
JS: java.lang.reflect.Method.invoke(Native Method)
JS: java.lang.reflect.Method.invoke(Method.java:372)
JS: com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.ja
va:1404)
JS: com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
JS: Email available? true
JS: Error: Error: android.content.ActivityNotFoundException: No Activity found t
o handle Intent { act=android.intent.action.SENDTO typ=text/plain flg=0x10000000
(has extras) }
JS: android.app.Instrumentation.checkStartActivityResult(Instrumentation.jav
a:1861)
JS: android.app.Instrumentation.execStartActivity(Instrumentation.java:1534)
JS: android.app.ContextImpl.startActivity(ContextImpl.java:1658)
JS: android.app.ContextImpl.startActivity(ContextImpl.java:1640)
JS: android.content.ContextWrapper.startActivity(ContextWrapper.java:338)
JS: com.tns.Runtime.callJSMethodNative(Native Method)
JS: com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1043)
JS: com.tns.Runtime.callJSMethodImpl(Runtime.java:925)
JS: com.tns.Runtime.callJSMethod(Runtime.java:912)
JS: com.tns.Runtime.callJSMethod(Runtime.java:896)
JS: com.tns.Runtime.callJSMethod(Runtime.java:888)
JS: com.tns.gen.android.view.GestureDetector_SimpleOnGestureListener_frnal_t
s_helpers_l58_c38__TapAndDoubleTapGestureListenerImpl.onSingleTapUp(GestureDetec
tor_SimpleOnGestureListener_frnal_ts_helpers_l58_c38__TapAndDoubleTapGestureList
enerImpl.java:12)
JS: android.view.GestureDetector.onTouchEvent(GestureDetector.java:604)
JS: android.support.v4.view.GestureDetectorCompat$GestureDetectorCompatImplJ
ellybeanMr2.onTouchEvent(GestureDetectorCompat.java:479)
JS: android.support.v4.view.GestureDetectorCompat.onTouchEvent(GestureDetect
orCompat.java:542)
JS: com.tns.Runtime.callJSMethodNative(Native Method)
JS: com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1043)
JS: com.tns.Runtime.callJSMethodImpl(Runtime.java:925)
JS: com.tns.Runtime.callJSMethod(Runtime.java:912)
JS: com.tns.Runtime.callJSMethod(Runtime.java:896)
JS: com.tns.Runtime.callJSMethod(Runtime.java:888)
JS: com.tns.gen.java.lang.Object_frnal_ts_helpers_l58_c38__TouchListenerImpl
.onTouch(Object_frnal_ts_helpers_l58_c38__TouchListenerImpl.java:13)
JS: android.view.View.dispatchTouchEvent(View.java:9128)
JS: android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2680
)
JS: android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2351)
JS: android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2691
)
JS: android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2366)
JS: android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2691
)
JS: android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2366)
JS: android.widget.ScrollView.dispatchTouchEvent(ScrollView.java:614)
JS: android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2691
)
JS: android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2366)
JS: android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2691
)
JS: android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2366)
JS: android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2691
)
JS: android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2366)
JS: android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2691
)
JS: android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2366)
JS: android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2691
)
JS: android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2366)
JS: com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouc
hEvent(PhoneWindow.java:2743)
JS: com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(Pho
neWindow.java:1836)
JS: android.app.Activity.dispatchTouchEvent(Activity.java:3009)
JS: com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEven
t(PhoneWindow.java:2704)
JS: android.view.View.dispatchPointerEvent(View.java:9344)
JS: android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(View
RootImpl.java:5042)
JS: android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.j
ava:4880)
JS: android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4337)
JS: android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4
390)
JS: android.view.ViewRootImpl$InputStage.forward(ViewRootIm
JS: pl.java:4356)
JS: android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4482
)
JS: android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4364)
JS: android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4539)
JS: android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4337)
JS: android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4
390)
JS: android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4356)
JS: android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4364)
JS: android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4337)
JS: android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6938)
JS: android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6811)
JS: android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6782)
JS: android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRoot
Impl.java:7028)
JS: android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.ja
va:185)
JS: android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native M
ethod)
JS: android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventRece
iver.java:176)
JS: android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:6999)
JS: android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.j
ava:7051)
JS: android.view.Choreographer$CallbackRecord.run(Choreographer.java:777)
JS: android.view.Choreographer.doCallbacks(Choreographer.java:590)
JS: android.view.Choreographer.doFrame(Choreographer.java:558)
JS: android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.j
ava:763)
JS: android.os.Handler.handleCallback(Handler.java:739)
JS: android.os.Handler.dispatchMessage(Handler.java:95)
JS: android.os.Looper.loop(Looper.java:145)
JS: android.app.ActivityThread.main(ActivityThread.java:6946)
JS: java.lang.reflect.Method.invoke(Native Method)
JS: java.lang.reflect.Method.invoke(Method.java:372)
JS: com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.ja
va:1404)
JS: com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
Is there a way to execute a code after email is sent. Basically is there any callback for this functionality?
Hi on ios device available() also returns false
I'm getting the following error in case of email send! Any help on this? Thanks
this just takes me to my ios desktop. then i can see my app is still running however, it wasnt directed back. I used this in my messenger plugin to retain view:
var delegate = CustomMessageCompositeViewControllerDelegate.alloc().initWithResolveReject(resolve, reject);
// retain the delegate because messageComposeDelegate property won't do it for us
CFRetain(delegate);
controller.messageComposeDelegate = delegate;
var page = frameModule.topmost().ios.controller;
page.presentModalViewControllerAnimated(controller, true);
Hey Eddy, when I discard a draft sometimes the app crashes on my device. This is my code:
export function teamEmailMessage(){
var emails = [];
model.roster.forEach(function(element){
if(element.email.length > 0){
emails.push(element.email);
}
}, this);
email.compose({
subject: "Team Message",
body: "\n\n Sent with TeamReps \n <a href='https://teamreps.co'>https://teamreps.co</a>",
to: emails,
appPickerTitle: 'Compose with..' // for Android, default: 'Open with..'
}).then(function() {
console.log("Email composer closed");
});
}
I ran it in debug and didnt even get an error message. It doesnt show anything just exits to the homescreen. The app is closed and needs to start again I'm not entirely sure what would be causing this, as i'm not seeing any error output. The other random thing that happens is it will just stay in the compose view, if you press send it sends the mail, but does not close the compose view. cancel does nothing when in this state.
Like in this article: https://sendgrid.com/blog/embedding-images-emails-facts/
Would be great if we could do that sort of CID thing.
I have just tried uploading a build to the Apple app store and I received an email from AppStore Team saying it rejected my app due to new privacy-sensitive data usage policy. See the email contents below:
"
_Dear developer,
We have discovered one or more issues with your recent delivery for "App Name". To process your delivery, the following issues must be corrected:
This app attempts to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSCalendarsUsageDescription key with a string value explaining to the user how the app uses this data.
Once these issues have been corrected, you can then redeliver the corrected binary.
Regards,
The App Store team_
"
The only part of my app that could relate to NSCalendarUsageDescription is your email plugin. Do you think this is correct?
If so, do you know what I need to put in the app info.plist in order to successfully submit the app again?
many thanks
hello, sorry but i don't understand if to open the email client i should use the nativescript social plugin or also this plugin can do it both on android and ios
It displays the following error:
System.err: An uncaught Exception occurred on "main" thread.
System.err: Unable to create application com.tns.NativeScriptApplication: com.tns.NativeScriptException: Error calling module function
System.err: Error: Cannot find module 'tns-core-modules/application'
System.err: File: (file: src/webpack:/sanhua-mobile/webpack/bootstrap:27:0)
Since NS8 does not include tns-core-modules
anymore and uses @nativescript/core
instead, I believe this plugin isn't compatible with NS8 yet. Hopefully there's a way to make it support @nativescript/core
with higher priority than tns-core-modules
in case anyone needs to use it with NS8 but doesn't want to install tns-core-modules
.
My app is written using nativescript 6.8.0, "@nativescript/core": "^6.5.15", "@nativescript/email": "^2.0.0", android: 6.5.3 and ios: 6.5.2
The app executes the following code properly and correctly determines that email is available on my iphone and my ipads. However when run on my daughter's ipad pro 4th Generation (the newest ipad) it sets the button5Visibility to collapsed. The app is using the same data on all devices so I know that the business.email is present and has a length greater than 0. I've tried this using the 1.6.0 version of the plugin (nativescript-email) and the latest 2.0 version (@nativescript/email).
business.button5Visibility = "visible";
if (business.email && business.email.trim().length > 0) {
email.available().then((avail: boolean) => {
if (!avail) {
business.button5Visibility = "collapsed";
};
})
} else {
business.button5Visibility = "collapsed";
}
When I use a device or emulator running android 5 I get the following exception:
An uncaught Exception occurred on "main" thread.
com.tns.NativeScriptException:
Calling js method onTouch failed
Error calling module function
Error calling module function
TypeError: Cannot read property 'toString' of null
File: "file:///data/data/org.nativescript.someappname/files/app/tns_modules/nativescript-email/email.js, line: 178, column: 21
StackTrace:
Frame: function:'_cleanAttachmentFolder', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/nativescript-email/email.js', line: 178, column: 22
Frame: function:'', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/nativescript-email/email.js', line: 5, column: 3
Frame: function:'', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/nativescript-email/email.js', line: 6, column: 3
Frame: function:'require', file:'', line: 1, column: 266
Frame: function:'', file:'file:///data/data/org.nativescript.someappname/files/app/contact/contact-page.js', line: 10, column: 15
Frame: function:'require', file:'', line: 1, column: 266
Frame: function:'_loop_1', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/globals/globals.js', line: 60, column: 22
Frame: function:'global.loadModule', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/globals/globals.js', line: 68, column: 23
Frame: function:'', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/frame/frame-common.js', line: 82, column: 27
Frame: function:'', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/frame/frame-common.js', line: 108, column: 29
Frame: function:'FrameBase.navigate', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/frame/frame-common.js', line: 213, column: 28
Frame: function:'onGoToPage', file:'file:///data/data/org.nativescript.someappname/files/app/anonlanding/anonlanding-page.js', line: 145, column: 17
Frame: function:'_executeCallback', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/gestures/gestures.js', line: 283, column: 27
Frame: function:'TapAndDoubleTapGestureListenerImpl.onSingleTapUp', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/gestures/gestures.js', line: 25, column: 17
Frame: function:'GesturesObserver.androidOnTouchEvent', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/gestures/gestures.js', line: 229, column: 41
Frame: function:'', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/core/view/view.js', line: 34, column: 29
Frame: function:'TouchListenerImpl.onTouch', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/core/view/view.js', line: 33, column: 22
TypeError: Cannot read property 'toString' of null
File: ", line: 1, column: 265
StackTrace:
Frame: function:'_cleanAttachmentFolder', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/nativescript-email/email.js', line: 178, column: 22
Frame: function:'', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/nativescript-email/email.js', line: 5, column: 3
Frame: function:'', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/nativescript-email/email.js', line: 6, column: 3
Frame: function:'require', file:'', line: 1, column: 266
Frame: function:'', file:'file:///data/data/org.nativescript.someappname/files/app/contact/contact-page.js', line: 10, column: 15
Frame: function:'require', file:'', line: 1, column: 266
Frame: function:'_loop_1', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/globals/globals.js', line: 60, column: 22
Frame: function:'global.loadModule', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/globals/globals.js', line: 68, column: 23
Frame: function:'', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/frame/frame-common.js', line: 82, column: 27
Frame: function:'', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/frame/frame-common.js', line: 108, column: 29
Frame: function:'FrameBase.navigate', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/frame/frame-common.js', line: 213, column: 28
Frame: function:'onGoToPage', file:'file:///data/data/org.nativescript.someappname/files/app/anonlanding/anonlanding-page.js', line: 145, column: 17
Frame: function:'_executeCallback', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/gestures/gestures.js', line: 283, column: 27
Frame: function:'TapAndDoubleTapGestureListenerImpl.onSingleTapUp', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/gestures/gestures.js', line: 25, column: 17
Frame: function:'GesturesObserver.androidOnTouchEvent', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/gestures/gestures.js', line: 229, column: 41
Frame: function:'', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/core/view/view.js', line: 34, column: 29
Frame: function:'TouchListenerImpl.onTouch', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/core/view/view.js', line: 33, column: 22
TypeError: Cannot read property 'toString' of null
File: "file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/gestures/gestures.js, line: 229, column: 40
StackTrace:
Frame: function:'_cleanAttachmentFolder', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/nativescript-email/email.js', line: 178, column: 22
Frame: function:'', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/nativescript-email/email.js', line: 5, column: 3
Frame: function:'', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/nativescript-email/email.js', line: 6, column: 3
Frame: function:'require', file:'', line: 1, column: 266
Frame: function:'', file:'file:///data/data/org.nativescript.someappname/files/app/contact/contact-page.js', line: 10, column: 15
Frame: function:'require', file:'', line: 1, column: 266
Frame: function:'_loop_1', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/globals/globals.js', line: 60, column: 22
Frame: function:'global.loadModule', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/globals/globals.js', line: 68, column: 23
Frame: function:'', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/frame/frame-common.js', line: 82, column: 27
Frame: function:'', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/frame/frame-common.js', line: 108, column: 29
Frame: function:'FrameBase.navigate', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/frame/frame-common.js', line: 213, column: 28
Frame: function:'onGoToPage', file:'file:///data/data/org.nativescript.someappname/files/app/anonlanding/anonlanding-page.js', line: 145, column: 17
Frame: function:'_executeCallback', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/gestures/gestures.js', line: 283, column: 27
Frame: function:'TapAndDoubleTapGestureListenerImpl.onSingleTapUp', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/gestures/gestures.js', line: 25, column: 17
Frame: function:'GesturesObserver.androidOnTouchEvent', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/gestures/gestures.js', line: 229, column: 41
Frame: function:'', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/core/view/view.js', line: 34, column: 29
Frame: function:'TouchListenerImpl.onTouch', file:'file:///data/data/org.nativescript.someappname/files/app/tns_modules/tns-core-modules/ui/core/view/view.js', line: 33, column: 22
at com.tns.Runtime.callJSMethodNative(Native Method)
at com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1088)
at com.tns.Runtime.callJSMethodImpl(Runtime.java:970)
at com.tns.Runtime.callJSMethod(Runtime.java:957)
at com.tns.Runtime.callJSMethod(Runtime.java:941)
at com.tns.Runtime.callJSMethod(Runtime.java:933)
at com.tns.gen.java.lang.Object_frnal_ts_helpers_l58_c38__TouchListenerImpl.onTouch(Object_frnal_ts_helpers_l58_c38__TouchListenerImpl.java:13)
at android.view.View.dispatchTouchEvent(View.java:8465)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2399)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2092)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2369)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1719)
at android.app.Activity.dispatchTouchEvent(Activity.java:2742)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2330)
at android.view.View.dispatchPointerEvent(View.java:8666)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4123)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3989)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3680)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3737)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5807)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5781)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5752)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5897)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:143)
at android.os.Looper.loop(Looper.java:122)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
If I send an email with an attachment with invalid filename - that rightly prints the file-not-found message but doesn't reject the promise. Continues on to selection of e-mail client...shouldn't this be an error message.
Not a big deal but I have a uri to a file (from image-picker) that looks like the following, maybe this format could be parsed.
content://com.android.providers.media.documents/document/image%3A742
Thanks.
Since iOS9-ish Apple no longer reports "simulator" in the device name, but the host device (your Mac's name)... we relied on the former.
Email plugin Not working in nativiescript + ng but works in just nativescript
Error - JS: Unhandled Promise rejection: Cannot read property 'startActivity' of undefined ;
Zone: angular ; Task: Promise.then ; Value: TypeError: Cannot read property 'startActivity' of undefined
JS: Error: Uncaught (in promise): TypeError: Cannot read property 'startActivity' of undefined
Does attaching PDFs work with this plugin? I am getting a 'File not Found' error for the remote URL path to the PDF, but it is the correct path and is accessible when the URL is plugged into a browser.
Thanks!
After update nativescript plugin to latest version, my code don't work. I have this error.
JS: Error in email.compose: Error: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
android.app.ContextImpl.startActivity(ContextImpl.java:1344)
JS: android.app.ContextImpl.startActivity(ContextImpl.java:1331)
JS: android.content.ContextWrapper.startActivity(ContextWrapper.java:322)
JS: com.tns.Runtime.callJSMethodNative(Native Method)
JS: com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1043)
JS: com.tns.Runtime.callJSMethodImpl(Runtime.java:925)
JS: com.tns.Runtime.callJSMethod(Runtime.java:912)
JS: com.tns.Runtime.callJSMethod(Runtime.java:896)
JS: com.tns.Runtime.callJSMethod(Runtime.java:888)
JS: com.tns.gen.java.lang.Object_frnal_ts_helpers_l58_c38__MenuItemClickListenerImpl.onMenuItemClick(Object_frnal_ts_helpers_l58_c38__MenuItemClickListenerImpl.java:12)
JS: android.support.v7.widget.Toolbar$1.onMenuItemClick(Toolbar.java:203)
JS: android.support.v7.widget.ActionMenuView$MenuBuilderCallback.onMenuItemSelected(ActionMenuView.java:762)
JS: android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:810)
JS: android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:152)
JS: android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:957)
JS: android.support.v7.view.menu.MenuPopup.onItemClick(MenuPopup.java:127)
JS: android.widget.AdapterView.performItemClick(AdapterView.java:300)
JS: android.widget.AbsListView.performItemClick(AbsListView.java:1186)
JS: android.widget.AbsListView$PerformClick.run(AbsListView.java:3099)
JS: android.widget.AbsListView$3.run(AbsListView.java:4046)
JS: android.os.Handler.handleCallback(Handler.java:739)
JS: android.os.Handler.dispatchMessage(Handler.java:95)
JS: android.os.Looper.loop(Looper.java:135)
JS: android.app.ActivityThread.main(ActivityThread.java:5354)
JS: java.lang.reflect.Method.invoke(Native Method)
JS: java.lang.reflect.Method.invoke(Method.java:372)
JS: com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
JS: com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
Consider removing this bit so any change the user makes in their settings app will have effect without them having to restart the app.
I get the following error on my Samsung S5 android phone:
"All apps associated with this action have been disabled, blocked, or are not installed."
I am running android 6.0.1
First off, thank you for the plugin.
I was wondering if there is a way to use full HTML in the composed email to support links and font colors and style (bold, italic, etc)?
I'm testing the plugin with an Android device and the Gmail app, thanks
I just found out that there's an issue with (the latest?) Webpack on Android. Easy fix though.
Hi,
I got gmail email app as well as Outlook email app installed on my phone.
When I select gmail, it composes the email fine with a body, and also can send attachments without any issue. However, using outlook client I get nothing appearing in the body of the email, and the attachment looks like it attaches OK with correct name and size, and can see image as thumbnail, but when I received the email the attachment is empty. Using Angular2 style. Any ideas ?
Also just before calling compose I get a message in the console - ( I get this when choosing the client app)
W/Bundle (10798): at com.tns.Runtime.callJSMethodNative(Native Method)
Also, the console.log("Email composer closed"); would log before I had even chosen an email client.
Android shows non-email apps when sharing. We can be more restrictive by adding mail.setData(android.net.Uri.parse("mailto:"))
to the intent.
Only applies when no attachments are shared.
This wasn't needed for my test apps, but a user reported a crash on Slack so let's do it..
First off, thanks for making this! ๐
I use gmail as my main email client, would be sweet to incorporate that as a check, so possibly check for gmail first, if that isnt installed revert to ios mail app? Check out this stack overflow, shows how to accomplish in ios.
http://stackoverflow.com/questions/32114455/open-gmail-app-from-my-app
android:
http://stackoverflow.com/questions/3470042/intent-uri-to-launch-gmail-app
Crashes on a complete clean NativeScript 1.4 app.
Reproducible by:
tns create myapp
cd myapp
tns platform add ios
tns plugin add nativescript-email
# editing the main-page.js so that it looks like the snippet below.
# editing the main-page.xml so that it has a label with tap="tapAction"
tns emulate ios --device iPhone-6
On tap, screen looks like this for a second:
Notice how only subject is filled out, not to
, body
, cc
etc.
Then it crashes with this crash log: https://gist.github.com/emiloberg/c6ef9a1d69d3a9a964b8
var email = require("nativescript-email");
function pageLoaded(args) {
var page = args.object;
}
function tapAction() {
email.available().then(function(avail) {
console.log("Email available? " + avail);
email.compose({
subject: "Yo",
body: "Hello <strong>dude</strong> :)",
to: ['[email protected]', '[email protected]'],
cc: ['[email protected]'],
bcc: ['[email protected]', '[email protected]']
}).then(function(r) {
console.log("Email composer closed");
});
})
}
exports.pageLoaded = pageLoaded;
exports.tapAction = tapAction;
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.