Move mobile UI to its own page, and redirect to it
This commit is contained in:
parent
b836e5e8eb
commit
1672d4de94
@ -3,12 +3,14 @@ import { Route, HashRouter } from "@solidjs/router";
|
||||
import { Editor } from "./pages/Editor";
|
||||
import { Index } from "./pages/Index";
|
||||
import { Arrow } from "./pages/Arrow";
|
||||
import { IndexMobile } from "./pages/IndexMobile";
|
||||
|
||||
export default function() {
|
||||
return (
|
||||
<>
|
||||
<HashRouter>
|
||||
<Route path="/" component={Index} />
|
||||
<Route path="/mobile" component={IndexMobile} />
|
||||
<Route path="/editor" component={Editor} />
|
||||
<Route path="/arrow" component={Arrow} />
|
||||
</HashRouter>
|
||||
|
@ -10,6 +10,13 @@ export function Index() {
|
||||
const container = <div class="md:h-[98vh] h-[65vh] md:rounded-lg dark:opacity-60" />;
|
||||
|
||||
onMount(() => {
|
||||
// Detect screen size and ratio,
|
||||
// and redirect to mobile page if neccesary
|
||||
if (window.matchMedia("only screen and (max-width: 760px)").matches) {
|
||||
window.location.replace("/#/mobile");
|
||||
return;
|
||||
}
|
||||
|
||||
global_map = L.map(container as HTMLElement)
|
||||
.setView([-16.40171, -71.53040], 13);
|
||||
|
||||
|
@ -1,8 +1,154 @@
|
||||
import { createEffect, createResource, createSignal, For, onMount } from "solid-js";
|
||||
import L from "leaflet";
|
||||
import { Line, Lines, Route, Routes } from "../new_types";
|
||||
|
||||
let global_map: L.Map | null = null;
|
||||
const [global_count, set_global_count] = createSignal(0);
|
||||
|
||||
export function IndexMobile() {
|
||||
const container = <div class="h-screen w-screen md:rounded-lg dark:opacity-80" />;
|
||||
|
||||
onMount(() => {
|
||||
// Detect screen size and ratio,
|
||||
// and redirect to pc page if neccesary
|
||||
if (!window.matchMedia("only screen and (max-width: 760px)").matches) {
|
||||
window.location.replace("/#/");
|
||||
return;
|
||||
}
|
||||
|
||||
global_map = L.map(container as HTMLElement)
|
||||
.setView([-16.40171, -71.53040], 13);
|
||||
|
||||
L.tileLayer("/tiles/{z}/{x}/{y}.jpg", {
|
||||
maxZoom: 17,
|
||||
minZoom: 12,
|
||||
attribution: "Map data © <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a>",
|
||||
}).addTo(global_map);
|
||||
});
|
||||
|
||||
return (
|
||||
<div>
|
||||
Mobile index :D
|
||||
{container}
|
||||
<LinesContainer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function LinesContainer() {
|
||||
const [selected_line, set_selected_line] = createSignal(-1);
|
||||
const [linesData] = createResource<Lines>(async() => {
|
||||
const res = await fetch("/n/lines.json");
|
||||
if (!res.ok) throw new Error("Error fetching data");
|
||||
return res.json();
|
||||
});
|
||||
|
||||
return (
|
||||
<div class="fixed bottom-0 left-0 w-screen text-c-on-bg z-[500]">
|
||||
<div class="py-1">
|
||||
<For each={linesData() ?? []}>
|
||||
{(line) => <RouteChipContainer line={line} active_line={selected_line()} />}
|
||||
</For>
|
||||
</div>
|
||||
<div class="py-2 bg-c-bg">
|
||||
<For each={linesData() ?? []}>
|
||||
{(line) => (
|
||||
<LineChip
|
||||
line={line}
|
||||
activate={() => set_selected_line(line.id)}
|
||||
deactivate={() => set_selected_line(-1)}
|
||||
selected={selected_line() === line.id}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function LineChip(props: {
|
||||
line: Line,
|
||||
selected: boolean,
|
||||
activate: () => void,
|
||||
deactivate: () => void,
|
||||
}) {
|
||||
const active_classes = () => (props.selected ? "bg-r-hover-bg text-r-hover-on-bg" : "text-r-hover-bg");
|
||||
return (
|
||||
<button
|
||||
class={`inline-block border-2 border-r-hover-bg py-1 px-4 rounded-lg ml-2 font-bold ${active_classes()}`}
|
||||
style={`--hover-bg: ${props.line.hover_bg};--hover-on-bg: ${props.line.hover_on_bg}`}
|
||||
onClick={() => {
|
||||
if (props.selected) {
|
||||
props.deactivate();
|
||||
} else {
|
||||
props.activate();
|
||||
}
|
||||
}}
|
||||
>
|
||||
Linea {props.line.name}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
function RouteChipContainer(props: {line: Line, active_line: number}) {
|
||||
const [routesData] = createResource<Routes>(async() => {
|
||||
const res = await fetch(`/n/routes_${props.line.id}.json`);
|
||||
if (!res.ok) throw new Error("Error fetching data");
|
||||
return res.json();
|
||||
});
|
||||
|
||||
const container_classes = () => (props.active_line === props.line.id ? "inline-block" : "hidden");
|
||||
return (
|
||||
<div class={container_classes()}
|
||||
style={`--hover-bg: ${props.line.hover_bg};--hover-on-bg: ${props.line.hover_on_bg}`}
|
||||
>
|
||||
<For each={routesData() ?? []}>
|
||||
{(route) => <RouteChip route={route} color={props.line.color} />}
|
||||
</For>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function RouteChip(props: {route: Route, color: string}) {
|
||||
const route = props.route;
|
||||
const [active, set_active] = createSignal(false);
|
||||
|
||||
// Create departure and return polylines
|
||||
const departure_polyline = L.polyline(route.departure, { color: props.color });
|
||||
const return_polyline = L.polyline(route.return, { color: props.color });
|
||||
|
||||
// Render the lines into the map
|
||||
// TODO: Change the UI to allow selecting departure and return separately
|
||||
// and then update this
|
||||
|
||||
createEffect(() => {
|
||||
if (global_count() === 0 || active() === true) {
|
||||
departure_polyline.addTo(global_map!);
|
||||
return_polyline.addTo(global_map!);
|
||||
} else {
|
||||
departure_polyline.removeFrom(global_map!);
|
||||
return_polyline.removeFrom(global_map!);
|
||||
}
|
||||
});
|
||||
|
||||
const toggle_active = () => {
|
||||
if (active()) {
|
||||
set_active(false);
|
||||
set_global_count((c) => c - 1);
|
||||
} else {
|
||||
set_active(true);
|
||||
set_global_count((c) => c + 1);
|
||||
}
|
||||
};
|
||||
|
||||
const active_classes = () => (active() === true ? "bg-r-hover-bg text-r-hover-on-bg" : "bg-white text-r-hover-bg");
|
||||
return (
|
||||
<button
|
||||
class={`inline-block rounded-full ml-2 border border-r-hover-bg py-1 px-2
|
||||
${active_classes()}`}
|
||||
onClick={toggle_active}
|
||||
>
|
||||
Ruta {route.name}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user