Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ec15749

Browse files
Merge pull request #57 from ekonstantinidis/native-notifications
Native Notifications
2 parents 5e78c37 + eca42dd commit ec15749

File tree

11 files changed

+196
-39
lines changed

11 files changed

+196
-39
lines changed

‎package.json‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
"watch": "grunt build && npm build && npm run watch-js | grunt watch",
1111
"start": "electron .",
1212
"dist": "rm -rf Gitify.app/ && electron-packager . Gitify --platform=darwin --arch=x64 --version=0.27.2 --icon=images/app-icon.icns --prune --ignore=src",
13-
"test": "jsxhint --reporter node_modules/jshint-stylish/stylish.js 'src/**/*.js', 'index.js' --exclude 'Gruntfile.js' && jscs 'src/js/' && jest",
14-
"coveralls": "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js"
13+
"test": "jsxhint --reporter node_modules/jshint-stylish/stylish.js 'src/**/*.js', 'index.js' --exclude 'Gruntfile.js' && jscs 'src/js/' && jest"
1514
},
1615
"jshintConfig": {
1716
"browserify": true,
@@ -76,7 +75,8 @@
7675
"src/js/stores/auth.js": true,
7776
"src/js/stores/notifications.js": true,
7877
"src/js/stores/search.js": true,
79-
"src/js/stores/settings.js": true
78+
"src/js/stores/settings.js": true,
79+
"src/js/stores/sound-notification.js": true
8080
},
8181
"unmockedModulePathPatterns": [
8282
"node_modules/react",

‎src/js/__tests__/components/notification.js‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ describe('Test for Notification Component', function () {
3434
item: false,
3535
getItem: function () {
3636
return this.item;
37+
},
38+
setItem: function (item) {
39+
this.item = item;
3740
}
3841
};
3942

‎src/js/__tests__/components/notifications.js‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ describe('Test for Notifications Component', function () {
3434
item: false,
3535
getItem: function () {
3636
return this.item;
37+
},
38+
setItem: function (item) {
39+
this.item = item;
3740
}
3841
};
3942

‎src/js/__tests__/components/settings.js‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ describe('Test for Settings Component', function () {
2828
item: false,
2929
getItem: function () {
3030
return this.item;
31+
},
32+
setItem: function (item) {
33+
this.item = item;
3134
}
3235
};
3336

‎src/js/__tests__/stores/notifications.js‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,26 @@ describe('Tests for NotificationsStore', function () {
2727
item: false,
2828
getItem: function () {
2929
return this.item;
30+
},
31+
setItem: function (item) {
32+
this.item = item;
3033
}
3134
};
3235

3336
// Mock Audio
34-
window.Audio = function (src) {
35-
console.log('Loading Audio: ' + src);
37+
window.Audio = function () {
3638
return {
3739
play: function () {}
3840
};
3941
};
4042

43+
// Mock Notifications
44+
window.Notification = function () {
45+
return {
46+
onClick: function () {}
47+
};
48+
};
49+
4150
Actions = require('../../actions/actions.js');
4251
apiRequests = require('../../utils/api-requests.js');
4352
NotificationsStore = require('../../stores/notifications.js');
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*global jest, describe, it, expect, spyOn, beforeEach */
2+
3+
'use strict';
4+
5+
jest.dontMock('reflux');
6+
jest.dontMock('../../stores/sound-notification.js');
7+
jest.dontMock('../../utils/api-requests.js');
8+
jest.dontMock('../../actions/actions.js');
9+
10+
describe('Tests for SoundNotificationStore', function () {
11+
12+
var SoundNotificationStore, Actions;
13+
14+
beforeEach(function () {
15+
16+
// Mock Electron's window.require
17+
window.require = function () {
18+
return {
19+
sendChannel: function () {
20+
return;
21+
}
22+
};
23+
};
24+
25+
// Mock localStorage
26+
window.localStorage = {
27+
item: false,
28+
getItem: function () {
29+
return this.item;
30+
},
31+
setItem: function (item) {
32+
this.item = item;
33+
}
34+
};
35+
36+
// Mock Audio
37+
window.Audio = function () {
38+
return {
39+
play: function () {}
40+
};
41+
};
42+
43+
// Mock Notifications
44+
window.Notification = function () {
45+
return {
46+
onClick: function () {}
47+
};
48+
};
49+
50+
Actions = require('../../actions/actions.js');
51+
SoundNotificationStore = require('../../stores/sound-notification.js');
52+
});
53+
54+
it('should get a payload and check if it should play sound & show notification.', function () {
55+
56+
spyOn(SoundNotificationStore, 'showNotification');
57+
58+
var payload = [{
59+
'id': '1',
60+
'repository': {
61+
'id': 1296269,
62+
'full_name': 'octocat/Hello-World',
63+
'description': 'This your first repo!'
64+
},
65+
'subject': {
66+
'title': 'Greetings',
67+
'url': 'https://api.github.com/repos/octokit/octokit.rb/issues/123'
68+
}
69+
}];
70+
71+
SoundNotificationStore.onIsNewNotification(payload);
72+
73+
expect(SoundNotificationStore.showNotification).toHaveBeenCalled();
74+
75+
});
76+
77+
});

‎src/js/actions/actions.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ var Actions = Reflux.createActions({
55
'login': {},
66
'logout': {},
77
'getNotifications': {asyncResult: true},
8+
'isNewNotification': {},
89
'updateSearchTerm': {},
910
'clearSearchTerm': {},
1011
'setSetting': {}

‎src/js/components/settings.js‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ var SettingsPage = React.createClass({
1111
var settings = SettingsStore.getSettings();
1212
return {
1313
participating: settings.participating,
14-
playSound: settings.playSound
14+
playSound: settings.playSound,
15+
showNotifications: settings.showNotifications
1516
};
1617
},
1718

@@ -42,6 +43,14 @@ var SettingsPage = React.createClass({
4243
onChange={this.toggleSetting.bind(this, 'playSound')} />
4344
</div>
4445
</div>
46+
<div className='row'>
47+
<div className='col-xs-8'>Show notifications</div>
48+
<div className='col-xs-4'>
49+
<Toggle
50+
defaultChecked={this.state.showNotifications}
51+
onChange={this.toggleSetting.bind(this, 'showNotifications')} />
52+
</div>
53+
</div>
4554
<div className='row'>
4655
<button
4756
className='btn btn-block btn-danger btn-close'

‎src/js/stores/notifications.js‎

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ var Actions = require('../actions/actions');
66
var apiRequests = require('../utils/api-requests');
77
var SettingsStore = require('../stores/settings');
88

9+
require('../stores/sound-notification');
10+
911
var NotificationsStore = Reflux.createStore({
1012
listenables: Actions,
1113

1214
init: function () {
1315
this._notifications = [];
14-
this._previousNotifications = [];
1516
},
1617

1718
updateTrayIcon: function (notifications) {
@@ -22,35 +23,6 @@ var NotificationsStore = Reflux.createStore({
2223
}
2324
},
2425

25-
isNewNotification: function (response) {
26-
var self = this;
27-
var playSound = SettingsStore.getSettings().playSound;
28-
29-
if (!playSound) { return; }
30-
31-
// Check if notification is already in the store.
32-
var isNew = false;
33-
_.map(response, function (obj) {
34-
if (!_.contains(self._previousNotifications, obj.id)) {
35-
isNew = true;
36-
}
37-
});
38-
39-
// Play Sound.
40-
if (isNew) {
41-
if (playSound) {
42-
var audio = new Audio('sounds/digi.wav');
43-
audio.play();
44-
}
45-
}
46-
47-
// Now Reset the previousNotifications array.
48-
self._previousNotifications = [];
49-
_.map(response, function (obj) {
50-
self._previousNotifications.push(obj.id);
51-
});
52-
},
53-
5426
onGetNotifications: function () {
5527
var self = this;
5628
var participating = SettingsStore.getSettings().participating;
@@ -63,7 +35,7 @@ var NotificationsStore = Reflux.createStore({
6335
// Success - Do Something.
6436
Actions.getNotifications.completed(response.body);
6537
self.updateTrayIcon(response.body);
66-
self.isNewNotification(response.body);
38+
Actions.isNewNotification(response.body);
6739
} else {
6840
// Error - Show messages.
6941
Actions.getNotifications.failed(err);

‎src/js/stores/settings.js‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,28 @@ var SettingsStore = Reflux.createStore({
99

1010
if (!settings) {
1111
settings = {
12-
'participating': false,
13-
'playSound': true
12+
participating: false,
13+
playSound: true,
14+
showNotifications: true
1415
};
1516
}
1617

1718
if (settings[0] === '{') {
1819
settings = JSON.parse(settings);
1920
}
2021

22+
if (!settings.participating) {
23+
settings.participating = false;
24+
}
25+
if (!settings.playSound) {
26+
settings.playSound = true;
27+
}
28+
if (!settings.showNotifications) {
29+
settings.showNotifications = true;
30+
}
31+
2132
this._settings = settings;
33+
window.localStorage.setItem('settings', JSON.stringify(this._settings));
2234
},
2335

2436
getSettings: function () {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /