Skip to content

Commit f6adf9f

Browse files
committed
generate flavor lists and JSONs statically to clean up code. [#5]
1 parent 97eea2c commit f6adf9f

File tree

4 files changed

+66
-43
lines changed

4 files changed

+66
-43
lines changed

app/App.tsx

Lines changed: 21 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,11 @@
1-
import { For, createSignal, createEffect, onMount, Component } from "solid-js";
1+
import { For, createSignal, createEffect, createResource, onMount, Component, Show } from "solid-js";
22
import "maplibre-gl/dist/maplibre-gl.css";
33
import "./App.css";
44
import maplibregl from "maplibre-gl";
55
import { StyleSpecification } from "maplibre-gl";
66
import { Flavor, layers } from "@protomaps/basemaps";
77

8-
const FLAVORS = ["bio", "dusk_rose", "iris_bloom","rainforest", "seafoam", "flat"];
9-
10-
const nameToFlavor = new Map<string, Flavor>();
11-
12-
import bio from "../flavors/bio.ts";
13-
nameToFlavor.set("bio", bio);
14-
15-
import iris_bloom from "../flavors/iris_bloom.ts";
16-
nameToFlavor.set("iris_bloom", iris_bloom);
17-
18-
import seafoam from "../flavors/seafoam.ts";
19-
nameToFlavor.set("seafoam", seafoam);
20-
21-
// import sol from "../flavors/sol.ts";
22-
// nameToFlavor.set("sol", sol);
23-
24-
import flat from "../flavors/flat.ts";
25-
nameToFlavor.set("flat", flat);
26-
27-
import dusk_rose from "../flavors/dusk_rose.ts";
28-
nameToFlavor.set("dusk_rose", dusk_rose);
29-
30-
import rainforest from "../flavors/rainforest.ts";
31-
nameToFlavor.set("rainforest", rainforest);
32-
33-
const getStyle = (index: number, showLabels: boolean): StyleSpecification => {
34-
let flavorName = FLAVORS[index];
8+
const getStyle = (flavor: Flavor | undefined, showLabels: boolean): StyleSpecification => {
359
return {
3610
version: 8,
3711
glyphs:
@@ -42,13 +16,13 @@ const getStyle = (index: number, showLabels: boolean): StyleSpecification => {
4216
url: "https://api.protomaps.com/tiles/v4.json?key=1003762824b9687f",
4317
},
4418
},
45-
layers: layers("protomaps", nameToFlavor.get(flavorName)!, { lang: showLabels ? "en" : undefined }),
19+
layers: flavor ? layers("protomaps", flavor, { lang: showLabels ? "en" : undefined }) : []
4620
};
4721
};
4822

49-
const FlavorRow: Component<{ name: string, flavor: Flavor }> = (props) => {
23+
const FlavorRow: Component<{ name: string }> = (props) => {
5024
return (
51-
<div class="flavorRow" style={{ "background-color": props.flavor.background, "color": props.flavor.city_label }}>
25+
<div class="flavorRow">
5226
{props.name}
5327
</div>
5428
)
@@ -57,7 +31,7 @@ const FlavorRow: Component<{ name: string, flavor: Flavor }> = (props) => {
5731
function App() {
5832
let map: maplibregl.Map;
5933

60-
const [selectedIndex, setSelectedIndex] = createSignal(0);
34+
const [selectedFlavorName, setSelectedFlavorName] = createSignal();
6135
const [showLabels, setShowLabels] = createSignal(true);
6236

6337
onMount(async () => {
@@ -68,17 +42,23 @@ function App() {
6842

6943
map = new maplibregl.Map({
7044
container: "map",
71-
style: getStyle(selectedIndex(), showLabels()),
45+
style: getStyle(undefined, showLabels()),
7246
});
7347
});
7448

75-
createEffect(() => {
76-
map.setStyle(getStyle(selectedIndex(), showLabels()));
49+
const [flavorList] = createResource(async () => {
50+
const resp = await fetch("/flavors.json");
51+
return await resp.json();
52+
})
53+
54+
const [flavorJson] = createResource(selectedFlavorName, async () => {
55+
const resp = await fetch(`/flavors/${selectedFlavorName()}.json`);
56+
return await resp.json();
7757
});
7858

79-
const selectFlavor = (i: number) => {
80-
setSelectedIndex(i);
81-
}
59+
createEffect(() => {
60+
map.setStyle(getStyle(flavorJson(), showLabels()));
61+
});
8262

8363
const handleShowLabelsChange = (event: Event) => {
8464
const target = event.target as HTMLInputElement;
@@ -88,7 +68,9 @@ function App() {
8868
return (
8969
<div id="container">
9070
<div class="sidebar">
91-
<For each={FLAVORS}>{(flavorName,i) => <div onClick={() => selectFlavor(i())}><FlavorRow name={flavorName} flavor={nameToFlavor.get(flavorName)!}/></div>}</For>
71+
<Show when={flavorList()}>
72+
<For each={flavorList()}>{(flavorName) => <div onClick={() => setSelectedFlavorName(flavorName)}><FlavorRow name={flavorName}/></div>}</For>
73+
</Show>
9274
<input
9375
id="showLabels"
9476
type="checkbox"

flavors/black_and_white.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export default <Flavor>{
8181
city_label_halo: WHITE,
8282
state_label: BLACK,
8383
state_label_halo: WHITE,
84-
country_label: BLACK
84+
country_label: BLACK,
8585

8686
address_label: BLACK,
8787
address_label_halo: WHITE,

flavors/sol.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export default <Flavor> {
9292
glacier: 'rgba(239, 240, 231, 1)',
9393
scrub: 'rgba(176, 205, 174, 1)',
9494
forest: 'rgba(149, 207, 194, 1)'
95-
}
95+
},
9696

9797
address_label: "black",
9898
address_label_halo: "white",

vite.config.ts

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,47 @@
11
import { defineConfig } from 'vite'
22
import solid from 'vite-plugin-solid'
3+
import path from 'path'
4+
import fs from 'fs'
5+
6+
const flavorList = () => {
7+
const contentDir = path.resolve(__dirname, 'flavors')
8+
let files = fs.readdirSync(contentDir)
9+
return files.filter(f => f.endsWith('.ts')).map(f => f.slice(0,-3));
10+
}
11+
12+
const flavorBody = async (name: string) => {
13+
return (await import(`./flavors/${name}.ts`)).default;
14+
}
315

416
export default defineConfig({
5-
plugins: [solid()],
6-
})
17+
plugins: [
18+
{
19+
'name':'basemaps-flavors',
20+
configureServer(server) {
21+
server.middlewares.use(async (req, res, next) => {
22+
if (req.url === '/flavors.json') {
23+
res.setHeader('Content-Type', 'application/json');
24+
res.end(JSON.stringify(flavorList()));
25+
return
26+
}
27+
if (req.url && req.url.startsWith("/flavors/")) {
28+
res.setHeader('Content-Type', 'application/json');
29+
res.end(JSON.stringify(await flavorBody(req.url.slice(9,-5))));
30+
return
31+
}
32+
next()
33+
})
34+
},
35+
async generateBundle() {
36+
const flist = flavorList();
37+
fs.writeFileSync(path.resolve(__dirname, 'dist', 'flavors.json'), JSON.stringify(flist, null, 2))
38+
const dir = path.resolve(__dirname, 'dist', 'flavors')
39+
fs.mkdirSync(dir);
40+
for (const name of flist) {
41+
fs.writeFileSync(path.resolve(__dirname, 'dist', 'flavors', `${name}.json`), JSON.stringify(await flavorBody(name), null, 2))
42+
}
43+
},
44+
},
45+
solid()
46+
]
47+
});

0 commit comments

Comments
 (0)