chore: new thumbnails
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 26 KiB |
@@ -1,39 +1,52 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="stock-thumbnails" ref="thumbnailsRef">
|
<div class="stock-thumbnails" ref="thumbnailsRef">
|
||||||
<div
|
<ul>
|
||||||
class="thumbnail-item"
|
<li
|
||||||
v-for="(stock, stockIndex) in store.stockList"
|
class="thumbnail-item"
|
||||||
:key="stockIndex"
|
v-for="(stock, stockIndex) in store.stockList"
|
||||||
:data-selected="store.chosenStockListIndex == stockIndex"
|
:key="stockIndex"
|
||||||
:data-sponsor-only="
|
:data-selected="store.chosenStockListIndex == stockIndex"
|
||||||
stock.vehicleRef.sponsorOnlyTimestamp && stock.vehicleRef.sponsorOnlyTimestamp > Date.now()
|
:data-sponsor-only="
|
||||||
"
|
stock.vehicleRef.sponsorOnlyTimestamp &&
|
||||||
:data-team-only="stock.vehicleRef.teamOnly"
|
stock.vehicleRef.sponsorOnlyTimestamp > Date.now()
|
||||||
draggable="true"
|
"
|
||||||
@dragstart="onDragStart(stockIndex)"
|
:data-team-only="stock.vehicleRef.teamOnly"
|
||||||
@drop="onDrop($event, stockIndex)"
|
draggable="true"
|
||||||
@dragover="allowDrop"
|
@dragstart="onDragStart(stockIndex)"
|
||||||
@click="onListItemClick(stockIndex)"
|
@drop="onDrop($event, stockIndex)"
|
||||||
>
|
@dragover="allowDrop"
|
||||||
<b>
|
@click="onListItemClick(stockIndex)"
|
||||||
{{ stock.vehicleRef.type }}
|
>
|
||||||
</b>
|
<div class="stock-text">
|
||||||
|
<p>
|
||||||
|
{{ stock.vehicleRef.type.replace(/_/g, ' ') }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<img
|
<span>
|
||||||
draggable="false"
|
<img
|
||||||
:src="`https://static.spythere.eu/thumbnails/${stock.vehicleRef.type}.png`"
|
v-for="thumbnail in getVehicleThumbnails(stock.vehicleRef.type)"
|
||||||
:alt="stock.vehicleRef.type"
|
draggable="false"
|
||||||
:title="stock.vehicleRef.type"
|
style="min-width: 200px"
|
||||||
@error="stockImageError($event, stock)"
|
:src="`https://static.spythere.eu/thumbnails/v2/${thumbnail.src}.png`"
|
||||||
/>
|
:alt="stock.vehicleRef.type"
|
||||||
</div>
|
:title="stock.vehicleRef.type"
|
||||||
|
@load="($event) => (($event.target as HTMLImageElement).style.minWidth = 'auto')"
|
||||||
|
@error="
|
||||||
|
($event) =>
|
||||||
|
(($event.target as HTMLImageElement).src = `/images/${thumbnail.fallbackSrc}.png`)
|
||||||
|
"
|
||||||
|
height="70"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Ref, computed, nextTick, ref, watch } from 'vue';
|
import { Ref, computed, nextTick, ref, watch } from 'vue';
|
||||||
import { useStore } from '../../store';
|
import { useStore } from '../../store';
|
||||||
import { IStock } from '../../types';
|
|
||||||
|
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
const emit = defineEmits(['listItemClick']);
|
const emit = defineEmits(['listItemClick']);
|
||||||
@@ -45,10 +58,6 @@ const onListItemClick = (index: number) => {
|
|||||||
emit('listItemClick', index);
|
emit('listItemClick', index);
|
||||||
};
|
};
|
||||||
|
|
||||||
const stockImageError = (e: Event, stock: IStock) => {
|
|
||||||
(e.target as HTMLImageElement).src = `images/${stock.vehicleRef.group}-unknown.png`;
|
|
||||||
};
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
computed(() => store.chosenStockListIndex),
|
computed(() => store.chosenStockListIndex),
|
||||||
(index) => {
|
(index) => {
|
||||||
@@ -56,7 +65,7 @@ watch(
|
|||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
(thumbnailsRef.value as HTMLElement)
|
(thumbnailsRef.value as HTMLElement)
|
||||||
.querySelector(`div:nth-child(${index + 1})`)
|
.querySelector(`li:nth-child(${index + 1})`)
|
||||||
?.scrollIntoView({
|
?.scrollIntoView({
|
||||||
block: 'nearest',
|
block: 'nearest',
|
||||||
inline: 'start',
|
inline: 'start',
|
||||||
@@ -74,7 +83,7 @@ const onDragStart = (vehicleIndex: number) => {
|
|||||||
const onDrop = (e: DragEvent, vehicleIndex: number) => {
|
const onDrop = (e: DragEvent, vehicleIndex: number) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
let targetEl = thumbnailsRef.value.querySelector(`div:nth-child(${vehicleIndex + 1})`);
|
let targetEl = thumbnailsRef.value.querySelector(`li:nth-child(${vehicleIndex + 1})`);
|
||||||
|
|
||||||
if (!targetEl && draggedIndex.value != -1) return;
|
if (!targetEl && draggedIndex.value != -1) return;
|
||||||
|
|
||||||
@@ -88,31 +97,100 @@ const onDrop = (e: DragEvent, vehicleIndex: number) => {
|
|||||||
const allowDrop = (e: DragEvent) => {
|
const allowDrop = (e: DragEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getVehicleThumbnails = (vehicleString: string) => {
|
||||||
|
const [vehicleName, vehicleCargo] = vehicleString.split(':');
|
||||||
|
|
||||||
|
const thumbnails: { src: string; fallbackSrc: string }[] = [];
|
||||||
|
|
||||||
|
// Generowanie członów EN57
|
||||||
|
if (vehicleName.startsWith('EN57')) {
|
||||||
|
thumbnails.push(
|
||||||
|
{ src: vehicleName + 'ra', fallbackSrc: 'unknown_ezt-ra' },
|
||||||
|
{ src: vehicleName + 's', fallbackSrc: 'unknown_ezt-s' },
|
||||||
|
{ src: vehicleName + 'rb', fallbackSrc: 'unknown_ezt-rb' }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generowanie członów EN71
|
||||||
|
else if (vehicleName.startsWith('EN71')) {
|
||||||
|
thumbnails.push(
|
||||||
|
{ src: vehicleName + 'ra', fallbackSrc: 'unknown_ezt-ra' },
|
||||||
|
{ src: vehicleName + 'sa', fallbackSrc: 'unknown_ezt-sa' },
|
||||||
|
{ src: vehicleName + 'sb', fallbackSrc: 'unknown_ezt-sb' },
|
||||||
|
{ src: vehicleName + 'rb', fallbackSrc: 'unknown_ezt-rb' }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generowanie pojazdów i członów 2EN57
|
||||||
|
else if (vehicleString.startsWith('2EN57')) {
|
||||||
|
const [firstVehicleNumber, secondVehicleNumber] = vehicleString
|
||||||
|
.replace('2EN57-', '')
|
||||||
|
.split('+');
|
||||||
|
|
||||||
|
thumbnails.push(
|
||||||
|
{ src: `EN57-${firstVehicleNumber}ra`, fallbackSrc: 'unknown_ezt-ra' },
|
||||||
|
{ src: `EN57-${firstVehicleNumber}s`, fallbackSrc: 'unknown_ezt-s' },
|
||||||
|
{ src: `EN57-${firstVehicleNumber}rb`, fallbackSrc: 'unknown_ezt-rb' },
|
||||||
|
{ src: `EN57-${secondVehicleNumber}ra`, fallbackSrc: 'unknown_ezt-ra' },
|
||||||
|
{ src: `EN57-${secondVehicleNumber}s`, fallbackSrc: 'unknown_ezt-s' },
|
||||||
|
{ src: `EN57-${secondVehicleNumber}rb`, fallbackSrc: 'unknown_ezt-rb' }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generowanie członów Gor77
|
||||||
|
else if (vehicleString.startsWith('Gor77')) {
|
||||||
|
thumbnails.push(
|
||||||
|
{ src: vehicleName + '-A', fallbackSrc: 'unknown_Gor77-A' },
|
||||||
|
{ src: vehicleName + '-B', fallbackSrc: 'unknown_Gor77-B' },
|
||||||
|
{ src: vehicleName + '-C', fallbackSrc: 'unknown_Gor77-C' },
|
||||||
|
{ src: vehicleName + '-D', fallbackSrc: 'unknown_Gor77-D' }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generowanie członów ET41
|
||||||
|
else if (vehicleString.startsWith('ET41')) {
|
||||||
|
thumbnails.push(
|
||||||
|
{ src: vehicleName + '-A', fallbackSrc: 'unknown_ET41-A' },
|
||||||
|
{ src: vehicleName + '-B', fallbackSrc: 'unknown_ET41-B' }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generowanie pozostałych pojazdów
|
||||||
|
else {
|
||||||
|
let fallbackVehicleImage = 'unknown_cargo';
|
||||||
|
|
||||||
|
if (/^(EP|EU)/.test(vehicleName)) fallbackVehicleImage = 'unknown_train';
|
||||||
|
else if (/^(SM42)/.test(vehicleName)) fallbackVehicleImage = 'unknown_SM42';
|
||||||
|
else if (/(\d{3}a|(Bau|Gor)\d{2}|304C)_/.test(vehicleName))
|
||||||
|
fallbackVehicleImage = 'unknown_passenger';
|
||||||
|
|
||||||
|
thumbnails.push({ src: vehicleName, fallbackSrc: fallbackVehicleImage });
|
||||||
|
}
|
||||||
|
|
||||||
|
return thumbnails;
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '../../styles/global.scss';
|
@import '../../styles/global.scss';
|
||||||
|
|
||||||
.stock-thumbnails {
|
.stock-thumbnails {
|
||||||
display: flex;
|
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
background-color: #353a57;
|
background-color: #353a57;
|
||||||
min-height: 100px;
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
min-height: 110px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.thumbnail-item {
|
.thumbnail-item {
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 0.5em;
|
|
||||||
|
|
||||||
padding-top: 0.5em;
|
|
||||||
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
min-height: 100px;
|
|
||||||
font-size: 0.85em;
|
font-size: 0.85em;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
user-select: none;
|
user-select: none;
|
||||||
-moz-user-select: none;
|
-moz-user-select: none;
|
||||||
@@ -122,11 +200,6 @@ const allowDrop = (e: DragEvent) => {
|
|||||||
background-color: rebeccapurple;
|
background-color: rebeccapurple;
|
||||||
}
|
}
|
||||||
|
|
||||||
b {
|
|
||||||
color: #ccc;
|
|
||||||
margin: 0 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
&[data-sponsor-only='true'] > b {
|
&[data-sponsor-only='true'] > b {
|
||||||
color: $sponsorColor;
|
color: $sponsorColor;
|
||||||
}
|
}
|
||||||
@@ -136,7 +209,22 @@ const allowDrop = (e: DragEvent) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
max-height: 60px;
|
max-height: 70px;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stock-text {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ccc;
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumbnail-item > span {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-end;
|
||||||
|
cursor: crosshair;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||