dodano dymki kontekstowe oraz podgląd pojazdu

This commit is contained in:
2024-03-22 23:41:43 +01:00
parent e3b72c81ea
commit c7162dbd14
12 changed files with 319 additions and 24 deletions
+39
View File
@@ -0,0 +1,39 @@
<template>
<div class="popup-content">
<img src="/images/icon-diamond.svg" alt="" />
<span>{{ popupStore.currentPopupContent }}</span>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { usePopupStore } from '../../store/popupStore';
export default defineComponent({
data() {
return {
popupStore: usePopupStore()
};
}
});
</script>
<style lang="scss" scoped>
.popup-content {
gap: 0.5em;
padding: 0.5em;
border-radius: 0.25em;
width: 100%;
background-color: #333;
box-shadow: 0 0 10px 2px #aaa;
}
img {
vertical-align: middle;
height: 1em;
margin-right: 0.5em;
}
</style>
+54
View File
@@ -0,0 +1,54 @@
<template>
<div class="popup" v-show="popupStore.currentPopupComponent" ref="preview">
<component v-if="popupStore.currentPopupComponent" :is="popupStore.currentPopupComponent" />
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import DonatorPopUp from './DonatorPopUp.vue';
import TrainCommentsPopUp from './TrainCommentsPopUp.vue';
import VehiclePreviewPopUp from './VehiclePreviewPopUp.vue';
import { usePopupStore } from '../../store/popupStore';
export default defineComponent({
components: { DonatorPopUp, TrainCommentsPopUp, VehiclePreviewPopUp },
data() {
return {
popupStore: usePopupStore()
};
},
watch: {
'popupStore.popupPosition': {
deep: true,
handler(val: typeof this.popupStore.popupPosition) {
const previewEl = this.$refs['preview'] as HTMLElement;
previewEl.style.top = `${val.y}px`;
previewEl.style.left = `${val.x}px`;
previewEl.style.transform = 'translateY(1.5rem)';
this.$nextTick(() => {
const isOutside =
val.y + previewEl.getBoundingClientRect().height > window.innerHeight + window.scrollY;
previewEl.style.transform = `translate(-50%, calc(${
isOutside ? '-100% - 1.5rem' : '1.5rem'
}))`;
});
}
}
}
});
</script>
<style lang="scss" scoped>
.popup {
position: absolute;
z-index: 250;
max-width: 400px;
text-align: center;
}
</style>
@@ -0,0 +1,38 @@
<template>
<div class="popup-content">
<span>{{ popupStore.currentPopupContent }}</span>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { usePopupStore } from '../../store/popupStore';
export default defineComponent({
data() {
return {
popupStore: usePopupStore()
};
}
});
</script>
<style lang="scss" scoped>
.popup-content {
display: flex;
justify-content: center;
align-items: center;
gap: 0.5em;
padding: 0.25em 0.5em;
border-radius: 0.25em;
width: 100%;
background-color: #333;
box-shadow: 0 0 5px 2px #aaa;
}
img {
height: 1em;
}
</style>
@@ -0,0 +1,85 @@
<template>
<div class="popup-content">
<div v-if="imageState == 'loading'" class="loading-info">
{{ $t('vehicle-preview.loading') }}
</div>
<div v-if="imageState == 'error'">{{ $t('vehicle-preview.error') }}</div>
<img
v-if="popupStore.currentPopupContent"
@load="onImageLoad"
@error="onImageError"
width="300"
height="176"
class="rounded-md w-full h-auto"
:src="`https://spythere.github.io/api/td2/images/${popupStore.currentPopupContent}--300px.jpg`"
/>
<div class="vehicle-name" v-if="imageState != 'error'">
{{ popupStore.currentPopupContent.replace(/_/g, ' ') }}
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { usePopupStore } from '../../store/popupStore';
export default defineComponent({
data() {
return {
popupStore: usePopupStore(),
imageState: 'loading'
};
},
mounted() {
this.imageState = 'loading';
},
methods: {
onImageLoad() {
this.imageState = 'loaded';
},
onImageError(e: Event) {
this.imageState = 'error';
(e.target as HTMLElement).style.display = 'none';
}
}
});
</script>
<style lang="scss" scoped>
.popup-content {
// min-w-[300px] min-h-[200px] p-2 bg-slate-800 rounded-md
width: 300px;
min-height: 200px;
background-color: #333;
box-shadow: 0 0 10px 2px #aaa;
padding: 0.5em;
border-radius: 0.5em;
}
.loading-info {
position: absolute;
left: 50%;
transform: translateX(-50%);
}
img {
width: 100%;
height: auto;
}
.vehicle-name {
text-align: center;
margin-top: 0.5em;
color: #ccc;
text-wrap: wrap;
}
</style>