Skip to content

Commit

Permalink
feat: Adding new ConnectionDetails.svelte component and helper files …
Browse files Browse the repository at this point in the history
…from motis/ui (#52)

* feat: implementation of ConnectionDetail.svelte and helper files

* feat: minor style changes & language removal & checking for undefined Itineraries in itinerary ov altered

- removed unnecessary languages like de, pl, fr and more
- scaled down logo by a bit
- checking for undefined itineraries in itinerary ov now happens through checking length and amount of legs

* chore: reordering of files from lib into ui folder

* chore: remove old "Leg" class

* chore: add documentation for helper methods / components
  • Loading branch information
MoPhliFra authored Feb 16, 2025
1 parent 4e2d229 commit b630c09
Show file tree
Hide file tree
Showing 15 changed files with 885 additions and 35 deletions.
93 changes: 93 additions & 0 deletions visual-debugger/src/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,98 @@
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>

<svg style="display: none">
<symbol id="train" viewBox="0 0 24 24">
<path
d="M4,15.5C4,17.43 5.57,19 7.5,19L6,20.5v0.5h12v-0.5L16.5,19c1.93,0 3.5,-1.57 3.5,-3.5L20,5c0,-3.5 -3.58,-4 -8,-4s-8,0.5 -8,4v10.5zM12,17c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2zM18,10L6,10L6,5h12v5z"
/>
</symbol>
<symbol id="sbahn" viewBox="0 0 64 64">
<path
d="M 23.9104,17.8176 c 0,-2.7648 2.5344,-5.1456 7.0144,-5.1456 7.8592,0
14.5408,4.224 19.0208,9.0368 l 0,-8.3968 C 44.8,9.3184 38.2976,6.9376
31.0784,6.9376 c -8.6784,0 -18.3296,5.3248 -18.3296,15.232 0,18.8672
28.6208,12.1088 28.6208,23.0144 0,2.9184 -3.7888,5.632 -8.576,5.632 -7.7312,0
-15.4368,-4.7104 -19.6608,-10.7776 l 0,10.0864 c 4.48,3.9936 12.6208,7.168
19.6608,7.168 12.672,0 20.1984,-9.0368 20.1984,-16.768 0,-19.2512
-29.0816,-11.008 -29.0816,-22.7072 z"
/>
</symbol>
<symbol id="ubahn" viewBox="0 0 500 500">
<path
d="M269.02771 462.03556C301.49095 458.86693 331.81940 448.53888 355.90324
432.45098C368.00616 424.36627 385.07594 407.62587 392.49694 396.56338C403.34218
380.39638 411.21817 360.97199 415.43165 340C417.06374 331.87653 417.26314
317.60376 417.59707 185L417.96486 38.947368L317.89474 38.947368L317.89474
172.67306C317.89474 260.58200 317.50921 309.85624 316.76948 316.49013C315.44428
328.37460 311.53547 342.57976 307.56662 349.93462C302.58644 359.16362 293.39802
367.94547 283.81131 372.63882C257.43623 385.55122 218.84256 380.90205 200.54920
362.60869C191.23263 353.29213 184.83222 338.29015 182.14617 319.47368C181.48964
314.87452 181.08649 260.77515 181.07348 175.52632L181.05263 38.947368L82.105263
38.947368L82.105263 177.25689C82.105263 316.01926 82.371267 327.73304 85.920452
345.26316C94.686023 388.55802 121.69624 423.01667 163.04724 443.65869C193.35569
458.78839 232.59204 465.59192 269.02771 462.03556Z"
/>
</symbol>
<symbol id="tram" viewBox="0 0 24 24">
<path
d="M17,18C16.4,18 16,17.6 16,17C16,16.4 16.4,16 17,16C17.6,16 18,16.4 18,17C18,17.6 17.6,18 17,18M6.7,10.7L7,7.3C7,6.6 7.6,6 8.3,6H15.6C16.4,6 17,6.6 17,7.3L17.3,10.6C17.3,11.3 16.7,11.9 16,11.9H8C7.3,12 6.7,11.4 6.7,10.7M7,18C6.4,18 6,17.6 6,17C6,16.4 6.4,16 7,16C7.6,16 8,16.4 8,17C8,17.6 7.6,18 7,18M19,6A2,2 0 0,0 17,4H15A2,2 0 0,0 13,2H11A2,2 0 0,0 9,4H7A2,2 0 0,0 5,6L4,18A2,2 0 0,0 6,20H8L7,22H17.1L16.1,20H18A2,2 0 0,0 20,18L19,6Z"
/>
</symbol>
<symbol id="bus" viewBox="0 0 24 24">
<path
d="M4,16c0,0.88 0.39,1.67 1,2.22L5,20c0,0.55 0.45,1 1,1h1c0.55,0 1,-0.45 1,-1v-1h8v1c0,0.55 0.45,1 1,1h1c0.55,0 1,-0.45 1,-1v-1.78c0.61,-0.55 1,-1.34 1,-2.22L20,6c0,-3.5 -3.58,-4 -8,-4s-8,0.5 -8,4v10zM7.5,17c-0.83,0 -1.5,-0.67 -1.5,-1.5S6.67,14 7.5,14s1.5,0.67 1.5,1.5S8.33,17 7.5,17zM16.5,17c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5 1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5zM18,11L6,11L6,6h12v5z"
/>
</symbol>
<symbol id="walk" viewBox="0 0 24 24">
<path
d="M13.5 5.5c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zM9.8 8.9L7 23h2.1l1.8-8 2.1 2v6h2v-7.5l-2.1-2 .6-3C14.8 12 16.8 13 19 13v-2c-1.9 0-3.5-1-4.3-2.4l-1-1.6c-.4-.6-1-1-1.7-1-.3 0-.5.1-.8.1L6 8.3V13h2V9.6l1.8-.7"
/>
</symbol>
<symbol id="bike" viewBox="0 0 24 24">
<path d="M0 0h24v24H0z" fill="none" />
<path
d="M15.5 5.5c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zM5 12c-2.8 0-5 2.2-5 5s2.2 5 5 5 5-2.2 5-5-2.2-5-5-5zm0 8.5c-1.9 0-3.5-1.6-3.5-3.5s1.6-3.5 3.5-3.5 3.5 1.6 3.5 3.5-1.6 3.5-3.5 3.5zm5.8-10l2.4-2.4.8.8c1.3 1.3 3 2.1 5.1 2.1V9c-1.5 0-2.7-.6-3.6-1.5l-1.9-1.9c-.5-.4-1-.6-1.6-.6s-1.1.2-1.4.6L7.8 8.4c-.4.4-.6.9-.6 1.4 0 .6.2 1.1.6 1.4L11 14v5h2v-6.2l-2.2-2.3zM19 12c-2.8 0-5 2.2-5 5s2.2 5 5 5 5-2.2 5-5-2.2-5-5-5zm0 8.5c-1.9 0-3.5-1.6-3.5-3.5s1.6-3.5 3.5-3.5 3.5 1.6 3.5 3.5-1.6 3.5-3.5 3.5z"
/>
</symbol>
<symbol id="cargo_bike" viewBox="0 0 24 24">
<path
fill="currentColor"
d="M21 11.5V10l-7.5-1V5H9v1.5h3v7.8h-1L9 10c.3-.1.5-.4.5-.7c0-.4-.3-.8-.7-.8h-2c-.5 0-.8.3-.8.7s.3.8.8.8h.6l2 4.2H7.9C7.6 12.4 6 11 4 11c-2.2 0-4 1.8-4 4s1.8 4 4 4c2 0 3.6-1.4 3.9-3.2h8.6c.2-2.4 2.1-4.3 4.5-4.3M6.4 15.8c-.3 1-1.3 1.8-2.4 1.8c-1.4 0-2.5-1.1-2.5-2.5s1.1-2.5 2.5-2.5c1.1 0 2.1.7 2.4 1.8H4v1.5h2.4M21 13c-1.7 0-3 1.3-3 3s1.3 3 3 3s3-1.3 3-3s-1.3-3-3-3m0 4.5c-.8 0-1.5-.7-1.5-1.5s.7-1.5 1.5-1.5s1.5.7 1.5 1.5s-.7 1.5-1.5 1.5"
/>
</symbol>
<symbol id="scooter" viewBox="0 0 24 24">
<path
fill="currentColor"
d="M7.82 19H15v-1c0-2.21 1.79-4 4-4h.74l-1.9-8.44A2.01 2.01 0 0 0 15.89 4H12v2h3.89l1.4 6.25h-.01A6.01 6.01 0 0 0 13.09 17H7.82a2.996 2.996 0 0 0-3.42-1.94c-1.18.23-2.13 1.2-2.35 2.38A3.002 3.002 0 0 0 5 21c1.3 0 2.4-.84 2.82-2M5 19c-.55 0-1-.45-1-1s.45-1 1-1s1 .45 1 1s-.45 1-1 1m14-4c-1.66 0-3 1.34-3 3s1.34 3 3 3s3-1.34 3-3s-1.34-3-3-3m0 4c-.55 0-1-.45-1-1s.45-1 1-1s1 .45 1 1s-.45 1-1 1"
/>
</symbol>
<symbol id="moped" viewBox="0 0 24 24">
<path
fill="currentColor"
d="M19 15c.55 0 1 .45 1 1s-.45 1-1 1s-1-.45-1-1s.45-1 1-1m0-2c-1.66 0-3 1.34-3 3s1.34 3 3 3s3-1.34 3-3s-1.34-3-3-3m-9-7H5v2h5zm7-1h-3v2h3v2.65L13.5 14H10V9H6c-2.21 0-4 1.79-4 4v3h2c0 1.66 1.34 3 3 3s3-1.34 3-3h4.5l4.5-5.65V7a2 2 0 0 0-2-2M7 17c-.55 0-1-.45-1-1h2c0 .55-.45 1-1 1"
/>
</symbol>
<symbol id="car" viewBox="0 0 24 24">
<path
d="M18.92 6.01C18.72 5.42 18.16 5 17.5 5h-11c-.66 0-1.21.42-1.42 1.01L3 12v8c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-1h12v1c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-8l-2.08-5.99zM6.5 16c-.83 0-1.5-.67-1.5-1.5S5.67 13 6.5 13s1.5.67 1.5 1.5S7.33 16 6.5 16zm11 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zM5 11l1.5-4.5h11L19 11H5z"
/>
<path d="M0 0h24v24H0z" fill="none" />
</symbol>
<symbol id="ship" viewBox="0 0 24 24">
<path d="M0 0h24v24H0z" fill="none" />
<path
d="M20 21c-1.39 0-2.78-.47-4-1.32-2.44 1.71-5.56 1.71-8 0C6.78 20.53 5.39 21 4 21H2v2h2c1.38 0 2.74-.35 4-.99 2.52 1.29 5.48 1.29 8 0 1.26.65 2.62.99 4 .99h2v-2h-2zM3.95 19H4c1.6 0 3.02-.88 4-2 .98 1.12 2.4 2 4 2s3.02-.88 4-2c.98 1.12 2.4 2 4 2h.05l1.89-6.68c.08-.26.06-.54-.06-.78s-.34-.42-.6-.5L20 10.62V6c0-1.1-.9-2-2-2h-3V1H9v3H6c-1.1 0-2 .9-2 2v4.62l-1.29.42c-.26.08-.48.26-.6.5s-.15.52-.06.78L3.95 19zM6 6h12v3.97L12 8 6 9.97V6z"
/>
</symbol>
<symbol id="plane" viewBox="0 0 24 24">
<path d="M0 0h24v24H0z" fill="none" />
<path
d="M21 16v-2l-8-5V3.5c0-.83-.67-1.5-1.5-1.5S10 2.67 10 3.5V9l-8 5v2l8-2.5V19l-2 1.5V22l3.5-1 3.5 1v-1.5L13 19v-5.5l8 2.5z"
/>
</symbol>
</svg>

</body>
</html>
176 changes: 164 additions & 12 deletions visual-debugger/src/data-processing/type-declarations/planTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,35 +42,187 @@ export class Itinerary {
transfers: number = 0;
legs: Leg[] = new Array<Leg>();
cssClass: string = cssClasses.planEntryDefault;
match: boolean = false;
index: number = 0;
}

/**
* Leg type used for parsing plan responses
*/

export class Leg {
mode: string = "";
/**
* Transport mode for this leg
*/
mode: Mode = 'WALK';
from: Place = new Place();
to: Place = new Place();
/**
* Leg duration in seconds
*
* If leg is footpath:
* The footpath duration is derived from the default footpath
* duration using the query parameters `transferTimeFactor` and
* `additionalTransferTime` as follows:
* `leg.duration = defaultDuration * transferTimeFactor + additionalTransferTime.`
* In case the defaultDuration is needed, it can be calculated by
* `defaultDuration = (leg.duration - additionalTransferTime) / transferTimeFactor`.
* Note that the default values are `transferTimeFactor = 1` and
* `additionalTransferTime = 0` in case they are not explicitly
* provided in the query.
*
*/
duration: number = 0;
/**
* leg departure time
*/
startTime: string = "";
/**
* leg arrival time
*/
endTime: string = "";
/**
* scheduled leg departure time
*/
scheduledStartTime: string = "";
/**
* scheduled leg arrival time
*/
scheduledEndTime: string = "";
/**
* Whether there is real-time data about this leg
*/
realTime: boolean = true;
/**
* For non-transit legs the distance traveled while traversing this leg in meters.
*/
distance?: number = 0;
/**
* For transit legs, if the rider should stay on the vehicle as it changes route names.
*/
interlineWithPreviousLeg?: boolean = true;
/**
* For transit legs, the headsign of the bus or train being used.
* For non-transit legs, null
*
*/
headsign?: string = "";
routeColor?: string = "";
routeTextColor?: string = "";
routeType?: string = "";
agencyName?: string = "";
agencyUrl?: string = "";
agencyId?: string = "";
tripId?: string = "";
routeShortName?: string = "";
/**
* Filename and line number where this trip is from
*/
source?: string = "";
/**
* For transit legs, intermediate stops between the Place where the leg originates
* and the Place where the leg ends. For non-transit legs, null.
*
*/
intermediateStops?: Array<Place>;
legGeometry: EncodedPolyline = new EncodedPolyline();
headsign: string = "";
routeShortName: string = "";
intermediateStops: Array<Place> = new Array<Place>();
source: string = "";
tripId: string = "";
}
/**
* A series of turn by turn instructions
* used for walking, biking and driving.
*
*/
steps?: Array<StepInstruction>;
rental?: Rental;
};

