diff --git a/fasthtml/live_reload.py b/fasthtml/live_reload.py
index a9d0d073..84cfbd30 100644
--- a/fasthtml/live_reload.py
+++ b/fasthtml/live_reload.py
@@ -4,24 +4,25 @@
__all__ = ["FastHTMLWithLiveReload"]
-LIVE_RELOAD_SCRIPT = """
- (function() {{
- var socket = new WebSocket(`ws://${{window.location.host}}/live-reload`);
- var maxReloadAttempts = {reload_attempts};
- var reloadInterval = {reload_interval}; // time between reload attempts in ms
- socket.onclose = function() {{
+def LiveReloadJs(reload_attempts:int=1, reload_interval:float=1000., **kwargs):
+ src = """
+ (function() {
+ var socket = new WebSocket(`ws://${window.location.host}/live-reload`);
+ var maxReloadAttempts = %s;
+ var reloadInterval = %s; // time between reload attempts in ms
+ socket.onclose = function() {
let reloadAttempts = 0;
- const intervalFn = setInterval(function(){{
+ const intervalFn = setInterval(function(){
window.location.reload();
reloadAttempts++;
if (reloadAttempts === maxReloadAttempts) clearInterval(intervalFn);
- }}, reloadInterval);
- }}
- }})();
+ }, reloadInterval);
+ }
+ })();
"""
+ return Script(src % (reload_attempts, reload_interval))
-
-async def live_reload_websocket(websocket): await websocket.accept()
+async def live_reload_ws(websocket): await websocket.accept()
class FastHTMLWithLiveReload(FastHTML):
"""
@@ -47,19 +48,8 @@ class FastHTMLWithLiveReload(FastHTML):
Run:
serve()
"""
- LIVE_RELOAD_ROUTE = WebSocketRoute("/live-reload", endpoint=live_reload_websocket)
-
def __init__(self, *args, **kwargs):
- # Create the live reload script to be injected into the webpage
- self.LIVE_RELOAD_HEADER = Script(
- LIVE_RELOAD_SCRIPT.format(
- reload_attempts=kwargs.get("reload_attempts", 1),
- reload_interval=kwargs.get("reload_interval", 1000),
- )
- )
-
# "hdrs" and "routes" can be missing, None, a list or a tuple.
- kwargs["hdrs"] = [*(kwargs.get("hdrs") or []), self.LIVE_RELOAD_HEADER]
- kwargs["routes"] = [*(kwargs.get("routes") or []), self.LIVE_RELOAD_ROUTE]
+ kwargs["hdrs"] = [*(kwargs.get("hdrs") or []), LiveReloadJs(**kwargs)]
+ kwargs["routes"] = [*(kwargs.get("routes") or []), WebSocketRoute("/live-reload", endpoint=live_reload_ws)]
super().__init__(*args, **kwargs)
-
diff --git a/fasthtml/toaster.py b/fasthtml/toaster.py
index 5856643b..2991798b 100644
--- a/fasthtml/toaster.py
+++ b/fasthtml/toaster.py
@@ -31,27 +31,31 @@
.fh-toast-error { background-color: #F44336; }
"""
-toast_js = """
-export function proc_htmx(sel, func) {{
- htmx.onLoad(elt => {{
+def ToastJs(duration:float):
+ duration = int(1000*duration)
+ src = """
+export function proc_htmx(sel, func) {
+ htmx.onLoad(elt => {
const elements = any(sel, elt, false);
if (elt.matches && elt.matches(sel)) elements.unshift(elt);
elements.forEach(func);
- }});
-}}
-proc_htmx('.fh-toast-container', async function(toast) {{
+ });
+}
+proc_htmx('.fh-toast-container', async function(toast) {
await sleep(100);
toast.style.opacity = '0.8';
- await sleep({duration});
+ await sleep(%s);
toast.style.opacity = '0';
await sleep(300);
toast.remove();
-}});
+});
-proc_htmx('.fh-toast-dismiss', function(elem) {{
- elem.addEventListener('click', (e) => {{ e.target.parentElement.remove() }});
-}});
+proc_htmx('.fh-toast-dismiss', function(elem) {
+ elem.addEventListener('click', (e) => { e.target.parentElement.remove() });
+});
"""
+ return Script(src % (duration,), type="module")
+
def add_toast(sess, message, typ="info"):
assert typ in ("info", "success", "warning", "error"), '`typ` not in ("info", "success", "warning", "error")'
@@ -65,5 +69,5 @@ def toast_after(resp, req, sess):
if sk in sess and (not resp or isinstance(resp, (tuple,FT,FtResponse))): req.injects.append(render_toasts(sess))
def setup_toasts(app, duration:float=10.):
- app.hdrs += (Style(toast_css), Script(toast_js.format(duration=1000*duration), type="module"))
+ app.hdrs += (Style(toast_css), ToastJs(duration))
app.after.append(toast_after)