sidebar
This commit is contained in:
@@ -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({
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
46
src/components/Sidebar.js
Normal 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)
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
@@ -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)"
|
||||||
Reference in New Issue
Block a user