export type Mode = 'WALK' | 'BIKE' | 'RENTAL' | 'CAR' | 'CAR_PARKING' | 'TRANSIT' | 'TRAM' | 'SUBWAY' | 'FERRY' | 'AIRPLANE' | 'METRO' | 'BUS' | 'COACH' | 'RAIL' | 'HIGHSPEED_RAIL' | 'LONG_DISTANCE' | 'NIGHT_RAIL' | 'REGIONAL_FAST_RAIL' | 'REGIONAL_RAIL' | 'OTHER';

export type RentalFormFactor = 'BICYCLE' | 'CARGO_BICYCLE' | 'CAR' | 'MOPED' | 'SCOOTER_STANDING' | 'SCOOTER_SEATED' | 'OTHER';

export type RentalPropulsionType = 'HUMAN' | 'ELECTRIC_ASSIST' | 'ELECTRIC' | 'COMBUSTION' | 'COMBUSTION_DIESEL' | 'HYBRID' | 'PLUG_IN_HYBRID' | 'HYDROGEN_FUEL_CELL';

export type RentalReturnConstraint = 'NONE' | 'ANY_STATION' | 'ROUNDTRIP_STATION';

export type Direction = 'DEPART' | 'HARD_LEFT' | 'LEFT' | 'SLIGHTLY_LEFT' | 'CONTINUE' | 'SLIGHTLY_RIGHT' | 'RIGHT' | 'HARD_RIGHT' | 'CIRCLE_CLOCKWISE' | 'CIRCLE_COUNTERCLOCKWISE' | 'STAIRS' | 'ELEVATOR' | 'UTURN_LEFT' | 'UTURN_RIGHT';

