This commit is contained in:
metacryst
2026-01-13 18:06:32 -06:00
parent 5b0f69b7aa
commit fd27ac9c69
6 changed files with 154 additions and 71 deletions

View File

@@ -1,69 +1,36 @@
import "./components/Sidebar.js"
class Home extends Shadow { class Home extends Shadow {
tracking = false tracking = false
logs = [] logs = []
timer = null timer = null
async startTracking() {
if (!navigator.geolocation) {
alert("Geolocation is not supported by your browser.");
return;
}
this.tracking = true
navigator.geolocation.requestPermission?.() || Promise.resolve('granted');
const permission = await new Promise((resolve) => {
navigator.geolocation.getCurrentPosition(
() => resolve('granted'),
() => resolve('denied')
);
});
if (permission === 'denied') {
alert("Location permission required");
this.tracking = false
return;
}
const timer = setInterval(async () => {
navigator.geolocation.getCurrentPosition(
async (pos) => {
const { latitude, longitude } = pos.coords;
const now = new Date();
const log = `${now.toISOString()} — (${latitude}, ${longitude})`;
const timestamp = this.formatCentralTime(now);
this.logs = [log, ...this.logs]
this.updateLogs()
await this.sendLocation(latitude, longitude, timestamp);
},
(err) => console.error("Location error:", err),
{ enableHighAccuracy: true }
);
}, 1000);
this.timer = timer
}
stopTracking() {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
this.tracking = false;
}
}
render() { render() {
ZStack(() => { ZStack(() => {
Sidebar()
// Title bar // Title bar
HStack(() => { HStack(() => {
img("./_/icons/runner.svg", "2em", "2em") img("./_/icons/runner.svg", "2em", "2em")
p("San Marcos, TX") p("San Marcos, TX")
.fontSize(1.2, em) .fontSize(1.2, em)
img("./_/icons/hamburger.svg", "2em", "2em") img("./_/icons/hamburger.svg", "2em", "2em")
.transition("scale .3s")
.zIndex(2)
.onTouch(function (start) {
if(start) {
this.style.scale = 0.8
} else {
this.style.scale = 1
}
if(start === false) {
$("sidebar-").toggle()
}
})
}) })
.gap(15, vw) .gap(15, vw)
.position("fixed") .position("fixed")
@@ -144,6 +111,58 @@ class Home extends Shadow {
.fontFamily("Arial") .fontFamily("Arial")
} }
async startTracking() {
if (!navigator.geolocation) {
alert("Geolocation is not supported by your browser.");
return;
}
this.tracking = true
navigator.geolocation.requestPermission?.() || Promise.resolve('granted');
const permission = await new Promise((resolve) => {
navigator.geolocation.getCurrentPosition(
() => resolve('granted'),
() => resolve('denied')
);
});
if (permission === 'denied') {
alert("Location permission required");
this.tracking = false
return;
}
const timer = setInterval(async () => {
navigator.geolocation.getCurrentPosition(
async (pos) => {
const { latitude, longitude } = pos.coords;
const now = new Date();
const log = `${now.toISOString()} — (${latitude}, ${longitude})`;
const timestamp = this.formatCentralTime(now);
this.logs = [log, ...this.logs]
this.updateLogs()
await this.sendLocation(latitude, longitude, timestamp);
},
(err) => console.error("Location error:", err),
{ enableHighAccuracy: true }
);
}, 1000);
this.timer = timer
}
stopTracking() {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
this.tracking = false;
}
}
showTracking() { showTracking() {
this.$("#playButton").rerender() this.$("#playButton").rerender()
this.$("#playButton").style.backgroundColor = this.tracking ? "#CD593E" : "#A6EABD" this.$("#playButton").style.backgroundColor = this.tracking ? "#CD593E" : "#A6EABD"
@@ -176,7 +195,7 @@ class Home extends Shadow {
async sendLocation(lat, lon, timestamp) { async sendLocation(lat, lon, timestamp) {
try { try {
const resp = await fetch('http://localhost:3008/api/location', { const resp = await fetch('http://localhost:3009/api/location', {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ body: JSON.stringify({

View File

@@ -51,12 +51,17 @@ window.setQuery = function(key, value) {
return newUrl; return newUrl;
}; };
window.navigateTo = function(url) { window.navigateTo = function(url) {
window.dispatchEvent(new Event('navigate')); window.dispatchEvent(new Event('navigate'));
window.history.pushState({}, '', url); window.history.pushState({}, '', url);
} }
window.setLocation = function(url) {
window.dispatchEvent(new Event('navigate'));
window.history.replaceState({}, '', url);
}
/* $ SELECTOR */ /* $ SELECTOR */
HTMLElement.prototype.$ = function(selector) { HTMLElement.prototype.$ = function(selector) {
@@ -91,8 +96,6 @@ console.green = function(message) {
} }
/* GET CSS VARIABLES FOR DARK OR LIGHT MODE */ /* GET CSS VARIABLES FOR DARK OR LIGHT MODE */
window.darkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
document.documentElement.classList.add(darkMode ? 'dark' : 'light');
window.getColor = function(name) { window.getColor = function(name) {
const rootStyles = getComputedStyle(document.documentElement); const rootStyles = getComputedStyle(document.documentElement);
@@ -815,6 +818,20 @@ window.input = function(placeholder = "", width, height) {
return el return el
} }
window.select = function(cb) {
let el = document.createElement("select")
el.render = cb
quill.render(el)
return el
}
window.option = function(placeholder = "") {
let el = document.createElement("option")
el.innerText = placeholder
quill.render(el)
return el
}
window.label = function(inside) { window.label = function(inside) {
let el = document.createElement("label") let el = document.createElement("label")
if(typeof inside === "string") { if(typeof inside === "string") {
@@ -1034,7 +1051,7 @@ HTMLElement.prototype.onInput = function(cb) {
}; };
HTMLElement.prototype.onChange = function(cb) { HTMLElement.prototype.onChange = function(cb) {
if(!this.matches('input, textarea, [contenteditable=""], [contenteditable="true"]')) if(!this.matches('input, textarea, select, [contenteditable=""], [contenteditable="true"]'))
throw new Error("Can't put input event on non-input element!") throw new Error("Can't put input event on non-input element!")
this._storeListener("change", cb); this._storeListener("change", cb);
return this; return this;

View File

@@ -9,4 +9,17 @@
:root { :root {
} }
}
html,
body {
padding: 0;
margin: 0;
}
body {
padding-top: env(safe-area-inset-top);
padding-bottom: env(safe-area-inset-bottom);
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
} }

46
src/components/Sidebar.js Normal file
View File

@@ -0,0 +1,46 @@
class Sidebar extends Shadow {
SidebarItem(text) {
return p(text)
.fontSize(1.5, em)
.fontWeight("bold")
.fontFamily("Sedan SC")
.marginLeft(2, em)
.fontStyle("italic")
.onClick(function () {
if(this.innerText === "Home") {
window.navigateTo("/")
return
}
window.navigateTo(this.innerText.toLowerCase().replace(/\s+/g, ""))
})
}
render() {
VStack(() => {
this.SidebarItem("Home")
this.SidebarItem("Map")
this.SidebarItem("Logout")
})
.gap(2, em)
.paddingTop(30, vh)
.height(100, vh)
.width(70, vw)
.borderLeft("1px solid black")
.position("fixed")
.background("var(--main)")
.xRight(-70, vw)
.transition("right .3s")
.zIndex(1)
}
toggle() {
if(this.style.right === "-70vw") {
this.style.right = "0vw"
} else {
this.style.right = "-70vw"
}
}
}
register(Sidebar)

View File

@@ -1,12 +0,0 @@
html,
body {
padding: 0;
margin: 0;
}
body {
padding-top: env(safe-area-inset-top);
padding-bottom: env(safe-area-inset-bottom);
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
}

View File

@@ -1,3 +1,3 @@
import "./js/Home.js" import "./Home.js"
Home() Home()
document.body.style.backgroundColor = "var(--main)" document.body.style.backgroundColor = "var(--main)"