diff --git a/src/assets/icon-historyczna.svg b/src/assets/icon-historyczna.svg index aed6e11..4bece83 100644 --- a/src/assets/icon-historyczna.svg +++ b/src/assets/icon-historyczna.svg @@ -1,18 +1,20 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/StationsView/FilterOption.vue b/src/components/StationsView/FilterOption.vue index ce66ff5..fe175fc 100644 --- a/src/components/StationsView/FilterOption.vue +++ b/src/components/StationsView/FilterOption.vue @@ -1,5 +1,11 @@ @@ -29,20 +35,51 @@ export default defineComponent({ filterStore: useStationFiltersStore(), }; }, + methods: { - handleChange() { + handleLeftClick() { this.option.value = !this.option.value; + this.filterStore.lastClickedFilterId = ''; this.filterStore.changeFilterValue({ name: this.option.name, value: !this.option.value, }); }, + + handleDbClick(e: Event) { + e.preventDefault(); + + + const lastClicked = this.filterStore.lastClickedFilterId == this.option.id; + console.log(this.filterStore.lastClickedFilterId); + this.filterStore.lastClickedFilterId = this.option.id; + this.option.value = true; + + this.filterStore.changeFilterValue({ + name: this.option.name, + value: !this.option.value, + }); + + this.filterStore.inputs.options + .filter((option) => { + return option.section == this.option.section && option.id != this.option.id; + }) + .forEach((option) => { + this.filterStore.changeFilterValue({ + name: option.name, + value: this.option.value, + }); + + option.value = !this.option.value; + }); + }, }, }); + diff --git a/src/components/StationsView/StationFilterCard.vue b/src/components/StationsView/StationFilterCard.vue index 65e397f..20878fb 100644 --- a/src/components/StationsView/StationFilterCard.vue +++ b/src/components/StationsView/StationFilterCard.vue @@ -26,15 +26,28 @@
{{ $t('filters.title') }}
+

- +
+

+ {{ $t(`filters.sections.${section}`) }} + + +

