mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-03 13:28:11 +00:00
Globalny TrainModal; animacja przejścia
This commit is contained in:
@@ -17,6 +17,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal-anim {
|
||||||
|
&-enter-active,
|
||||||
|
&-leave-active {
|
||||||
|
transition: all $animDuration $animType;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-enter-from,
|
||||||
|
&-leave-to {
|
||||||
|
transform: translateY(-25%);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.route {
|
.route {
|
||||||
margin: 0 0.2em;
|
margin: 0 0.2em;
|
||||||
|
|
||||||
|
|||||||
+11
-4
@@ -1,7 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app_container">
|
<div class="app_container">
|
||||||
<UpdateModal />
|
<UpdateModal />
|
||||||
|
|
||||||
|
<transition name="modal-anim">
|
||||||
|
<keep-alive>
|
||||||
|
<TrainModal v-if="store.chosenModalTrain" />
|
||||||
|
</keep-alive>
|
||||||
|
</transition>
|
||||||
|
|
||||||
<header class="app_header">
|
<header class="app_header">
|
||||||
<div class="header_container">
|
<div class="header_container">
|
||||||
<div class="header_icons">
|
<div class="header_icons">
|
||||||
@@ -59,7 +65,6 @@
|
|||||||
|
|
||||||
<main class="app_main">
|
<main class="app_main">
|
||||||
<router-view v-slot="{ Component }">
|
<router-view v-slot="{ Component }">
|
||||||
<!-- <transition name="view-anim" mode="out-in"> -->
|
|
||||||
<keep-alive>
|
<keep-alive>
|
||||||
<component :is="Component" :key="$route.path" />
|
<component :is="Component" :key="$route.path" />
|
||||||
</keep-alive>
|
</keep-alive>
|
||||||
@@ -89,14 +94,16 @@ import StatusIndicator from '@/components/App/StatusIndicator.vue';
|
|||||||
import SelectBox from '@/components/Global/SelectBox.vue';
|
import SelectBox from '@/components/Global/SelectBox.vue';
|
||||||
import { useStore } from './store/store';
|
import { useStore } from './store/store';
|
||||||
import UpdateModal from './components/App/UpdateModal.vue';
|
import UpdateModal from './components/App/UpdateModal.vue';
|
||||||
|
import TrainModal from './components/Global/TrainModal.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
Clock,
|
Clock,
|
||||||
StatusIndicator,
|
StatusIndicator,
|
||||||
SelectBox,
|
SelectBox,
|
||||||
UpdateModal
|
UpdateModal,
|
||||||
},
|
TrainModal,
|
||||||
|
},
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
|||||||
@@ -1,38 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="train-modal" @keydown.esc="closeModal">
|
<div class="train-modal" v-if="store.chosenModalTrain" @keydown.esc="closeModal">
|
||||||
<div class="modal_background" @click="closeModal"></div>
|
<div class="modal_background" @click="closeModal"></div>
|
||||||
<div class="modal_content" ref="content" tabindex="0">
|
<div class="modal_content" ref="content" tabindex="0">
|
||||||
<!-- <transition name="top-info-bar-anim">
|
|
||||||
<div class="top-info-bar" v-if="isTopBarVisible">
|
|
||||||
<span v-if="chosenTrain.timetableData">
|
|
||||||
<b class="text--primary">{{ chosenTrain.timetableData.category }} {{ chosenTrain.trainNo }}</b>
|
|
||||||
{{ chosenTrain.driverName }} •
|
|
||||||
<b>{{ chosenTrain.timetableData.route.replace('|', ' > ') }}</b>
|
|
||||||
•
|
|
||||||
{{ currentDistance(chosenTrain.timetableData.followingStops) }} km /
|
|
||||||
<span class="text--primary">{{ chosenTrain.timetableData.routeDistance }} km</span>
|
|
||||||
•
|
|
||||||
<span class="text--grayed">{{ displayTrainPosition(chosenTrain) }}</span>
|
|
||||||
•
|
|
||||||
{{ chosenTrain.speed }}km/h
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</transition> -->
|
|
||||||
|
|
||||||
<button class="btn exit" @click="closeModal">
|
<button class="btn exit" @click="closeModal">
|
||||||
<img :src="icons.exit" alt="close card" />
|
<img :src="icons.exit" alt="close card" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<TrainInfo :train="chosenTrain" :extended="false" ref="trainInfo" />
|
<TrainInfo :train="store.chosenModalTrain" :extended="false" ref="trainInfo" />
|
||||||
<TrainSchedule :train="chosenTrain" tabindex="0" />
|
<TrainSchedule :train="store.chosenModalTrain" tabindex="0" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import trainInfoMixin from '@/mixins/trainInfoMixin';
|
import trainInfoMixin from '@/mixins/trainInfoMixin';
|
||||||
import Train from '@/scripts/interfaces/Train';
|
import { useStore } from '@/store/store';
|
||||||
import { defineComponent, PropType } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import TrainInfo from '../TrainsView/TrainInfo.vue';
|
import TrainInfo from '../TrainsView/TrainInfo.vue';
|
||||||
import TrainSchedule from '../TrainsView/TrainSchedule.vue';
|
import TrainSchedule from '../TrainsView/TrainSchedule.vue';
|
||||||
|
|
||||||
@@ -40,8 +23,6 @@ export default defineComponent({
|
|||||||
components: { TrainInfo, TrainSchedule },
|
components: { TrainInfo, TrainSchedule },
|
||||||
mixins: [trainInfoMixin],
|
mixins: [trainInfoMixin],
|
||||||
|
|
||||||
emits: ['closeModal'],
|
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isTopBarVisible: false,
|
isTopBarVisible: false,
|
||||||
@@ -52,11 +33,12 @@ export default defineComponent({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
setup() {
|
||||||
chosenTrain: {
|
const store = useStore();
|
||||||
type: Object as PropType<Train>,
|
|
||||||
required: true,
|
return {
|
||||||
},
|
store,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
activated() {
|
activated() {
|
||||||
@@ -65,23 +47,11 @@ export default defineComponent({
|
|||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
contentEl.focus();
|
contentEl.focus();
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.style.overflowY = 'hidden';
|
|
||||||
// document.body.blur();
|
|
||||||
|
|
||||||
// contentEl.addEventListener('scroll', this.handleContentScroll);
|
|
||||||
},
|
|
||||||
|
|
||||||
deactivated() {
|
|
||||||
document.body.style.overflowY = 'scroll';
|
|
||||||
|
|
||||||
// (this.$refs['content'] as HTMLElement).removeEventListener('scroll', this.handleContentScroll);
|
|
||||||
// this.isTopBarVisible = false;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
closeModal() {
|
closeModal() {
|
||||||
this.$emit('closeModal');
|
this.store.chosenModalTrain = undefined;
|
||||||
},
|
},
|
||||||
|
|
||||||
handleContentScroll(e: Event) {
|
handleContentScroll(e: Event) {
|
||||||
@@ -120,7 +90,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
padding: 0.25em;
|
padding: 0.25em;
|
||||||
|
|
||||||
z-index: 101;
|
z-index: 201;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 1.5rem;
|
width: 1.5rem;
|
||||||
@@ -134,10 +104,9 @@ export default defineComponent({
|
|||||||
left: 0;
|
left: 0;
|
||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
color: white;
|
color: white;
|
||||||
z-index: 100;
|
z-index: 200;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -149,8 +118,8 @@ export default defineComponent({
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100vw;
|
||||||
height: 100%;
|
height: 100vh;
|
||||||
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
@@ -164,26 +133,10 @@ export default defineComponent({
|
|||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
|
|
||||||
width: 95vw;
|
width: 95vw;
|
||||||
height: 95vh;
|
max-height: 96vh;
|
||||||
|
|
||||||
background-color: #1a1a1a;
|
background-color: #1a1a1a;
|
||||||
}
|
box-shadow: 0 0 15px 10px #0e0e0e;
|
||||||
.top-info-bar {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
padding: 0.5em 1em;
|
|
||||||
padding-right: 4em;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
z-index: 101;
|
|
||||||
|
|
||||||
background-color: #000000dd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@include midScreen {
|
@include midScreen {
|
||||||
@@ -194,10 +147,6 @@ export default defineComponent({
|
|||||||
width: 1.75rem;
|
width: 1.75rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-info-bar {
|
|
||||||
padding: 0.5em 1em;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@include smallScreen {
|
@include smallScreen {
|
||||||
@@ -206,7 +155,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
.modal_content {
|
.modal_content {
|
||||||
max-height: 75vh;
|
max-height: 85vh;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -11,10 +11,10 @@
|
|||||||
v-for="(train, i) in computedStationTrains"
|
v-for="(train, i) in computedStationTrains"
|
||||||
class="badge user"
|
class="badge user"
|
||||||
:class="train.stopStatus"
|
:class="train.stopStatus"
|
||||||
:key="train.trainNo + i"
|
:key="train.trainId"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
@click="navigateTo('/trains', { trainNo: train.trainNo, driverName: train.driverName })"
|
@click="selectTrain(train.trainId)"
|
||||||
@keydown.enter="navigateTo('/trains', { trainNo: train.trainNo, driverName: train.driverName })"
|
@keydown.enter="selectTrain(train.trainId)"
|
||||||
>
|
>
|
||||||
<span class="user_train">{{ train.trainNo }}</span>
|
<span class="user_train">{{ train.trainNo }}</span>
|
||||||
<span class="user_name">{{ train.driverName }}</span>
|
<span class="user_name">{{ train.driverName }}</span>
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import routerMixin from '@/mixins/routerMixin';
|
import routerMixin from '@/mixins/routerMixin';
|
||||||
import Station from '@/scripts/interfaces/Station';
|
import Station from '@/scripts/interfaces/Station';
|
||||||
|
import { useStore } from '@/store/store';
|
||||||
import { computed, defineComponent } from 'vue';
|
import { computed, defineComponent } from 'vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
@@ -42,6 +43,8 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
setup(props) {
|
setup(props) {
|
||||||
|
const store = useStore();
|
||||||
|
|
||||||
const computedStationTrains = computed(() => {
|
const computedStationTrains = computed(() => {
|
||||||
if (!props.station) return [];
|
if (!props.station) return [];
|
||||||
|
|
||||||
@@ -59,7 +62,7 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return { computedStationTrains };
|
return { computedStationTrains, store };
|
||||||
},
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
@@ -67,6 +70,12 @@ export default defineComponent({
|
|||||||
user: require('@/assets/icon-user.svg'),
|
user: require('@/assets/icon-user.svg'),
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
selectTrain(trainId: string) {
|
||||||
|
this.store.chosenModalTrain = this.store.trainList.find((train) => train.trainId == trainId);
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -130,3 +139,4 @@ $disconnected: slategray;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -25,10 +25,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<keep-alive>
|
|
||||||
<TrainModal v-if="chosenTrain" :chosen-train="chosenTrain" @close-modal="closeTrainModal" />
|
|
||||||
</keep-alive>
|
|
||||||
|
|
||||||
<div class="timetable-list">
|
<div class="timetable-list">
|
||||||
<!-- <transition name="scenery-timetable-list-anim" mode="out-in"> -->
|
<!-- <transition name="scenery-timetable-list-anim" mode="out-in"> -->
|
||||||
<!-- <div :key="store.dataStatuses.trains + selectedCheckpoint" class="scenery-timetable-list"> -->
|
<!-- <div :key="store.dataStatuses.trains + selectedCheckpoint" class="scenery-timetable-list"> -->
|
||||||
@@ -188,8 +184,6 @@ export default defineComponent({
|
|||||||
warning: require('@/assets/icon-warning.svg'),
|
warning: require('@/assets/icon-warning.svg'),
|
||||||
timetable: require('@/assets/icon-timetable.svg'),
|
timetable: require('@/assets/icon-timetable.svg'),
|
||||||
},
|
},
|
||||||
|
|
||||||
chosenTrainId: null as string | null,
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
setup(props) {
|
setup(props) {
|
||||||
@@ -238,12 +232,6 @@ export default defineComponent({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
|
||||||
chosenTrain() {
|
|
||||||
return this.store.trainList.find((train) => train.trainId == this.chosenTrainId);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
loadSelectedOption() {
|
loadSelectedOption() {
|
||||||
if (!this.station) return;
|
if (!this.station) return;
|
||||||
@@ -261,11 +249,7 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
selectTrain(trainId: string) {
|
selectTrain(trainId: string) {
|
||||||
this.chosenTrainId = trainId;
|
this.store.chosenModalTrain = this.store.trainList.find((train) => train.trainId == trainId);
|
||||||
},
|
|
||||||
|
|
||||||
closeTrainModal() {
|
|
||||||
this.chosenTrainId = null;
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -191,10 +191,11 @@ $stopNameClr: #22a8d1;
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.stock-list {
|
ul.stock-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
overflow-x: auto;
|
overflow: auto;
|
||||||
padding-bottom: 1em;
|
padding-bottom: 1em;
|
||||||
|
|
||||||
li > div {
|
li > div {
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<keep-alive>
|
<div class="train-table">
|
||||||
<TrainModal v-if="chosenTrain" :chosen-train="chosenTrain" @close-modal="closeTimetable" />
|
|
||||||
</keep-alive>
|
|
||||||
|
|
||||||
<div class="train-table" @keydown.esc="closeTimetable">
|
|
||||||
<button class="return-btn" @click="scrollToTop" v-if="showReturnButton">
|
<button class="return-btn" @click="scrollToTop" v-if="showReturnButton">
|
||||||
<img :src="icons.arrowAsc" alt="return arrow" />
|
<img :src="icons.arrowAsc" alt="return arrow" />
|
||||||
</button>
|
</button>
|
||||||
@@ -20,9 +16,9 @@
|
|||||||
<li
|
<li
|
||||||
class="train-row"
|
class="train-row"
|
||||||
v-for="train in currentTrains"
|
v-for="train in currentTrains"
|
||||||
:key="train.trainNo + train.driverId"
|
:key="train.trainId"
|
||||||
@click.stop="toggleTimetable(train)"
|
@click.stop="selectTrain(train.trainId)"
|
||||||
@keydown.enter="toggleTimetable(train)"
|
@keydown.enter="selectTrain(train.trainId)"
|
||||||
>
|
>
|
||||||
<TrainInfo :train="train" />
|
<TrainInfo :train="train" />
|
||||||
</li>
|
</li>
|
||||||
@@ -73,7 +69,6 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
defaultVehicleIcons: defaultVehicleIconsJSON,
|
defaultVehicleIcons: defaultVehicleIconsJSON,
|
||||||
chosenTrainId: null as string | null,
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
setup(props) {
|
setup(props) {
|
||||||
@@ -99,12 +94,6 @@ export default defineComponent({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
|
||||||
chosenTrain() {
|
|
||||||
return this.trains.find((train) => train.trainId == this.chosenTrainId);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
activated() {
|
activated() {
|
||||||
const query = this.$route.query;
|
const query = this.$route.query;
|
||||||
|
|
||||||
@@ -113,15 +102,11 @@ export default defineComponent({
|
|||||||
this.searchedTrain = query.trainNo.toString();
|
this.searchedTrain = query.trainNo.toString();
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.chosenTrainId = query.driverName + <string>query.trainNo;
|
this.selectTrain(query.driverName + <string>query.trainNo);
|
||||||
}, 20);
|
}, 20);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
deactivated() {
|
|
||||||
this.chosenTrainId = null;
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
enter(el: HTMLElement) {
|
enter(el: HTMLElement) {
|
||||||
const maxHeight = getComputedStyle(el).height;
|
const maxHeight = getComputedStyle(el).height;
|
||||||
@@ -147,17 +132,8 @@ export default defineComponent({
|
|||||||
}, 10);
|
}, 10);
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleTimetable(train: Train, state?: boolean) {
|
selectTrain(trainId: string) {
|
||||||
if (state !== undefined) {
|
this.store.chosenModalTrain = this.store.trainList.find((train) => train.trainId == trainId);
|
||||||
this.chosenTrainId = train.trainId;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.chosenTrainId = this.chosenTrainId && this.chosenTrainId == train.trainId ? null : train.trainId;
|
|
||||||
},
|
|
||||||
|
|
||||||
closeTimetable() {
|
|
||||||
this.chosenTrainId = null;
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ export default interface Station {
|
|||||||
driverName: string;
|
driverName: string;
|
||||||
driverId: number;
|
driverId: number;
|
||||||
trainNo: number;
|
trainNo: number;
|
||||||
|
trainId: string;
|
||||||
stopStatus?: string;
|
stopStatus?: string;
|
||||||
}[];
|
}[];
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -41,6 +41,8 @@ export const useStore = defineStore('store', {
|
|||||||
driverStatsName: '',
|
driverStatsName: '',
|
||||||
driverStatsData: undefined,
|
driverStatsData: undefined,
|
||||||
|
|
||||||
|
chosenModalTrain: undefined as Train | undefined,
|
||||||
|
|
||||||
dataStatuses: {
|
dataStatuses: {
|
||||||
connection: DataStatus.Loading,
|
connection: DataStatus.Loading,
|
||||||
sceneries: DataStatus.Loading,
|
sceneries: DataStatus.Loading,
|
||||||
@@ -202,7 +204,7 @@ export const useStore = defineStore('store', {
|
|||||||
(train) =>
|
(train) =>
|
||||||
train?.region === this.region.id && train.online && train.currentStationName === stationAPIData.stationName
|
train?.region === this.region.id && train.online && train.currentStationName === stationAPIData.stationName
|
||||||
)
|
)
|
||||||
.map((train) => ({ driverName: train.driverName, driverId: train.driverId, trainNo: train.trainNo }));
|
.map((train) => ({ driverName: train.driverName, driverId: train.driverId, trainNo: train.trainNo, trainId: train.trainId }));
|
||||||
},
|
},
|
||||||
|
|
||||||
setStationsOnlineInfo() {
|
setStationsOnlineInfo() {
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ export interface StoreState {
|
|||||||
driverStatsName: string;
|
driverStatsName: string;
|
||||||
driverStatsData?: DriverStatsAPIData;
|
driverStatsData?: DriverStatsAPIData;
|
||||||
|
|
||||||
|
chosenModalTrain?: Train;
|
||||||
|
|
||||||
dataStatuses: {
|
dataStatuses: {
|
||||||
connection: DataStatus;
|
connection: DataStatus;
|
||||||
sceneries: DataStatus;
|
sceneries: DataStatus;
|
||||||
|
|||||||
Reference in New Issue
Block a user