Mercurial > libervia-web
diff libervia/web/pages/_browser/dialog.py @ 1518:eb00d593801d
refactoring: rename `libervia` to `libervia.web` + update imports following backend changes
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 02 Jun 2023 16:49:28 +0200 |
parents | libervia/pages/_browser/dialog.py@409d10211b20 |
children | e47c24204449 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libervia/web/pages/_browser/dialog.py Fri Jun 02 16:49:28 2023 +0200 @@ -0,0 +1,131 @@ +"""manage common dialogs""" + +from browser import document, window, timer, console as log +from template import Template + +log.warning = log.warn + + +class Confirm: + + def __init__(self, message, ok_label="", cancel_label="", ok_color="success"): + self._tpl = Template("dialogs/confirm.html") + self.message = message + self.ok_label = ok_label + assert ok_color in ("success", "danger") + self.ok_color = ok_color + self.cancel_label = cancel_label + + def cancel_cb(self, evt, notif_elt): + notif_elt.remove() + + def show(self, ok_cb, cancel_cb=None): + if cancel_cb is None: + cancel_cb = self.cancel_cb + notif_elt = self._tpl.get_elt({ + "message": self.message, + "ok_label": self.ok_label, + "ok_color": self.ok_color, + "cancel_label": self.cancel_label, + }) + + document['notifs_area'] <= notif_elt + timer.set_timeout(lambda: notif_elt.classList.add('state_appended'), 0) + for cancel_elt in notif_elt.select(".click_to_cancel"): + cancel_elt.bind("click", lambda evt: cancel_cb(evt, notif_elt)) + for cancel_elt in notif_elt.select(".click_to_ok"): + cancel_elt.bind("click", lambda evt: ok_cb(evt, notif_elt)) + + def _ashow_cb(self, evt, notif_elt, resolve_cb, confirmed): + evt.stopPropagation() + notif_elt.remove() + resolve_cb(confirmed) + + async def ashow(self): + return window.Promise.new( + lambda resolve_cb, reject_cb: + self.show( + lambda evt, notif_elt: self._ashow_cb(evt, notif_elt, resolve_cb, True), + lambda evt, notif_elt: self._ashow_cb(evt, notif_elt, resolve_cb, False) + ) + ) + + +class Notification: + + def __init__(self): + self._tpl = Template("dialogs/notification.html") + + def close(self, notif_elt): + notif_elt.classList.remove('state_appended') + notif_elt.bind("transitionend", lambda __: notif_elt.remove()) + + def show( + self, + message: str, + level: str = "info", + delay: int = 5 + ) -> None: + # we log in console error messages, may be useful + if level in ("warning", "error"): + print(f"[{level}] {message}") + notif_elt = self._tpl.get_elt({ + "message": message, + "level": level, + }) + document["notifs_area"] <= notif_elt + timer.set_timeout(lambda: notif_elt.classList.add('state_appended'), 0) + timer.set_timeout(lambda: self.close(notif_elt), delay * 1000) + for elt in notif_elt.select('.click_to_close'): + elt.bind('click', lambda __: self.close(notif_elt)) + + +class RetryNotification: + def __init__(self, retry_cb): + self._tpl = Template("dialogs/retry-notification.html") + self.retry_cb = retry_cb + self.counter = 0 + self.timer = None + + def retry(self, notif_elt): + if self.timer is not None: + timer.clear_interval(self.timer) + self.timer = None + notif_elt.classList.remove('state_appended') + notif_elt.bind("transitionend", lambda __: notif_elt.remove()) + self.retry_cb() + + def update_counter(self, notif_elt): + counter = notif_elt.select_one(".retry_counter") + counter.text = str(self.counter) + self.counter -= 1 + if self.counter < 0: + self.retry(notif_elt) + + def show( + self, + message: str, + level: str = "warning", + delay: int = 5 + ) -> None: + # we log in console error messages, may be useful + if level == "error": + log.error(message) + elif level == "warning": + log.warning(message) + self.counter = delay + notif_elt = self._tpl.get_elt({ + "message": message, + "level": level, + }) + self.update_counter(notif_elt) + document["notifs_area"] <= notif_elt + timer.set_timeout(lambda: notif_elt.classList.add('state_appended'), 0) + self.timer = timer.set_interval(self.update_counter, 1000, notif_elt) + for elt in notif_elt.select('.click_to_retry'): + elt.bind('click', lambda __: self.retry(notif_elt)) + + + + +notification = Notification()