Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions API_CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ Check back here regularly to stay ahead of removals.
| 2026-03-07 | `StopoverResource.departure` is deprecated → use `departureReal` (if not null) or `departurePlanned` instead | 2026-09-30 | [#4551](https://github.com/Traewelling/traewelling/pull/4551) |
| 2026-03-05 | `StopoverResource.rilIdentifier` is always `null` → use the station identifiers endpoint instead | 2026-09-30 | [#4502](https://github.com/Traewelling/traewelling/pull/4502) |
| 2026-03-05 | `StopoverResource.evaIdentifier` is always `null` → use the station identifiers endpoint instead | 2026-09-30 | [#4502](https://github.com/Traewelling/traewelling/pull/4502) |
| 2026-01-20 | `StatusResource.train` is deprecated → use `checkin` instead | 2026-07-31 | [#4313](https://github.com/Traewelling/traewelling/pull/4313) |
| 2026-01-20 | `StatusResource.userDetails` is deprecated → use `user` instead | 2026-07-31 | [#4313](https://github.com/Traewelling/traewelling/pull/4313) |
| 2026-01-20 | `LightUserResource.mastodonUrl` is always `null` → use `mastodon.server` instead | 2026-07-31 | [#4313](https://github.com/Traewelling/traewelling/pull/4313) |
| 2026-03-20 | `POST /api/v1/report` is deprecated → use `POST /api/v1/reports` instead | 2026-09-30 | [#4602](https://github.com/Traewelling/traewelling/pull/4602) |
| 2026-03-30 | `GET /api/v1/static/privacy` is deprecated -> use `GET /api/v1/privacy-policies/current` instead | 2026-09-30 | [#4650](https://github.com/Traewelling/traewelling/pull/4650) |
| 2026-03-30 | `PUT /api/v1/settings/acceptPrivacy` is deprecated -> use `PUT /api/v1/privacy-policies/accept` instead | 2026-09-30 | [#4650](https://github.com/Traewelling/traewelling/pull/4650) |
Expand All @@ -45,6 +42,16 @@ Check back here regularly to stay ahead of removals.

---

# 2026-09-27

Removed the following deprecated fields, announced on 2026-01-20:

- `StatusResource.train`: use `checkin` instead, it contains the same data
- `StatusResource.userDetails`: use `user` instead, it contains the same data
- `LightUserResource.mastodonUrl`: was always `null`, use `mastodon.server` instead

---

# 2026-09-25

New station identifier type `local_code`: a short code a local transport authority or operator uses for a station.
Expand Down
1 change: 0 additions & 1 deletion app/Http/Resources/LightUserResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ public function toArray($request): array
'server' => $mastodonServer?->domain,
'user_id' => $socialProfile?->mastodon_id,
],
'mastodonUrl' => null, // TODO: remove after 2026-07 (this is not lightweight enough for a LightResource)
'preventIndex' => (bool) $user->prevent_index,
];
}
Expand Down
4 changes: 0 additions & 4 deletions app/Http/Resources/StatusResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@
'isLikable',
'client',
'createdAt',
'train',
'event',
'userDetails',
'tags',
'checkin',
'user',
Expand Down Expand Up @@ -161,8 +159,6 @@ public function toArray($request): array
),
'createdAt' => $this->created_at->toIso8601String(),

'train' => new TransportResource($this->checkin), // TODO: delete after 2026-07 (replaced by 'checkin')
'userDetails' => new LightUserResource($this->user), // TODO: delete after 2026-07 (replaced by 'user')
];
}
}
24 changes: 12 additions & 12 deletions resources/vue/components/ActiveStatusCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,18 @@ export default defineComponent({
},
computed: {
departure() {
const manual = this.state.status?.train?.manualDeparture ?? null;
const manual = this.state.status?.checkin?.manualDeparture ?? null;
if (manual) return DateTime.fromISO(manual);
const dep =
this.state.status?.train?.origin?.departure ?? this.state.status?.train?.origin?.arrival ?? null;
this.state.status?.checkin?.origin?.departure ?? this.state.status?.checkin?.origin?.arrival ?? null;
return DateTime.fromISO(dep);
},
arrival() {
const manual = this.state.status?.train?.manualArrival ?? null;
const manual = this.state.status?.checkin?.manualArrival ?? null;
if (manual) return DateTime.fromISO(manual);
const arr =
this.state.status?.train?.destination?.arrival ??
this.state.status?.train?.destination?.departure ??
this.state.status?.checkin?.destination?.arrival ??
this.state.status?.checkin?.destination?.departure ??
null;
return DateTime.fromISO(arr);
},
Expand Down Expand Up @@ -107,21 +107,21 @@ export default defineComponent({
<div class="card hover-card w-100 shadow-sm" @click="goToStatus">
<div class="card-body py-2 px-3">
<p class="mb-0">
{{ state.status?.train?.origin?.name }}
{{ state.status?.checkin?.origin?.name }}
<small class="float-end text-muted">{{ format(departure) }}</small>
</p>

<p v-show="state.status?.train?.lineName" class="ms-2 col-auto align-items-center d-flex my-0">
<p v-show="state.status?.checkin?.lineName" class="ms-2 col-auto align-items-center d-flex my-0">
<LineIndicator
:product-name="state.status?.train?.category"
:number="state.status?.train?.lineName ?? ''"
:color="state.status?.train?.routeTextColor"
:background-color="state.status?.train?.routeColor"
:product-name="state.status?.checkin?.category"
:number="state.status?.checkin?.lineName ?? ''"
:color="state.status?.checkin?.routeTextColor"
:background-color="state.status?.checkin?.routeColor"
/>
<span v-show="nextStation" class="ms-1">next: {{ nextStation?.name }}</span>
</p>
<p class="mb-0">
{{ state.status?.train?.destination?.name }}
{{ state.status?.checkin?.destination?.name }}
<small class="float-end text-muted">{{ format(arrival) }}</small>
</p>

Expand Down
23 changes: 10 additions & 13 deletions resources/vue/components/CheckinSuccessHelper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ export default {
<p>
{{
trans('checkin.success.body2', {
lineName: status?.train?.lineName ?? '',
distance: ((status?.train?.distance ?? 0) / 1000).toFixed(2).toString(),
origin: status?.train?.origin?.name ?? '',
destination: status?.train?.destination?.name ?? '',
lineName: status?.checkin?.lineName ?? '',
distance: ((status?.checkin?.distance ?? 0) / 1000).toFixed(2).toString(),
origin: status?.checkin?.origin?.name ?? '',
destination: status?.checkin?.destination?.name ?? '',
})
}}
</p>
Expand Down Expand Up @@ -99,28 +99,25 @@ export default {
aria-current="true"
>
<img
:src="connectionStatus.userDetails.profilePicture"
:src="connectionStatus.user.profilePicture"
alt="Profilbild"
class="rounded-circle flex-shrink-0"
style="width: 40px; height: 40px; object-fit: cover"
/>

<div class="d-flex flex-column flex-grow-1">
<h6 class="mb-1 fw-bold opacity-75 text-truncate">
{{ connectionStatus.userDetails.displayName }}
{{ connectionStatus.user.displayName }}
<span
v-if="
connectionStatus.userDetails.displayName !==
connectionStatus.userDetails.username
"
v-if="connectionStatus.user.displayName !== connectionStatus.user.username"
class="text-muted"
>
(@{{ connectionStatus.userDetails.username }})
(@{{ connectionStatus.user.username }})
</span>
</h6>
<p class="mb-0 text-truncate">
{{ connectionStatus?.train?.origin?.name }} ➜
{{ connectionStatus?.train?.destination?.name }}
{{ connectionStatus?.checkin?.origin?.name }} ➜
{{ connectionStatus?.checkin?.destination?.name }}
</p>
</div>
</a>
Expand Down
10 changes: 5 additions & 5 deletions resources/vue/components/Status/Partials/DestinationRow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const stationboardWhen = computed(() => {
<template>
<li>
<i class="trwl-bulletpoint" aria-hidden="true" />
<span class="text-trwl float-end" :class="{ 'cancelled-time': status.train.destination.cancelled }">
<span class="text-trwl float-end" :class="{ 'cancelled-time': status.checkin.destination.cancelled }">
<s v-show="arrival.originalTime" class="text-muted me-1">
{{ arrival.originalTime?.toLocaleString(DateTime.TIME_SIMPLE) }}
</s>
Expand All @@ -51,12 +51,12 @@ const stationboardWhen = computed(() => {
</span>
</span>
<a
:href="`/stationboard?stationId=${status.train.destination.id}&stationName=${status.train.destination.name}&when=${encodeURIComponent(stationboardWhen)}`"
:href="`/stationboard?stationId=${status.checkin.destination.id}&stationName=${status.checkin.destination.name}&when=${encodeURIComponent(stationboardWhen)}`"
class="text-trwl clearfix"
:class="{ 'cancelled-name': status.train.destination.cancelled }"
:class="{ 'cancelled-name': status.checkin.destination.cancelled }"
>
{{ status.train.destination.name }}
<small v-if="status.train.destination.cancelled" class="badge cancelled-badge ms-1">{{
{{ status.checkin.destination.name }}
<small v-if="status.checkin.destination.cancelled" class="badge cancelled-badge ms-1">{{
$t('stationboard.stop-cancelled')
}}</small>
</a>
Expand Down
36 changes: 18 additions & 18 deletions resources/vue/components/Status/Partials/OriginRow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const stationboardWhen = computed(() => {
<template>
<li>
<i class="trwl-bulletpoint" aria-hidden="true" />
<span class="text-trwl float-end" :class="{ 'cancelled-time': status.train.origin.cancelled }">
<span class="text-trwl float-end" :class="{ 'cancelled-time': status.checkin.origin.cancelled }">
<s v-show="arrival.originalTime" class="text-muted me-1">
{{ arrival.originalTime?.toLocaleString(DateTime.TIME_SIMPLE) }}
</s>
Expand All @@ -68,51 +68,51 @@ const stationboardWhen = computed(() => {
</span>

<a
:href="`/stationboard?stationId=${status.train.origin.id}&stationName=${status.train.origin.name}&when=${encodeURIComponent(stationboardWhen)}`"
:href="`/stationboard?stationId=${status.checkin.origin.id}&stationName=${status.checkin.origin.name}&when=${encodeURIComponent(stationboardWhen)}`"
class="text-trwl clearfix"
:class="{ 'cancelled-name': status.train.origin.cancelled }"
:class="{ 'cancelled-name': status.checkin.origin.cancelled }"
>
{{ status.train.origin.name }}
<small v-if="status.train.origin.cancelled" class="badge cancelled-badge ms-1">{{
{{ status.checkin.origin.name }}
<small v-if="status.checkin.origin.cancelled" class="badge cancelled-badge ms-1">{{
$t('stationboard.stop-cancelled')
}}</small>
</a>

<p class="train-status text-muted m-0">
<span class="align-middle">
<ProductIcon :mode="status.train.mode" :product="status.train.category" />
<ProductIcon :mode="status.checkin.mode" :product="status.checkin.category" />

<LineIndicator
class-name="line-badge align-middle line-indicator"
:product-name="status.train.category"
:number="status.train.lineName"
:mode="status.train.mode"
:color="status.train.routeTextColor"
:background-color="status.train.routeColor"
:product-name="status.checkin.category"
:number="status.checkin.lineName"
:mode="status.checkin.mode"
:color="status.checkin.routeTextColor"
:background-color="status.checkin.routeColor"
/>

<small
v-if="status.train.manualJourneyNumber"
v-if="status.checkin.manualJourneyNumber"
data-bs-toggle="tooltip"
data-bs-placement="top"
:title="trans('status.manual_journey_number')"
>
({{ status.train.manualJourneyNumber }})
({{ status.checkin.manualJourneyNumber }})
</small>
<small
v-else-if="
status.train.journeyNumber &&
!status.train.lineName.includes(status.train.journeyNumber.toString())
status.checkin.journeyNumber &&
!status.checkin.lineName.includes(status.checkin.journeyNumber.toString())
"
>
({{ status.train.journeyNumber }})
({{ status.checkin.journeyNumber }})
</small>
</span>

<span class="ps-2">
<i class="fa fa-route d-inline" aria-hidden="true" />&nbsp;
<span v-if="status.train.distance < 1000">{{ status.train.distance }} <small>m</small></span>
<span v-else>{{ (status.train.distance / 1000).toFixed(0) }} <small>km</small></span>
<span v-if="status.checkin.distance < 1000">{{ status.checkin.distance }} <small>m</small></span>
<span v-else>{{ (status.checkin.distance / 1000).toFixed(0) }} <small>km</small></span>
</span>

<span class="ps-2">
Expand Down
Loading
Loading