From 7b8594debceb93a1fa400d48fe1dcff943bd5af6 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 26 Jun 2025 23:44:25 +0200 Subject: Implement stop sheet modal for map stop interactions (#27) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: arielcostas <94913521+arielcostas@users.noreply.github.com> Co-authored-by: Ariel Costas Guerrero --- src/frontend/app/data/StopDataProvider.ts | 205 +++++++++++++++--------------- 1 file changed, 104 insertions(+), 101 deletions(-) (limited to 'src/frontend/app/data/StopDataProvider.ts') diff --git a/src/frontend/app/data/StopDataProvider.ts b/src/frontend/app/data/StopDataProvider.ts index 0c1e46e..efb0414 100644 --- a/src/frontend/app/data/StopDataProvider.ts +++ b/src/frontend/app/data/StopDataProvider.ts @@ -1,20 +1,20 @@ export interface CachedStopList { - timestamp: number; - data: Stop[]; + timestamp: number; + data: Stop[]; } export type StopName = { - original: string; - intersect?: string; -} + original: string; + intersect?: string; +}; export interface Stop { - stopId: number; - name: StopName; - latitude?: number; - longitude?: number; - lines: string[]; - favourite?: boolean; + stopId: number; + name: StopName; + latitude?: number; + longitude?: number; + lines: string[]; + favourite?: boolean; } // In-memory cache and lookup map @@ -25,136 +25,139 @@ let customNames: Record = {}; // 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; - } + 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; + } } async function getStops(): Promise { - 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!; + 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!; } // New: get single stop by id async function getStopById(stopId: number): Promise { - 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; + 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; } // Updated display name to include custom names function getDisplayName(stop: Stop): string { - if (customNames[stop.stopId]) return customNames[stop.stopId]; - const nameObj = stop.name; - return nameObj.intersect || nameObj.original; + 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)); + customNames[stopId] = label; + localStorage.setItem("customStopNames", JSON.stringify(customNames)); } function removeCustomName(stopId: number) { - delete customNames[stopId]; - localStorage.setItem('customStopNames', JSON.stringify(customNames)); + 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]; + return customNames[stopId]; } function addFavourite(stopId: number) { - const rawFavouriteStops = localStorage.getItem('favouriteStops'); - let favouriteStops: number[] = []; - if (rawFavouriteStops) { - favouriteStops = JSON.parse(rawFavouriteStops) as number[]; - } - - if (!favouriteStops.includes(stopId)) { - favouriteStops.push(stopId); - localStorage.setItem('favouriteStops', JSON.stringify(favouriteStops)); - } + const rawFavouriteStops = localStorage.getItem("favouriteStops"); + let favouriteStops: number[] = []; + if (rawFavouriteStops) { + favouriteStops = JSON.parse(rawFavouriteStops) as number[]; + } + + if (!favouriteStops.includes(stopId)) { + favouriteStops.push(stopId); + localStorage.setItem("favouriteStops", JSON.stringify(favouriteStops)); + } } function removeFavourite(stopId: number) { - const rawFavouriteStops = localStorage.getItem('favouriteStops'); - let favouriteStops: number[] = []; - if (rawFavouriteStops) { - favouriteStops = JSON.parse(rawFavouriteStops) as number[]; - } - - const newFavouriteStops = favouriteStops.filter(id => id !== stopId); - localStorage.setItem('favouriteStops', JSON.stringify(newFavouriteStops)); + const rawFavouriteStops = localStorage.getItem("favouriteStops"); + let favouriteStops: number[] = []; + if (rawFavouriteStops) { + favouriteStops = JSON.parse(rawFavouriteStops) as number[]; + } + + const newFavouriteStops = favouriteStops.filter((id) => id !== stopId); + localStorage.setItem("favouriteStops", JSON.stringify(newFavouriteStops)); } function isFavourite(stopId: number): boolean { - const rawFavouriteStops = localStorage.getItem('favouriteStops'); - if (rawFavouriteStops) { - const favouriteStops = JSON.parse(rawFavouriteStops) as number[]; - return favouriteStops.includes(stopId); - } - return false; + const rawFavouriteStops = localStorage.getItem("favouriteStops"); + if (rawFavouriteStops) { + const favouriteStops = JSON.parse(rawFavouriteStops) as number[]; + return favouriteStops.includes(stopId); + } + return false; } const RECENT_STOPS_LIMIT = 10; function pushRecent(stopId: number) { - const rawRecentStops = localStorage.getItem('recentStops'); - let recentStops: Set = new Set(); - if (rawRecentStops) { - recentStops = new Set(JSON.parse(rawRecentStops) as number[]); - } - - recentStops.add(stopId); - if (recentStops.size > RECENT_STOPS_LIMIT) { - const iterator = recentStops.values(); - const val = iterator.next().value as number; - recentStops.delete(val); - } - - localStorage.setItem('recentStops', JSON.stringify(Array.from(recentStops))); + const rawRecentStops = localStorage.getItem("recentStops"); + let recentStops: Set = new Set(); + if (rawRecentStops) { + recentStops = new Set(JSON.parse(rawRecentStops) as number[]); + } + + recentStops.add(stopId); + if (recentStops.size > RECENT_STOPS_LIMIT) { + const iterator = recentStops.values(); + const val = iterator.next().value as number; + recentStops.delete(val); + } + + localStorage.setItem("recentStops", JSON.stringify(Array.from(recentStops))); } function getRecent(): number[] { - const rawRecentStops = localStorage.getItem('recentStops'); - if (rawRecentStops) { - return JSON.parse(rawRecentStops) as number[]; - } - return []; + const rawRecentStops = localStorage.getItem("recentStops"); + if (rawRecentStops) { + return JSON.parse(rawRecentStops) as number[]; + } + return []; } export default { - getStops, - getStopById, - getCustomName, - getDisplayName, - setCustomName, - removeCustomName, - addFavourite, - removeFavourite, - isFavourite, - pushRecent, - getRecent + getStops, + getStopById, + getCustomName, + getDisplayName, + setCustomName, + removeCustomName, + addFavourite, + removeFavourite, + isFavourite, + pushRecent, + getRecent, }; -- cgit v1.3