Skip to content

Commit ee7916a

Browse files
authored
Merge pull request #341 from mikaelbr/timeoutNotifySend
feat: implements proper timeout/wait behaviour for notify-send
2 parents 1c74ea9 + e3decb2 commit ee7916a

File tree

6 files changed

+76
-37
lines changed

6 files changed

+76
-37
lines changed

.prettierrc

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
22
"printWidth": 80,
3-
"singleQuote": true
3+
"singleQuote": true,
4+
"trailingComma": "none"
45
}

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
### `v8.0.0`
4+
5+
Breaking changes:
6+
7+
- Expire time for notify-send is made to match macOS and Windows with default time of 10 seconds. The API is changed to take seconds as input and converting it to milliseconds before passing it on to notify-send. See [#341](https://github.com/mikaelbr/node-notifier/pull/341).
8+
39
### `v7.0.2`
410

511
- Updates dependencies

README.md

+9-7
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,16 @@ notifier.notify(
7070
sound: true, // Only Notification Center or Windows Toasters
7171
wait: true // Wait with callback, until user action is taken against notification, does not apply to Windows Toasters as they always wait or notify-send as it does not support the wait option
7272
},
73-
function(err, response) {
73+
function (err, response) {
7474
// Response is response from notification
7575
}
7676
);
7777

78-
notifier.on('click', function(notifierObject, options, event) {
78+
notifier.on('click', function (notifierObject, options, event) {
7979
// Triggers if `wait: true` and user clicks notification
8080
});
8181

82-
notifier.on('timeout', function(notifierObject, options) {
82+
notifier.on('timeout', function (notifierObject, options) {
8383
// Triggers if `wait: true` and notification closes
8484
});
8585
```
@@ -179,7 +179,7 @@ notifier.notify(
179179
dropdownLabel: undefined, // String. Label to be used if multiple actions
180180
reply: false // Boolean. If notification should take input. Value passed as third argument in callback and event emitter.
181181
},
182-
function(error, response, metadata) {
182+
function (error, response, metadata) {
183183
console.log(response, metadata);
184184
}
185185
);
@@ -278,7 +278,7 @@ notifier.notify(
278278
remove: undefined, // Number. Refer to previously created notification to close.
279279
install: undefined // String (path, application, app id). Creates a shortcut <path> in the start menu which point to the executable <application>, appID used for the notifications.
280280
},
281-
function(error, response) {
281+
function (error, response) {
282282
console.log(response);
283283
}
284284
);
@@ -333,7 +333,7 @@ notifier.notify(
333333
wait: false, // Wait for User Action against Notification
334334
type: 'info' // The notification type : info | warn | error
335335
},
336-
function(error, response) {
336+
function (error, response) {
337337
console.log(response);
338338
}
339339
);
@@ -355,10 +355,12 @@ notifier.notify({
355355
message: 'Hello World',
356356
icon: __dirname + '/coulson.jpg',
357357

358+
wait: false, // Defaults no exipre time set. If true expire time of 5 seconds is used
359+
timeout: 10, // Alias for expire-time, time etc. Time before notify-send expires. Defaults to 10 seconds.
360+
358361
// .. and other notify-send flags:
359362
'app-name': 'node-notifier',
360363
urgency: undefined,
361-
time: undefined,
362364
category: undefined,
363365
hint: undefined
364366
});

lib/utils.js

+11
Original file line numberDiff line numberDiff line change
@@ -162,13 +162,24 @@ module.exports.mapToNotifySend = function (options) {
162162
options = mapAppIcon(options);
163163
options = mapText(options);
164164

165+
if (options.timeout === false) {
166+
delete options.timeout;
167+
}
168+
if (options.wait === true) {
169+
options['expire-time'] = 5; // 5 seconds default time (multipled below)
170+
}
165171
for (var key in options) {
166172
if (key === 'message' || key === 'title') continue;
167173
if (options.hasOwnProperty(key) && notifySendFlags[key] !== key) {
168174
options[notifySendFlags[key]] = options[key];
169175
delete options[key];
170176
}
171177
}
178+
if (typeof options['expire-time'] === 'undefined') {
179+
options['expire-time'] = 10 * 1000; // 10 sec timeout by default
180+
} else if (typeof options['expire-time'] === 'number') {
181+
options['expire-time'] = options['expire-time'] * 1000; // notify send uses milliseconds
182+
}
172183

173184
return options;
174185
};

test/notify-send.js

+33-19
Original file line numberDiff line numberDiff line change
@@ -2,83 +2,97 @@ var Notify = require('../notifiers/notifysend');
22
var utils = require('../lib/utils');
33
var os = require('os');
44

5-
describe('notify-send', function() {
5+
describe('notify-send', function () {
66
var original = utils.command;
77
var originalType = os.type;
88

9-
beforeEach(function() {
10-
os.type = function() {
9+
beforeEach(function () {
10+
os.type = function () {
1111
return 'Linux';
1212
};
1313
});
1414

15-
afterEach(function() {
15+
afterEach(function () {
1616
utils.command = original;
1717
os.type = originalType;
1818
});
1919

2020
function expectArgsListToBe(expected, done) {
21-
utils.command = function(notifier, argsList, callback) {
21+
utils.command = function (notifier, argsList, callback) {
2222
expect(argsList).toEqual(expected);
2323
done();
2424
};
2525
}
2626

27-
it('should pass on title and body', function(done) {
28-
var expected = ['"title"', '"body"'];
27+
it('should pass on title and body', function (done) {
28+
var expected = ['"title"', '"body"', '--expire-time', '"10000"'];
2929
expectArgsListToBe(expected, done);
3030
var notifier = new Notify({ suppressOsdCheck: true });
3131
notifier.notify({ title: 'title', message: 'body' });
3232
});
3333

34-
it('should pass have default title', function(done) {
35-
var expected = ['"Node Notification:"', '"body"'];
34+
it('should pass have default title', function (done) {
35+
var expected = [
36+
'"Node Notification:"',
37+
'"body"',
38+
'--expire-time',
39+
'"10000"'
40+
];
3641

3742
expectArgsListToBe(expected, done);
3843
var notifier = new Notify({ suppressOsdCheck: true });
3944
notifier.notify({ message: 'body' });
4045
});
4146

42-
it('should throw error if no message is passed', function(done) {
43-
utils.command = function(notifier, argsList, callback) {
47+
it('should throw error if no message is passed', function (done) {
48+
utils.command = function (notifier, argsList, callback) {
4449
expect(argsList).toBeUndefined();
4550
};
4651

4752
var notifier = new Notify({ suppressOsdCheck: true });
48-
notifier.notify({}, function(err) {
53+
notifier.notify({}, function (err) {
4954
expect(err.message).toBe('Message is required.');
5055
done();
5156
});
5257
});
5358

54-
it('should escape message input', function(done) {
59+
it('should escape message input', function (done) {
5560
var excapedNewline = process.platform === 'win32' ? '\\r\\n' : '\\n';
5661
var expected = [
5762
'"Node Notification:"',
58-
'"some' + excapedNewline + ' \\"me\'ss\\`age\\`\\""'
63+
'"some' + excapedNewline + ' \\"me\'ss\\`age\\`\\""',
64+
'--expire-time',
65+
'"10000"'
5966
];
6067

6168
expectArgsListToBe(expected, done);
6269
var notifier = new Notify({ suppressOsdCheck: true });
6370
notifier.notify({ message: 'some\n "me\'ss`age`"' });
6471
});
6572

66-
it('should send additional parameters as --"keyname"', function(done) {
67-
var expected = ['"title"', '"body"', '--icon', '"icon-string"'];
73+
it('should send additional parameters as --"keyname"', function (done) {
74+
var expected = [
75+
'"title"',
76+
'"body"',
77+
'--icon',
78+
'"icon-string"',
79+
'--expire-time',
80+
'"10000"'
81+
];
6882

6983
expectArgsListToBe(expected, done);
7084
var notifier = new Notify({ suppressOsdCheck: true });
7185
notifier.notify({ title: 'title', message: 'body', icon: 'icon-string' });
7286
});
7387

74-
it('should remove extra options that are not supported by notify-send', function(done) {
88+
it('should remove extra options that are not supported by notify-send', function (done) {
7589
var expected = [
7690
'"title"',
7791
'"body"',
7892
'--icon',
7993
'"icon-string"',
8094
'--expire-time',
81-
'"100"'
95+
'"1000"'
8296
];
8397

8498
expectArgsListToBe(expected, done);
@@ -87,7 +101,7 @@ describe('notify-send', function() {
87101
title: 'title',
88102
message: 'body',
89103
icon: 'icon-string',
90-
time: 100,
104+
time: 1,
91105
tullball: 'notValid'
92106
});
93107
});

test/utils.js

+15-10
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ var path = require('path');
22
var fs = require('fs');
33
var _ = require('../lib/utils');
44

5-
describe('utils', function() {
6-
describe('clone', function() {
7-
it('should clone nested objects', function() {
5+
describe('utils', function () {
6+
describe('clone', function () {
7+
it('should clone nested objects', function () {
88
var obj = { a: { b: 42 }, c: 123 };
99
var obj2 = _.clone(obj);
1010

@@ -15,9 +15,14 @@ describe('utils', function() {
1515
});
1616
});
1717

18-
describe('mapping', function() {
19-
it('should map icon for notify-send', function() {
20-
var expected = { title: 'Foo', message: 'Bar', icon: 'foobar' };
18+
describe('mapping', function () {
19+
it('should map icon for notify-send', function () {
20+
var expected = {
21+
title: 'Foo',
22+
message: 'Bar',
23+
icon: 'foobar',
24+
'expire-time': 10000
25+
};
2126

2227
expect(
2328
_.mapToNotifySend({ title: 'Foo', message: 'Bar', appIcon: 'foobar' })
@@ -28,7 +33,7 @@ describe('utils', function() {
2833
).toEqual(expected);
2934
});
3035

31-
it('should map short hand for notify-sned', function() {
36+
it('should map short hand for notify-sned', function () {
3237
var expected = {
3338
urgency: 'a',
3439
'expire-time': 'b',
@@ -42,7 +47,7 @@ describe('utils', function() {
4247
).toEqual(expected);
4348
});
4449

45-
it('should map icon for notification center', function() {
50+
it('should map icon for notification center', function () {
4651
var expected = {
4752
title: 'Foo',
4853
message: 'Bar',
@@ -60,7 +65,7 @@ describe('utils', function() {
6065
);
6166
});
6267

63-
it('should map icon for growl', function() {
68+
it('should map icon for growl', function () {
6469
var icon = path.join(__dirname, 'fixture', 'coulson.jpg');
6570
var iconRead = fs.readFileSync(icon);
6671

@@ -78,7 +83,7 @@ describe('utils', function() {
7883
expect(Buffer.isBuffer(obj.icon)).toBeTruthy();
7984
});
8085

81-
it('should not map icon url for growl', function() {
86+
it('should not map icon url for growl', function () {
8287
var icon = 'http://hostname.com/logo.png';
8388

8489
var expected = { title: 'Foo', message: 'Bar', icon: icon };

0 commit comments

Comments
 (0)