From ea68e415925946b44fa645bbf3f6087f48fe63cf Mon Sep 17 00:00:00 2001
From: 7222e800-c703-472d-a787-71b6b5cba4ef <mem@estrogen.zone>
Date: Sun, 14 Sep 2025 17:20:55 +0000
Subject: refactor: Move a lot of inline shit out of Timetable.svelte

---
 src/lib/Timetable.svelte | 80 ++++++------------------------------------------
 1 file changed, 10 insertions(+), 70 deletions(-)

(limited to 'src/lib/Timetable.svelte')

diff --git a/src/lib/Timetable.svelte b/src/lib/Timetable.svelte
index f6f4a4e..1ed0900 100644
--- a/src/lib/Timetable.svelte
+++ b/src/lib/Timetable.svelte
@@ -7,6 +7,12 @@
   import Pictogram from './assets/Pictogram.svelte';
   import { Mode, type StoptimesResponse } from './motis-types';
   import { m } from './paraglide/messages';
+  import {
+    blacklistedAgencyURLs,
+    getPictogram,
+    stopTimeShouldRenderGlyph,
+    stopTimeToShortName,
+  } from './RenderUtil';
 
   let relativeSecondPrecision = $derived(
     ['seconds', 'second', 'sec', 'secs', 's', '2'].includes(
@@ -142,7 +148,7 @@
 {#if stopTimes}
   {#each stopTimes.stopTimes
     // garbage data
-    .filter((v) => v.agencyUrl !== 'http://www.rta.ae') as departure}
+    .filter((v) => !blacklistedAgencyURLs.includes(v.agencyUrl)) as departure}
     {@const expectedTime =
       new Date(
         (isArrivals
@@ -159,74 +165,8 @@
       1000 /
       60}
     {@const delayMinutes = receivedTime - expectedTime}
-    {@const avoidGlyph = departure.routeShortName.startsWith('FlixTrain')}
-    {@const routeShortName = (() => {
-      let n = departure.routeShortName;
-      if (n.startsWith('EC ')) n = n.replace('EC ', 'EC');
-      if (departure.mode === 'TRAM' && !isNaN(parseInt(n))) n = 'T ' + n;
-      if (departure.mode === 'BUS' && !isNaN(parseInt(n))) n = 'B ' + n;
-      if (
-        departure.routeShortName === 'European Sleeper' &&
-        departure.agencyName === 'Eu Sleeper'
-      )
-        n = 'EN'; // TODO: validate these are real euronights
-      if (n === '?') n = '';
-      if (n.startsWith('FlixTrain ')) n = n.substring(10);
-      // Note: may also catch ECs/ICs/EXTs operated by DB
-      if (
-        departure.agencyId === '12681' &&
-        departure.agencyName === 'DB Fernverkehr AG' &&
-        departure.mode === 'HIGHSPEED_RAIL' &&
-        departure.source.startsWith('de_DELFI.gtfs.zip/') &&
-        !isNaN(parseInt(n))
-      )
-        n = `ICE ${n}`;
-      return n;
-    })()}
-    {@const pictogram = (() => {
-      switch (true) {
-        case departure.mode === Mode.Bike:
-          return 'Velo_l';
-        case departure.mode === Mode.ODM:
-        case departure.mode === Mode.Rental:
-          return 'Taxi_l';
-        case departure.mode === Mode.Car:
-        case departure.mode === Mode.CarDropoff:
-        case departure.mode === Mode.CarParking:
-          return 'Auto_l';
-
-        // Transit //
-        case departure.mode === Mode.Airplane:
-          return 'Abflug_l';
-        case departure.mode === Mode.LongDistanceRail:
-        case departure.mode === Mode.RegionalFastRail:
-        case departure.mode === Mode.RegionalRail:
-        case departure.mode === Mode.Metro:
-        case departure.mode === Mode.HighspeedRail:
-          return 'Zug_l';
-        case departure.mode === Mode.NightRail:
-          return 'Schlafwagen';
-        case departure.mode === Mode.Subway:
-          return 'Metro_l_' + (m.lang_short() === 'en' ? 'de' : m.lang_short());
-        case departure.mode === Mode.Bus:
-          return 'Bus_l';
-        case departure.mode === Mode.Coach:
-          return 'Fernbus_l';
-        case departure.mode === Mode.Tram:
-        case departure.mode === Mode.CableTram:
-          return 'Tram_l';
-        case departure.mode === Mode.Funicular:
-          return 'Zahnradbahn_l';
-        case departure.mode === Mode.AerialLift:
-          // return 'Gondelbahn_l';
-          return 'Luftseilbahn_l';
-        case departure.mode === Mode.Ferry:
-          return 'Schiff_l';
-        case departure.mode === Mode.Other:
-        default:
-          return 'Licht';
-      }
-    })()}
+    {@const routeShortName = stopTimeToShortName(departure)}
+    {@const pictogram = getPictogram(departure.mode)}
     {@const notices = (() => {
       let notices = [] as [pictogram: string[], content: string][];
       if (departure.cancelled)
@@ -267,7 +207,7 @@
           {#if pictogram}
             <Pictogram which={pictogram} />
           {/if}
-          {#if ([Mode.NightRail, Mode.HighspeedRail, Mode.LongDistanceRail, Mode.RegionalFastRail, Mode.RegionalRail].includes(departure.mode) || (departure.mode === 'BUS' && routeShortName.startsWith('EV')) || (departure.mode === 'METRO' && departure.routeShortName.startsWith('S'))) && !avoidGlyph}
+          {#if stopTimeShouldRenderGlyph(departure, routeShortName)}
             <LineGlyph
               currentColor="#fff"
               kind={routeShortName}
-- 
cgit v1.2.3

