annotate libervia/web/pages/_browser/dialog.py @ 1625:698eaabfca0e

browser (chat): side/panel and keyword handling: - `dialog.Modal` can now be used with a `position` argument. The default `center` keeps the old behaviour of modal in the middle of the screen, while using one of the direction makes the modal appear from top/bottom/right/left with an animation. The closing cross has been removed in favor of clicking/touching any part outside of the modal. - A method to create mockup clones of elements is now used to make placeholders. It is used for the input panel in the main area when it is moved to a sub-panel modal, this way there is not element disappearing. - Clicking on a keyword now shows a sub-messages panel with all messages with this keyword, in a similar way as for threads. Writing a messages there will add the keyword automatically. - Sub-messages panel will auto-scroll when messages are added. rel 458
author Goffi <goffi@goffi.org>
date Fri, 06 Jun 2025 11:08:05 +0200
parents 3a60bf3762ef
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1299
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
1 """manage common dialogs"""
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
2
1625
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
3 from typing import Callable, Literal
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
4 from browser import document, window, timer, console as log
1299
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
5 from template import Template
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
6
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
7 log.warning = log.warn
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
8
1299
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
9
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
10 class CancelError(Exception):
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
11 """Dialog is cancelled"""
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
12
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1589
diff changeset
13 def __init__(self, reason: str = "", text: str = "") -> None:
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1589
diff changeset
14 self.reason = reason
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1589
diff changeset
15 self.text = text
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1589
diff changeset
16 super().__init__(text)
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1589
diff changeset
17
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
18
1299
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
19 class Confirm:
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
20
1343
8729d2708f65 browser (dialog): color of `OK` button can be specified:
Goffi <goffi@goffi.org>
parents: 1328
diff changeset
21 def __init__(self, message, ok_label="", cancel_label="", ok_color="success"):
1299
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
22 self._tpl = Template("dialogs/confirm.html")
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
23 self.message = message
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
24 self.ok_label = ok_label
1343
8729d2708f65 browser (dialog): color of `OK` button can be specified:
Goffi <goffi@goffi.org>
parents: 1328
diff changeset
25 assert ok_color in ("success", "danger")
8729d2708f65 browser (dialog): color of `OK` button can be specified:
Goffi <goffi@goffi.org>
parents: 1328
diff changeset
26 self.ok_color = ok_color
1299
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
27 self.cancel_label = cancel_label
1589
7228fc3c4744 browser (dialog): be sure to remove dialog on `OK` and `Cancel` click + avoid side effects
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
28 self._notif_elt = None
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
29 self.reset()
1299
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
30
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
31 def reset(self):
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
32 """Reset values of callbacks and notif element"""
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
33 self._ok_cb = None
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
34 self._cancel_cb = None
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
35 self._reject_cb = None
1589
7228fc3c4744 browser (dialog): be sure to remove dialog on `OK` and `Cancel` click + avoid side effects
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
36 if self._notif_elt is not None:
7228fc3c4744 browser (dialog): be sure to remove dialog on `OK` and `Cancel` click + avoid side effects
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
37 self._notif_elt.remove()
7228fc3c4744 browser (dialog): be sure to remove dialog on `OK` and `Cancel` click + avoid side effects
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
38 self._notif_elt = None
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
39
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
40 def _default_cancel_cb(self, evt, notif_elt):
1299
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
41 notif_elt.remove()
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
42
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1589
diff changeset
43 def cancel(self, reason: str = "", text: str = ""):
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
44 """Cancel the dialog, without calling any callback
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
45
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
46 will raise a CancelError
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
47 """
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
48 if self._notif_elt is None:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
49 log.warning("calling cancel on an unshown dialog")
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
50 else:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
51 self._notif_elt.remove()
1589
7228fc3c4744 browser (dialog): be sure to remove dialog on `OK` and `Cancel` click + avoid side effects
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
52 self._notif_elt = None
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
53 if self._reject_cb is not None:
1600
0a4433a343a3 browser (calls): implement WebRTC file sharing:
Goffi <goffi@goffi.org>
parents: 1589
diff changeset
54 self._reject_cb(CancelError(reason, text))
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
55 else:
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
56 log.warning("no reject callback set")
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
57 self.reset()
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
58
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
59 def on_ok_click(self, evt):
1589
7228fc3c4744 browser (dialog): be sure to remove dialog on `OK` and `Cancel` click + avoid side effects
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
60 evt.preventDefault()
7228fc3c4744 browser (dialog): be sure to remove dialog on `OK` and `Cancel` click + avoid side effects
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
61 evt.stopPropagation()
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
62 assert self._ok_cb is not None
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
63 self._ok_cb(evt, self._notif_elt)
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
64 self.reset()
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
65
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
66 def on_cancel_click(self, evt) -> None:
1589
7228fc3c4744 browser (dialog): be sure to remove dialog on `OK` and `Cancel` click + avoid side effects
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
67 evt.preventDefault()
7228fc3c4744 browser (dialog): be sure to remove dialog on `OK` and `Cancel` click + avoid side effects
Goffi <goffi@goffi.org>
parents: 1549
diff changeset
68 evt.stopPropagation()
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
69 assert self._cancel_cb is not None
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
70 self._cancel_cb(evt, self._notif_elt)
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
71 self.reset()
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
72
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
73 def show(self, ok_cb, cancel_cb=None, reject_cb=None):
1299
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
74 if cancel_cb is None:
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
75 cancel_cb = self._default_cancel_cb
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
76 self._ok_cb = ok_cb
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
77 self._cancel_cb = cancel_cb
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
78 self._reject_cb = reject_cb
1299
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
79 notif_elt = self._tpl.get_elt({
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
80 "message": self.message,
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
81 "ok_label": self.ok_label,
1343
8729d2708f65 browser (dialog): color of `OK` button can be specified:
Goffi <goffi@goffi.org>
parents: 1328
diff changeset
82 "ok_color": self.ok_color,
1299
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
83 "cancel_label": self.cancel_label,
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
84 })
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
85 self._notif_elt = notif_elt
1299
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
86
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
87 document['notifs_area'] <= notif_elt
053141849206 browser: module to handle dialogs, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
88 timer.set_timeout(lambda: notif_elt.classList.add('state_appended'), 0)
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
89 for ok_elt in notif_elt.select(".click_to_ok"):
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
90 ok_elt.bind("click", self.on_ok_click)
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
91 for ok_elt in notif_elt.select(".click_to_cancel"):
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
92 ok_elt.bind("click", self.on_cancel_click)
1328
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
93
1385
4b6f711b09cb browser (dialog): new `ashow` method to use `Confirm` in async methods
Goffi <goffi@goffi.org>
parents: 1343
diff changeset
94 def _ashow_cb(self, evt, notif_elt, resolve_cb, confirmed):
4b6f711b09cb browser (dialog): new `ashow` method to use `Confirm` in async methods
Goffi <goffi@goffi.org>
parents: 1343
diff changeset
95 evt.stopPropagation()
4b6f711b09cb browser (dialog): new `ashow` method to use `Confirm` in async methods
Goffi <goffi@goffi.org>
parents: 1343
diff changeset
96 notif_elt.remove()
4b6f711b09cb browser (dialog): new `ashow` method to use `Confirm` in async methods
Goffi <goffi@goffi.org>
parents: 1343
diff changeset
97 resolve_cb(confirmed)
4b6f711b09cb browser (dialog): new `ashow` method to use `Confirm` in async methods
Goffi <goffi@goffi.org>
parents: 1343
diff changeset
98
4b6f711b09cb browser (dialog): new `ashow` method to use `Confirm` in async methods
Goffi <goffi@goffi.org>
parents: 1343
diff changeset
99 async def ashow(self):
4b6f711b09cb browser (dialog): new `ashow` method to use `Confirm` in async methods
Goffi <goffi@goffi.org>
parents: 1343
diff changeset
100 return window.Promise.new(
4b6f711b09cb browser (dialog): new `ashow` method to use `Confirm` in async methods
Goffi <goffi@goffi.org>
parents: 1343
diff changeset
101 lambda resolve_cb, reject_cb:
4b6f711b09cb browser (dialog): new `ashow` method to use `Confirm` in async methods
Goffi <goffi@goffi.org>
parents: 1343
diff changeset
102 self.show(
4b6f711b09cb browser (dialog): new `ashow` method to use `Confirm` in async methods
Goffi <goffi@goffi.org>
parents: 1343
diff changeset
103 lambda evt, notif_elt: self._ashow_cb(evt, notif_elt, resolve_cb, True),
1549
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
104 lambda evt, notif_elt: self._ashow_cb(evt, notif_elt, resolve_cb, False),
e47c24204449 browser (calls): update call to handle search, control buttons, and better UI/UX:
Goffi <goffi@goffi.org>
parents: 1518
diff changeset
105 reject_cb
1385
4b6f711b09cb browser (dialog): new `ashow` method to use `Confirm` in async methods
Goffi <goffi@goffi.org>
parents: 1343
diff changeset
106 )
4b6f711b09cb browser (dialog): new `ashow` method to use `Confirm` in async methods
Goffi <goffi@goffi.org>
parents: 1343
diff changeset
107 )
4b6f711b09cb browser (dialog): new `ashow` method to use `Confirm` in async methods
Goffi <goffi@goffi.org>
parents: 1343
diff changeset
108
1328
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
109
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
110 class Notification:
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
111
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
112 def __init__(self):
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
113 self._tpl = Template("dialogs/notification.html")
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
114
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
115 def close(self, notif_elt):
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
116 notif_elt.classList.remove('state_appended')
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
117 notif_elt.bind("transitionend", lambda __: notif_elt.remove())
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
118
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
119 def show(
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
120 self,
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
121 message: str,
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
122 level: str = "info",
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
123 delay: int = 5
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
124 ) -> None:
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
125 # we log in console error messages, may be useful
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
126 if level in ("warning", "error"):
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
127 print(f"[{level}] {message}")
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
128 notif_elt = self._tpl.get_elt({
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
129 "message": message,
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
130 "level": level,
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
131 })
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
132 document["notifs_area"] <= notif_elt
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
133 timer.set_timeout(lambda: notif_elt.classList.add('state_appended'), 0)
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
134 timer.set_timeout(lambda: self.close(notif_elt), delay * 1000)
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
135 for elt in notif_elt.select('.click_to_close'):
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
136 elt.bind('click', lambda __: self.close(notif_elt))
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
137
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
138
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
139 class RetryNotification:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
140 def __init__(self, retry_cb):
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
141 self._tpl = Template("dialogs/retry-notification.html")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
142 self.retry_cb = retry_cb
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
143 self.counter = 0
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
144 self.timer = None
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
145
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
146 def retry(self, notif_elt):
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
147 if self.timer is not None:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
148 timer.clear_interval(self.timer)
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
149 self.timer = None
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
150 notif_elt.classList.remove('state_appended')
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
151 notif_elt.bind("transitionend", lambda __: notif_elt.remove())
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
152 self.retry_cb()
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
153
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
154 def update_counter(self, notif_elt):
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
155 counter = notif_elt.select_one(".retry_counter")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
156 counter.text = str(self.counter)
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
157 self.counter -= 1
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
158 if self.counter < 0:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
159 self.retry(notif_elt)
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
160
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
161 def show(
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
162 self,
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
163 message: str,
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
164 level: str = "warning",
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
165 delay: int = 5
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
166 ) -> None:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
167 # we log in console error messages, may be useful
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
168 if level == "error":
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
169 log.error(message)
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
170 elif level == "warning":
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
171 log.warning(message)
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
172 self.counter = delay
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
173 notif_elt = self._tpl.get_elt({
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
174 "message": message,
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
175 "level": level,
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
176 })
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
177 self.update_counter(notif_elt)
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
178 document["notifs_area"] <= notif_elt
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
179 timer.set_timeout(lambda: notif_elt.classList.add('state_appended'), 0)
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
180 self.timer = timer.set_interval(self.update_counter, 1000, notif_elt)
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
181 for elt in notif_elt.select('.click_to_retry'):
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
182 elt.bind('click', lambda __: self.retry(notif_elt))
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
183
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
184
1619
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
185 class Modal:
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
186
1625
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
187 def __init__(
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
188 self,
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
189 content_elt,
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
190 is_card: bool = False,
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
191 closable: bool = False,
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
192 close_cb: Callable|None = None,
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
193 position: Literal["center", "left", "right", "top", "bottom"] = "center"
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
194 ) -> None:
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
195 self.position = position
1619
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
196 self.is_card = is_card
1625
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
197 if is_card and position == 'center':
1619
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
198 if not content_elt.classList.contains("modal-card"):
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
199 raise ValueError(
1625
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
200 'Element must have a "modal-card" class when `is_card` is used for center modal'
1619
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
201 )
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
202 self.closable = closable
1620
3a60bf3762ef browser: threads and replies implementation:
Goffi <goffi@goffi.org>
parents: 1619
diff changeset
203 self._close_cb = close_cb
1619
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
204 self._tpl = Template("dialogs/modal.html")
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
205 self.content_elt = content_elt
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
206 self._modal_elt = None
1625
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
207 self._closing = False
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
208 self._is_panel = position != 'center'
1619
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
209
1625
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
210 def _cleanup(self):
1619
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
211 if self._modal_elt is not None:
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
212 self._modal_elt.remove()
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
213 self._modal_elt = None
1625
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
214 self._closing = False
1619
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
215
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
216 def close(self):
1625
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
217 if self._modal_elt is None or self._closing:
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
218 return
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
219
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
220 self._closing = True
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
221
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
222 self._modal_elt.classList.remove('is-active')
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
223
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
224 if self._is_panel:
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
225 self._modal_elt.classList.add('closing')
1619
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
226
1625
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
227 def on_close_finished():
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
228 if self._close_cb:
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
229 self._close_cb()
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
230 self._cleanup()
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
231
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
232 timer.set_timeout(on_close_finished, 300)
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
233
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
234 def on_background_click(self, evt):
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
235 if self.closable and not self._closing:
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
236 evt.preventDefault()
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
237 evt.stopPropagation()
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
238 self.close()
1619
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
239
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
240 def show(self) -> None:
1625
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
241 if self._modal_elt:
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
242 self._cleanup()
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
243
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
244 self._modal_elt = self._tpl.get_elt({
1619
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
245 "closable": self.closable,
1625
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
246 "position": self.position,
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
247 "is_panel": self._is_panel
1619
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
248 })
1625
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
249
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
250 if self.position == 'center':
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
251 container_elt = self._modal_elt.select_one(".modal-content")
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
252 container_elt <= self.content_elt
1619
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
253 else:
1625
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
254 container_elt = self._modal_elt.select_one(".modal-panel-container")
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
255 container_elt <= self.content_elt
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
256 container_elt.classList.add(f"is-{self.position}")
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
257
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
258 document['notifs_area'] <= self._modal_elt
1619
a2cd4222c702 browser: Updates for new design:
Goffi <goffi@goffi.org>
parents: 1600
diff changeset
259
1625
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
260 if self.closable:
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
261 bg = self._modal_elt.select_one(".modal-background, .modal-panel-background")
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
262 if bg:
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
263 bg.bind("click", self.on_background_click)
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
264
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
265 # Add active class after a small delay to trigger animation
698eaabfca0e browser (chat): side/panel and keyword handling:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
266 timer.set_timeout(lambda: self._modal_elt.classList.add('is-active'), 10)
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
267
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1385
diff changeset
268
1328
683e50799d6d browser (dialog): new class to handle notifications
Goffi <goffi@goffi.org>
parents: 1299
diff changeset
269 notification = Notification()