Mercurial > libervia-web
comparison browser_side/notification.py @ 423:f9130176bc8d
browser side: notifications enhancements:
- moved sevaral part from Javascript to Python (is hidden, self.enabled)
- fixed Notification call (a new was missing)
- fixed notification closing: after 5 s, notification is closed (former behaviour was to let the notification visible until manual close)
- workaround for Chromium behaviour: notification permission request is not possible on page loading, it need a user interaction. So, if Chromium is detected, Window.onClick is used to request the permission on first click.
- for Chromium < 32 (and >= 22) a dialog is shown on loading to indicate how to activate manually notifications
- add browser tab highlighting (for pinned tabs), number of unseen notifications is shown in page title
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 26 Mar 2014 17:42:14 +0100 |
parents | 835a8ae799e7 |
children | 4ba4b099d266 |
comparison
equal
deleted
inserted
replaced
422:20c508f9b32a | 423:f9130176bc8d |
---|---|
1 from __pyjamas__ import JS | 1 from __pyjamas__ import JS, wnd |
2 from pyjamas import Window | |
3 from pyjamas.Timer import Timer | |
4 from browser_side import dialog | |
5 from sat.core.i18n import _ | |
6 | |
7 TIMER_DELAY = 5000 | |
2 | 8 |
3 | 9 |
4 class Notification(object): | 10 class Notification(object): |
5 """ | 11 """ |
6 If the browser supports it, the user allowed it to and the tab is in the | 12 If the browser supports it, the user allowed it to and the tab is in the |
8 | 14 |
9 Requires both Web Notifications and Page Visibility API. | 15 Requires both Web Notifications and Page Visibility API. |
10 """ | 16 """ |
11 | 17 |
12 def __init__(self): | 18 def __init__(self): |
19 self.enabled = False | |
20 user_agent = None | |
21 notif_permission = None | |
13 JS(""" | 22 JS(""" |
14 this.enabled = false; | |
15 | |
16 if (!('hidden' in document)) | 23 if (!('hidden' in document)) |
17 document.hidden = false; | 24 document.hidden = false; |
18 | 25 |
26 user_agent = navigator.userAgent | |
27 | |
19 if (!('Notification' in window)) | 28 if (!('Notification' in window)) |
20 return; | 29 return; |
30 | |
31 notif_permission = Notification.permission | |
21 | 32 |
22 if (Notification.permission === 'granted') | 33 if (Notification.permission === 'granted') |
23 this.enabled = true; | 34 this.enabled = true; |
24 | 35 |
25 else if (Notification.permission === 'default') { | 36 else if (Notification.permission === 'default') { |
26 Notification.requestPermission(function(permission){ | 37 Notification.requestPermission(function(permission){ |
27 if (permission !== 'granted') | 38 if (permission !== 'granted') |
28 return; | 39 return; |
29 | 40 |
30 this.enabled = true; | 41 self.enabled = true; //need to use self instead of this |
31 }); | 42 }); |
32 } | 43 } |
33 """) | 44 """) |
34 | 45 |
46 if "Chrome" in user_agent and notif_permission not in ['granted', 'denied']: | |
47 self.user_agent = user_agent | |
48 self._installChromiumWorkaround() | |
49 | |
50 wnd().onfocus = self.onFocus | |
51 # wnd().onblur = self.onBlur | |
52 self._notif_count = 0 | |
53 self._orig_title = Window.getTitle() | |
54 | |
55 def _installChromiumWorkaround(self): | |
56 # XXX: Workaround for Chromium behaviour, it's doens't manage requestPermission on onLoad event | |
57 # see https://code.google.com/p/chromium/issues/detail?id=274284 | |
58 # FIXME: need to be removed if Chromium behaviour changes | |
59 try: | |
60 version_full = [s for s in self.user_agent.split() if "Chrome" in s][0].split('/')[1] | |
61 version = int(version_full.split('.')[0]) | |
62 except (IndexError, ValueError): | |
63 print "Can't find Chromium version" | |
64 version = 0 | |
65 print "Chromium version: %d" % (version,) | |
66 if version < 22: | |
67 print "Notification use the old prefixed version or are unmanaged" | |
68 return | |
69 if version < 32: | |
70 dialog.InfoDialog(_("Notifications activation for Chromium"), _('You need to activate notifications manually for your Chromium version.\nTo activate notifications, click on the favicon on the left of the address bar')).show() | |
71 return | |
72 | |
73 print "==> Installing Chromium notifications request workaround <==" | |
74 self._old_click = wnd().onclick | |
75 wnd().onclick = self._chromiumWorkaround | |
76 | |
77 def _chromiumWorkaround(self): | |
78 print "Activating workaround" | |
79 JS(""" | |
80 Notification.requestPermission(function(permission){ | |
81 if (permission !== 'granted') | |
82 return; | |
83 self.enabled = true; //need to use self instead of this | |
84 }); | |
85 """) | |
86 wnd().onclick = self._old_click | |
87 | |
88 def onFocus(self): | |
89 Window.setTitle(self._orig_title) | |
90 self._notif_count = 0 | |
91 | |
92 # def onBlur(self): | |
93 # pass | |
94 | |
95 def isHidden(self): | |
96 JS("""return document.hidden;""") | |
97 | |
98 def _notify(self, title, body, icon): | |
99 if not self.enabled: | |
100 return | |
101 notification = None | |
102 JS(""" | |
103 notification = new Notification(title, {body: body, icon: icon}); | |
104 // Probably won’t work, but it doesn’t hurt to try. | |
105 notification.addEventListener('click', function() { | |
106 window.focus(); | |
107 }); | |
108 """) | |
109 notification.onshow = lambda: Timer(TIMER_DELAY, lambda timer: notification.close()) | |
110 | |
111 def highlightTab(self): | |
112 self._notif_count += 1 | |
113 Window.setTitle("%s (%d)" % (self._orig_title, self._notif_count)) | |
114 | |
35 def notify(self, title, body, icon='/media/icons/apps/48/sat.png'): | 115 def notify(self, title, body, icon='/media/icons/apps/48/sat.png'): |
36 JS(""" | 116 if self.isHidden(): |
37 if (this.enabled && document.hidden) { | 117 self._notify(title, body, icon) |
38 notification = Notification(title, {body: body, icon: icon}); | 118 self.highlightTab() |
39 | |
40 // Probably won’t work, but it doesn’t hurt to try. | |
41 notification.addEventListener('click', function() { | |
42 window.focus(); | |
43 }); | |
44 } | |
45 """) |