summaryrefslogtreecommitdiff
path: root/web/templates.templ
diff options
context:
space:
mode:
authorMartin Kagamino Lehoux <martin@lehoux.net>2026-08-16 13:19:22 +0200
committerMartin Kagamino Lehoux <martin@lehoux.net>2026-08-16 13:19:22 +0200
commitbe78280c669a04c112afaf1801f22ed2eec7c55a (patch)
tree0d630af1d0502aae12b1a8cf4ee609a9cba9e4e3 /web/templates.templ
parente7bd55d20974f4ee5b892cd2e81c62b5c5408920 (diff)
refactor(web): establish JavaScript module tooling
Diffstat (limited to 'web/templates.templ')
-rw-r--r--web/templates.templ104
1 files changed, 3 insertions, 101 deletions
diff --git a/web/templates.templ b/web/templates.templ
index fe5c363..68327a1 100644
--- a/web/templates.templ
+++ b/web/templates.templ
@@ -170,10 +170,8 @@ templ RideDetailContent(data RideDetailView) {
if data.HasRoute {
@templ.JSONScript("ride-route", data.Route)
@templ.JSONScript("ride-profile", data.Profile)
- <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" defer></script>
- <script src="/static/official-climb-profile-logic.js" defer></script>
- <script src="/static/official-climb-profile.js" defer></script>
- <script src="/static/ride-detail.js" defer></script>
+ <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
+ <script type="module" src="/static/ride-detail.js"></script>
}
}
@@ -214,101 +212,5 @@ templ SyncContent(data SyncPageData) {
</div>
}
</section>
- <script>
- (() => {
- const form = document.getElementById("sync-form");
- if (!form) return;
- const button = form.querySelector("button[type=submit]");
- const progressPanel = document.getElementById("sync-progress");
- const progressBar = document.getElementById("sync-progress-bar");
- const progressCount = document.getElementById("sync-progress-count");
- const progressDetails = document.getElementById("sync-progress-details");
- const notice = document.getElementById("sync-notice");
- const error = document.getElementById("sync-error");
-
- const showError = (message) => {
- error.textContent = message;
- error.hidden = false;
- };
- const updateProgress = (progress) => {
- progressPanel.hidden = false;
- progressBar.max = Math.max(progress.total, 1);
- progressBar.value = progress.completed;
- progressCount.textContent = `${progress.completed} / ${progress.total}`;
- progressDetails.textContent = `${progress.imported} imported ยท ${progress.skipped} skipped`;
- };
- const handleEvent = (eventName, data) => {
- if (eventName === "progress") {
- updateProgress(data);
- return false;
- }
- if (eventName === "complete") {
- updateProgress(data);
- notice.textContent = `Sync complete: ${data.imported} imported, ${data.skipped} skipped.`;
- notice.hidden = false;
- return true;
- }
- if (eventName === "error") {
- if (data.progress) updateProgress(data.progress);
- throw new Error(data.message || "Strava sync failed");
- }
- return false;
- };
- const consumeEvents = async (response) => {
- const reader = response.body.getReader();
- const decoder = new TextDecoder();
- let buffer = "";
- let completed = false;
- const consumeBlock = (block) => {
- let eventName = "message";
- let data = "";
- for (const line of block.split(/\r?\n/)) {
- if (line.startsWith("event: ")) eventName = line.slice(7);
- if (line.startsWith("data: ")) data += line.slice(6);
- }
- if (data) completed = handleEvent(eventName, JSON.parse(data)) || completed;
- };
- while (true) {
- const { value, done } = await reader.read();
- buffer += decoder.decode(value || new Uint8Array(), { stream: !done });
- const blocks = buffer.split(/\r?\n\r?\n/);
- buffer = blocks.pop();
- for (const block of blocks) consumeBlock(block);
- if (done) break;
- }
- if (buffer.trim()) consumeBlock(buffer);
- if (!completed) throw new Error("Strava sync ended before completion");
- };
-
- form.addEventListener("submit", async (event) => {
- event.preventDefault();
- button.disabled = true;
- button.textContent = "Syncing...";
- notice.hidden = true;
- error.hidden = true;
- progressPanel.hidden = false;
- progressCount.textContent = "0 / 0";
- progressDetails.textContent = "Preparing import...";
- try {
- const response = await fetch(form.action, {
- method: "POST",
- body: new FormData(form),
- headers: { Accept: "text/event-stream" },
- });
- if (response.redirected) {
- window.location.assign(response.url);
- return;
- }
- if (!response.ok) throw new Error(await response.text() || `Sync failed (HTTP ${response.status})`);
- if (!response.body) throw new Error("The browser does not support streaming responses");
- await consumeEvents(response);
- } catch (caught) {
- showError(caught instanceof Error ? caught.message : "Strava sync failed");
- } finally {
- button.disabled = false;
- button.textContent = "Sync rides";
- }
- });
- })();
- </script>
+ <script type="module" src="/static/sync.js"></script>
}