/**
* EncodedPolyline type used for parsing plan responses
*/
export class EncodedPolyline {
points: string = "";
length: number = 0;
}
}

export type StepInstruction = {
relativeDirection: Direction;
/**
* The distance in meters that this step takes.
*/
distance: number;
/**
* level where this segment starts, based on OpenStreetMap data
*/
fromLevel: number;
/**
* level where this segment starts, based on OpenStreetMap data
*/
toLevel: number;
/**
* OpenStreetMap way index
*/
osmWay?: number;
polyline: EncodedPolyline;
/**
* The name of the street.
*/
streetName: string;
/**
* Not implemented!
* When exiting a highway or traffic circle, the exit name/number.
*
*/
exit: string;
/**
* Not implemented!
* Indicates whether or not a street changes direction at an intersection.
*
*/
stayOn: boolean;
/**
* Not implemented!
* This step is on an open area, such as a plaza or train platform,
* and thus the directions should say something like "cross"
*
*/
area: boolean;
};

export type Rental = {
/**
* Vehicle share system ID
*/
systemId: string;
/**
* Vehicle share system name
*/
systemName?: string;
/**
* URL of the vehicle share system
*/
url?: string;
/**
* Name of the station
*/
stationName?: string;
/**
* Rental URI for Android (deep link to the specific station or vehicle)
*/
rentalUriAndroid?: string;
/**
* Rental URI for iOS (deep link to the specific station or vehicle)
*/
rentalUriIOS?: string;
/**
* Rental URI for web (deep link to the specific station or vehicle)
*/
rentalUriWeb?: string;
formFactor?: RentalFormFactor;
propulsionType?: RentalPropulsionType;
returnConstraint?: RentalReturnConstraint;
};
56 changes: 56 additions & 0 deletions visual-debugger/src/lib/Time.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<!--
Component to display formatted time based on provided timestamps and variant.
Props:
- class (optional): Additional CSS classes to apply to the component.
- timestamp (string): The timestamp to be displayed.
- scheduledTimestamp (string): The scheduled timestamp for comparison.
- isRealtime (boolean): Flag indicating if the time is in real-time.
- variant ('schedule' | 'realtime' | 'realtime-show-always'): Determines which time to display and under what conditions.
Derived values:
- t: Date object derived from the provided timestamp.
- scheduled: Date object derived from the scheduled timestamp.
- delayMinutes: The difference in minutes between the timestamp and the scheduled timestamp.
- highDelay: Boolean indicating if the delay is more than 3 minutes and is in real-time.
- lowDelay: Boolean indicating if the delay is 3 minutes or less and is in real-time.
Conditional rendering:
- If variant is 'schedule', the scheduled time is displayed.
- If variant is 'realtime-show-always' or (variant is 'realtime' and isRealtime is true), the real-time is displayed with conditional styling based on delay.
-->
<script lang="ts">
import { formatTime } from './toDateTime';
import { cn } from './utils';
let {
class: className,
timestamp,
scheduledTimestamp,
isRealtime,
variant
}: {
class?: string;
timestamp: string;
scheduledTimestamp: string;
isRealtime: boolean;
variant: 'schedule' | 'realtime' | 'realtime-show-always';
} = $props();
const t = $derived(new Date(timestamp));
const scheduled = $derived(new Date(scheduledTimestamp));
const delayMinutes = $derived((t.getTime() - scheduled.getTime()) / 60000);
const highDelay = $derived(isRealtime && delayMinutes > 3);
const lowDelay = $derived(isRealtime && delayMinutes <= 3);
</script>

<div class={cn('text-nowrap', className)}>
{#if variant == 'schedule'}
{formatTime(scheduled)}
{:else if variant === 'realtime-show-always' || (variant === 'realtime' && isRealtime)}
<div class:text-destructive={highDelay} class:text-green-600={lowDelay}>
{formatTime(t)}
</div>
{/if}
</div>
Loading

0 comments on commit b630c09

Please sign in to comment.