mirror of
https://github.com/Spythere/pojazdownik.git
synced 2026-05-03 05:18:10 +00:00
Wybór ładunku, podgląd i wyłączanie z losowania
This commit is contained in:
@@ -161,6 +161,7 @@ main {
|
|||||||
grid-template-rows: auto 360px minmax(400px, 1fr);
|
grid-template-rows: auto 360px minmax(400px, 1fr);
|
||||||
|
|
||||||
padding: 0 1em;
|
padding: 0 1em;
|
||||||
|
margin-bottom: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FOOTER SECTION */
|
/* FOOTER SECTION */
|
||||||
|
|||||||
@@ -18,8 +18,8 @@
|
|||||||
<select
|
<select
|
||||||
id="locomotives-list"
|
id="locomotives-list"
|
||||||
v-model="store.chosenLoco"
|
v-model="store.chosenLoco"
|
||||||
@focus="onVehicleSelect('loco')"
|
@focus="previewVehicleByType('loco')"
|
||||||
@change="onVehicleSelect('loco')"
|
@change="previewVehicleByType('loco')"
|
||||||
@keydown.enter.prevent="addOrSwitchVehicle"
|
@keydown.enter.prevent="addOrSwitchVehicle"
|
||||||
@keydown.backspace="removeVehicle"
|
@keydown.backspace="removeVehicle"
|
||||||
>
|
>
|
||||||
@@ -45,8 +45,8 @@
|
|||||||
<select
|
<select
|
||||||
id="carwagons-list"
|
id="carwagons-list"
|
||||||
v-model="store.chosenCar"
|
v-model="store.chosenCar"
|
||||||
@focus="onVehicleSelect('car')"
|
@focus="previewVehicleByType('car')"
|
||||||
@change="onVehicleSelect('car')"
|
@change="previewVehicleByType('car')"
|
||||||
@keydown.enter.prevent="addOrSwitchVehicle"
|
@keydown.enter.prevent="addOrSwitchVehicle"
|
||||||
@keydown.backspace="removeVehicle"
|
@keydown.backspace="removeVehicle"
|
||||||
>
|
>
|
||||||
@@ -70,8 +70,8 @@
|
|||||||
data-select="cargo"
|
data-select="cargo"
|
||||||
data-ignore-outside="1"
|
data-ignore-outside="1"
|
||||||
v-model="store.chosenCargo"
|
v-model="store.chosenCargo"
|
||||||
@focus="onVehicleSelect('cargo')"
|
@focus="previewVehicleByType('cargo')"
|
||||||
@change="onVehicleSelect('cargo')"
|
@change="previewVehicleByType('cargo')"
|
||||||
@keydown.enter.prevent="addOrSwitchVehicle"
|
@keydown.enter.prevent="addOrSwitchVehicle"
|
||||||
@keydown.backspace="removeVehicle"
|
@keydown.backspace="removeVehicle"
|
||||||
>
|
>
|
||||||
@@ -111,6 +111,7 @@ import { IStock } from '../types';
|
|||||||
import imageMixin from '../mixins/imageMixin';
|
import imageMixin from '../mixins/imageMixin';
|
||||||
import { useStore } from '../store';
|
import { useStore } from '../store';
|
||||||
import { isLocomotive } from '../utils/vehicleUtils';
|
import { isLocomotive } from '../utils/vehicleUtils';
|
||||||
|
import stockPreviewMixin from '../mixins/stockPreviewMixin';
|
||||||
|
|
||||||
interface ILocoType {
|
interface ILocoType {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -119,7 +120,7 @@ interface ILocoType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
mixins: [imageMixin],
|
mixins: [imageMixin, stockPreviewMixin],
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
locomotiveTypeList: [
|
locomotiveTypeList: [
|
||||||
@@ -167,49 +168,11 @@ export default defineComponent({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
|
||||||
locoOptions() {
|
|
||||||
return this.store.locoDataList
|
|
||||||
.sort((a, b) => (a.type > b.type ? 1 : -1))
|
|
||||||
.filter((loco) => loco.power == this.store.chosenLocoPower);
|
|
||||||
},
|
|
||||||
|
|
||||||
carOptions() {
|
|
||||||
return this.store.carDataList
|
|
||||||
.sort((a, b) => (a.type > b.type ? 1 : -1))
|
|
||||||
.filter((car) => car.useType == this.store.chosenCarUseType);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
selectLocoType(locoTypeId: string) {
|
|
||||||
this.store.chosenLocoPower = locoTypeId;
|
|
||||||
this.store.chosenVehicle = this.locoOptions[0];
|
|
||||||
this.store.chosenLoco = this.locoOptions[0];
|
|
||||||
},
|
|
||||||
|
|
||||||
selectCarWagonType(carWagonTypeId: string) {
|
|
||||||
this.store.chosenCarUseType = carWagonTypeId;
|
|
||||||
this.store.chosenVehicle = this.carOptions[0];
|
|
||||||
this.store.chosenCar = this.carOptions[0];
|
|
||||||
this.store.chosenCargo = null;
|
|
||||||
},
|
|
||||||
|
|
||||||
prepareSwapVehicles() {
|
prepareSwapVehicles() {
|
||||||
this.store.swapVehicles = true;
|
this.store.swapVehicles = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
onVehicleSelect(type: 'loco' | 'car' | 'cargo') {
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if (!this.store.chosenLoco && !this.store.chosenCar) return;
|
|
||||||
|
|
||||||
this.store.chosenVehicle = type == 'loco' ? this.store.chosenLoco : this.store.chosenCar;
|
|
||||||
|
|
||||||
this.store.chosenCargo =
|
|
||||||
this.store.chosenCar?.cargoList.find((cargo) => cargo.id == this.store.chosenCargo?.id) || null;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
addOrSwitchVehicle() {
|
addOrSwitchVehicle() {
|
||||||
if (this.store.chosenStockListIndex == -1) this.addVehicle();
|
if (this.store.chosenStockListIndex == -1) this.addVehicle();
|
||||||
else this.switchVehicles();
|
else this.switchVehicles();
|
||||||
|
|||||||
@@ -33,11 +33,25 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2>WYBRANE WAGONY</h2>
|
<h2>WYBRANE WAGONY</h2>
|
||||||
<p>Wagony posiadające wybrane ładunki. Kliknij na pojazd, aby został wyłączony z losowania.</p>
|
<p>
|
||||||
|
Wagony posiadające wybrane ładunki. Najedź na nazwę, aby zobaczyć podgląd wagonu. Kliknij, aby wyłączyć z
|
||||||
|
losowania (tylko podświetlone nazwy będą uwzględnione).
|
||||||
|
</p>
|
||||||
|
|
||||||
<div class="generator_vehicles">
|
<div class="generator_vehicles">
|
||||||
<button :data-chosen="true" class="btn" v-for="car in chosenCarTypes" @click="previewCar(car)">
|
<button
|
||||||
{{ car }}
|
:data-chosen="true"
|
||||||
|
:data-excluded="excludedCarTypes.includes(carType)"
|
||||||
|
class="btn"
|
||||||
|
v-for="carType in computedChosenCarTypes"
|
||||||
|
:key="carType"
|
||||||
|
@mouseover="onMouseHover(carType)"
|
||||||
|
@mouseleave="onMouseLeave"
|
||||||
|
@click="toggleCarExclusion(carType)"
|
||||||
|
>
|
||||||
|
{{ carType }}
|
||||||
|
|
||||||
|
<!-- <span>X</span> -->
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -49,7 +63,6 @@ import { defineComponent } from 'vue';
|
|||||||
import { useStore } from '../store';
|
import { useStore } from '../store';
|
||||||
|
|
||||||
import generatorData from '../data/generatorData.json';
|
import generatorData from '../data/generatorData.json';
|
||||||
import { ICarWagon } from '../types';
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'stock-generator',
|
name: 'stock-generator',
|
||||||
@@ -63,22 +76,52 @@ export default defineComponent({
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
generatorData,
|
generatorData,
|
||||||
chosenCarTypes: new Set() as Set<string>,
|
chosenCarTypes: [] as string[],
|
||||||
|
excludedCarTypes: [] as string[],
|
||||||
|
|
||||||
chosenCargoTypes: [] as string[],
|
chosenCargoTypes: [] as string[],
|
||||||
|
|
||||||
|
previewTimeout: -1,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
computedChosenCarTypes() {
|
||||||
|
return new Set<string>(this.chosenCarTypes.sort((c1, c2) => (c1 > c2 ? 1 : -1)));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
onMouseHover(type: string) {
|
||||||
|
window.clearTimeout(this.previewTimeout);
|
||||||
|
|
||||||
|
this.previewTimeout = window.setTimeout(() => {
|
||||||
|
this.previewCar(type);
|
||||||
|
}, 400);
|
||||||
|
},
|
||||||
|
|
||||||
|
onMouseLeave() {
|
||||||
|
window.clearTimeout(this.previewTimeout);
|
||||||
|
},
|
||||||
|
|
||||||
previewCar(type: string) {
|
previewCar(type: string) {
|
||||||
this.store.chosenCar = this.store.carDataList.find((c) => c.constructionType == type) || null;
|
const c = this.store.carDataList.find((c) => c.type.startsWith(type)) || null;
|
||||||
this.store.chosenVehicle = this.store.chosenCar;
|
|
||||||
|
this.store.chosenVehicle = c;
|
||||||
|
this.store.chosenCar = c;
|
||||||
|
this.store.chosenLoco = null;
|
||||||
|
this.store.chosenCargo = null;
|
||||||
|
|
||||||
|
if (c) this.store.chosenCarUseType = c?.useType;
|
||||||
|
|
||||||
|
// this.store.chosenVehicle = this.store.chosenCar;
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleCargoChosen(cargoType: string, vehicles: string[]) {
|
toggleCargoChosen(cargoType: string, vehicles: string[]) {
|
||||||
if (this.chosenCargoTypes.includes(cargoType)) {
|
if (this.chosenCargoTypes.includes(cargoType)) {
|
||||||
vehicles.forEach((v) => {
|
vehicles.forEach((v) => {
|
||||||
const [type] = v.split(':');
|
const [type] = v.split(':');
|
||||||
this.chosenCarTypes.delete(type);
|
this.chosenCarTypes.splice(this.chosenCarTypes.indexOf(type), 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.chosenCargoTypes.splice(this.chosenCargoTypes.indexOf(cargoType), 1);
|
this.chosenCargoTypes.splice(this.chosenCargoTypes.indexOf(cargoType), 1);
|
||||||
@@ -89,11 +132,16 @@ export default defineComponent({
|
|||||||
|
|
||||||
vehicles.forEach((v) => {
|
vehicles.forEach((v) => {
|
||||||
const [type] = v.split(':');
|
const [type] = v.split(':');
|
||||||
const cars = this.store.carDataList.filter((c) => c.constructionType == type);
|
// const cars = this.store.carDataList.filter((c) => c.constructionType == type);
|
||||||
|
|
||||||
this.chosenCarTypes.add(type);
|
this.chosenCarTypes.push(type);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
toggleCarExclusion(type: string) {
|
||||||
|
if (!this.excludedCarTypes.includes(type)) this.excludedCarTypes.push(type);
|
||||||
|
else this.excludedCarTypes = this.excludedCarTypes.filter((c) => c != type);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@@ -128,12 +176,14 @@ h2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.generator_cargo, .generator_vehicles {
|
.generator_cargo,
|
||||||
|
.generator_vehicles {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 0.5em;
|
gap: 0.5em;
|
||||||
grid-template-columns: repeat(4, 1fr);
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
|
||||||
button {
|
button {
|
||||||
|
position: relative;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -145,8 +195,25 @@ h2 {
|
|||||||
&[data-chosen='true'] {
|
&[data-chosen='true'] {
|
||||||
background-color: $accentColor;
|
background-color: $accentColor;
|
||||||
color: black;
|
color: black;
|
||||||
|
|
||||||
|
box-shadow: 0 0 5px 1px $accentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-excluded='true'] {
|
||||||
|
background-color: gray;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 50%;
|
||||||
|
padding: 5px;
|
||||||
|
|
||||||
|
transform: translate(-8px, -50%);
|
||||||
|
background-color: $bgColor;
|
||||||
|
color: white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -118,6 +118,7 @@
|
|||||||
<div class="warning" v-if="tooManyLocomotives">Ten skład posiada za dużo pojazdów trakcyjnych!</div>
|
<div class="warning" v-if="tooManyLocomotives">Ten skład posiada za dużo pojazdów trakcyjnych!</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Stock list -->
|
||||||
<ul ref="list">
|
<ul ref="list">
|
||||||
<li v-if="store.stockList.length == 0" class="list-empty">
|
<li v-if="store.stockList.length == 0" class="list-empty">
|
||||||
<div class="stock-info">Lista pojazdów jest pusta!</div>
|
<div class="stock-info">Lista pojazdów jest pusta!</div>
|
||||||
@@ -172,12 +173,13 @@ import TrainImage from './TrainImageSection.vue';
|
|||||||
import { useStore } from '../store';
|
import { useStore } from '../store';
|
||||||
import warningsMixin from '../mixins/warningsMixin';
|
import warningsMixin from '../mixins/warningsMixin';
|
||||||
import imageMixin from '../mixins/imageMixin';
|
import imageMixin from '../mixins/imageMixin';
|
||||||
|
import stockPreviewMixin from '../mixins/stockPreviewMixin';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'stock-list',
|
name: 'stock-list',
|
||||||
components: { TrainImage },
|
components: { TrainImage },
|
||||||
|
|
||||||
mixins: [warningsMixin, imageMixin],
|
mixins: [warningsMixin, imageMixin, stockPreviewMixin],
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
@@ -230,41 +232,20 @@ export default defineComponent({
|
|||||||
}, 20);
|
}, 20);
|
||||||
},
|
},
|
||||||
|
|
||||||
onListItemClick(vehicleID: number) {
|
onListItemClick(stockID: number) {
|
||||||
const vehicle = this.store.stockList[vehicleID];
|
const stock = this.store.stockList[stockID];
|
||||||
|
|
||||||
this.store.chosenStockListIndex =
|
this.store.chosenStockListIndex =
|
||||||
this.store.chosenStockListIndex == vehicleID && this.store.chosenVehicle?.type == vehicle.type ? -1 : vehicleID;
|
this.store.chosenStockListIndex == stockID && this.store.chosenVehicle?.type == stock.type ? -1 : stockID;
|
||||||
|
|
||||||
if (this.store.chosenStockListIndex == -1) {
|
if (this.store.chosenStockListIndex == -1) {
|
||||||
this.store.chosenVehicle = null;
|
this.store.chosenVehicle = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.store.chosenVehicle?.imageSrc != vehicle.imgSrc) this.store.imageLoading = true;
|
if (this.store.swapVehicles) this.store.swapVehicles = false;
|
||||||
|
|
||||||
if (this.store.showSupporter && !vehicle.supportersOnly) {
|
this.previewStock(stock);
|
||||||
this.store.showSupporter = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vehicle.isLoco) {
|
|
||||||
const chosenLoco = this.store.locoDataList.find((v) => v.type == vehicle.type) || null;
|
|
||||||
this.store.chosenVehicle = chosenLoco;
|
|
||||||
this.store.chosenLoco = chosenLoco;
|
|
||||||
// this.store.chosenCargo = null;
|
|
||||||
this.store.chosenLocoPower = vehicle.useType;
|
|
||||||
} else {
|
|
||||||
const chosenCar = this.store.carDataList.find((v) => v.type == vehicle.type) || null;
|
|
||||||
this.store.chosenVehicle = chosenCar;
|
|
||||||
this.store.chosenCar = chosenCar;
|
|
||||||
|
|
||||||
this.store.chosenCargo = vehicle.cargo || null;
|
|
||||||
this.store.chosenCarUseType = vehicle.useType;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.store.swapVehicles) {
|
|
||||||
this.store.swapVehicles = false;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getCarSpecFromType(typeStr: string) {
|
getCarSpecFromType(typeStr: string) {
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ export default defineComponent({
|
|||||||
grid-column: 1;
|
grid-column: 1;
|
||||||
|
|
||||||
margin-top: 2em;
|
margin-top: 2em;
|
||||||
height: 20em;
|
height: 22em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.train-image {
|
.train-image {
|
||||||
|
|||||||
@@ -91,9 +91,11 @@ export default defineComponent({
|
|||||||
const stockArray = stockString.split(';');
|
const stockArray = stockString.split(';');
|
||||||
|
|
||||||
this.store.stockList.length = 0;
|
this.store.stockList.length = 0;
|
||||||
|
this.store.chosenVehicle = null;
|
||||||
this.store.chosenCar = null;
|
this.store.chosenCar = null;
|
||||||
this.store.chosenCargo = null;
|
this.store.chosenCargo = null;
|
||||||
this.store.chosenLoco = null;
|
this.store.chosenLoco = null;
|
||||||
|
this.store.chosenStockListIndex = -1;
|
||||||
|
|
||||||
this.store.swapVehicles = false;
|
this.store.swapVehicles = false;
|
||||||
|
|
||||||
@@ -105,9 +107,6 @@ export default defineComponent({
|
|||||||
this.addVehicle(vehicle);
|
this.addVehicle(vehicle);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.store.chosenStockListIndex = -1;
|
|
||||||
this.store.chosenVehicle = null;
|
|
||||||
|
|
||||||
this.store.isRealStockListCardOpen = false;
|
this.store.isRealStockListCardOpen = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
import { defineComponent } from 'vue';
|
||||||
|
import { useStore } from '../store';
|
||||||
|
import { IStock, Vehicle } from '../types';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
store: useStore(),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
locoOptions() {
|
||||||
|
return this.store.locoDataList
|
||||||
|
.sort((a, b) => (a.type > b.type ? 1 : -1))
|
||||||
|
.filter((loco) => loco.power == this.store.chosenLocoPower);
|
||||||
|
},
|
||||||
|
|
||||||
|
carOptions() {
|
||||||
|
return this.store.carDataList
|
||||||
|
.sort((a, b) => (a.type > b.type ? 1 : -1))
|
||||||
|
.filter((car) => car.useType == this.store.chosenCarUseType);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
selectLocoType(locoTypeId: string) {
|
||||||
|
this.store.chosenLocoPower = locoTypeId;
|
||||||
|
this.store.chosenVehicle = this.locoOptions[0];
|
||||||
|
this.store.chosenLoco = this.locoOptions[0];
|
||||||
|
},
|
||||||
|
|
||||||
|
selectCarWagonType(carWagonTypeId: string) {
|
||||||
|
this.store.chosenCarUseType = carWagonTypeId;
|
||||||
|
this.store.chosenVehicle = this.carOptions[0];
|
||||||
|
this.store.chosenCar = this.carOptions[0];
|
||||||
|
this.store.chosenCargo = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
previewVehicleByType(type: 'loco' | 'car' | 'cargo') {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (!this.store.chosenLoco && !this.store.chosenCar) return;
|
||||||
|
|
||||||
|
this.store.chosenVehicle = type == 'loco' ? this.store.chosenLoco : this.store.chosenCar;
|
||||||
|
|
||||||
|
this.store.chosenCargo =
|
||||||
|
this.store.chosenCar?.cargoList.find((cargo) => cargo.id == this.store.chosenCargo?.id) || null;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
previewStock(stock: IStock) {
|
||||||
|
if (this.store.chosenVehicle?.imageSrc != stock.imgSrc) this.store.imageLoading = true;
|
||||||
|
|
||||||
|
if (stock.isLoco) {
|
||||||
|
const chosenLoco = this.store.locoDataList.find((v) => v.type == stock.type) || null;
|
||||||
|
this.store.chosenVehicle = chosenLoco;
|
||||||
|
this.store.chosenLoco = chosenLoco;
|
||||||
|
this.store.chosenCargo = null;
|
||||||
|
this.store.chosenLocoPower = stock.useType;
|
||||||
|
} else {
|
||||||
|
const chosenCar = this.store.carDataList.find((v) => v.type == stock.type) || null;
|
||||||
|
this.store.chosenVehicle = chosenCar;
|
||||||
|
this.store.chosenCar = chosenCar;
|
||||||
|
|
||||||
|
this.store.chosenCargo = stock.cargo || null;
|
||||||
|
this.store.chosenCarUseType = stock.useType;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
resetPreview() {
|
||||||
|
this.store.chosenVehicle = null;
|
||||||
|
this.store.chosenCar = null;
|
||||||
|
this.store.chosenCargo = null;
|
||||||
|
this.store.chosenLoco = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user