UNPKG

2.48 kBJavaScriptView Raw
1/**
2 * Wrapper for the toaster (https://github.com/nels-o/toaster)
3 */
4var path = require('path');
5var notifier = path.resolve(__dirname, '../vendor/snoreToast/SnoreToast.exe');
6var utils = require('../lib/utils');
7var Balloon = require('./balloon');
8
9var EventEmitter = require('events').EventEmitter;
10var util = require('util');
11
12var fallback = void 0;
13
14module.exports = WindowsToaster;
15
16function WindowsToaster(options) {
17 options = utils.clone(options || {});
18 if (!(this instanceof WindowsToaster)) {
19 return new WindowsToaster(options);
20 }
21
22 this.options = options;
23
24 EventEmitter.call(this);
25}
26util.inherits(WindowsToaster, EventEmitter);
27
28function noop() {
29}
30
31var timeoutMessage = 'the toast has timed out';
32var successMessage = 'user clicked on the toast';
33
34function hasText(str, txt) {
35 return str && str.indexOf(txt) !== -1;
36}
37
38WindowsToaster.prototype.notify = function(options, callback) {
39 options = utils.clone(options || {});
40 callback = callback || noop;
41
42 if (typeof options === 'string') {
43 options = { title: 'node-notifier', message: options };
44 }
45
46 if (typeof callback !== 'function') {
47 throw new TypeError(
48 'The second argument must be a function callback. You have passed ' +
49 typeof fn
50 );
51 }
52
53 var actionJackedCallback = utils.actionJackerDecorator(
54 this,
55 options,
56 function cb(err, data) {
57 // Needs to filter out timeout. Not an actual error.
58 if (err && hasText(data, timeoutMessage)) {
59 return callback(null, data);
60 }
61 callback(err, data);
62 },
63 function mapper(data) {
64 if (hasText(data, successMessage)) {
65 return 'click';
66 }
67 if (hasText(data, timeoutMessage)) {
68 return 'timeout';
69 }
70 return false;
71 }
72 );
73
74 options.title = options.title || 'Node Notification:';
75 if (
76 typeof options.message === 'undefined' &&
77 typeof options.close === 'undefined'
78 ) {
79 callback(new Error('Message or ID to close is required.'));
80 return this;
81 }
82
83 if (!utils.isWin8() && !!this.options.withFallback) {
84 fallback = fallback || new Balloon(this.options);
85 return fallback.notify(options, callback);
86 }
87
88 options = utils.mapToWin8(options);
89 var argsList = utils.constructArgumentList(options, {
90 explicitTrue: true,
91 wrapper: '',
92 keepNewlines: true,
93 noEscape: true
94 });
95 utils.fileCommand(
96 this.options.customPath || notifier,
97 argsList,
98 actionJackedCallback
99 );
100 return this;
101};