Mercurial > libervia-web
comparison browser/sat_browser/notification.py @ 1124:28e3eb3bb217
files reorganisation and installation rework:
- files have been reorganised to follow other SàT projects and usual Python organisation (no more "/src" directory)
- VERSION file is now used, as for other SàT projects
- replace the overcomplicated setup.py be a more sane one. Pyjamas part is not compiled anymore by setup.py, it must be done separatly
- removed check for data_dir if it's empty
- installation tested working in virtual env
- libervia launching script is now in bin/libervia
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 25 Aug 2018 17:59:48 +0200 |
parents | src/browser/sat_browser/notification.py@620306b3d5be |
children |
comparison
equal
deleted
inserted
replaced
1123:63a4b8fe9782 | 1124:28e3eb3bb217 |
---|---|
1 from __pyjamas__ import JS, wnd | |
2 from sat.core.log import getLogger | |
3 log = getLogger(__name__) | |
4 from sat.core.i18n import _ | |
5 | |
6 from pyjamas import Window | |
7 from pyjamas.Timer import Timer | |
8 import favico.min.js | |
9 | |
10 import dialog | |
11 | |
12 TIMER_DELAY = 5000 | |
13 | |
14 | |
15 class Notification(object): | |
16 """ | |
17 If the browser supports it, the user allowed it to and the tab is in the | |
18 background, send desktop notifications on messages. | |
19 | |
20 Requires both Web Notifications and Page Visibility API. | |
21 """ | |
22 | |
23 def __init__(self, alerts_counter): | |
24 """ | |
25 | |
26 @param alerts_counter (FaviconCounter): counter instance | |
27 """ | |
28 self.alerts_counter = alerts_counter | |
29 self.enabled = False | |
30 user_agent = None | |
31 notif_permission = None | |
32 JS(""" | |
33 if (!('hidden' in document)) | |
34 document.hidden = false; | |
35 | |
36 user_agent = navigator.userAgent | |
37 | |
38 if (!('Notification' in window)) | |
39 return; | |
40 | |
41 notif_permission = Notification.permission | |
42 | |
43 if (Notification.permission === 'granted') | |
44 this.enabled = true; | |
45 | |
46 else if (Notification.permission === 'default') { | |
47 Notification.requestPermission(function(permission){ | |
48 if (permission !== 'granted') | |
49 return; | |
50 | |
51 self.enabled = true; //need to use self instead of this | |
52 }); | |
53 } | |
54 """) | |
55 | |
56 if "Chrome" in user_agent and notif_permission not in ['granted', 'denied']: | |
57 self.user_agent = user_agent | |
58 self._installChromiumWorkaround() | |
59 | |
60 wnd().onfocus = self.onFocus | |
61 # wnd().onblur = self.onBlur | |
62 | |
63 def _installChromiumWorkaround(self): | |
64 # XXX: Workaround for Chromium behaviour, it's doens't manage requestPermission on onLoad event | |
65 # see https://code.google.com/p/chromium/issues/detail?id=274284 | |
66 # FIXME: need to be removed if Chromium behaviour changes | |
67 try: | |
68 version_full = [s for s in self.user_agent.split() if "Chrome" in s][0].split('/')[1] | |
69 version = int(version_full.split('.')[0]) | |
70 except (IndexError, ValueError): | |
71 log.warning("Can't find Chromium version") | |
72 version = 0 | |
73 log.info("Chromium version: %d" % (version,)) | |
74 if version < 22: | |
75 log.info("Notification use the old prefixed version or are unmanaged") | |
76 return | |
77 if version < 32: | |
78 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() | |
79 return | |
80 | |
81 log.info("==> Installing Chromium notifications request workaround <==") | |
82 self._old_click = wnd().onclick | |
83 wnd().onclick = self._chromiumWorkaround | |
84 | |
85 def _chromiumWorkaround(self): | |
86 log.info("Activating workaround") | |
87 JS(""" | |
88 Notification.requestPermission(function(permission){ | |
89 if (permission !== 'granted') | |
90 return; | |
91 self.enabled = true; //need to use self instead of this | |
92 }); | |
93 """) | |
94 wnd().onclick = self._old_click | |
95 | |
96 def onFocus(self, event=None): | |
97 self.alerts_counter.update(extra=0) | |
98 | |
99 # def onBlur(self, event=None): | |
100 # pass | |
101 | |
102 def isHidden(self): | |
103 JS("""return document.hidden;""") | |
104 | |
105 def _notify(self, title, body, icon): | |
106 if not self.enabled: | |
107 return | |
108 notification = None | |
109 # FIXME: icon has been removed because the notification can't display a HTTPS file | |
110 JS(""" | |
111 notification = new Notification(title, {body: body}); | |
112 // Probably won’t work, but it doesn’t hurt to try. | |
113 notification.addEventListener('click', function() { | |
114 window.focus(); | |
115 }); | |
116 """) | |
117 notification.onshow = lambda: Timer(TIMER_DELAY, lambda timer: notification.close()) | |
118 | |
119 def notify(self, title, body, icon='/media/icons/apps/48/sat.png'): | |
120 if self.isHidden(): | |
121 self._notify(title, body, icon) | |
122 | |
123 | |
124 class FaviconCounter(object): | |
125 """Display numbers over the favicon to signal e.g. waiting messages""" | |
126 | |
127 def __init__(self): | |
128 # XXX: the file favico.min.js is loaded from public/libervia.html because I get NS_ERROR_FAILURE when it's loaded with Pyjamas. It sounds like a context issue, with the favicon not being found. | |
129 | |
130 JS(""" | |
131 self.counter = new top.Favico({ | |
132 animation : 'slide', | |
133 bgColor: '#5CB85C', | |
134 }); | |
135 """) | |
136 | |
137 self.count = 0 # messages that are not displayed | |
138 self.extra = 0 # messages that are displayed but the window is hidden | |
139 | |
140 def update(self, count=None, extra=None): | |
141 """Update the favicon counter. | |
142 | |
143 @param count (int): primary counter | |
144 @param extra (int): extra counter | |
145 """ | |
146 if count is not None: | |
147 self.count = count | |
148 if extra is not None: | |
149 self.extra = extra | |
150 self.counter.badge(self.count + self.extra) |