A Gmail-watching Apps Script (documented in docs/deployment.adoc) posts the session ID from each LiveTrack email to a new webhook, which stores it in data/livetrack.json; a new sidebar panel lists what's been received.
72 lines
2.4 KiB
JavaScript
72 lines
2.4 KiB
JavaScript
import { LIVETRACK_ICON } from "/js/icons.js";
|
|
import { notifySidePanelOpen, onlyOneSidePanelOpen } from "/js/panels.js";
|
|
|
|
const SESSIONS_URL = "/api/livetrack/sessions";
|
|
|
|
// A sidebar icon that opens a side panel listing Garmin LiveTrack session
|
|
// IDs received via the webhook (see docs/deployment.adoc) — read-only, just
|
|
// so they're visible somewhere instead of only in data/livetrack.json.
|
|
export class LiveTrackPanelControl {
|
|
mount(sidebar) {
|
|
this._container = document.createElement("div");
|
|
this._container.className = "sidebar-item";
|
|
this._container.innerHTML = `<button type="button" class="sidebar-icon" title="LiveTrack" aria-label="LiveTrack">${LIVETRACK_ICON}</button>`;
|
|
this._icon = this._container.querySelector(".sidebar-icon");
|
|
this._icon.addEventListener("click", () => this._togglePanel());
|
|
|
|
this._panel = document.getElementById("livetrack-panel");
|
|
this._list = this._panel.querySelector(".livetrack-panel__list");
|
|
this._panel
|
|
.querySelector(".basemap-panel__close")
|
|
.addEventListener("click", () => this._togglePanel(false));
|
|
|
|
onlyOneSidePanelOpen(this._panel, () => this._icon.classList.remove("active"));
|
|
|
|
sidebar.appendChild(this._container);
|
|
}
|
|
|
|
_togglePanel(force) {
|
|
const open = force === undefined ? this._panel.hidden : force;
|
|
this._panel.hidden = !open;
|
|
this._icon.classList.toggle("active", open);
|
|
if (open) {
|
|
notifySidePanelOpen(this._panel);
|
|
this._loadSessions();
|
|
}
|
|
}
|
|
|
|
async _loadSessions() {
|
|
const response = await fetch(SESSIONS_URL);
|
|
const { sessions } = await response.json();
|
|
this._renderSessions(sessions);
|
|
}
|
|
|
|
_renderSessions(sessions) {
|
|
this._list.innerHTML = "";
|
|
|
|
if (sessions.length === 0) {
|
|
const li = document.createElement("li");
|
|
li.className = "gpx-tree__empty";
|
|
li.textContent = "No sessions yet";
|
|
this._list.appendChild(li);
|
|
return;
|
|
}
|
|
|
|
sessions.forEach(({ id, received_at }) => {
|
|
const li = document.createElement("li");
|
|
li.className = "livetrack-panel__item";
|
|
|
|
const idSpan = document.createElement("span");
|
|
idSpan.className = "livetrack-panel__id";
|
|
idSpan.textContent = id;
|
|
|
|
const timeSpan = document.createElement("span");
|
|
timeSpan.className = "livetrack-panel__time";
|
|
timeSpan.textContent = new Date(received_at).toLocaleString();
|
|
|
|
li.append(idSpan, timeSpan);
|
|
this._list.appendChild(li);
|
|
});
|
|
}
|
|
}
|