From 5742405f67b0ec31daae30507d2ea3bd1371157a Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sat, 17 Aug 2013 22:37:30 +0200 Subject: [PATCH 01/10] Add desktop notification permission granting setting and notice. --- lib/polyfill.coffee | 16 ++++++++++++++-- src/General/Config.coffee | 1 + src/General/Header.coffee | 30 ++++++++++++++++++++++++++++++ src/Monitoring/Unread.coffee | 4 ++-- src/Posting/QR.coffee | 2 +- 5 files changed, 48 insertions(+), 5 deletions(-) diff --git a/lib/polyfill.coffee b/lib/polyfill.coffee index 6bab699cb..44ad79c18 100644 --- a/lib/polyfill.coffee +++ b/lib/polyfill.coffee @@ -1,9 +1,21 @@ Polyfill = init: -> <% if (type === 'crx') { %> - Polyfill.toBlob() - Polyfill.visibility() + @notificationPermission() + @toBlob() + @visibility() <% } %> + notificationPermission: -> + return if window.Notification and 'permission' of Notification + Object.defineProperty Notification, 'permission', + get: -> + switch webkitNotifications.checkPermission() + when 0 + 'granted' + when 1 + 'default' + when 2 + 'denied' toBlob: -> HTMLCanvasElement::toBlob or= (cb) -> data = atob @toDataURL()[22..] diff --git a/src/General/Config.coffee b/src/General/Config.coffee index 2270444ec..cd0aa1413 100644 --- a/src/General/Config.coffee +++ b/src/General/Config.coffee @@ -2,6 +2,7 @@ Config = main: 'Miscellaneous': 'Enable 4chan\'s Extension': [false, 'Compatibility between <%= meta.name %> and 4chan\'s inline extension is NOT guaranteed.'] + 'Desktop Notifications': [true, 'Enables desktop notifications across various <%= meta.name %> features.'] 'Announcement Hiding': [true, 'Add button to hide 4chan announcements.'] '404 Redirect': [true, 'Redirect dead threads and images.'] 'Keybinds': [true, 'Bind actions to keyboard shortcuts.'] diff --git a/src/General/Header.coffee b/src/General/Header.coffee index fd81f49cb..9c395a752 100644 --- a/src/General/Header.coffee +++ b/src/General/Header.coffee @@ -89,6 +89,8 @@ Header = Header.setCatalogLinks Conf['Header catalog links'] $.sync 'Header catalog links', Header.setCatalogLinks + @enableDesktopNotifications() + setBoardList: -> nav = $.id 'boardNavDesktop' if a = $ "a[href*='/#{g.BOARD}/']", nav @@ -268,3 +270,31 @@ Header = {type, content, lifetime, cb} = e.detail notif = new Notice type, content, lifetime cb notif if cb + + areNotificationsEnabled: false + enableDesktopNotifications: -> + return unless window.Notification and Conf['Desktop Notifications'] + switch Notification.permission + when 'granted' + Header.areNotificationsEnabled = true + return + when 'denied' + # requestPermission doesn't work if status is 'denied', + # but it'll still work if status is 'default'. + return + + el = $.el 'span', + innerHTML: """ + Desktop notification permissions are not granted:
+ or + """ + [authorize, disable] = $$ 'button', el + $.on authorize, 'click', -> + Notification.requestPermission (status) -> + Header.areNotificationsEnabled = status is 'granted' + return if status is 'default' + notice.close() + $.on disable, 'click', -> + $.set 'Desktop Notifications', false + notice.close() + notice = new Notice 'info', el diff --git a/src/Monitoring/Unread.coffee b/src/Monitoring/Unread.coffee index 29e549653..be5495b8d 100644 --- a/src/Monitoring/Unread.coffee +++ b/src/Monitoring/Unread.coffee @@ -96,12 +96,12 @@ Unread = Unread.openNotification post return openNotification: (post) -> - return unless d.hidden + return unless d.hidden and Header.areNotificationsEnabled name = if Conf['Anonymize'] 'Anonymous' else $('.nameBlock', post.nodes.info).textContent.trim() - notif = new Notification "#{name} replied to you.", + notif = new Notification "#{name} replied to you", body: post.info.comment icon: Favicon.logo notif.onclick = -> diff --git a/src/Posting/QR.coffee b/src/Posting/QR.coffee index 794005af6..c54662a00 100644 --- a/src/Posting/QR.coffee +++ b/src/Posting/QR.coffee @@ -113,7 +113,7 @@ QR = QR.captcha.nodes.input.focus() notice = new Notice 'warning', el QR.notifications.push notice - return unless d.hidden + return unless d.hidden and Header.areNotificationsEnabled notif = new Notification 'Quick reply warning', body: el.textContent icon: Favicon.logo From 25f77a12da16bdb29c8f57bc48e178db79259ce5 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sat, 17 Aug 2013 22:54:51 +0200 Subject: [PATCH 02/10] Don't handle a notification's onclose on Firefox. Mozilla hates devs and won't let us distinguish an automatic closing to a user's closing action. --- src/Posting/QR.coffee | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Posting/QR.coffee b/src/Posting/QR.coffee index c54662a00..e9c1e2924 100644 --- a/src/Posting/QR.coffee +++ b/src/Posting/QR.coffee @@ -118,11 +118,15 @@ QR = body: el.textContent icon: Favicon.logo notif.onclick = -> window.focus() + <% if (type === 'crx') { %> + # Firefox automatically closes notifications + # so we can't control the onclose properly. notif.onclose = -> notice.close() setTimeout -> notif.onclose = null notif.close() , 5 * $.SECOND + <% } %> notifications: [] cleanNotifications: -> for notification in QR.notifications From 7c9f43a5f091d578bd15cb7f5471b53865ae6b4e Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sat, 17 Aug 2013 23:00:06 +0200 Subject: [PATCH 03/10] Fix Polyfill.notificationPermission on Opera. Opera doesn't have notifications. --- lib/polyfill.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/polyfill.coffee b/lib/polyfill.coffee index 44ad79c18..cba68a122 100644 --- a/lib/polyfill.coffee +++ b/lib/polyfill.coffee @@ -6,7 +6,7 @@ Polyfill = @visibility() <% } %> notificationPermission: -> - return if window.Notification and 'permission' of Notification + return if !window.Notification or 'permission' of Notification Object.defineProperty Notification, 'permission', get: -> switch webkitNotifications.checkPermission() From eb2ea88edec4b0d510de883e5a1ad27a3f24cf31 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sat, 17 Aug 2013 23:11:02 +0200 Subject: [PATCH 04/10] Opera doesn't actually support the "minimum_opera_version" key. I assume it follows the "minimum_chrome_version"? --- src/Meta/manifest.json | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Meta/manifest.json b/src/Meta/manifest.json index fb8cfba4e..53039fd37 100644 --- a/src/Meta/manifest.json +++ b/src/Meta/manifest.json @@ -16,7 +16,6 @@ }], "homepage_url": "<%= meta.page %>", "minimum_chrome_version": "27", - "minimum_opera_version": "15", "permissions": [ "storage" ] From dd8748fbfbcad5d79717d891b3c6e703f7795e63 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sun, 18 Aug 2013 00:15:50 +0200 Subject: [PATCH 05/10] Fix #1243. --- src/Images/ImageExpand.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Images/ImageExpand.coffee b/src/Images/ImageExpand.coffee index 94c566482..b9153461f 100644 --- a/src/Images/ImageExpand.coffee +++ b/src/Images/ImageExpand.coffee @@ -22,7 +22,7 @@ ImageExpand = ImageExpand.contract @ ImageExpand.expand @ return - if ImageExpand.on and !@isHidden + if ImageExpand.on and !@isHidden and (Conf['Expand spoilers'] or !@file.isSpoiler) ImageExpand.expand @ cb: toggle: (e) -> From 346010e1884b7d50427f98245d7edf529b2d5be2 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sun, 18 Aug 2013 00:20:07 +0200 Subject: [PATCH 06/10] Show a desktop notification even if the tab is visible. --- src/Monitoring/Unread.coffee | 2 +- src/Posting/QR.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Monitoring/Unread.coffee b/src/Monitoring/Unread.coffee index be5495b8d..af85ad18f 100644 --- a/src/Monitoring/Unread.coffee +++ b/src/Monitoring/Unread.coffee @@ -96,7 +96,7 @@ Unread = Unread.openNotification post return openNotification: (post) -> - return unless d.hidden and Header.areNotificationsEnabled + return unless Header.areNotificationsEnabled name = if Conf['Anonymize'] 'Anonymous' else diff --git a/src/Posting/QR.coffee b/src/Posting/QR.coffee index e9c1e2924..31407b2e0 100644 --- a/src/Posting/QR.coffee +++ b/src/Posting/QR.coffee @@ -113,7 +113,7 @@ QR = QR.captcha.nodes.input.focus() notice = new Notice 'warning', el QR.notifications.push notice - return unless d.hidden and Header.areNotificationsEnabled + return unless Header.areNotificationsEnabled notif = new Notification 'Quick reply warning', body: el.textContent icon: Favicon.logo From a088db9ee26e2794651388a611b116d257deaaaf Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sun, 18 Aug 2013 00:28:48 +0200 Subject: [PATCH 07/10] Use document.hasFocus() instead. --- src/Monitoring/Unread.coffee | 2 +- src/Posting/QR.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Monitoring/Unread.coffee b/src/Monitoring/Unread.coffee index af85ad18f..ad3f07575 100644 --- a/src/Monitoring/Unread.coffee +++ b/src/Monitoring/Unread.coffee @@ -96,7 +96,7 @@ Unread = Unread.openNotification post return openNotification: (post) -> - return unless Header.areNotificationsEnabled + return unless !document.hasFocus() and Header.areNotificationsEnabled name = if Conf['Anonymize'] 'Anonymous' else diff --git a/src/Posting/QR.coffee b/src/Posting/QR.coffee index 31407b2e0..e3c590a9d 100644 --- a/src/Posting/QR.coffee +++ b/src/Posting/QR.coffee @@ -113,7 +113,7 @@ QR = QR.captcha.nodes.input.focus() notice = new Notice 'warning', el QR.notifications.push notice - return unless Header.areNotificationsEnabled + return unless !document.hasFocus and Header.areNotificationsEnabled notif = new Notification 'Quick reply warning', body: el.textContent icon: Favicon.logo From f9005c02bf00e116dc58be74c1b9302d411fee09 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sun, 18 Aug 2013 00:44:45 +0200 Subject: [PATCH 08/10] Fix missing () --- src/Posting/QR.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Posting/QR.coffee b/src/Posting/QR.coffee index e3c590a9d..2e221422b 100644 --- a/src/Posting/QR.coffee +++ b/src/Posting/QR.coffee @@ -113,7 +113,7 @@ QR = QR.captcha.nodes.input.focus() notice = new Notice 'warning', el QR.notifications.push notice - return unless !document.hasFocus and Header.areNotificationsEnabled + return unless !document.hasFocus() and Header.areNotificationsEnabled notif = new Notification 'Quick reply warning', body: el.textContent icon: Favicon.logo From 2c0946068e5af2bc45ef10fd748d46febab90487 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sun, 18 Aug 2013 00:49:16 +0200 Subject: [PATCH 09/10] Fix the spacing between the last shortcut and the right bracket. @ferongr --- css/style.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/css/style.css b/css/style.css index 7536f8ec9..3be4907ab 100644 --- a/css/style.css +++ b/css/style.css @@ -191,6 +191,9 @@ a[href="javascript:;"] { text-decoration: none; padding: 1px; } +#shortcuts::after { + margin-left: 2px; +} .shortcut:not(:last-child)::after { content: " / "; } From 8e98e030c25fbbeca3b3995ff86b735e9dc6a240 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sun, 18 Aug 2013 03:38:13 +0200 Subject: [PATCH 10/10] document.hasFocus() doesn't always work as intended in Chrome stable. See crbug.com/64846 --- src/Monitoring/Unread.coffee | 2 +- src/Posting/QR.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Monitoring/Unread.coffee b/src/Monitoring/Unread.coffee index ad3f07575..af85ad18f 100644 --- a/src/Monitoring/Unread.coffee +++ b/src/Monitoring/Unread.coffee @@ -96,7 +96,7 @@ Unread = Unread.openNotification post return openNotification: (post) -> - return unless !document.hasFocus() and Header.areNotificationsEnabled + return unless Header.areNotificationsEnabled name = if Conf['Anonymize'] 'Anonymous' else diff --git a/src/Posting/QR.coffee b/src/Posting/QR.coffee index 2e221422b..31407b2e0 100644 --- a/src/Posting/QR.coffee +++ b/src/Posting/QR.coffee @@ -113,7 +113,7 @@ QR = QR.captcha.nodes.input.focus() notice = new Notice 'warning', el QR.notifications.push notice - return unless !document.hasFocus() and Header.areNotificationsEnabled + return unless Header.areNotificationsEnabled notif = new Notification 'Quick reply warning', body: el.textContent icon: Favicon.logo