diff --git a/src/App.vue b/src/App.vue index f2878d8..3f9fec7 100644 --- a/src/App.vue +++ b/src/App.vue @@ -10,13 +10,15 @@ Scenerie online: {{stationCount}} | Maszyniści online: {{ trainCount }} -
-
- -
+
+
+
+ +
-
- +
+ +
@@ -70,6 +72,14 @@ export default Vue.extend({ this.getStationList(); setInterval(this.getStationList, 5000); + + document.addEventListener("scroll", e => { + const appBarEl = this.$refs.appBar as Element; + + if (appBarEl.getBoundingClientRect().top < 0) + appBarEl.classList.add("sticky"); + else appBarEl.classList.remove("sticky"); + }); } }); @@ -83,11 +93,9 @@ html { } body { + width: 100%; margin: 0; font-family: "Lato", sans-serif; - background: $bgCol; - width: 100%; - min-height: 100vh; } button, @@ -141,7 +149,10 @@ ul { } .app { + background: $bgCol; color: white; + width: 100%; + overflow: hidden; &-container { @@ -171,7 +182,7 @@ ul { } .online { - font-size: calc(0.6rem + 0.4vw); + font-size: calc(0.3rem + 0.8vw); } } @@ -179,13 +190,14 @@ ul { display: flex; align-items: center; justify-content: space-between; - font-size: calc(0.8rem + 0.2vw); + position: sticky; + top: 0; + background: #222; } } - footer { background: #111; padding: 0.3rem; diff --git a/src/components/states/Error.vue b/src/components/states/Error.vue index dee8915..764fb22 100644 --- a/src/components/states/Error.vue +++ b/src/components/states/Error.vue @@ -19,7 +19,7 @@ export default { justify-content: center; align-items: center; - min-height: 100vh; + min-height: 100%; flex-direction: column; diff --git a/src/components/states/Loading.vue b/src/components/states/Loading.vue index 922e010..4b94f08 100644 --- a/src/components/states/Loading.vue +++ b/src/components/states/Loading.vue @@ -13,7 +13,7 @@ export default Vue.extend({}); justify-content: center; align-items: center; - min-height: 100vh; + min-height: 100%; font-size: calc(0.75rem + 1vw); diff --git a/src/components/ui/List.vue b/src/components/ui/List.vue index 4c20c20..c807808 100644 --- a/src/components/ui/List.vue +++ b/src/components/ui/List.vue @@ -188,11 +188,6 @@ export default Vue.extend({ @import "../../styles/variables.scss"; @import "../../styles/responsive.scss"; -ul { - list-style: none; - padding: 0; -} - .hour { padding: 0.4em; border-radius: 1rem; @@ -247,17 +242,18 @@ ul { } display: block; - white-space: nowrap; border-collapse: collapse; font-size: calc(0.6rem + 0.4vw); - cursor: pointer; + + @include smallScreen() { + font-size: 0.5rem; + } thead th { - padding: 0.8rem; + padding: 0.2rem; background-color: #444; - min-width: 100px; } tr { @@ -284,6 +280,8 @@ ul { text-align: center; vertical-align: middle; + cursor: pointer; + @include smallScreen() { margin: 0; padding: 0.1rem 0.5rem; diff --git a/src/components/ui/Options.vue b/src/components/ui/Options.vue index 2cd14b6..673d161 100644 --- a/src/components/ui/Options.vue +++ b/src/components/ui/Options.vue @@ -51,14 +51,14 @@ export default Vue.extend({ .options { position: relative; - font-size: calc(0.7rem + 0.5vw); + font-size: calc(0.6rem + 0.9vw); display: flex; } button { color: #e0e0e0; - font-size: 1em; + font-size: 0.8em; display: flex; align-items: center; diff --git a/src/components/utils/ListFilter.vue b/src/components/utils/ListFilter.vue index f366d8b..b9549d1 100644 --- a/src/components/utils/ListFilter.vue +++ b/src/components/utils/ListFilter.vue @@ -12,6 +12,7 @@ :type="el.type" :id="item.id" :name="item.name" + v-model="item.value" checked @change="handleChange" /> @@ -30,15 +31,16 @@
 do 
+ +
+ +
+
+ +
+ +
+
+ +
  • + +
  • @@ -133,7 +168,22 @@ import { mapActions } from "vuex"; export default Vue.extend({ name: "list-filter", + watch: { + gridElements: { + handler: (v1, v2) => {}, + deep: true + } + }, data: () => ({ + oneWay: true, + twoWay: true, + levelFrom: 0, + levelTo: 20, + oneWayCatenary: 0, + oneWayOther: 0, + twoWayCatenary: 0, + twoWayOther: 0, + gridElements: { access: { title: "Dostępność", @@ -141,16 +191,19 @@ export default Vue.extend({ items: [ { id: "is-default", + value: true, name: "default", content: "w paczce z grą" }, { id: "not-default", + value: true, name: "notDefault", content: "poza paczką z grą" }, { id: "non-public", + value: true, name: "nonPublic", content: "niepubliczna" } @@ -164,21 +217,25 @@ export default Vue.extend({ items: [ { id: "SPK", + value: true, name: "SPK", content: "SPK" }, { id: "SCS", + value: true, name: "SCS", content: "SCS" }, { id: "by-hand", + value: true, name: "ręczne", content: "ręczne" }, { id: "levers", + value: true, name: "mechaniczne", content: "mechaniczne" } @@ -192,21 +249,25 @@ export default Vue.extend({ items: [ { id: "modern", + value: true, name: "współczesna", content: "współczesna" }, { id: "semaphore", + value: true, name: "kształtowa", content: "kształtowa" }, { id: "mixed", + value: true, name: "mieszana", content: "mieszana" }, { id: "historic", + value: true, name: "historyczna", content: "historyczna" } @@ -215,7 +276,7 @@ export default Vue.extend({ } }), methods: { - ...mapActions(["setFilter"]), + ...mapActions(["setFilter", "resetFilters"]), handleChange(e: any) { this.setFilter({ filterName: e.target.name, value: !e.target.checked }); }, @@ -224,6 +285,24 @@ export default Vue.extend({ filterName: e.target.name, value: parseInt(e.target.value) }); + }, + reset() { + for (const [key, value] of Object.entries(this.gridElements)) { + for (const item of this.gridElements[key].items) { + item.value = true; + } + } + + this.oneWay = true; + this.twoWay = true; + this.levelFrom = 0; + this.levelTo = 20; + this.oneWayCatenary = 0; + this.oneWayOther = 0; + this.twoWayCatenary = 0; + this.twoWayOther = 0; + + this.resetFilters(); } } }); @@ -246,6 +325,10 @@ export default Vue.extend({ white-space: nowrap; font-size: calc(0.6rem + 0.4vw); + + @include smallScreen() { + font-size: 0.65rem; + } } .grid { @@ -271,12 +354,13 @@ export default Vue.extend({ -webkit-user-select: none; } } +.item { + &-title { + text-align: center; + margin-bottom: 0.5rem; + font-weight: bold; -.item-title { - text-align: center; - margin-bottom: 0.5rem; - font-weight: bold; - - color: $accentCol; + color: $accentCol; + } } \ No newline at end of file diff --git a/src/store/backup.ts b/src/store/backup.ts deleted file mode 100644 index 164a5a0..0000000 --- a/src/store/backup.ts +++ /dev/null @@ -1,134 +0,0 @@ -import Vue from 'vue' -import Vuex from 'vuex' -import data from '@/data/stations.json'; - -Vue.use(Vuex) - -export default new Vuex.Store({ - state: { - stations: [], - filteredStations: [], - filters: [], - trainCount: 0 - }, - actions: { - fetchStations: async ({ commit }) => { - let onlineStations, statusList, onlineTrains - - try { - onlineStations = (await (await fetch('https://api.td2.info.pl:9640/?method=getStationsOnline')).json()).message - statusList = (await (await fetch('https://api.td2.info.pl:9640/?method=readFromSWDR&value=getDispatcherStatusList%3B1')).json()).message - onlineTrains = (await (await fetch('https://api.td2.info.pl:9640/?method=getTrainsOnline')).json()).message - } catch (error) { - throw Error(error.message); - } - - commit('setTrainCount', onlineTrains.filter((train) => train.isOnline && train.region === 'eu').length); - - const mappedStations = onlineStations - .filter((station) => station.region === 'eu') - .filter((station) => station.isOnline) - .map(( - { stationName = '', stationHash = '', maxUsers = 0, currentUsers = 0, spawnString = '', - dispatcherRate = 0, dispatcherName = '', dispatcherExp = 0, dispatcherId = 0 }) => { - - const status = statusList.find((s) => s[0] === stationHash && s[1] === 'eu') - let occupiedTo = "---" - let occupiedTimestamp = 0 - - if (!status) - occupiedTo = "NIEZALOGOWANY"; - else { - let occupiedCode = status[2]; - - occupiedTimestamp = status[3]; - occupiedTo = "NIEDOSTĘPNY"; - - if (occupiedCode === 0) { - if (occupiedTimestamp - Date.now() > 21000000) - occupiedTo = "BEZ LIMITU"; - else - occupiedTo = new Date(status[3]) - .toLocaleTimeString('en-US', - { hour12: false, hour: '2-digit', minute: '2-digit' }); - } - - if (occupiedCode === 1) - occupiedTo = "Z/W"; - - if (occupiedCode === 2 && occupiedTimestamp === 0) - occupiedTo = "KOŃCZY"; - - if (occupiedCode === 3) - occupiedTo = "BRAK MIEJSCA"; - } - - const trains = onlineTrains.filter((train) => - train.region === 'eu' && train.isOnline === 1 && train.station.stationName === stationName) - - const stationData = data.find((station) => station.stationName === stationName) || { stationName, stationURL: "" } - - return { - ...stationData, - stationHash, - maxUsers, - currentUsers, - spawnString: spawnString && spawnString.split(';').map(v => v.split(',')[6] ? v.split(',')[6] : v.split(',')[0]), - dispatcherName, - dispatcherRate, - dispatcherId, - dispatcherExp: dispatcherExp < 2 ? 'L' : dispatcherExp, - occupiedTo, - trains - } - }) - - commit('setStations', mappedStations); - commit('filterStations'); - }, - - addFilters({ commit }, filterId) { - commit('addFilters', filterId); - commit('filterStations'); - }, - - removeFilters({ commit }, filterId) { - commit('removeFilters', filterId); - commit('filterStations'); - } - }, - mutations: { - setStations: (state, stations) => state.stations = stations, - setTrainCount: (state, count) => state.trainCount = count, - - addFilters(state, filters) { - state.filters.push(...filters); - }, - removeFilters: (state, filters) => { - filters.forEach(filter => { - state.filters = state.filters.filter((id) => id !== filter); - }) - }, - - filterStations(state) { - state.filteredStations = state.stations.filter((station) => { - if (station.default && state.filters.includes("default")) return false; - if ((!station.default) && state.filters.includes("notDefault")) return false; - if ((station.nonPublic || !station.reqLevel) && (state.filters.includes("nonPublic"))) return false; - - if (state.filters.includes(station.controlType)) return false; - if (state.filters.includes(station.signalType)) return false; - - if (station.controlType && state.filters.filter((f) => station.controlType.includes(f)).length > 0) return false; - - return true; - }) - } - }, - getters: { - getStations: state => state.filteredStations, - getStationCount: state => state.stations.length, - getTrainCount: state => state.trainCount, - getFilters: state => state.filters, - } -}) \ No newline at end of file diff --git a/src/store/modules/store.ts b/src/store/modules/store.ts index d5cc4c8..6111768 100644 --- a/src/store/modules/store.ts +++ b/src/store/modules/store.ts @@ -27,6 +27,28 @@ class Store extends VuexModule { public filteredStations: {}[] = []; + public 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, + "levelFrom": 0, + "levelTo": 20, + "1track-ne": 0, + "2track-ne": 0, + "1track-e": 0, + "2track-e": 0, + "no-1track": false, + "no-2track": false + } as const; + public filters = { "default": false, "notDefault": false, @@ -45,6 +67,8 @@ class Store extends VuexModule { "2track-ne": 0, "1track-e": 0, "2track-e": 0, + "no-1track": false, + "no-2track": false } as any; @@ -70,6 +94,12 @@ class Store extends VuexModule { this.context.commit('filterStations'); } + @Action + public resetFilters() { + this.context.commit('resetFilterList'); + this.context.commit('filterStations'); + } + @Action public async fetchStations() { let onlineStations: { @@ -175,6 +205,9 @@ class Store extends VuexModule { if (station.reqLevel < this.filters['level-from']) return false; if (station.reqLevel > this.filters['level-to']) 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['1track-e']) return false; if (station.routes.oneWay.noCatenary < this.filters['1track-ne']) return false; @@ -195,6 +228,11 @@ class Store extends VuexModule { }) } + @Mutation + public resetFilterList() { + this.filters = { ...this.filterInitStates }; + } + @Mutation public setStations(stations: []) { this.stations = stations; diff --git a/tsconfig.json b/tsconfig.json index daa3f80..b2c2bcf 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,6 +5,8 @@ "strict": true, "jsx": "preserve", "importHelpers": true, + "suppressImplicitAnyIndexErrors": true, + "noImplicitAny": false, "moduleResolution": "node", "experimentalDecorators": true, "esModuleInterop": true,