2026-03-22 06:40:31 +00:00
|
|
|
<style scoped>
|
|
|
|
|
.modal.show {
|
|
|
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
|
|
|
}
|
|
|
|
|
</style>
|
2026-03-22 06:27:18 +00:00
|
|
|
<template>
|
|
|
|
|
<div
|
|
|
|
|
class="modal fade"
|
|
|
|
|
:class="{ 'show d-block': show }"
|
|
|
|
|
tabindex="-1"
|
|
|
|
|
v-show="show"
|
2026-03-22 07:20:11 +00:00
|
|
|
@click.self="emit('close')"
|
2026-03-22 06:27:18 +00:00
|
|
|
>
|
|
|
|
|
<div class="modal-dialog modal-lg modal-dialog-centered">
|
|
|
|
|
<div class="modal-content">
|
|
|
|
|
<div class="modal-header">
|
|
|
|
|
<h5 class="modal-title">
|
2026-03-31 14:52:53 +00:00
|
|
|
Image {{ currentImageIndex + 1 }} of
|
2026-03-22 06:27:18 +00:00
|
|
|
{{ images.length || 0 }}
|
|
|
|
|
</h5>
|
|
|
|
|
<button
|
|
|
|
|
type="button"
|
|
|
|
|
class="btn-close"
|
2026-03-22 07:20:11 +00:00
|
|
|
@click="emit('close')"
|
2026-03-22 06:27:18 +00:00
|
|
|
></button>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-body text-center">
|
|
|
|
|
<div v-if="images && show">
|
|
|
|
|
<img
|
2026-03-31 14:52:53 +00:00
|
|
|
:src="images[currentImageIndex].url_content"
|
2026-03-22 06:27:18 +00:00
|
|
|
class="img-fluid rounded"
|
|
|
|
|
style="max-height: 60vh"
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<!-- EXIF Data Section -->
|
|
|
|
|
<div class="mt-4 pt-3 border-top text-start">
|
2026-03-31 14:52:53 +00:00
|
|
|
<h6 class="text-muted mb-3">Image Information</h6>
|
2026-03-22 06:27:18 +00:00
|
|
|
<div class="row g-3">
|
|
|
|
|
<div class="col-md-4">
|
|
|
|
|
<small class="text-muted d-block">Date Taken</small>
|
|
|
|
|
<span>
|
2026-03-31 14:52:53 +00:00
|
|
|
{{ images[currentImageIndex].exif?.created || "N/A" }}
|
2026-03-22 06:27:18 +00:00
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-4">
|
|
|
|
|
<small class="text-muted d-block">Camera</small>
|
|
|
|
|
<span>
|
|
|
|
|
{{
|
2026-03-31 14:52:53 +00:00
|
|
|
(images[currentImageIndex].exif?.make || "") +
|
2026-03-22 06:27:18 +00:00
|
|
|
" " +
|
2026-03-31 14:52:53 +00:00
|
|
|
(images[currentImageIndex].exif?.model || "") || "N/A"
|
2026-03-22 06:27:18 +00:00
|
|
|
}}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-4">
|
|
|
|
|
<small class="text-muted d-block"
|
|
|
|
|
>Distance from Reporter</small
|
|
|
|
|
>
|
2026-03-31 14:52:53 +00:00
|
|
|
<span v-if="images[currentImageIndex].location != null">
|
2026-03-22 06:27:18 +00:00
|
|
|
{{
|
|
|
|
|
formatDistance(
|
2026-03-31 14:52:53 +00:00
|
|
|
images[currentImageIndex].distance_from_reporter_meters,
|
2026-03-22 06:27:18 +00:00
|
|
|
)
|
|
|
|
|
}}
|
|
|
|
|
</span>
|
|
|
|
|
<span v-else>No location data in image</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-footer justify-content-between">
|
|
|
|
|
<button
|
|
|
|
|
class="btn btn-outline-secondary"
|
2026-03-22 07:16:42 +00:00
|
|
|
@click="emit('imagePrevious')"
|
2026-03-31 14:52:53 +00:00
|
|
|
:disabled="currentImageIndex === 0"
|
2026-03-22 06:27:18 +00:00
|
|
|
>
|
|
|
|
|
<i class="bi bi-chevron-left"></i> Previous
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
class="btn btn-outline-secondary"
|
2026-03-22 07:16:42 +00:00
|
|
|
@click="emit('imageNext')"
|
2026-03-31 14:52:53 +00:00
|
|
|
:disabled="currentImageIndex >= (images?.length || 1) - 1"
|
2026-03-22 06:27:18 +00:00
|
|
|
>
|
|
|
|
|
Next <i class="bi bi-chevron-right"></i>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div
|
|
|
|
|
class="modal-backdrop fade show"
|
|
|
|
|
v-show="show"
|
2026-03-22 07:20:11 +00:00
|
|
|
@click="emit('close')"
|
2026-03-22 06:27:18 +00:00
|
|
|
></div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
2026-03-31 14:52:53 +00:00
|
|
|
import { formatDistance } from "@/format";
|
|
|
|
|
import { Image } from "@/types";
|
|
|
|
|
|
2026-03-22 07:16:42 +00:00
|
|
|
interface Emits {
|
2026-03-22 07:20:11 +00:00
|
|
|
(e: "close"): void;
|
2026-03-22 07:16:42 +00:00
|
|
|
(e: "imageNext"): void;
|
|
|
|
|
(e: "imagePrevious"): void;
|
|
|
|
|
}
|
2026-03-22 06:27:18 +00:00
|
|
|
interface Props {
|
2026-03-31 14:52:53 +00:00
|
|
|
currentImageIndex: number;
|
|
|
|
|
images: Image[];
|
2026-03-22 06:27:18 +00:00
|
|
|
show: boolean;
|
|
|
|
|
}
|
2026-03-22 07:16:42 +00:00
|
|
|
const emit = defineEmits<Emits>();
|
2026-03-22 06:27:18 +00:00
|
|
|
const props = defineProps<Props>();
|
|
|
|
|
</script>
|