From 3fdf5aac9226dd68a5b6efc76403bebe87971af9 Mon Sep 17 00:00:00 2001 From: Emmanouil Konstantinidis Date: Fri, 12 Jun 2015 20:27:42 +0100 Subject: [PATCH 1/6] Play sound on notications --- sounds/click.wav | Bin 0 -> 20946 bytes sounds/digi.wav | Bin 0 -> 32886 bytes src/js/stores/notifications.js | 4 ++++ 3 files changed, 4 insertions(+) create mode 100644 sounds/click.wav create mode 100644 sounds/digi.wav diff --git a/sounds/click.wav b/sounds/click.wav new file mode 100644 index 0000000000000000000000000000000000000000..44ff1af046acc5f654e98ad53a87c60c753602eb GIT binary patch literal 20946 zcmeI)%S#(U90%~pCRL&|4;!^es{sXtpe7}@QQCv=2O{x-dI(~Cq=;IjL=6;Lu~MiY zSPddg3%#_~5?U)g)PqD1UJ8YHP&{~0iNt40G^oUw?Mzg#w;qa6_|7uBznS^{W@kTt zz*ZC&6#OVBq$ayM-_&ka$_OC>!jU{XA+oO=5fK?_GMbIEWpn`z0uX?}6$>l{mxA$p zJikr0NiaMZJ|~}(I~7iaU+$N;MzluE1ZD!`JL5a$2jvG9z6xLZYWnKn%HYbt=D?=^ z*niwF>zC=n^kF%NIftr9Rb*vSWs)vMmm-u3r6#}0pX^EYY;J9C8IBA`apE{}p`cKp zTvx6qEG8`Gx^i8sqE%65Ff*9yPIZ^;m+YGqCWW?0TQsGa(&%DzF=nw@oG49{j><-5 zgWMoz_u9SFYtw5Jt_jz|#=?eo&$~C~8}kWH1SdA3P3Vz$B<@&uY>&K0ZWG(YDo(|v z^XdG3diByvaw<8s1T2BRU|;Zxsqs1pKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_@J|IAyPB1^=#GN(&NgTNwqwtWR$5$H6;B7oCUaYxv7s%B z#w@?8xxKR^OR3SS)6|4CG+WFDj@3l4+kBl!_BkV(5Os8(+Gzh$&|+mZtSuiJ?Nzk1 zr+(x?^vz-3L5Au?p~d++(rM)#p}EimAkah=ZB4tGm>XP+t9crlU?3(Zj-wbwdx!f2Mks-*Wxy2jRNNdN3t{E6*-Httlg z^Rn|azcEL-OFJI6G%EFvJIF_RZq|=! zeYg8P_l?GSn#cO(W})+w(H}ULyIXcgtFGH%oIbS8+zl{4V}Uc)7lo z*1df9=l&XPTF>rl-jQFOUBmVd3%&nx)&Cfm7S>cV{mC1I{PfwJgnTdhoA3Ayx3ME& literal 0 HcmV?d00001 diff --git a/sounds/digi.wav b/sounds/digi.wav new file mode 100644 index 0000000000000000000000000000000000000000..fe851eb5b300c599fb95322dccb6eb6fe8d9292a GIT binary patch literal 32886 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 Ktf|2n{OzCYu+fqL literal 0 HcmV?d00001 diff --git a/src/js/stores/notifications.js b/src/js/stores/notifications.js index 1dc5f96ae..f25748ef4 100644 --- a/src/js/stores/notifications.js +++ b/src/js/stores/notifications.js @@ -16,6 +16,10 @@ var NotificationsStore = Reflux.createStore({ updateTrayIcon: function (notifications) { if (notifications.length > 0) { ipc.sendChannel('update-icon', 'TrayActive'); + + var audio = new Audio('sounds/digi.wav'); + audio.play(); + } else { ipc.sendChannel('update-icon', 'TrayIdle'); } From 3447a310ff2f6e1006226644c2220826a284963d Mon Sep 17 00:00:00 2001 From: Emmanouil Konstantinidis Date: Fri, 12 Jun 2015 20:51:02 +0100 Subject: [PATCH 2/6] Check if notification has been received and if not play sound --- src/js/stores/notifications.js | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/js/stores/notifications.js b/src/js/stores/notifications.js index f25748ef4..01f12c293 100644 --- a/src/js/stores/notifications.js +++ b/src/js/stores/notifications.js @@ -11,18 +11,39 @@ var NotificationsStore = Reflux.createStore({ init: function () { this._notifications = []; + this._previousNotifications = []; }, updateTrayIcon: function (notifications) { if (notifications.length > 0) { ipc.sendChannel('update-icon', 'TrayActive'); + } else { + ipc.sendChannel('update-icon', 'TrayIdle'); + } + }, + isNewNotification: function (response) { + var self = this; + + // Check if notification is already in the store. + var isNew = false; + _.map(response, function (obj) { + if (!_.contains(self._previousNotifications, obj.id)) { + isNew = true; + } + }); + + // Play Sound. + if (isNew) { var audio = new Audio('sounds/digi.wav'); audio.play(); - - } else { - ipc.sendChannel('update-icon', 'TrayIdle'); } + + // Now Reset the previousNotifications array. + self._previousNotifications = []; + _.map(response, function (obj) { + self._previousNotifications.push(obj.id); + }); }, onGetNotifications: function () { @@ -37,6 +58,7 @@ var NotificationsStore = Reflux.createStore({ // Success - Do Something. Actions.getNotifications.completed(response.body); self.updateTrayIcon(response.body); + self.isNewNotification(response.body); } else { // Error - Show messages. Actions.getNotifications.failed(err); From 35af639046c16a4f77fd26474e287651198f9dae Mon Sep 17 00:00:00 2001 From: Emmanouil Konstantinidis Date: Fri, 12 Jun 2015 21:02:58 +0100 Subject: [PATCH 3/6] Setting for 'play sound' & play sound only if on --- src/js/components/settings.js | 14 +++++++++++--- src/js/stores/notifications.js | 6 +++++- src/js/stores/settings.js | 3 ++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/js/components/settings.js b/src/js/components/settings.js index 17eb84b3e..9e00f7809 100644 --- a/src/js/components/settings.js +++ b/src/js/components/settings.js @@ -13,8 +13,8 @@ var SettingsPage = React.createClass({ }; }, - toggleParticipating: function (event) { - Actions.setSetting('participating', event.target.checked); + toggleSetting: function (key, event) { + Actions.setSetting(key, event.target.checked); }, appQuit: function () { @@ -29,7 +29,15 @@ var SettingsPage = React.createClass({
+ onChange={this.toggleSetting.bind(this, 'participating')} /> +
+ +
+
Play sound
+
+
diff --git a/src/js/stores/notifications.js b/src/js/stores/notifications.js index 01f12c293..4234cae29 100644 --- a/src/js/stores/notifications.js +++ b/src/js/stores/notifications.js @@ -49,6 +49,7 @@ var NotificationsStore = Reflux.createStore({ onGetNotifications: function () { var self = this; var participating = SettingsStore.getSettings().participating; + var playSound = SettingsStore.getSettings().playSound; apiRequests .getAuth('https://api.github.com/notifications?participating=' + @@ -58,7 +59,10 @@ var NotificationsStore = Reflux.createStore({ // Success - Do Something. Actions.getNotifications.completed(response.body); self.updateTrayIcon(response.body); - self.isNewNotification(response.body); + + if (playSound) { + self.isNewNotification(response.body); + } } else { // Error - Show messages. Actions.getNotifications.failed(err); diff --git a/src/js/stores/settings.js b/src/js/stores/settings.js index ce0af1788..a4b71983d 100644 --- a/src/js/stores/settings.js +++ b/src/js/stores/settings.js @@ -9,7 +9,8 @@ var SettingsStore = Reflux.createStore({ if (!settings) { settings = { - 'participating': false + 'participating': false, + 'playSound': true }; } From 25bad56217445641979e7ec89eef14b4af19b326 Mon Sep 17 00:00:00 2001 From: Emmanouil Konstantinidis Date: Fri, 12 Jun 2015 21:34:12 +0100 Subject: [PATCH 4/6] Mock Audio --- package.json | 2 +- src/js/__tests__/stores/notifications.js | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 277ff0f3e..8761a426c 100644 --- a/package.json +++ b/package.json @@ -133,7 +133,7 @@ "grunt-contrib-copy": "=0.8.0", "grunt-contrib-less": "=1.0.1", "grunt-contrib-watch": "=0.6.1", - "jest-cli": "=0.4.5", + "jest-cli": "=0.4.12", "jscs": "^1.13.1", "jshint-stylish": "=1.0.2", "jsxhint": "=0.15.0", diff --git a/src/js/__tests__/stores/notifications.js b/src/js/__tests__/stores/notifications.js index b84cec828..53fc68c15 100644 --- a/src/js/__tests__/stores/notifications.js +++ b/src/js/__tests__/stores/notifications.js @@ -30,6 +30,14 @@ describe('Tests for NotificationsStore', function () { } }; + // Mock Audio + window.Audio = function (src) { + console.log('Loading Audio: ' + src); + return { + play: function () {} + }; + }; + Actions = require('../../actions/actions.js'); apiRequests = require('../../utils/api-requests.js'); NotificationsStore = require('../../stores/notifications.js'); From 0776ba5b60596a8be5753b9a553a39ad5b053f98 Mon Sep 17 00:00:00 2001 From: Emmanouil Konstantinidis Date: Fri, 12 Jun 2015 21:47:15 +0100 Subject: [PATCH 5/6] Correct settings/sound and fix tests --- src/js/__tests__/components/settings.js | 4 ++-- src/js/components/settings.js | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/js/__tests__/components/settings.js b/src/js/__tests__/components/settings.js index b5eda9a71..da9177a7b 100644 --- a/src/js/__tests__/components/settings.js +++ b/src/js/__tests__/components/settings.js @@ -43,10 +43,10 @@ describe('Test for Settings Component', function () { var instance = TestUtils.renderIntoDocument(); expect(instance.state.participating).toBeFalsy(); - expect(instance.toggleParticipating).toBeDefined(); + expect(instance.toggleSetting).toBeDefined(); expect(instance.appQuit).toBeDefined(); - instance.toggleParticipating({ + instance.toggleSetting('participating', { target: { checked: true } diff --git a/src/js/components/settings.js b/src/js/components/settings.js index 9e00f7809..bba22e1ab 100644 --- a/src/js/components/settings.js +++ b/src/js/components/settings.js @@ -8,8 +8,10 @@ var SettingsStore = require('../stores/settings'); var SettingsPage = React.createClass({ getInitialState: function () { + var settings = SettingsStore.getSettings(); return { - participating: SettingsStore.getSettings().participating + participating: settings.participating, + playSound: settings.playSound }; }, @@ -36,8 +38,8 @@ var SettingsPage = React.createClass({
Play sound
+ defaultChecked={this.state.playSound} + onChange={this.toggleSetting.bind(this, 'playSound')} />
From 24c973e8f8286cc356effa91e68d958e10f56a06 Mon Sep 17 00:00:00 2001 From: Emmanouil Konstantinidis Date: Fri, 12 Jun 2015 23:45:28 +0100 Subject: [PATCH 6/6] Prepare native notifications --- src/js/stores/notifications.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/js/stores/notifications.js b/src/js/stores/notifications.js index 4234cae29..e3648a14f 100644 --- a/src/js/stores/notifications.js +++ b/src/js/stores/notifications.js @@ -24,6 +24,9 @@ var NotificationsStore = Reflux.createStore({ isNewNotification: function (response) { var self = this; + var playSound = SettingsStore.getSettings().playSound; + + if (!playSound) { return; } // Check if notification is already in the store. var isNew = false; @@ -35,8 +38,10 @@ var NotificationsStore = Reflux.createStore({ // Play Sound. if (isNew) { - var audio = new Audio('sounds/digi.wav'); - audio.play(); + if (playSound) { + var audio = new Audio('sounds/digi.wav'); + audio.play(); + } } // Now Reset the previousNotifications array. @@ -49,7 +54,6 @@ var NotificationsStore = Reflux.createStore({ onGetNotifications: function () { var self = this; var participating = SettingsStore.getSettings().participating; - var playSound = SettingsStore.getSettings().playSound; apiRequests .getAuth('https://api.github.com/notifications?participating=' + @@ -59,10 +63,7 @@ var NotificationsStore = Reflux.createStore({ // Success - Do Something. Actions.getNotifications.completed(response.body); self.updateTrayIcon(response.body); - - if (playSound) { - self.isNewNotification(response.body); - } + self.isNewNotification(response.body); } else { // Error - Show messages. Actions.getNotifications.failed(err);