Czyszczenie i restrukturyzacja store'a

This commit is contained in:
2021-06-11 00:29:57 +02:00
parent b6267ad88c
commit 5f028fe9c8
8 changed files with 231 additions and 125 deletions
+2 -6
View File
@@ -391,12 +391,8 @@ h3 {
-webkit-transition: background-color 200ms; -webkit-transition: background-color 200ms;
} }
&.no-timetable { &.no-timetable .user_train {
pointer-events: none; background-color: $no-timetable;
& > .user_train {
background-color: $no-timetable;
}
} }
&.departed > &_train { &.departed > &_train {
@@ -347,7 +347,7 @@ h3 {
} }
&.empty { &.empty {
color: $accentCol; color: #bbb;
} }
} }
+15 -5
View File
@@ -207,18 +207,18 @@
).length ).length
}}</span> }}</span>
</td> </td>
<!--
<td class="station_stats">
<div class="stats_wrapper"></div>
</td>-->
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>
<div class="no-stations" v-if="stations.length == 0"> <div class="no-stations" v-if="stations.length == 0 && isDataLoaded">
{{ $t("sceneries.no-stations") }} {{ $t("sceneries.no-stations") }}
</div> </div>
<div class="no-stations" v-else-if="!isDataLoaded">
{{ $t("app.loading") }}
</div>
</section> </section>
</template> </template>
@@ -228,7 +228,11 @@ import { Component, Prop } from "vue-property-decorator";
import Station from "@/scripts/interfaces/Station"; import Station from "@/scripts/interfaces/Station";
import styleMixin from "@/mixins/styleMixin"; import styleMixin from "@/mixins/styleMixin";
import { Getter } from "vuex-class";
import Options from "@/components/StationsView/Options.vue"; import Options from "@/components/StationsView/Options.vue";
import { StoreData } from "@/scripts/interfaces/StoreData";
import { DataStatus } from "@/scripts/enums/DataStatus";
@Component({ @Component({
components: { Options }, components: { Options },
@@ -240,6 +244,8 @@ export default class StationTable extends styleMixin {
@Prop() readonly setFocusedStation!: () => void; @Prop() readonly setFocusedStation!: () => void;
@Prop() readonly changeSorter!: () => void; @Prop() readonly changeSorter!: () => void;
@Getter("getAllData") storeAPIData!: StoreData;
likeIcon: string = require("@/assets/icon-like.svg"); likeIcon: string = require("@/assets/icon-like.svg");
spawnIcon: string = require("@/assets/icon-spawn.svg"); spawnIcon: string = require("@/assets/icon-spawn.svg");
timetableIcon: string = require("@/assets/icon-timetable.svg"); timetableIcon: string = require("@/assets/icon-timetable.svg");
@@ -286,6 +292,10 @@ export default class StationTable extends styleMixin {
query: { station: station.stationName.replaceAll(" ", "_") }, query: { station: station.stationName.replaceAll(" ", "_") },
}); });
} }
get isDataLoaded() {
return this.storeAPIData.dataConnectionStatus == DataStatus.Loaded;
}
} }
</script> </script>
+6 -3
View File
@@ -1,5 +1,5 @@
import Train from './Train'; import Train from "./Train";
import ScheduledTrain from './ScheduledTrain'; import ScheduledTrain from "./ScheduledTrain";
export default interface Station { export default interface Station {
stationName: string; stationName: string;
@@ -52,6 +52,9 @@ export default interface Station {
statusTimeString: string; statusTimeString: string;
statusID: string; statusID: string;
stationTrains: Train[]; stationTrains: {
driverName: number;
trainNo: number;
}[];
scheduledTrains: ScheduledTrain[]; scheduledTrains: ScheduledTrain[];
} }
+3 -1
View File
@@ -1,4 +1,4 @@
import TrainStop from '@/scripts/interfaces/TrainStop'; import TrainStop from "@/scripts/interfaces/TrainStop";
export default interface Train { export default interface Train {
mass: number; mass: number;
@@ -16,6 +16,8 @@ export default interface Train {
locoType: string; locoType: string;
online: boolean; online: boolean;
cars: string[];
timetableData?: { timetableData?: {
timetableId: number; timetableId: number;
category: string; category: string;
+7 -7
View File
@@ -5,17 +5,17 @@ export default interface TrainStop {
stopDistance: number; stopDistance: number;
mainStop: boolean; mainStop: boolean;
arrivalLine: string; arrivalLine: string | null;
arrivalTimeString: string; arrivalTimeString: string | null;
arrivalTimestamp: number; arrivalTimestamp: number;
arrivalRealTimeString: string; arrivalRealTimeString: string | null;
arrivalRealTimestamp: number; arrivalRealTimestamp: number;
arrivalDelay: number; arrivalDelay: number;
departureLine: string; departureLine: string | null;
departureTimeString: string; departureTimeString: string | null;
departureTimestamp: number; departureTimestamp: number;
departureRealTimeString: string; departureRealTimeString: string | null;
departureRealTimestamp: number; departureRealTimestamp: number;
departureDelay: number; departureDelay: number;
@@ -25,5 +25,5 @@ export default interface TrainStop {
terminatesHere: boolean; terminatesHere: boolean;
confirmed: boolean; confirmed: boolean;
stopped: boolean; stopped: boolean;
stopTime: number; stopTime: number | null;
} }
+1 -1
View File
@@ -69,7 +69,7 @@ const parseSpawns = (spawnString: string) => {
}); });
}; };
const getTimestamp = (date: string) => (date ? new Date(date).getTime() : 0); const getTimestamp = (date: string | null) => (date ? new Date(date).getTime() : 0);
const timestampToString = (timestamp: number) => const timestampToString = (timestamp: number) =>
new Date(timestamp).toLocaleTimeString("pl-PL", { new Date(timestamp).toLocaleTimeString("pl-PL", {
+196 -101
View File
@@ -11,23 +11,42 @@ import utils from "@/scripts/utils/storeUtils";
import { DataStatus } from "@/scripts/enums/DataStatus"; import { DataStatus } from "@/scripts/enums/DataStatus";
import { StoreData } from "@/scripts/interfaces/StoreData"; import { StoreData } from "@/scripts/interfaces/StoreData";
interface TimetableData { interface TimetableAPIData {
trainNo: number; trainInfo: {
driverName: string; timetableId: number;
driverId: number; trainNo: number;
currentStationName: string; trainCategoryCode: string;
currentStationHash: string; driverId: number;
timetableId: number; driverName: string;
category: string; route: string;
route: string; twr: boolean;
TWR: boolean; skr: boolean;
SKR: boolean; sceneries: string[];
routeDistance: number; };
followingStops: TrainStop[];
followingSceneries: string[]; stopPoints: {
arrivalLine: string | null;
arrivalTime: string | null;
arrivalDelay: number;
arrivalRealTime: string | null;
pointDistance: number;
pointName: string;
pointNameRAW: string;
entryId: number;
pointId: number;
comments: string | null;
confirmed: boolean;
isStopped: boolean;
pointStopTime: number | null;
pointStopType: string;
departureLine: string | null;
departureTime: string | null;
departureDelay: number;
departureRealTime: string | null;
}[];
} }
interface IOnlineStationData { interface StationAPIData {
dispatcherId: number; dispatcherId: number;
dispatcherName: string; dispatcherName: string;
dispatcherIsSupporter: boolean; dispatcherIsSupporter: boolean;
@@ -46,6 +65,77 @@ interface IOnlineStationData {
dispatcherRate: number; dispatcherRate: number;
} }
interface TrainAPIData {
trainNo: number;
driverId: number;
driverName: string;
driverIsSupporter: boolean;
station: StationAPIData;
dataSignal: string;
dataSceneryConnection: string;
dataDistance: number;
dataCon: string;
dataSpeed: number;
dataMass: number;
dataLength: number;
region: string;
isOnline: boolean;
lastSeen: number;
}
interface Timetable {
trainNo: number;
driverName: string;
driverId: number;
currentStationName: string;
currentStationHash: string;
timetableId: number;
category: string;
route: string;
TWR: boolean;
SKR: boolean;
routeDistance: number;
followingStops: TrainStop[];
followingSceneries: string[];
}
// interface OnlineStationData {
// dispatcherId: number;
// dispatcherName: string;
// dispatcherIsSupporter: boolean;
// stationName: string;
// stationHash: string;
// region: string;
// maxUsers: number;
// currentUsers: number;
// spawn: number;
// lastSeen: number;
// dispatcherExp: number;
// nameFromHeader: string;
// spawnString: string;
// networkConnectionString: string;
// isOnline: number;
// dispatcherRate: number;
// }
// interface TrainData {
// trainNo: number;
// driverId: number;
// driverName: string;
// driverIsSupporter: boolean;
// dataSignal: string;
// dataSceneryConnection: string;
// dataDistance: number;
// dataCon: string;
// dataSpeed: number;
// dataMass: number;
// dataLength: number;
// station: OnlineStationData;
// region: string;
// isOnline: number;
// lastSeen: number;
// }
const URLs = { const URLs = {
stations: "https://api.td2.info.pl:9640/?method=getStationsOnline", stations: "https://api.td2.info.pl:9640/?method=getStationsOnline",
trains: "https://api.td2.info.pl:9640/?method=getTrainsOnline", trains: "https://api.td2.info.pl:9640/?method=getTrainsOnline",
@@ -108,15 +198,95 @@ export default class Store extends VuexModule {
setInterval(() => this.context.dispatch("fetchOnlineData"), 20000); setInterval(() => this.context.dispatch("fetchOnlineData"), 20000);
} }
// Fetching all station and train data from API
@Action
async fetchOnlineData() {
Promise.all([axios.get(URLs.stations), axios.get(URLs.trains), axios.get(URLs.dispatchers)])
.then(async response => {
const onlineStationsData: StationAPIData[] = response[0].data.message;
const onlineTrainsData: TrainAPIData[] = await response[1].data.message;
const onlineDispatchersData: string[][] = await response[2].data.message;
const updatedStationList = onlineStationsData.reduce((acc, station) => {
if (station.region !== "eu" || !station.isOnline) return acc;
const stationStatus = onlineDispatchersData.find((status: string[]) => status[0] == station.stationHash && status[1] == "eu");
const statusTimestamp = utils.getStatusTimestamp(stationStatus);
const statusID = utils.getStatusID(stationStatus);
const stationTrains = onlineTrainsData
.filter(train => train.region === "eu" && train.isOnline && train.station.stationName === station.stationName)
.map(train => ({ driverName: train.driverName, trainNo: train.trainNo }));
acc.push({
stationName: station.stationName,
stationHash: station.stationHash,
maxUsers: station.maxUsers,
currentUsers: station.currentUsers,
spawns: utils.parseSpawns(station.spawnString),
dispatcherName: station.dispatcherName,
dispatcherRate: station.dispatcherRate,
dispatcherId: station.dispatcherId,
dispatcherExp: station.dispatcherExp,
dispatcherIsSupporter: station.dispatcherIsSupporter,
stationTrains,
statusTimestamp,
statusID,
statusTimeString: utils.timestampToString(statusTimestamp)
});
return acc;
}, [] as any);
const updatedTrainList = await Promise.all(
onlineTrainsData
.filter(train => train.region === "eu")
.map(async train => {
const locoType = train.dataCon.split(";") ? train.dataCon.split(";")[0] : train.dataCon;
return {
trainNo: train.trainNo,
mass: train.dataMass,
length: train.dataLength,
speed: train.dataSpeed,
distance: train.dataDistance,
signal: train.dataSignal,
online: train.isOnline,
driverId: train.driverId,
driverName: train.driverName,
currentStationName: train.station.stationName,
currentStationHash: train.station.stationHash,
connectedTrack: train.dataSceneryConnection,
locoType,
locoURL: utils.getLocoURL(locoType),
cars: train.dataCon.split(";").filter((train, i) => i > 0) || []
};
})
);
this.context.commit("updateOnlineStations", updatedStationList);
this.context.commit("updateOnlineTrains", updatedTrainList);
this.context.dispatch("fetchTimetableData");
})
.catch(() => {
this.context.commit("setDataConnectionStatus", DataStatus.Error);
});
}
// Fetching timetable data from API basing on online trains
@Action({ commit: "updateTimetableData" }) @Action({ commit: "updateTimetableData" })
async fetchTimetableData() { async fetchTimetableData() {
return this.trainList.reduce(async (acc: Promise<TimetableData[]>, train) => { return this.trainList.reduce(async (acc: Promise<Timetable[]>, train: Train) => {
const timetable = await (await axios.get(utils.timetableURL(train.trainNo))).data.message; const timetable: TimetableAPIData = await (await axios.get(utils.timetableURL(train.trainNo))).data.message;
const trainInfo = timetable.trainInfo; const trainInfo = timetable.trainInfo;
if (!timetable || !trainInfo) return acc; if (!timetable || !trainInfo) return acc;
const followingStops: TrainStop[] = timetable.stopPoints.reduce((stopsAcc: TrainStop[], point) => { const followingStops: TrainStop[] = timetable.stopPoints.reduce((stopsAcc: TrainStop[], point) => {
if (point.pointNameRAW.toLowerCase().includes("sbl")) return stopsAcc;
const arrivalTimestamp = utils.getTimestamp(point.arrivalTime); const arrivalTimestamp = utils.getTimestamp(point.arrivalTime);
const arrivalRealTimestamp = utils.getTimestamp(point.arrivalRealTime); const arrivalRealTimestamp = utils.getTimestamp(point.arrivalRealTime);
@@ -132,16 +302,16 @@ export default class Store extends VuexModule {
mainStop: point.pointName.includes("strong"), mainStop: point.pointName.includes("strong"),
arrivalLine: point.arrivalLine, arrivalLine: point.arrivalLine,
arrivalTimeString: utils.timestampToString(point.arrivalTime), arrivalTimeString: point.arrivalTime,
arrivalTimestamp: arrivalTimestamp, arrivalTimestamp: arrivalTimestamp,
arrivalRealTimeString: utils.timestampToString(point.arrivalRealTime), arrivalRealTimeString: point.arrivalRealTime,
arrivalRealTimestamp: arrivalRealTimestamp, arrivalRealTimestamp: arrivalRealTimestamp,
arrivalDelay: point.arrivalDelay, arrivalDelay: point.arrivalDelay,
departureLine: point.departureLine, departureLine: point.departureLine,
departureTimeString: utils.timestampToString(point.departureTime), departureTimeString: point.departureTime,
departureTimestamp: departureTimestamp, departureTimestamp: departureTimestamp,
departureRealTimeString: utils.timestampToString(point.departureRealTime), departureRealTimeString: point.departureRealTime,
departureRealTimestamp: departureRealTimestamp, departureRealTimestamp: departureRealTimestamp,
departureDelay: point.departureDelay, departureDelay: point.departureDelay,
@@ -176,81 +346,6 @@ export default class Store extends VuexModule {
}, Promise.resolve([])); }, Promise.resolve([]));
} }
@Action
async fetchOnlineData() {
Promise.all([axios.get(URLs.stations), axios.get(URLs.trains), axios.get(URLs.dispatchers)])
.then(async response => {
const onlineStationsData: IOnlineStationData[] = response[0].data.message;
const onlineTrainsData = await response[1].data.message;
const onlineDispatchersData = await response[2].data.message;
let updatedStationList = onlineStationsData.reduce((acc, station) => {
if (station.region !== "eu" || !station.isOnline) return acc;
const stationStatus = onlineDispatchersData.find(status => status[0] == station.stationHash && status[1] == "eu");
const statusTimestamp = utils.getStatusTimestamp(stationStatus);
const statusID = utils.getStatusID(stationStatus);
const stationTrains = onlineTrainsData.filter(
train => train.region === "eu" && train.isOnline && train.station.stationName === station.stationName
);
acc.push({
stationName: station.stationName,
stationHash: station.stationHash,
maxUsers: station.maxUsers,
currentUsers: station.currentUsers,
spawns: utils.parseSpawns(station.spawnString),
dispatcherName: station.dispatcherName,
dispatcherRate: station.dispatcherRate,
dispatcherId: station.dispatcherId,
dispatcherExp: station.dispatcherExp,
dispatcherIsSupporter: station.dispatcherIsSupporter,
stationTrains,
statusTimestamp,
statusID,
statusTimeString: utils.timestampToString(statusTimestamp)
});
return acc;
}, [] as any);
let updatedTrainList = await Promise.all(
onlineTrainsData
.filter(train => train.region === "eu")
.map(async train => {
const locoType = train.dataCon.split(";") ? train.dataCon.split(";")[0] : train.dataCon;
return {
trainNo: train.trainNo,
mass: train.dataMass,
length: train.dataLength,
speed: train.dataSpeed,
distance: train.dataDistance,
signal: train.dataSignal,
online: train.isOnline,
driverId: train.driverId,
driverName: train.driverName,
currentStationName: train.station.stationName,
currentStationHash: train.station.stationHash,
connectedTrack: train.dataSceneryConnection,
locoType,
locoURL: utils.getLocoURL(locoType)
};
})
);
this.context.commit("updateOnlineStations", updatedStationList);
this.context.commit("updateOnlineTrains", updatedTrainList);
this.context.dispatch("fetchTimetableData");
})
.catch(err => {
this.context.commit("setDataConnectionStatus", DataStatus.Error);
});
}
//MUTATIONS //MUTATIONS
@Mutation @Mutation
private setDataConnectionStatus(status: DataStatus) { private setDataConnectionStatus(status: DataStatus) {
@@ -336,7 +431,7 @@ export default class Store extends VuexModule {
private updateOnlineStations(updatedStationList: any[]) { private updateOnlineStations(updatedStationList: any[]) {
this.stationList = this.stationList.reduce((acc: Station[], station) => { this.stationList = this.stationList.reduce((acc: Station[], station) => {
const onlineStationData = updatedStationList.find(updatedStation => updatedStation.stationName === station.stationName); const onlineStationData = updatedStationList.find(updatedStation => updatedStation.stationName === station.stationName);
const registeredStation = JSONStationData.find(data => data[0] === station.stationName); const listedStationData = JSONStationData.find(data => data[0] === station.stationName);
if (onlineStationData) if (onlineStationData)
acc.push({ acc.push({
@@ -344,7 +439,7 @@ export default class Store extends VuexModule {
...onlineStationData, ...onlineStationData,
online: true online: true
}); });
else if (registeredStation) else if (listedStationData)
acc.push({ acc.push({
...station, ...station,
stationProject: "", stationProject: "",
@@ -374,7 +469,7 @@ export default class Store extends VuexModule {
this.stationList.push({ this.stationList.push({
...uStation, ...uStation,
scheduledTrains: [], scheduledTrains: [],
stationTrains: [], stationTrains: uStation.stationTrains || [],
subStations: [], subStations: [],
online: true, online: true,
reqLevel: "-1", reqLevel: "-1",
@@ -402,11 +497,11 @@ export default class Store extends VuexModule {
} }
@Mutation @Mutation
private updateTimetableData(timetableList: TimetableData[]) { private updateTimetableData(timetableList: Timetable[]) {
this.stationList = this.stationList.map(station => { this.stationList = this.stationList.map(station => {
const stationName = station.stationName.toLowerCase(); const stationName = station.stationName.toLowerCase();
const scheduledTrains: Station["scheduledTrains"] = timetableList.reduce((acc: Station["scheduledTrains"], timetable: TimetableData, index) => { const scheduledTrains: Station["scheduledTrains"] = timetableList.reduce((acc: Station["scheduledTrains"], timetable: Timetable, index) => {
if (!timetable.followingSceneries.includes(station.stationHash)) return acc; if (!timetable.followingSceneries.includes(station.stationHash)) return acc;
const stopInfoIndex = timetable.followingStops.findIndex(stop => { const stopInfoIndex = timetable.followingStops.findIndex(stop => {