aboutsummaryrefslogtreecommitdiff
path: root/src/data
diff options
context:
space:
mode:
authorAriel Costas Guerrero <ariel@costas.dev>2025-04-20 20:15:55 +0200
committerAriel Costas Guerrero <ariel@costas.dev>2025-04-20 20:15:55 +0200
commit3676b1d1d9216a676c7d5a40affa5b3256ca8df3 (patch)
treeefa63a0d21ae52e32e405fe7b4ce56b02d782e86 /src/data
parentc86b4655f72c86362c064dd50bb701782b39e6eb (diff)
Refactor stop data handling with caching and custom names support
Diffstat (limited to 'src/data')
-rw-r--r--src/data/StopDataProvider.ts101
1 files changed, 73 insertions, 28 deletions
diff --git a/src/data/StopDataProvider.ts b/src/data/StopDataProvider.ts
index 55d0e78..0c1e46e 100644
--- a/src/data/StopDataProvider.ts
+++ b/src/data/StopDataProvider.ts
@@ -17,41 +17,72 @@ export interface Stop {
favourite?: boolean;
}
-export default {
- getStops,
- getDisplayName,
- addFavourite,
- removeFavourite,
- isFavourite,
- pushRecent,
- getRecent
-};
+// In-memory cache and lookup map
+let cachedStops: Stop[] | null = null;
+let stopsMap: Record<number, Stop> = {};
+// Custom names loaded from localStorage
+let customNames: Record<number, string> = {};
-async function getStops(): Promise<Stop[]> {
- const rawFavouriteStops = localStorage.getItem('favouriteStops');
- let favouriteStops: number[] = [];
- if (rawFavouriteStops) {
- favouriteStops = JSON.parse(rawFavouriteStops) as number[];
- }
+// Initialize cachedStops and customNames once
+async function initStops() {
+ if (!cachedStops) {
+ const response = await fetch('/stops.json');
+ const stops = await response.json() as Stop[];
+ // build array and map
+ stopsMap = {};
+ cachedStops = stops.map(stop => {
+ const entry = { ...stop, favourite: false } as Stop;
+ stopsMap[stop.stopId] = entry;
+ return entry;
+ });
+ // load custom names
+ const rawCustom = localStorage.getItem('customStopNames');
+ if (rawCustom) customNames = JSON.parse(rawCustom) as Record<number, string>;
+ }
+}
- const response = await fetch('/stops.json');
- const stops = await response.json() as Stop[];
+async function getStops(): Promise<Stop[]> {
+ await initStops();
+ // update favourites
+ const rawFav = localStorage.getItem('favouriteStops');
+ const favouriteStops = rawFav ? JSON.parse(rawFav) as number[] : [];
+ cachedStops!.forEach(stop => stop.favourite = favouriteStops.includes(stop.stopId));
+ return cachedStops!;
+}
- return stops.map((stop: Stop) => {
- return {
- ...stop,
- favourite: favouriteStops.includes(stop.stopId)
- };
- });
+// New: get single stop by id
+async function getStopById(stopId: number): Promise<Stop | undefined> {
+ await initStops();
+ const stop = stopsMap[stopId];
+ if (stop) {
+ const rawFav = localStorage.getItem('favouriteStops');
+ const favouriteStops = rawFav ? JSON.parse(rawFav) as number[] : [];
+ stop.favourite = favouriteStops.includes(stopId);
+ }
+ return stop;
}
-// Get display name based on preferences or context
+// Updated display name to include custom names
function getDisplayName(stop: Stop): string {
- if (typeof stop.name === 'string') {
- return stop.name;
- }
+ if (customNames[stop.stopId]) return customNames[stop.stopId];
+ const nameObj = stop.name;
+ return nameObj.intersect || nameObj.original;
+}
+
+// New: set or remove custom names
+function setCustomName(stopId: number, label: string) {
+ customNames[stopId] = label;
+ localStorage.setItem('customStopNames', JSON.stringify(customNames));
+}
- return stop.name.intersect || stop.name.original;
+function removeCustomName(stopId: number) {
+ delete customNames[stopId];
+ localStorage.setItem('customStopNames', JSON.stringify(customNames));
+}
+
+// New: get custom label for a stop
+function getCustomName(stopId: number): string | undefined {
+ return customNames[stopId];
}
function addFavourite(stopId: number) {
@@ -113,3 +144,17 @@ function getRecent(): number[] {
}
return [];
}
+
+export default {
+ getStops,
+ getStopById,
+ getCustomName,
+ getDisplayName,
+ setCustomName,
+ removeCustomName,
+ addFavourite,
+ removeFavourite,
+ isFavourite,
+ pushRecent,
+ getRecent
+};