+ +
+ +
+ +
+
+
{{ $t('filters.minimum-hours-title') }}
@@ -80,18 +93,18 @@
- -
-
- - - - -
-
+ +
+
+ + + + +
+
@@ -181,15 +194,6 @@ export default defineComponent({ this.isVisible = !this.isVisible; }, - handleChange(change: { name: string; value: boolean }) { - this.filterStore.changeFilterValue({ - name: change.name, - value: !change.value, - }); - - if (this.saveOptions) StorageManager.setBooleanValue(change.name, change.value); - }, - handleInput(e: Event) { const target = e.target as HTMLInputElement; @@ -281,6 +285,14 @@ export default defineComponent({ } .card { + display: grid; + grid-template-rows: 1fr auto; + + &_info { + background-color: #111; + padding: 0.5em; + } + &_controls { display: flex; gap: 0.5em; @@ -292,13 +304,13 @@ export default defineComponent({ } &_content { + padding: 0.5em; + display: flex; flex-direction: column; + gap: 1em; - - max-height: 90vh; - - padding: 1em; + overflow: auto; } &_title { @@ -309,18 +321,6 @@ export default defineComponent({ text-align: center; } - &_options { - display: grid; - grid-template-columns: repeat(4, minmax(0, 1fr)); - grid-template-rows: repeat(4, 1fr); - gap: 0.5em; - - @include smallScreen() { - grid-template-columns: repeat(auto-fit, minmax(8em, 1fr)); - grid-template-rows: auto; - } - } - &_regions { display: flex; justify-content: center; @@ -391,6 +391,9 @@ export default defineComponent({ } &_actions { + width: 100%; + padding: 0.25em; + .filter-option { max-width: 50%; margin: 0 auto; @@ -417,6 +420,35 @@ export default defineComponent({ } } +.card_options { + .option-section h3 { + display: flex; + align-items: center; + margin-bottom: 0.25em; + + gap: 0.5em; + + button { + padding: 0.15em; + color: coral; + } + } + + .section-inputs { + display: grid; + // flex-wrap: wrap; + grid-template-columns: repeat(3, minmax(0, 1fr)); + // grid-template-rows: repeat(3, 1fr); + gap: 0.5em; + margin: 1em 0; + + // @include smallScreen() { + // grid-template-columns: repeat(auto-fit, minmax(8em, 1fr)); + // grid-template-rows: auto; + // } + } +} + .slider { display: flex; align-items: center; diff --git a/src/data/options.json b/src/data/options.json index 071fd8b..d532401 100644 --- a/src/data/options.json +++ b/src/data/options.json @@ -1,41 +1,38 @@ { + "optionSections": ["reality", "package-access", "access", "control", "addons", "blockades", "signals", "status"], + "options": [ - { - "id": "default", - "name": "default", - "iconName": "td2", - "section": "access", - "value": true, - "defaultValue": true - }, - { - "id": "not-default", - "name": "notDefault", - "iconName": "", - "section": "access", - "value": true, - "defaultValue": true - }, { "id": "real", "name": "real", - "iconName": "lock", - "section": "access", + "section": "reality", "value": true, "defaultValue": true }, { "id": "fictional", "name": "fictional", - "iconName": "user", - "section": "access", + "section": "reality", + "value": true, + "defaultValue": true + }, + { + "id": "default", + "name": "default", + "section": "package-access", + "value": true, + "defaultValue": true + }, + { + "id": "not-default", + "name": "notDefault", + "section": "package-access", "value": true, "defaultValue": true }, { "id": "non-public", "name": "nonPublic", - "iconName": "user", "section": "access", "value": true, "defaultValue": true @@ -43,7 +40,6 @@ { "id": "unavailable", "name": "unavailable", - "iconName": "user", "section": "access", "value": false, "defaultValue": false @@ -51,7 +47,6 @@ { "id": "abandoned", "name": "abandoned", - "iconName": "user", "section": "access", "value": false, "defaultValue": false @@ -59,7 +54,6 @@ { "id": "SPK", "name": "SPK", - "iconName": "SPK", "section": "control", "value": true, "defaultValue": true @@ -67,7 +61,6 @@ { "id": "SCS", "name": "SCS", - "iconName": "SCS", "section": "control", "value": true, "defaultValue": true @@ -75,15 +68,21 @@ { "id": "SPE", "name": "SPE", - "iconName": "SPE", + "section": "control", + "value": true, + "defaultValue": true + }, + + { + "id": "SPK-M", + "name": "mechaniczne+SPK", "section": "control", "value": true, "defaultValue": true }, { - "id": "manual", - "name": "ręczne", - "iconName": "ręczne", + "id": "SCS-M", + "name": "mechaniczne+SCS", "section": "control", "value": true, "defaultValue": true @@ -91,7 +90,27 @@ { "id": "mechanical", "name": "mechaniczne", - "iconName": "mechaniczne", + "section": "control", + "value": true, + "defaultValue": true + }, + { + "id": "SPK-R", + "name": "ręczne+SPK", + "section": "control", + "value": true, + "defaultValue": true + }, + { + "id": "SCS-R", + "name": "ręczne+SCS", + "section": "control", + "value": true, + "defaultValue": true + }, + { + "id": "manual", + "name": "ręczne", "section": "control", "value": true, "defaultValue": true @@ -99,23 +118,34 @@ { "id": "SUP", "name": "SUP", - "iconName": "SUP", - "section": "control", + "section": "addons", + "value": true, + "defaultValue": true + }, + { + "id": "noSUP", + "name": "noSUP", + "section": "addons", "value": true, "defaultValue": true }, { "id": "SBL", "name": "SBL", - "iconName": "SBL", - "section": "routes", + "section": "blockades", + "value": true, + "defaultValue": true + }, + { + "id": "PBL", + "name": "PBL", + "section": "blockades", "value": true, "defaultValue": true }, { "id": "modern", "name": "współczesna", - "iconName": "współczesna", "section": "signals", "value": true, "defaultValue": true @@ -123,7 +153,6 @@ { "id": "semaphores", "name": "kształtowa", - "iconName": "kształtowa", "section": "signals", "value": true, "defaultValue": true @@ -131,7 +160,6 @@ { "id": "mixed", "name": "mieszana", - "iconName": "mieszana", "section": "signals", "value": true, "defaultValue": true @@ -139,7 +167,6 @@ { "id": "historical", "name": "historyczna", - "iconName": "historyczna", "section": "signals", "value": true, "defaultValue": true @@ -148,7 +175,6 @@ { "id": "free", "name": "free", - "iconName": "", "section": "status", "value": false, @@ -157,7 +183,6 @@ { "id": "occupied", "name": "occupied", - "iconName": "", "section": "status", "value": true, @@ -166,7 +191,6 @@ { "id": "endingStatus", "name": "endingStatus", - "iconName": "", "section": "status", "value": true, @@ -175,7 +199,6 @@ { "id": "afkStatus", "name": "afkStatus", - "iconName": "", "section": "status", "value": true, @@ -184,7 +207,6 @@ { "id": "noSpaceStatus", "name": "noSpaceStatus", - "iconName": "", "section": "status", "value": true, @@ -193,7 +215,6 @@ { "id": "unavailableStatus", "name": "unavailableStatus", - "iconName": "", "section": "status", "value": true, @@ -254,7 +275,6 @@ { "id": "include-selected", "name": "include-selected", - "iconName": "", "section": "mode", "value": true, "defaultValue": true @@ -262,7 +282,6 @@ { "id": "save", "name": "save", - "iconName": "", "section": "mode", "value": true, "defaultValue": true diff --git a/src/locales/en.json b/src/locales/en.json index 413a0fe..264301a 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -35,7 +35,7 @@ "desc": { "control-type": "Control type: ", "signals-type": "Signals type: ", - "SBL": "This scenery has automatic line blockade system on following routes: ", + "SBL": "This scenery has automatic block signalling (ABS/SBL) system on following routes: ", "SUP": "Requires the SUP application (level crossing remote control simulator)", "TWB-all": "This scenery has two-way route blockade on all routes", "TWB-routes": "This scenery has two-way route blockade on following routes: ", @@ -129,14 +129,27 @@ "filter-active": "ACTIVE" }, "filters": { + "desc": " • Left mouse click: select / unselect chosen filter
• Double left click: unselect all filters but chosen from group
RESET: reset all filters from group", + + "sections": { + "reality": "SCENERY REALITY", + "package-access": "IN-GAME AVAILABILITY", + "access": "GENERAL AVAILABILITY", + "control": "CONTROLS", + "signals": "SIGNALLING", + "addons": "ADDITIONAL PROGRAMS", + "blockades": "BLOCKADE TYPE", + "status": "ONLINE STATUS" + }, + "endingStatus": "ENDS SOON", "afkStatus": "AFK", "noSpaceStatus": "NO SPACE", "unavailableStatus": "UNAVAILABLE", - "title": "STATION FILTER", - "default": "DEFAULT", - "not-default": "OTHER", + "title": "STATION FILTERS", + "default": "IN-GAME", + "not-default": "ADDITIONAL", "real": "REAL", "fictional": "FICTIONAL", "unavailable": "UNSUPPORTED", @@ -144,12 +157,22 @@ "abandoned": "ABANDONED", "SPK": "SPK", + "SPK-R": "SPK + MANUAL", + "SPK-M": "SPK + MECH.", "SCS": "SCS", + "SCS-R": "SCS + MANUAL", + "SCS-M": "SCS + MECH.", "SPE": "SPE", + "manual": "MANUAL", "mechanical": "MECHANICAL", - "SUP": "SUP", - "SBL": "SBL", + + "SUP": "SUP (RASP-UZK)", + "noSUP": "NO SUP", + + "SBL": "ABS (SBL)", + "PBL": "NO ABS (PBL)", + "modern": "MODERN", "semaphores": "SEMAPHORES", "mixed": "MIXED", @@ -170,7 +193,7 @@ "hour": "h", "no-limit": "NO LIMIT", "include-selected": "INCLUDE SELECTED", - "save": "SAVE FILTERS", + "save": "REMEMBER FILTERS", "reset": "RESET FILTERS", "close": "CLOSE FILTERS" }, diff --git a/src/locales/pl.json b/src/locales/pl.json index b4745e1..ebd2977 100644 --- a/src/locales/pl.json +++ b/src/locales/pl.json @@ -132,6 +132,19 @@ "filter-active": "AKTYWNE" }, "filters": { + "desc": " • Kliknięcie: zaznaczenie / odznaczenie filtru
• Podwójne kliknięcie: odznaczenie reszty filtrów z grupy
RESET: zresetowanie filtrów z grupy", + + "sections": { + "reality": "FIKCYJNOŚĆ SCENERII", + "package-access": "DOSTĘPNOŚĆ W PACZCE", + "access": "DOSTĘPNOŚĆ OGÓLNA", + "control": "TYP STEROWANIA", + "signals": "TYP SYGNALIZACJI", + "addons": "DODATKOWE PROGRAMY", + "blockades": "BLOKADY LINIOWE", + "status": "STATUS ONLINE" + }, + "endingStatus": "KOŃCZY", "afkStatus": "Z/W", "noSpaceStatus": "BRAK MIEJSCA", @@ -147,18 +160,29 @@ "abandoned": "WYCOFANA", "SPK": "SPK", + "SPK-R": "SPK + RĘCZNE", + "SPK-M": "SPK + MECH.", "SCS": "SCS", + "SCS-R": "SCS + RĘCZNE", + "SCS-M": "SCS + MECH.", "SPE": "SPE", "manual": "RĘCZNE", - "SUP": "SUP", + + "SUP": "SUP (RASP-UZK)", + "noSUP": "BEZ SUP", + "SBL": "SBL", + "PBL": "PBL", + "mechanical": "MECHANICZNE", "modern": "WSPÓŁCZESNA", "semaphores": "KSZTAŁTOWA", "mixed": "MIESZANA", "historical": "HISTORYCZNA", + "free": "WOLNA", "occupied": "ZAJĘTA", + "sliders": { "min-lvl": "MIN. WYMAGANY POZIOM DYŻURNEGO", "max-lvl": "MAKS. WYMAGANY POZIOM DYŻURNEGO", @@ -167,13 +191,14 @@ "routes-2t-cat": "SZLAKI DWUTOROWE ZELEKTR. (MINIMUM)", "routes-2t-other": "SZLAKI DWUTOROWE NIEZELEKTR. (MINIMUM)" }, + "authors-search": "Szukaj autora (uwzględnia inne filtry)", "minimum-hours-title": "POKAŻ TYLKO SCENERIE DOSTĘPNE MINIMUM DO:", "now": "TERAZ", "hour": " godz.", "no-limit": "BEZ LIMITU", "include-selected": "POKAŻ ZAZNACZONE", - "save": "ZAPISZ FILTRY", + "save": "ZAPAMIĘTAJ FILTRY", "reset": "RESETUJ FILTRY", "close": "ZAMKNIJ FILTRY" }, diff --git a/src/scripts/interfaces/Filter.ts b/src/scripts/interfaces/Filter.ts index 0afc51c..441b69e 100644 --- a/src/scripts/interfaces/Filter.ts +++ b/src/scripts/interfaces/Filter.ts @@ -1,16 +1,22 @@ export default interface Filter { - [key: string]: (boolean | number | string), + [key: string]: boolean | number | string; default: boolean; notDefault: boolean; real: boolean; fictional: boolean; - "SPK": boolean; - "SCS": boolean; - "SPE": boolean; - "SUP": boolean; + SPK: boolean; + SCS: boolean; + SPE: boolean; + SUP: boolean; + noSUP: boolean; ręczne: boolean; + 'ręczne+SPK': boolean; + 'ręczne+SCS': boolean; mechaniczne: boolean; - "SBL": boolean; + 'mechaniczne+SPK': boolean; + 'mechaniczne+SCS': boolean; + SBL: boolean; + PBL: boolean; współczesna: boolean; kształtowa: boolean; historyczna: boolean; diff --git a/src/store/stationFiltersStore.ts b/src/store/stationFiltersStore.ts index 8bd778c..8d9f95b 100644 --- a/src/store/stationFiltersStore.ts +++ b/src/store/stationFiltersStore.ts @@ -94,12 +94,12 @@ const filterStations = (station: Station, filters: Filter, isOffline = false) => return returnMode; if (station.generalInfo) { - const routes = station.generalInfo.routes; - const availability = station.generalInfo.availability; + const { routes, availability, controlType, lines, reqLevel, signalType, SUP, authors } = station.generalInfo; - if (filters['abandoned'] && availability == 'abandoned' && !station.onlineInfo) return returnMode; + if (availability == 'abandoned' && filters['abandoned'] && !station.onlineInfo) return returnMode; if (availability == 'default' && filters['default']) return returnMode; + if ( availability != 'default' && filters['notDefault'] && @@ -107,24 +107,17 @@ const filterStations = (station: Station, filters: Filter, isOffline = false) => ) return returnMode; - if (filters['real'] && station.generalInfo.lines != '') return returnMode; + if (filters['real'] && lines) return returnMode; + if (filters['fictional'] && !lines) return returnMode; + if ( - filters['fictional'] && - station.generalInfo.lines == '' && - availability != 'abandoned' && - availability != 'unavailable' + reqLevel + (availability == 'nonPublic' || availability == 'unavailable' || availability == 'abandoned' ? 1 : 0) < + filters['minLevel'] ) return returnMode; if ( - station.generalInfo.reqLevel + - (availability == 'nonPublic' || availability == 'unavailable' || availability == 'abandoned' ? 1 : 0) < - filters['minLevel'] - ) - return returnMode; - if ( - station.generalInfo.reqLevel + - (availability == 'nonPublic' || availability == 'unavailable' || availability == 'abandoned' ? 1 : 0) > + reqLevel + (availability == 'nonPublic' || availability == 'unavailable' || availability == 'abandoned' ? 1 : 0) > filters['maxLevel'] ) return returnMode; @@ -146,42 +139,32 @@ const filterStations = (station: Station, filters: Filter, isOffline = false) => if (routes.twoWayCatenaryRouteNames.length < filters['minTwoWayCatenary']) return returnMode; if (routes.twoWayNoCatenaryRouteNames.length < filters['minTwoWay']) return returnMode; - if (filters[station.generalInfo.controlType]) return returnMode; - if (filters[station.generalInfo.signalType]) return returnMode; + if (filters[controlType]) return returnMode; + if (filters[signalType]) return returnMode; - if ( - filters['SPK'] && - (station.generalInfo.controlType === 'SPK' || station.generalInfo.controlType.includes('+SPK')) - ) - return returnMode; - if ( - filters['SCS'] && - (station.generalInfo.controlType === 'SCS' || station.generalInfo.controlType.includes('+SCS')) - ) - return returnMode; - if ( - filters['SPE'] && - (station.generalInfo.controlType === 'SPE' || station.generalInfo.controlType.includes('+SPE')) - ) - return returnMode; - if (filters['SUP'] && station.generalInfo.SUP) return returnMode; + if (filters['SPK'] && controlType === 'SPK') return returnMode; + if (filters['SCS'] && controlType === 'SCS') return returnMode; + if (filters['SPE'] && controlType === 'SPE') return returnMode; + if (filters['SUP'] && SUP) return returnMode; + if (filters['noSUP'] && !SUP) return returnMode; - if ( - filters['SCS'] && - filters['SPK'] && - (station.generalInfo.controlType.includes('SPK') || station.generalInfo.controlType.includes('SCS')) - ) - return returnMode; + // if (filters['SCS'] && filters['SPK'] && (controlType.includes('SPK') || controlType.includes('SCS'))) + // return returnMode; - if (filters['mechaniczne'] && station.generalInfo.controlType.includes('mechaniczne')) return returnMode; + if (filters['mechaniczne'] && controlType == 'mechaniczne') return returnMode; + if (filters['mechaniczne+SPK'] && controlType == 'mechaniczne+SPK') return returnMode; + if (filters['mechaniczne+SCS'] && controlType == 'mechaniczne+SCS') return returnMode; - if (filters['ręczne'] && station.generalInfo.controlType.includes('ręczne')) return returnMode; + if (filters['ręczne'] && controlType == 'ręczne') return returnMode; + if (filters['ręczne+SPK'] && controlType == 'ręczne+SPK') return returnMode; + if (filters['ręczne+SCS'] && controlType == 'ręczne+SCS') return returnMode; if (filters['SBL'] && routes.sblRouteNames.length > 0) return returnMode; + if (filters['PBL'] && routes.sblRouteNames.length == 0) return returnMode; if ( filters['authors'].length > 3 && - !station.generalInfo.authors?.map((a) => a.toLocaleLowerCase()).includes(filters['authors'].toLocaleLowerCase()) + !authors?.map((a) => a.toLocaleLowerCase()).includes(filters['authors'].toLocaleLowerCase()) ) return returnMode; } @@ -198,13 +181,19 @@ const filterInitStates: Filter = { SCS: false, SPE: false, SUP: false, + noSUP: false, ręczne: false, + 'ręczne+SPK': false, + 'ręczne+SCS': false, mechaniczne: false, + 'mechaniczne+SPK': false, + 'mechaniczne+SCS': false, współczesna: false, kształtowa: false, historyczna: false, mieszana: false, SBL: false, + PBL: false, minLevel: 0, maxLevel: 20, minOneWayCatenary: 0, @@ -238,6 +227,7 @@ export const useStationFiltersStore = defineStore('stationFiltersStore', { filters: { ...filterInitStates }, sorterActive: { index: 0, dir: 1 }, store: useStore(), + lastClickedFilterId: '', }; }, @@ -295,6 +285,17 @@ export const useStationFiltersStore = defineStore('stationFiltersStore', { }); }, + resetSectionOptions(section: string) { + this.inputs.options.forEach((option) => { + if (option.section != section) return; + + option.value = option.defaultValue; + this.filters[option.id] = !option.defaultValue; + + StorageManager.setBooleanValue(option.name, !option.defaultValue); + }); + }, + changeSorter(index: number) { if (index > 4 && index < 7) return; @@ -305,4 +306,3 @@ export const useStationFiltersStore = defineStore('stationFiltersStore', { }, }, }); - diff --git a/src/store/utils/filterUtils.ts b/src/store/utils/filterUtils.ts new file mode 100644 index 0000000..1c19a31 --- /dev/null +++ b/src/store/utils/filterUtils.ts @@ -0,0 +1,185 @@ +import Station from '../../scripts/interfaces/Station'; + +export const sortStations = (a: Station, b: Station, sorter: { index: number; dir: number }) => { + switch (sorter.index) { + case 0: + return sorter.dir == 1 ? a.name.localeCompare(b.name) : b.name.localeCompare(a.name); + + case 1: + if ((a.generalInfo?.reqLevel || 0) > (b.generalInfo?.reqLevel || 0)) return sorter.dir; + if ((a.generalInfo?.reqLevel || 0) < (b.generalInfo?.reqLevel || 0)) return -sorter.dir; + break; + + case 2: + if ((a.onlineInfo?.statusTimestamp || 0) > (b.onlineInfo?.statusTimestamp || 0)) return sorter.dir; + if ((a.onlineInfo?.statusTimestamp || 0) < (b.onlineInfo?.statusTimestamp || 0)) return -sorter.dir; + break; + + case 3: + if ((a.onlineInfo?.dispatcherName.toLowerCase() || '') > (b.onlineInfo?.dispatcherName.toLowerCase() || '')) + return sorter.dir; + if ((a.onlineInfo?.dispatcherName.toLowerCase() || '') < (b.onlineInfo?.dispatcherName.toLowerCase() || '')) + return -sorter.dir; + break; + + case 4: + if ((a.onlineInfo?.dispatcherExp || 0) > (b.onlineInfo?.dispatcherExp || 0)) return sorter.dir; + if ((a.onlineInfo?.dispatcherExp || 0) < (b.onlineInfo?.dispatcherExp || 0)) return -sorter.dir; + break; + + case 7: + if ((a.onlineInfo?.currentUsers || 0) > (b.onlineInfo?.currentUsers || 0)) return sorter.dir; + if ((a.onlineInfo?.currentUsers || 0) < (b.onlineInfo?.currentUsers || 0)) return -sorter.dir; + + if ((a.onlineInfo?.maxUsers || 0) > (b.onlineInfo?.maxUsers || 0)) return sorter.dir; + if ((a.onlineInfo?.maxUsers || 0) < (b.onlineInfo?.maxUsers || 0)) return -sorter.dir; + break; + + case 8: + if ((a.onlineInfo?.spawns.length || 0) > (b.onlineInfo?.spawns.length || 0)) return sorter.dir; + if ((a.onlineInfo?.spawns.length || 0) < (b.onlineInfo?.spawns.length || 0)) return -sorter.dir; + + break; + + case 9: + if ((a.onlineInfo?.scheduledTrains?.length || 0) > (b.onlineInfo?.scheduledTrains?.length || 0)) + return sorter.dir; + if ((a.onlineInfo?.scheduledTrains?.length || 0) < (b.onlineInfo?.scheduledTrains?.length || 0)) + return -sorter.dir; + + default: + break; + } + + return a.name.localeCompare(b.name); +}; + +export const filterStations = (station: Station, filters: { [key: string]: any }, isOffline = false) => { + const returnMode = false; + + if ((station.generalInfo?.availability == 'nonPublic' || !station.generalInfo) && filters['nonPublic']) + return returnMode; + + if (station.onlineInfo?.statusID == 'ending' && filters['ending']) return returnMode; + + if ( + station.onlineInfo && + station.onlineInfo.statusTimestamp > 0 && + filters['onlineFromHours'] < 8 && + station.onlineInfo.statusTimestamp <= Date.now() + filters['onlineFromHours'] * 3600000 + ) + return returnMode; + + if (filters['onlineFromHours'] > 0 && station.onlineInfo && station.onlineInfo.statusTimestamp <= 0) + return returnMode; + if (filters['onlineFromHours'] == 8 && station.onlineInfo?.statusID != 'no-limit') return returnMode; + + if (station.onlineInfo?.statusID == 'ending' && filters['endingStatus']) return returnMode; + if ( + (station.onlineInfo?.statusID == 'not-signed' || station.onlineInfo?.statusID == 'unavailable') && + filters['unavailableStatus'] + ) + return returnMode; + if (station.onlineInfo?.statusID == 'brb' && filters['afkStatus']) return returnMode; + if (station.onlineInfo?.statusID == 'no-space' && filters['noSpaceStatus']) return returnMode; + + if (station.onlineInfo && filters['occupied']) return returnMode; + if (!station.onlineInfo && filters['free']) return returnMode; + if (station.generalInfo?.availability == 'unavailable' && filters['unavailable'] && !station.onlineInfo) + return returnMode; + + if (station.generalInfo) { + const routes = station.generalInfo.routes; + const availability = station.generalInfo.availability; + + if (filters['abandoned'] && availability == 'abandoned' && !station.onlineInfo) return returnMode; + + if (availability == 'default' && filters['default']) return returnMode; + if ( + availability != 'default' && + filters['notDefault'] && + !(availability == 'abandoned' || availability == 'unavailable') + ) + return returnMode; + + if (filters['real'] && station.generalInfo.lines != '') return returnMode; + if ( + filters['fictional'] && + station.generalInfo.lines == '' && + availability != 'abandoned' && + availability != 'unavailable' + ) + return returnMode; + + if ( + station.generalInfo.reqLevel + + (availability == 'nonPublic' || availability == 'unavailable' || availability == 'abandoned' ? 1 : 0) < + filters['minLevel'] + ) + return returnMode; + if ( + station.generalInfo.reqLevel + + (availability == 'nonPublic' || availability == 'unavailable' || availability == 'abandoned' ? 1 : 0) > + filters['maxLevel'] + ) + return returnMode; + + if ( + filters['no-1track'] && + (routes.oneWayCatenaryRouteNames.length != 0 || routes.oneWayNoCatenaryRouteNames.length != 0) + ) + return returnMode; + if ( + filters['no-2track'] && + (routes.twoWayCatenaryRouteNames.length != 0 || routes.twoWayNoCatenaryRouteNames.length != 0) + ) + return returnMode; + + if (routes.oneWayCatenaryRouteNames.length < filters['minOneWayCatenary']) return returnMode; + if (routes.oneWayNoCatenaryRouteNames.length < filters['minOneWay']) return returnMode; + + if (routes.twoWayCatenaryRouteNames.length < filters['minTwoWayCatenary']) return returnMode; + if (routes.twoWayNoCatenaryRouteNames.length < filters['minTwoWay']) return returnMode; + + if (filters[station.generalInfo.controlType]) return returnMode; + if (filters[station.generalInfo.signalType]) return returnMode; + + if ( + filters['SPK'] && + (station.generalInfo.controlType === 'SPK' || station.generalInfo.controlType.includes('+SPK')) + ) + return returnMode; + if ( + filters['SCS'] && + (station.generalInfo.controlType === 'SCS' || station.generalInfo.controlType.includes('+SCS')) + ) + return returnMode; + if ( + filters['SPE'] && + (station.generalInfo.controlType === 'SPE' || station.generalInfo.controlType.includes('+SPE')) + ) + return returnMode; + if (filters['SUP'] && station.generalInfo.SUP) return returnMode; + + if ( + filters['SCS'] && + filters['SPK'] && + (station.generalInfo.controlType.includes('SPK') || station.generalInfo.controlType.includes('SCS')) + ) + return returnMode; + + if (filters['mechaniczne'] && station.generalInfo.controlType.includes('mechaniczne')) return returnMode; + + if (filters['ręczne'] && station.generalInfo.controlType.includes('ręczne')) return returnMode; + + if (filters['SBL'] && routes.sblRouteNames.length > 0) return returnMode; + + if ( + filters['authors'].length > 3 && + !station.generalInfo.authors?.map((a) => a.toLocaleLowerCase()).includes(filters['authors'].toLocaleLowerCase()) + ) + return returnMode; + } + + return true; +}; diff --git a/src/styles/card.scss b/src/styles/card.scss index 80ecd71..0906d22 100644 --- a/src/styles/card.scss +++ b/src/styles/card.scss @@ -21,17 +21,15 @@ transform: translate(-50%, -50%); - overflow-x: hidden; - background: #202020da; + overflow: hidden; + background: #202020e8; box-shadow: 0 0 15px 5px #303030; - width: 600px; + width: 95%; + max-width: 700px; - @include smallScreen { - width: 100%; - height: 80vh; - } + max-height: 95vh; &-exit { position: absolute;