From 01a03622fbb4eab3bdcbf746834011e3401d86f9 Mon Sep 17 00:00:00 2001 From: Spythere Date: Wed, 29 Jun 2022 00:19:17 +0200 Subject: [PATCH] Dodano informacje o poc. offline --- src/App.vue | 8 +- .../SceneryInfo/SceneryInfoUserList.vue | 9 +- src/components/TrainsView/TrainInfo.vue | 4 + src/locales/en.json | 6 +- src/locales/pl.json | 7 +- src/mixins/trainInfoMixin.ts | 219 +++++++++--------- src/scripts/interfaces/Train.ts | 1 + src/store/store.ts | 12 +- 8 files changed, 147 insertions(+), 119 deletions(-) diff --git a/src/App.vue b/src/App.vue index 3ce9988..0cb897a 100644 --- a/src/App.vue +++ b/src/App.vue @@ -37,7 +37,7 @@ icon dispatcher {{ onlineDispatchers.length }} / - {{ store.trainList.length }} + {{ trainList.length }} icon train @@ -125,6 +125,12 @@ export default defineComponent({ }; }, + computed: { + trainList() { + return this.store.trainList.filter(train => train.online); + } + }, + data: () => ({ VERSION: packageInfo.version, updateModalVisible: false, diff --git a/src/components/SceneryView/SceneryInfo/SceneryInfoUserList.vue b/src/components/SceneryView/SceneryInfo/SceneryInfoUserList.vue index 949d4fa..49725d9 100644 --- a/src/components/SceneryView/SceneryInfo/SceneryInfoUserList.vue +++ b/src/components/SceneryView/SceneryInfo/SceneryInfoUserList.vue @@ -3,7 +3,8 @@

icon-user  {{ $t('scenery.users') }}   - {{ station.onlineInfo?.currentUsers || '0' }} / {{ station.onlineInfo?.maxUsers || '0' }} + {{ station.onlineInfo?.currentUsers || '0' }} / {{ station.onlineInfo?.maxUsers || '0' }}

{ + const computedStationTrains = computed(() => { if (!props.station) return []; const station = props.station as Station; @@ -49,9 +50,7 @@ export default defineComponent({ if (!station.onlineInfo.stationTrains) return []; return station.onlineInfo.stationTrains.map((train) => { - const scheduledTrainStatus = station.onlineInfo?.scheduledTrains?.find( - (st) => st.trainNo === train.trainNo - ); + const scheduledTrainStatus = station.onlineInfo?.scheduledTrains?.find((st) => st.trainNo === train.trainNo); return { ...train, diff --git a/src/components/TrainsView/TrainInfo.vue b/src/components/TrainsView/TrainInfo.vue index ecf2e2f..7903e2a 100644 --- a/src/components/TrainsView/TrainInfo.vue +++ b/src/components/TrainsView/TrainInfo.vue @@ -61,6 +61,10 @@
+
+ Offline - {{ lastSeenMessage(train.lastSeen) }} +
+
{{ $t('trains.current-scenery') }} {{ train['currentStationName'] }}  diff --git a/src/locales/en.json b/src/locales/en.json index 3e66830..e86bf69 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -181,7 +181,11 @@ "loco-diesel": "Diesel locomotive", "timetable-comments": "Exploitation comments available for this train", "comment": "Exploitation comments for: ", - "table-limit": "For performance reasons there's a limit of 10 trains shown at the same time." + "table-limit": "For performance reasons there's a limit of 10 trains shown at the same time.", + + "last-seen-now": "last seen: just now", + "last-seen-min": "last seen: one minute ago", + "last-seen-ago": "last seen: {minutes} mins ago" }, "journal": { "title": "DISPATCHER HISTORY", diff --git a/src/locales/pl.json b/src/locales/pl.json index 503b2b6..2b76150 100644 --- a/src/locales/pl.json +++ b/src/locales/pl.json @@ -161,7 +161,6 @@ "filter-noTimetable": "bez RJ", "filter-reset": "X RESETUJ", - "sorter-prefix": "Sortuj: ", "search-train": "Numer pociągu", "search-driver": "Nick maszynisty", @@ -183,7 +182,11 @@ "loco-diesel": "Spalinowóz", "timetable-comments": "Pociąg z uwagami eksploatacyjnymi", "comment": "Uwagi eksploatacyjne dla: ", - "table-limit": "Dla płynności działania strony pokazanych jest tylko 10 pociągów zgodnie z wybranymi filtrami." + "table-limit": "Dla płynności działania strony pokazanych jest tylko 10 pociągów zgodnie z wybranymi filtrami.", + + "last-seen-now": "ostatnio widziany: przed chwilą", + "last-seen-min": "ostatnio widziany: minutę temu", + "last-seen-ago": "ostatnio widziany: {minutes} min. temu" }, "journal": { "title": "HISTORIA DYŻURÓW", diff --git a/src/mixins/trainInfoMixin.ts b/src/mixins/trainInfoMixin.ts index cd1f452..3ae046e 100644 --- a/src/mixins/trainInfoMixin.ts +++ b/src/mixins/trainInfoMixin.ts @@ -1,117 +1,128 @@ -import Train from "@/scripts/interfaces/Train"; -import TrainStop from "@/scripts/interfaces/TrainStop"; -import { defineComponent } from "vue"; +import Train from '@/scripts/interfaces/Train'; +import TrainStop from '@/scripts/interfaces/TrainStop'; +import { defineComponent } from 'vue'; export default defineComponent({ - data: () => ({ - STATS: { - main: [ - { - name: 'speed', - unit: 'km/h', - }, - { - name: 'length', - unit: 'm', - }, - { - name: 'mass', - unit: 't', - multiplier: 0.001, - }, - ], - - position: [ - { - name: 'scenery', - prop: 'currentStationName', - }, - { - name: 'route', - prop: 'connectedTrack', - }, - { - name: 'signal', - prop: 'signal', - }, - { - name: 'distance', - prop: 'distance', - unit: 'm', - }, - ], + data: () => ({ + STATS: { + main: [ + { + name: 'speed', + unit: 'km/h', }, - }), - - methods: { - displayStopList(stops: TrainStop[]): string | undefined { - if (!stops) return ''; - - return stops - .reduce((acc: string[], stop: TrainStop, i: number) => { - if (stop.stopType.includes('ph') && !stop.stopNameRAW.includes('po.')) - acc.push(`${stop.stopName}`); - else if ( - i > 0 && - i < stops.length - 1 && - !stop.stopNameRAW.includes('po.') && - !stop.stopNameRAW.includes('SBL') - ) - acc.push(`${stop.stopName}`); - return acc; - }, []) - .join(' > '); + { + name: 'length', + unit: 'm', }, - - currentDistance(stops: TrainStop[]) { - return stops.filter(stop => stop.confirmed).slice(-1)[0]?.stopDistance || 0; + { + name: 'mass', + unit: 't', + multiplier: 0.001, }, + ], - confirmedPercentage(stops: TrainStop[]) { - return Number(((stops.filter((stop) => stop.confirmed).length / stops.length) * 100).toFixed(0)); + position: [ + { + name: 'scenery', + prop: 'currentStationName', }, - - currentDelay(stops: TrainStop[]) { - const delay = - stops.find((stop, i) => (i == 0 && !stop.confirmed) || (i > 0 && stops[i - 1].confirmed && !stop.confirmed)) - ?.departureDelay || 0; - - if (delay > 0) return `${this.$t('trains.delayed')} ${delay} min`; - else if (delay < 0) return `${this.$t('trains.preponed')} ${delay} min`; - else return this.$t('trains.on-time'); + { + name: 'route', + prop: 'connectedTrack', }, - - displayLocoInfo(locoType: string) { - if (locoType.includes('EN')) return `${this.$t('trains.EZT')}`; - if (locoType.includes('SN')) return `${this.$t('trains.SZT')}`; - if (locoType.startsWith('E')) return `${this.$t('trains.loco-electric')}`; - if (locoType.startsWith('S')) return `${this.$t('trains.loco-diesel')}`; - - return ''; + { + name: 'signal', + prop: 'signal', }, - - getSceneriesWithComments(timetableData: Train['timetableData']) { - const commentList = timetableData?.followingStops.reduce((acc, stop, i) => { - if (stop.comments) acc.push(stop.stopNameRAW); - - return acc; - }, [] as string[]) || [] - - const moreCount = commentList.length - 10; - - - return commentList.slice(0, 10).join(", ") + (moreCount > 0 ? `... (+${moreCount})` : ''); + { + name: 'distance', + prop: 'distance', + unit: 'm', }, + ], + }, + }), - displayDistance(distance: number) { - if (distance < 1000) return `${distance}m`; + methods: { + lastSeenMessage(timestamp: number) { + const diff = Date.now() - timestamp; + const diffMins = Math.floor(diff / 60000); - return `${(distance / 1000).toPrecision(2)}km`; - }, + return diffMins < 1 + ? this.$t('trains.last-seen-now') + : diffMins < 2 + ? this.$t('trains.last-seen-min') + : this.$t('trains.last-seen-ago', { minutes: diffMins }); + }, - onImageError(e: Event) { - const imageEl = e.target as HTMLImageElement; - imageEl.src = require('@/assets/unknown.png'); - } - } -}) \ No newline at end of file + displayStopList(stops: TrainStop[]): string | undefined { + if (!stops) return ''; + + return stops + .reduce((acc: string[], stop: TrainStop, i: number) => { + if (stop.stopType.includes('ph') && !stop.stopNameRAW.includes('po.')) + acc.push(`${stop.stopName}`); + else if ( + i > 0 && + i < stops.length - 1 && + !stop.stopNameRAW.includes('po.') && + !stop.stopNameRAW.includes('SBL') + ) + acc.push(`${stop.stopName}`); + return acc; + }, []) + .join(' > '); + }, + + currentDistance(stops: TrainStop[]) { + return stops.filter((stop) => stop.confirmed).slice(-1)[0]?.stopDistance || 0; + }, + + confirmedPercentage(stops: TrainStop[]) { + return Number(((stops.filter((stop) => stop.confirmed).length / stops.length) * 100).toFixed(0)); + }, + + currentDelay(stops: TrainStop[]) { + const delay = + stops.find((stop, i) => (i == 0 && !stop.confirmed) || (i > 0 && stops[i - 1].confirmed && !stop.confirmed)) + ?.departureDelay || 0; + + if (delay > 0) return `${this.$t('trains.delayed')} ${delay} min`; + else if (delay < 0) return `${this.$t('trains.preponed')} ${delay} min`; + else return this.$t('trains.on-time'); + }, + + displayLocoInfo(locoType: string) { + if (locoType.includes('EN')) return `${this.$t('trains.EZT')}`; + if (locoType.includes('SN')) return `${this.$t('trains.SZT')}`; + if (locoType.startsWith('E')) return `${this.$t('trains.loco-electric')}`; + if (locoType.startsWith('S')) return `${this.$t('trains.loco-diesel')}`; + + return ''; + }, + + getSceneriesWithComments(timetableData: Train['timetableData']) { + const commentList = + timetableData?.followingStops.reduce((acc, stop, i) => { + if (stop.comments) acc.push(stop.stopNameRAW); + + return acc; + }, [] as string[]) || []; + + const moreCount = commentList.length - 10; + + return commentList.slice(0, 10).join(', ') + (moreCount > 0 ? `... (+${moreCount})` : ''); + }, + + displayDistance(distance: number) { + if (distance < 1000) return `${distance}m`; + + return `${(distance / 1000).toPrecision(2)}km`; + }, + + onImageError(e: Event) { + const imageEl = e.target as HTMLImageElement; + imageEl.src = require('@/assets/unknown.png'); + }, + }, +}); diff --git a/src/scripts/interfaces/Train.ts b/src/scripts/interfaces/Train.ts index 4d11c31..a01b470 100644 --- a/src/scripts/interfaces/Train.ts +++ b/src/scripts/interfaces/Train.ts @@ -15,6 +15,7 @@ export default interface Train { locoURL: string; locoType: string; online: boolean; + lastSeen: number; region: string; cars: string[]; diff --git a/src/store/store.ts b/src/store/store.ts index 80bb84a..9e33a5c 100644 --- a/src/store/store.ts +++ b/src/store/store.ts @@ -1,11 +1,8 @@ import { DataStatus } from '@/scripts/enums/DataStatus'; -import { DispatcherStatsAPIData } from '@/scripts/interfaces/api/DispatcherStatsAPIData'; import StationAPIData from '@/scripts/interfaces/api/StationAPIData'; -import TrainAPIData from '@/scripts/interfaces/api/TrainAPIData'; import ScheduledTrain from '@/scripts/interfaces/ScheduledTrain'; import Station from '@/scripts/interfaces/Station'; import StationRoutes from '@/scripts/interfaces/StationRoutes'; -import { StoreData } from '@/scripts/interfaces/StoreData'; import Train from '@/scripts/interfaces/Train'; import { URLs } from '@/scripts/utils/apiURLs'; import { @@ -62,7 +59,10 @@ export const useStore = defineStore('store', { if (!trains) return []; this.trainList = trains - .filter((train) => train.region === this.region.id) + .filter( + (train) => + train.region === this.region.id && (train.online || train.timetable || train.lastSeen > Date.now() - 180000) + ) .map((train) => { const stock = train.stockString.split(';'); const locoType = stock ? stock[0] : train.stockString; @@ -88,6 +88,8 @@ export const useStore = defineStore('store', { locoURL: getLocoURL(locoType), cars: stock.slice(1), + lastSeen: train.lastSeen, + timetableData: timetable ? { timetableId: timetable.timetableId, @@ -206,7 +208,6 @@ export const useStore = defineStore('store', { const prevDispatcherStatuses: StoreState['lastDispatcherStatuses'] = []; this.apiData.stations?.forEach((stationAPIData) => { - if (stationAPIData.region !== this.region.id || !stationAPIData.isOnline) return; const station = this.stationList.find((s) => s.name === stationAPIData.stationName); @@ -345,7 +346,6 @@ export const useStore = defineStore('store', { this.setOnlineData(); console.log(data); - }); socket.emit('FETCH_DATA', {}, (data: APIData) => {