summaryrefslogtreecommitdiff
path: root/web/static/sync.js
diff options
context:
space:
mode:
authorMartin Kagamino Lehoux <martin@lehoux.net>2026-08-16 14:23:32 +0200
committerMartin Kagamino Lehoux <martin@lehoux.net>2026-08-16 14:23:32 +0200
commit53ab332e6d2afe9818914e0026310e4cadcc4202 (patch)
tree198d708fa05d4247bdcc0cf2900fdf551d61b7d6 /web/static/sync.js
parent2d18d177f48285eb123e7da8680fc00e7a6fe19c (diff)
refactor(web): migrate browser code to TypeScript
Diffstat (limited to 'web/static/sync.js')
-rw-r--r--web/static/sync.js103
1 files changed, 0 insertions, 103 deletions
diff --git a/web/static/sync.js b/web/static/sync.js
deleted file mode 100644
index 3cf6cca..0000000
--- a/web/static/sync.js
+++ /dev/null
@@ -1,103 +0,0 @@
-export const mountSync = () => {
- const form = /** @type {HTMLFormElement | null} */ (document.getElementById("sync-form"));
- if (!form) return;
- /** @type {HTMLButtonElement} */
- const button = form.querySelector("button[type=submit]");
- /** @type {HTMLElement} */
- const progressPanel = document.getElementById("sync-progress");
- const progressBar = /** @type {HTMLProgressElement} */ (document.getElementById("sync-progress-bar"));
- /** @type {HTMLElement} */
- const progressCount = document.getElementById("sync-progress-count");
- /** @type {HTMLElement} */
- const progressDetails = document.getElementById("sync-progress-details");
- /** @type {HTMLElement} */
- const notice = document.getElementById("sync-notice");
- /** @type {HTMLElement} */
- 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";
- }
- });
-};
-
-mountSync();