Mercurial > libervia-web
diff src/browser/sat_browser/notification.py @ 467:97c72fe4a5f2
browser_side: import fixes:
- moved browser modules in a sat_browser packages, to avoid import conflicts with std lib (e.g. logging), and let pyjsbuild work normaly
- refactored bad import practices: classes are most of time not imported directly, module is imported instead.
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 09 Jun 2014 22:15:26 +0200 |
parents | src/browser/notification.py@981ed669d3b3 |
children | e11e34ac0f67 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/browser/sat_browser/notification.py Mon Jun 09 22:15:26 2014 +0200 @@ -0,0 +1,122 @@ +from __pyjamas__ import JS, wnd +from sat.core.log import getLogger +log = getLogger(__name__) +from sat.core.i18n import _ + +from pyjamas import Window +from pyjamas.Timer import Timer + +import dialog + +TIMER_DELAY = 5000 + + +class Notification(object): + """ + If the browser supports it, the user allowed it to and the tab is in the + background, send desktop notifications on messages. + + Requires both Web Notifications and Page Visibility API. + """ + + def __init__(self): + self.enabled = False + user_agent = None + notif_permission = None + JS(""" + if (!('hidden' in document)) + document.hidden = false; + + user_agent = navigator.userAgent + + if (!('Notification' in window)) + return; + + notif_permission = Notification.permission + + if (Notification.permission === 'granted') + this.enabled = true; + + else if (Notification.permission === 'default') { + Notification.requestPermission(function(permission){ + if (permission !== 'granted') + return; + + self.enabled = true; //need to use self instead of this + }); + } + """) + + if "Chrome" in user_agent and notif_permission not in ['granted', 'denied']: + self.user_agent = user_agent + self._installChromiumWorkaround() + + wnd().onfocus = self.onFocus + # wnd().onblur = self.onBlur + self._notif_count = 0 + self._orig_title = Window.getTitle() + + def _installChromiumWorkaround(self): + # XXX: Workaround for Chromium behaviour, it's doens't manage requestPermission on onLoad event + # see https://code.google.com/p/chromium/issues/detail?id=274284 + # FIXME: need to be removed if Chromium behaviour changes + try: + version_full = [s for s in self.user_agent.split() if "Chrome" in s][0].split('/')[1] + version = int(version_full.split('.')[0]) + except (IndexError, ValueError): + log.warning("Can't find Chromium version") + version = 0 + log.info("Chromium version: %d" % (version,)) + if version < 22: + log.info("Notification use the old prefixed version or are unmanaged") + return + if version < 32: + dialog.InfoDialog(_("Notifications activation for Chromium"), _('You need to activate notifications manually for your Chromium version.<br/>To activate notifications, click on the favicon on the left of the address bar')).show() + return + + log.info("==> Installing Chromium notifications request workaround <==") + self._old_click = wnd().onclick + wnd().onclick = self._chromiumWorkaround + + def _chromiumWorkaround(self): + log.info("Activating workaround") + JS(""" + Notification.requestPermission(function(permission){ + if (permission !== 'granted') + return; + self.enabled = true; //need to use self instead of this + }); + """) + wnd().onclick = self._old_click + + def onFocus(self): + Window.setTitle(self._orig_title) + self._notif_count = 0 + + # def onBlur(self): + # pass + + def isHidden(self): + JS("""return document.hidden;""") + + def _notify(self, title, body, icon): + if not self.enabled: + return + notification = None + JS(""" + notification = new Notification(title, {body: body, icon: icon}); + // Probably won’t work, but it doesn’t hurt to try. + notification.addEventListener('click', function() { + window.focus(); + }); + """) + notification.onshow = lambda: Timer(TIMER_DELAY, lambda timer: notification.close()) + + def highlightTab(self): + self._notif_count += 1 + Window.setTitle("%s (%d)" % (self._orig_title, self._notif_count)) + + def notify(self, title, body, icon='/media/icons/apps/48/sat.png'): + if self.isHidden(): + self._notify(title, body, icon) + self.highlightTab()