From 355f92d3cdeba05d5a21b0d7e1169433b4c67bac Mon Sep 17 00:00:00 2001 From: Spythere Date: Wed, 26 Aug 2020 00:44:53 +0200 Subject: [PATCH] =?UTF-8?q?Dodanie=20funkcjonalno=C5=9Bci=20aktywnych=20rj?= =?UTF-8?q?=20dla=20stacji=20(W.I.P.)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/StationsView/StationCard.vue | 49 --- src/components/StationsView/StationTable.vue | 23 +- src/components/TrainsView/TrainTable.vue | 24 +- src/scripts/interfaces/Station.ts | 53 ++- src/scripts/interfaces/Train.ts | 2 +- src/store/index.ts | 21 +- src/store/modules/dist/store.js | 405 ------------------- src/store/modules/store.ts | 296 +++++++++----- src/store/modules/trains.ts | 149 +++++++ src/views/TrainsView.vue | 217 +++------- 10 files changed, 467 insertions(+), 772 deletions(-) delete mode 100644 src/store/modules/dist/store.js create mode 100644 src/store/modules/trains.ts diff --git a/src/components/StationsView/StationCard.vue b/src/components/StationsView/StationCard.vue index 207e0a8..3ddd7cf 100644 --- a/src/components/StationsView/StationCard.vue +++ b/src/components/StationsView/StationCard.vue @@ -152,55 +152,6 @@ export default class StationCard extends styleMixin { ? "L" : `${this.stationInfo.dispatcherExp}`; } - - // toLocaleDate(timestamp: number) { - // return new Date(timestamp).toLocaleDateString("pl-PL", { - // hour: "2-digit", - // minute: "2-digit", - // }); - // } - - // get computedHistory() { - // return this.history.sort((a, b) => { - // if (a.occupiedFrom < b.occupiedFrom) return 1; - // else return -1; - // }); - // } - - // async loadHistory() { - // const historyRef = await db - // .collection("history") - // .doc(this.stationInfo.stationName) - // .collection("dispatcherHistory") - // .get(); - - // this.history = historyRef.docs - // .filter((doc) => doc.data().occupiedTo != 0) - // .map((doc) => { - // const occupiedFrom = doc.data().occupiedFrom; - // const occupiedTo = doc.data().occupiedTo; - - // const sameDay = - // new Date(occupiedFrom).getDate() == new Date(occupiedTo).getDate(); - - // return { - // occupiedFrom, - // occupiedTo, - // dispatcher: - // doc.data().currentDispatcherName || doc.data().dispatcherName, - // sameDay, - // }; - // }); - // } - - // @Watch("stationInfo") - // async onStationChange(val: any, oldVal: any) { - // this.loadHistory(); - // } - - // created() { - // this.loadHistory(); - // } } diff --git a/src/components/StationsView/StationTable.vue b/src/components/StationsView/StationTable.vue index 57f8629..a89d743 100644 --- a/src/components/StationsView/StationTable.vue +++ b/src/components/StationsView/StationTable.vue @@ -51,7 +51,7 @@ {{station.dispatcherExp < 2 ? 'L' : station.dispatcherExp}} + >{{2 > station.dispatcherExp ? 'L' : station.dispatcherExp}} {{station.routes.oneWay.noCatenary}} - + {{station.scheduledTrains.length}} @@ -129,7 +132,11 @@ import Vue from "vue"; import { Component, Prop } from "vue-property-decorator"; +import { Getter } from "vuex-class"; + import Station from "@/scripts/interfaces/Station"; +import Train from "@/scripts/interfaces/Train"; + import styleMixin from "@/mixins/styleMixin"; import Options from "@/components/StationsView/Options.vue"; @@ -144,6 +151,9 @@ export default class StationTable extends styleMixin { @Prop() readonly stations!: Station[]; @Prop() readonly setFocusedStation!: () => void; + @Getter("trainsDataList") trains!: Train[]; + @Getter("trainsDataState") state!: number; + icons: { ascSVG; descSVG } = { ascSVG, descSVG }; sorterActive: { index: number; dir: number } = { index: 0, dir: 1 }; @@ -156,6 +166,7 @@ export default class StationTable extends styleMixin { ["Maszyniści"], ["Informacje", "ogólne"], ["Szlaki", "2tor | 1tor"], + ["Aktywne RJ"], ]; changeSorter(index: number) { @@ -168,6 +179,14 @@ export default class StationTable extends styleMixin { this.sorterActive.index = index; } + get test() { + return this.trains; + } + + showScheduledTrains(station) { + console.log(station.scheduledTrains); + } + get computedStations() { const dir: number = this.sorterActive.dir; diff --git a/src/components/TrainsView/TrainTable.vue b/src/components/TrainsView/TrainTable.vue index d2fe07c..4d3196b 100644 --- a/src/components/TrainsView/TrainTable.vue +++ b/src/components/TrainsView/TrainTable.vue @@ -28,7 +28,9 @@
- Przez: {{ train.sceneries }} + Przez: {{ mapTimetableSceneries(train.sceneries) }}
@@ -93,15 +95,19 @@ diff --git a/src/scripts/interfaces/Station.ts b/src/scripts/interfaces/Station.ts index 838d4e6..81c08cb 100644 --- a/src/scripts/interfaces/Station.ts +++ b/src/scripts/interfaces/Station.ts @@ -1,23 +1,32 @@ export default interface Station { - stationName: string; - stationHash: string; - maxUsers: number; - currentUsers: number; - spawnString: string; - dispatcherRate: number; - dispatcherName: string; - dispatcherExp: number; - dispatcherId: number; - stationLines: string; - stationProject: string; - reqLevel: string; - supportersOnly: string; - signalType: string; - controlType: string; - default: boolean; - nonPublic: boolean; - routes: { oneWay: { catenary: number; noCatenary: number; }, twoWay: { catenary: number; noCatenary: number; } }; - online: boolean; - occupiedTo: string; - statusTimestamp: number; -} \ No newline at end of file + stationName: string; + stationHash: string; + maxUsers: number; + currentUsers: number; + spawnString: string; + dispatcherRate: number; + dispatcherName: string; + dispatcherExp: number; + dispatcherId: number; + stationLines: string; + stationProject: string; + reqLevel: string; + supportersOnly: string; + signalType: string; + controlType: string; + default: boolean; + nonPublic: boolean; + routes: { + oneWay: { catenary: number; noCatenary: number }; + twoWay: { catenary: number; noCatenary: number }; + }; + online: boolean; + occupiedTo: string; + statusTimestamp: number; + scheduledTrains: { + trainNo: number; + trainCategory: string; + arrivalTime: string; + departureTime: string; + }[]; +} diff --git a/src/scripts/interfaces/Train.ts b/src/scripts/interfaces/Train.ts index 8cea6d3..79b934c 100644 --- a/src/scripts/interfaces/Train.ts +++ b/src/scripts/interfaces/Train.ts @@ -12,7 +12,7 @@ export default interface Train { route: string | null; timetableId: number | null; category: string | null; - sceneries: string | null; + sceneries: string[] | null; TWR: boolean | null; SKR: boolean | null; noTimetable: boolean; diff --git a/src/store/index.ts b/src/store/index.ts index 9b21490..9bc4080 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -1,10 +1,13 @@ -import Vue from 'vue' -import Vuex from 'vuex' -import Store from '@/store/modules/store' -Vue.use(Vuex) +import Vue from "vue"; +import Vuex from "vuex"; + +import Store from "@/store/modules/store"; +import TrainsModule from "@/store/modules/trains"; +Vue.use(Vuex); const store = new Vuex.Store({ - modules: { - Store - } -}) -export default store \ No newline at end of file + modules: { + Store, + TrainsModule, + }, +}); +export default store; diff --git a/src/store/modules/dist/store.js b/src/store/modules/dist/store.js deleted file mode 100644 index 02795d0..0000000 --- a/src/store/modules/dist/store.js +++ /dev/null @@ -1,405 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -var __assign = (this && this.__assign) || function () { - __assign = Object.assign || function(t) { - for (var s, i = 1, n = arguments.length; i < n; i++) { - s = arguments[i]; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) - t[p] = s[p]; - } - return t; - }; - return __assign.apply(this, arguments); -}; -var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (_) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } -}; -exports.__esModule = true; -var vuex_module_decorators_1 = require("vuex-module-decorators"); -var axios_1 = require("axios"); -var stations_json_1 = require("@/data/stations.json"); -var ConnState; -(function (ConnState) { - ConnState[ConnState["Loading"] = 0] = "Loading"; - ConnState[ConnState["Error"] = 1] = "Error"; - ConnState[ConnState["Connected"] = 2] = "Connected"; -})(ConnState || (ConnState = {})); -var Store = /** @class */ (function (_super) { - __extends(Store, _super); - function Store() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.trainCount = 0; - _this.stationCount = 0; - _this.connectionState = ConnState.Loading; - _this.apiURLS = { - stationDataURL: "https://api.td2.info.pl:9640/?method=getStationsOnline", - trainDataURL: "https://api.td2.info.pl:9640/?method=getTrainsOnline", - dispatcherDataURL: "https://api.td2.info.pl:9640/?method=readFromSWDR&value=getDispatcherStatusList%3B1" - }; - _this.stations = []; - _this.filteredStations = []; - _this.filterInitStates = { - "default": false, - notDefault: false, - nonPublic: false, - SPK: false, - SCS: false, - ręczne: false, - mechaniczne: false, - współczesna: false, - kształtowa: false, - historyczna: false, - mieszana: false, - minLevel: 0, - minOneWayCatenary: 0, - minOneWay: 0, - minTwoWayCatenary: 0, - minTwoWay: 0, - "no-1track": false, - "no-2track": false, - free: true, - occupied: false, - ending: false - }; - _this.filters = __assign({}, _this.filterInitStates); - return _this; - } - Object.defineProperty(Store.prototype, "getStationCount", { - get: function () { - return this.stationCount; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Store.prototype, "getTrainCount", { - get: function () { - return this.trainCount; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Store.prototype, "getStations", { - get: function () { - return this.filteredStations; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Store.prototype, "getAllStations", { - get: function () { - return this.stations; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Store.prototype, "getFilters", { - get: function () { - return this.filters; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Store.prototype, "getConnectionState", { - get: function () { - return this.connectionState; - }, - enumerable: false, - configurable: true - }); - Store.prototype.setFilter = function (payload) { - this.context.commit("mutateFilter", payload); - this.context.commit("filterStations"); - }; - Store.prototype.resetFilters = function () { - this.context.commit("resetFilterList"); - this.context.commit("filterStations"); - }; - Store.prototype.initStations = function () { - var _this = this; - this.context.commit("loadAllStations"); - this.context.dispatch("fetchStations"); - setInterval(function () { return _this.context.dispatch("fetchStations"); }, 15000); - }; - Store.prototype.fetchStations = function () { - var _this = this; - var onlineStationsData; - var onlineDispatchersData; - var onlineTrainsData; - var queryStations = (function () { return __awaiter(_this, void 0, void 0, function () { - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, axios_1["default"].get(this.apiURLS.stationDataURL)]; - case 1: return [2 /*return*/, (_a.sent()).data.message]; - } - }); - }); })(); - var queryTrains = (function () { return __awaiter(_this, void 0, void 0, function () { - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, axios_1["default"].get(this.apiURLS.trainDataURL)]; - case 1: return [4 /*yield*/, (_a.sent()).data.message]; - case 2: return [2 /*return*/, _a.sent()]; - } - }); - }); })(); - var queryDisptachers = (function () { return __awaiter(_this, void 0, void 0, function () { - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, axios_1["default"].get(this.apiURLS.dispatcherDataURL)]; - case 1: return [4 /*yield*/, (_a.sent()).data - .message]; - case 2: return [2 /*return*/, _a.sent()]; - } - }); - }); })(); - Promise.all([queryStations, queryTrains, queryDisptachers]) - .then(function (response) { - onlineStationsData = response[0]; - onlineTrainsData = response[1]; - onlineDispatchersData = response[2]; - var updatedStations = onlineStationsData - .filter(function (station) { return station.region === "eu" && station.isOnline; }) - .map(function (station) { - var stationStatus = onlineDispatchersData.find(function (status) { return status[0] == station.stationHash && status[1] == "eu"; }); - var statusLabel = ""; - var statusTimestamp = -1; - if (!stationStatus) - statusLabel = "NIEZALOGOWANY"; - else { - var statusCode = stationStatus[2]; - statusTimestamp = stationStatus[3]; - statusLabel = "NIEDOSTĘPNY"; - switch (statusCode) { - case 0: - if (statusTimestamp - Date.now() > 21000000) - statusLabel = "BEZ LIMITU"; - else - statusLabel = - "DO " + - new Date(statusTimestamp).toLocaleTimeString("en-US", { - hour12: false, - hour: "2-digit", - minute: "2-digit" - }); - break; - case 1: - statusLabel = "Z/W"; - break; - case 2: - if (statusTimestamp == 0) - statusLabel = "KOŃCZY"; - break; - case 3: - statusLabel = "BRAK MIEJSCA"; - break; - default: - break; - } - } - var trains = onlineTrainsData.filter(function (train) { - return train.region === "eu" && - train.isOnline && - train.station.stationName === station.stationName; - }); - var stationData = stations_json_1["default"].find(function (s) { return s.stationName === station.stationName; }) || { stationName: station.stationName, stationURL: "" }; - return __assign(__assign({}, stationData), { stationHash: station.stationHash, maxUsers: station.maxUsers, currentUsers: station.currentUsers, spawnString: station.spawnString && - station.spawnString - .split(";") - .map(function (v) { - return v.split(",")[6] ? v.split(",")[6] : v.split(",")[0]; - }), dispatcherName: station.dispatcherName, dispatcherRate: station.dispatcherRate, dispatcherId: station.dispatcherId, dispatcherExp: station.dispatcherExp, occupiedTo: statusLabel, statusTimestamp: statusTimestamp, - trains: trains }); - }); - _this.context.commit("updateStations", { - updatedStations: updatedStations, - trainCount: onlineTrainsData.filter(function (train) { return train.isOnline && train.region === "eu"; }).length - }); - _this.context.commit("filterStations"); - _this.context.commit("setConnState", ConnState.Connected); - })["catch"](function (err) { - _this.context.commit("setConnState", ConnState.Error); - }); - }; - Store.prototype.filterStations = function () { - var _this = this; - this.filteredStations = this.stations.filter(function (station) { - if ((station.nonPublic || !station.reqLevel) && _this.filters["nonPublic"]) - return false; - if (!station.reqLevel || station.reqLevel == "-1") - return true; - if (station.online && - station.occupiedTo == "KOŃCZY" && - _this.filters["ending"]) - return false; - if (station.online && _this.filters["occupied"]) - return false; - if (!station.online && _this.filters["free"]) - return false; - if (station["default"] && _this.filters["default"]) - return false; - if (!station["default"] && _this.filters["notDefault"]) - return false; - if (station.reqLevel < _this.filters["minLevel"]) - return false; - if (_this.filters["no-1track"] && - (station.routes.oneWay.catenary != 0 || - station.routes.oneWay.noCatenary != 0)) - return false; - if (_this.filters["no-2track"] && - (station.routes.twoWay.catenary != 0 || - station.routes.twoWay.noCatenary != 0)) - return false; - if (station.routes.oneWay.catenary < _this.filters["minOneWayCatenary"]) - return false; - if (station.routes.oneWay.noCatenary < _this.filters["minOneWay"]) - return false; - if (station.routes.twoWay.catenary < _this.filters["minTwoWayCatenary"]) - return false; - if (station.routes.twoWay.noCatenary < _this.filters["minTwoWay"]) - return false; - if (_this.filters[station.controlType]) - return false; - if (_this.filters[station.signalType]) - return false; - if (_this.filters["SPK"] && station.controlType.includes("SPK")) - return false; - if (_this.filters["SCS"] && station.controlType.includes("SCS")) - return false; - if (_this.filters["mechaniczne"] && - station.controlType.includes("mechaniczne")) - return false; - if (_this.filters["ręczne"] && station.controlType.includes("ręczne")) - return false; - return true; - }); - }; - Store.prototype.loadAllStations = function () { - this.stations = stations_json_1["default"].map(function (stationData) { return (__assign({ stationProject: "", spawnString: "", stationHash: "", maxUsers: 0, currentUsers: 0, dispatcherName: "", dispatcherRate: 0, dispatcherExp: -1, dispatcherId: 0, online: false, occupiedTo: "WOLNA", statusTimestamp: 0 }, stationData)); }); - }; - Store.prototype.updateStations = function (_a) { - var _this = this; - var updatedStations = _a.updatedStations, trainCount = _a.trainCount; - var _loop_1 = function (i) { - var toUpdate = updatedStations.find(function (updated) { return updated.stationName === _this.stations[i].stationName; }); - if (!toUpdate) { - this_1.stations[i].online = false; - this_1.stations[i].occupiedTo = "WOLNA"; - this_1.stations[i].statusTimestamp = -1; - this_1.stations[i].dispatcherExp = -1; - return "continue"; - } - this_1.stations[i] = __assign(__assign({}, this_1.stations[i]), toUpdate); - this_1.stations[i].online = true; - updatedStations = updatedStations.filter(function (updated) { return updated.stationName !== _this.stations[i].stationName; }); - }; - var this_1 = this; - for (var i = 0; i < this.stations.length; i++) { - _loop_1(i); - } - // Dodawanie do listy online potencjalnych scenerii niewpisanych do bazy - updatedStations.forEach(function (updated) { - var toUpdate = _this.stations.find(function (station) { return station.stationName === updated.stationName; }); - if (!toUpdate) { - _this.stations.push(__assign(__assign({}, updated), { online: true, reqLevel: "-1" })); - } - }); - // Aktualizacja liczników - this.stationCount = this.stations.filter(function (station) { return station.online; }).length; - this.trainCount = trainCount; - }; - Store.prototype.mutateFilter = function (payload) { - this.filters[payload.filterName] = payload.value; - }; - Store.prototype.resetFilterList = function () { - this.filters = __assign({}, this.filterInitStates); - }; - Store.prototype.setConnState = function (state) { - this.connectionState = state; - }; - __decorate([ - vuex_module_decorators_1.Action - ], Store.prototype, "setFilter"); - __decorate([ - vuex_module_decorators_1.Action - ], Store.prototype, "resetFilters"); - __decorate([ - vuex_module_decorators_1.Action - ], Store.prototype, "initStations"); - __decorate([ - vuex_module_decorators_1.Action - ], Store.prototype, "fetchStations"); - __decorate([ - vuex_module_decorators_1.Mutation - ], Store.prototype, "filterStations"); - __decorate([ - vuex_module_decorators_1.Mutation - ], Store.prototype, "loadAllStations"); - __decorate([ - vuex_module_decorators_1.Mutation - ], Store.prototype, "updateStations"); - __decorate([ - vuex_module_decorators_1.Mutation - ], Store.prototype, "mutateFilter"); - __decorate([ - vuex_module_decorators_1.Mutation - ], Store.prototype, "resetFilterList"); - __decorate([ - vuex_module_decorators_1.Mutation - ], Store.prototype, "setConnState"); - Store = __decorate([ - vuex_module_decorators_1.Module - ], Store); - return Store; -}(vuex_module_decorators_1.VuexModule)); -exports["default"] = Store; diff --git a/src/store/modules/store.ts b/src/store/modules/store.ts index e9fb885..8e611ac 100644 --- a/src/store/modules/store.ts +++ b/src/store/modules/store.ts @@ -10,6 +10,109 @@ enum ConnState { Connected = 2, } +const apiURLS = { + stationDataURL: "https://api.td2.info.pl:9640/?method=getStationsOnline", + trainDataURL: "https://api.td2.info.pl:9640/?method=getTrainsOnline", + dispatcherDataURL: + "https://api.td2.info.pl:9640/?method=readFromSWDR&value=getDispatcherStatusList%3B1", +}; + +interface TimetableResponseData { + stopPoints: + | { + arrivalTime: string; + arrivalDelay: number; + departureTime: string; + departureDelay: number; + pointNameRAW: string; + }[] + | []; + trainInfo: { + timetableId: number; + trainCategoryCode: string; + }; +} + +interface OnlineStationsResponseData { + stationName: string; + stationHash: string; + maxUsers: number; + currentUsers: number; + spawnString: string; + dispatcherRate: number; + dispatcherName: string; + dispatcherExp: number; + dispatcherId: number; + region: string; + isOnline: number; +} + +let onlineStationsData: OnlineStationsResponseData[]; + +let onlineDispatchersData: [string, string, number, number][]; + +let onlineTrainsData: { + isOnline: number; + region: string; + trainNo: number; + station: { stationName: string }; +}[]; + +const queryStations = (async () => { + return (await axios.get(apiURLS.stationDataURL)).data.message; +})(); + +const queryTrains = (async () => { + return await (await axios.get(apiURLS.trainDataURL)).data.message; +})(); + +const queryDisptachers = (async () => { + return await (await axios.get(apiURLS.dispatcherDataURL)).data.message; +})(); + +const queryTimetableData = async ( + trainNo: number +): Promise => + ( + await axios.get( + `https://api.td2.info.pl:9640/?method=readFromSWDR&value=getTimetable%3B${trainNo}%3Beu` + ) + ).data.message; + +async function getScheduledTrains(stationName: string) { + let scheduledTrains: any[] = []; + + for (let train of onlineTrainsData) { + if (train.region !== "eu" || !train.isOnline) continue; + + const timetable = await queryTimetableData(train.trainNo); + + if (!timetable.trainInfo) continue; + + const stop = timetable.stopPoints.find((point) => { + return ( + stationName.toLowerCase().includes(point.pointNameRAW.toLowerCase()) || + stationName + .toLowerCase() + .includes(point.pointNameRAW.toLowerCase().split(" ")[0]) || + stationName + .toLowerCase() + .includes(point.pointNameRAW.toLowerCase().split(",")[0]) + ); + }); + + if (!stop) continue; + + scheduledTrains.push({ + arrivalTime: stop?.arrivalTime, + departureTime: stop?.departureTime, + trainCategory: timetable.trainInfo?.trainCategoryCode, + trainNo: train.trainNo, + }); + } + + return scheduledTrains; +} @Module class Store extends VuexModule { private trainCount: number = 0; @@ -17,13 +120,6 @@ class Store extends VuexModule { private connectionState: ConnState = ConnState.Loading; - private apiURLS = { - stationDataURL: "https://api.td2.info.pl:9640/?method=getStationsOnline", - trainDataURL: "https://api.td2.info.pl:9640/?method=getTrainsOnline", - dispatcherDataURL: - "https://api.td2.info.pl:9640/?method=readFromSWDR&value=getDispatcherStatusList%3B1", - }; - private stations: Station[] = []; private filteredStations: {}[] = []; @@ -95,132 +191,107 @@ class Store extends VuexModule { this.context.commit("loadAllStations"); this.context.dispatch("fetchStations"); - setInterval(() => this.context.dispatch("fetchStations"), 15000); + setInterval(() => this.context.dispatch("fetchStations"), 10000); } @Action private fetchStations() { - let onlineStationsData: { - stationName: string; - stationHash: string; - maxUsers: number; - currentUsers: number; - spawnString: string; - dispatcherRate: number; - dispatcherName: string; - dispatcherExp: number; - dispatcherId: number; - region: string; - isOnline: number; - }[]; - - let onlineDispatchersData: [string, string, number, number][]; - - let onlineTrainsData: { - isOnline: number; - region: string; - station: { stationName: string }; - }[]; - - const queryStations = (async () => { - return (await axios.get(this.apiURLS.stationDataURL)).data.message; - })(); - - const queryTrains = (async () => { - return await (await axios.get(this.apiURLS.trainDataURL)).data.message; - })(); - - const queryDisptachers = (async () => { - return await (await axios.get(this.apiURLS.dispatcherDataURL)).data - .message; - })(); - Promise.all([queryStations, queryTrains, queryDisptachers]) - .then((response) => { + .then(async (response) => { onlineStationsData = response[0]; onlineTrainsData = response[1]; onlineDispatchersData = response[2]; - const updatedStations = onlineStationsData - .filter((station) => station.region === "eu" && station.isOnline) - .map((station) => { - const stationStatus = onlineDispatchersData.find( - (status) => status[0] == station.stationHash && status[1] == "eu" - ); + const updatedStations = await Promise.all( + onlineStationsData + .filter((station) => station.region === "eu" && station.isOnline) + .map(async (station) => { + const stationStatus = onlineDispatchersData.find( + (status) => + status[0] == station.stationHash && status[1] == "eu" + ); - let statusLabel = ""; - let statusTimestamp = -1; + let statusLabel = ""; + let statusTimestamp = -1; - if (!stationStatus) statusLabel = "NIEZALOGOWANY"; - else { - let statusCode = stationStatus[2]; - statusTimestamp = stationStatus[3]; + if (!stationStatus) statusLabel = "NIEZALOGOWANY"; + else { + let statusCode = stationStatus[2]; + statusTimestamp = stationStatus[3]; - statusLabel = "NIEDOSTĘPNY"; + statusLabel = "NIEDOSTĘPNY"; - switch (statusCode) { - case 0: - if (statusTimestamp - Date.now() > 21000000) - statusLabel = "BEZ LIMITU"; - else - statusLabel = - "DO " + - new Date(statusTimestamp).toLocaleTimeString("en-US", { - hour12: false, - hour: "2-digit", - minute: "2-digit", - }); - break; + switch (statusCode) { + case 0: + if (statusTimestamp - Date.now() > 21000000) + statusLabel = "BEZ LIMITU"; + else + statusLabel = + "DO " + + new Date(statusTimestamp).toLocaleTimeString("en-US", { + hour12: false, + hour: "2-digit", + minute: "2-digit", + }); + break; - case 1: - statusLabel = "Z/W"; - break; + case 1: + statusLabel = "Z/W"; + break; - case 2: - if (statusTimestamp == 0) statusLabel = "KOŃCZY"; - break; + case 2: + if (statusTimestamp == 0) statusLabel = "KOŃCZY"; + break; - case 3: - statusLabel = "BRAK MIEJSCA"; - break; + case 3: + statusLabel = "BRAK MIEJSCA"; + break; - default: - break; + default: + break; + } } - } - const trains = onlineTrainsData.filter( - (train) => - train.region === "eu" && - train.isOnline && - train.station.stationName === station.stationName - ); + const trains = onlineTrainsData.filter( + (train) => + train.region === "eu" && + train.isOnline && + train.station.stationName === station.stationName + ); - const stationData = data.find( - (s) => s.stationName === station.stationName - ) || { stationName: station.stationName, stationURL: "" }; + const stationData = data.find( + (s) => s.stationName === station.stationName + ) || { stationName: station.stationName, stationURL: "" }; - return { - ...stationData, - stationHash: station.stationHash, - maxUsers: station.maxUsers, - currentUsers: station.currentUsers, - spawnString: - station.spawnString && - station.spawnString - .split(";") - .map((v) => - v.split(",")[6] ? v.split(",")[6] : v.split(",")[0] - ), - dispatcherName: station.dispatcherName, - dispatcherRate: station.dispatcherRate, - dispatcherId: station.dispatcherId, - dispatcherExp: station.dispatcherExp, - occupiedTo: statusLabel, - statusTimestamp, - trains, - }; - }); + // let scheduledTrains = await getScheduledTrains( + // station.stationName + // ); + + let scheduledTrains = []; + + return { + ...stationData, + stationHash: station.stationHash, + maxUsers: station.maxUsers, + currentUsers: station.currentUsers, + spawnString: + station.spawnString && + station.spawnString + .split(";") + .map((v) => + v.split(",")[6] ? v.split(",")[6] : v.split(",")[0] + ), + dispatcherName: station.dispatcherName, + dispatcherRate: station.dispatcherRate, + dispatcherId: station.dispatcherId, + dispatcherExp: station.dispatcherExp, + occupiedTo: statusLabel, + statusTimestamp, + trains, + scheduledTrains, + }; + }) + ); this.context.commit("updateStations", { updatedStations, @@ -315,6 +386,7 @@ class Store extends VuexModule { online: false, occupiedTo: "WOLNA", statusTimestamp: 0, + scheduledTrains: [], ...stationData, })); } diff --git a/src/store/modules/trains.ts b/src/store/modules/trains.ts new file mode 100644 index 0000000..2c1929f --- /dev/null +++ b/src/store/modules/trains.ts @@ -0,0 +1,149 @@ +import { Module, VuexModule, Mutation, Action } from "vuex-module-decorators"; + +import Train from "@/scripts/interfaces/Train"; + +import axios from "axios"; +const API_URL = "https://api.td2.info.pl:9640/?method=getTrainsOnline"; + +enum ConnState { + Loading = 0, + Error = 1, + Connected = 2, +} + +interface TrainData { + driverId: number; + driverName: string; + trainNo: number; + station: { stationName: string }; + dataMass: number; + dataLength: number; + dataSpeed: number; + dataDistance: number; + dataSignal: string; + dataCon: string; + dataSceneryConnection: string; + isOnline: boolean; +} + +interface TimetableResponseData { + stopPoints: { pointDistance: number }[] | []; + trainInfo: { + timetableId: number; + trainCategoryCode: string; + route: string; + twr: boolean; + skr: boolean; + sceneries: string[]; + }; +} + +interface TimetableData { + timetableId: number; + trainCategoryCode: string; + route: string; + twr: boolean; + skr: boolean; + sceneries: string[]; + routeDistance: number; +} + +const getTimetableURL = (trainNo: number) => + `https://api.td2.info.pl:9640/?method=readFromSWDR&value=getTimetable%3B${trainNo}%3Beu`; + +const getLocoURL = (locoType: string) => + `https://rj.td2.info.pl/dist/img/thumbnails/${ + locoType.includes("EN") ? locoType + "rb" : locoType + }.png`; + +@Module +export default class TrainsModule extends VuexModule { + onlineTrainsData: Train[] = []; + onlineTrainsState: ConnState = ConnState.Loading; + + @Action({ commit: "loadTrainsData" }) + async fetchTrainsData() { + let trainDataResponse; + + try { + trainDataResponse = await axios.get(API_URL); + } catch (error) { + this.context.commit("setConnectionState", ConnState.Error); + return null; + } + + let onlineTrainsData: TrainData[] = trainDataResponse.data.message; + + return await Promise.all( + onlineTrainsData + .filter((train) => train.isOnline) + .map(async (train) => { + const timetableResponseData: TimetableResponseData | null = ( + await axios.get(getTimetableURL(train.trainNo)) + ).data.message; + + let timetableData: TimetableData | null = null; + + if (timetableResponseData && timetableResponseData.trainInfo) { + const routeDistance: number = + timetableResponseData.stopPoints[ + timetableResponseData.stopPoints.length - 1 + ].pointDistance; + + timetableData = { + ...timetableResponseData.trainInfo, + routeDistance, + }; + } + + const locoType = train.dataCon.split(";") + ? train.dataCon.split(";")[0] + : train.dataCon; + + return { + driverId: train.driverId, + driverName: train.driverName, + trainNo: train.trainNo, + currentStationName: train.station.stationName, + mass: train.dataMass, + length: train.dataLength, + speed: train.dataSpeed, + distance: train.dataDistance, + signal: train.dataSignal, + connectedTrack: train.dataSceneryConnection, + locoType, + locoURL: getLocoURL(locoType), + noTimetable: timetableData == null, + route: timetableData && timetableData.route, + timetableId: timetableData && timetableData.timetableId, + category: timetableData && timetableData.trainCategoryCode, + routeDistance: (timetableData && timetableData.routeDistance) || 0, + sceneries: timetableData && timetableData.sceneries, + TWR: timetableData && timetableData.twr, + SKR: timetableData && timetableData.skr, + }; + }) + ); + } + + @Mutation + private loadTrainsData(data: Train[] | null) { + if (data) { + this.onlineTrainsData = data; + this.onlineTrainsState = ConnState.Connected; + } + } + + @Mutation + private setConnectionState(state: ConnState) { + this.onlineTrainsState = state; + } + + get trainsDataList() { + return this.onlineTrainsData; + } + + get trainsDataState() { + return this.onlineTrainsState; + } +} diff --git a/src/views/TrainsView.vue b/src/views/TrainsView.vue index d89940a..799b4fa 100644 --- a/src/views/TrainsView.vue +++ b/src/views/TrainsView.vue @@ -1,6 +1,6 @@