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)