designtopack/src/components/project/virtual-sample/DynamicView.vue

188 lines
4.5 KiB
Vue
Raw Normal View History

<template>
<div class="dialog__inner">
2025-02-12 10:50:42 +01:00
<header class="tracks-header | flex">
<div class="tracks">
2025-05-27 15:29:57 +02:00
<Selector
v-for="track in tracks"
:key="track.slug"
:label="track.title"
:items="track.variations"
:isCompareModeEnabled="isCompareModeEnabled"
2025-05-28 15:27:41 +02:00
@update:selectedItems="selectTrack"
/>
</div>
2024-12-17 15:08:03 +01:00
<button
2025-02-05 11:31:43 +01:00
v-if="tracks.length > 1"
2024-12-17 15:08:03 +01:00
class="btn | ml-auto"
:class="{ 'btn--secondary': isCompareModeEnabled }"
2024-12-17 15:08:03 +01:00
@click="isCompareModeEnabled = !isCompareModeEnabled"
>
2024-12-17 15:29:26 +01:00
<span>{{
isCompareModeEnabled
2025-02-05 11:31:43 +01:00
? 'Quitter le mode comparer'
: 'Comparer les pistes'
2024-12-17 15:29:26 +01:00
}}</span>
</button>
</header>
<div class="track">
2024-12-17 15:08:03 +01:00
<template v-for="activeTrack in activeTracks" :key="activeTrack.title">
<Interactive360
v-if="activeTrack.files.length > 1"
:activeTrack="activeTrack"
/>
<SingleImage v-else :file="activeTrack.files[0]" />
2024-12-17 15:08:03 +01:00
</template>
2024-12-17 15:29:26 +01:00
<div
v-if="isCompareModeEnabled && activeTracks.length < 2"
class="track-empty | bg-white rounded-xl w-full p-32"
>
<p>Sélectionnez sur la piste que vous souhaitez comparer</p>
</div>
</div>
</div>
</template>
<script setup>
import { computed, watch, onMounted, onBeforeMount } from 'vue';
2025-02-05 11:31:43 +01:00
import { storeToRefs } from 'pinia';
import { usePageStore } from '../../../stores/page';
import { useDialogStore } from '../../../stores/dialog';
import { useVirtualSampleStore } from '../../../stores/virtualSample';
2025-02-19 17:36:51 +01:00
import { useRoute } from 'vue-router';
import Interactive360 from './Interactive360.vue';
import SingleImage from './SingleImage.vue';
2025-05-27 15:29:57 +02:00
import Selector from '../../Selector.vue';
import slugify from 'slugify';
2025-02-19 17:36:51 +01:00
const route = useRoute();
const { page } = storeToRefs(usePageStore());
const { isCommentsOpen, isCommentPanelEnabled, activeTracks, openedFile } =
storeToRefs(useDialogStore());
2024-12-20 15:52:42 +01:00
const { isCompareModeEnabled } = storeToRefs(useVirtualSampleStore());
const rawTracks = page.value.steps.find(
(step) => step.slug === 'virtual-sample'
).files.dynamic;
2025-02-19 17:36:51 +01:00
onBeforeMount(() => {
activeTracks.value = [rawTracks[Object.keys(rawTracks)[0]][0]];
// if (route.hash.length > 0) {
// const trackToOpen = tracks.value.find(
// (track) => track.slug === route.hash.substring(1)
// );
// activeTracks.value = [trackToOpen];
// } else {
// activeTracks.value = [tracks.value[0]];
// }
2025-02-19 17:36:51 +01:00
});
onMounted(() => {
if (route.hash.length > 0) {
const targetBtn = document.querySelector(route.hash);
targetBtn.scrollIntoView();
}
});
const tracks = computed(() => {
const rawTracks = page.value.steps.find(
(step) => step.slug === 'virtual-sample'
).files.dynamic;
const tracks = [];
for (const key in rawTracks) {
tracks.push({
title: key,
slug: slugify(key),
variations: rawTracks[key],
});
}
return tracks;
});
const isSingleImage = computed(() => {
return (
activeTracks.value?.length === 1 &&
activeTracks.value[0]?.files?.length === 1
);
});
const singleFile = computed(() => {
return isSingleImage.value && activeTracks.value[0].files[0];
});
watch(
singleFile,
(newValue) => {
if (newValue) {
openedFile.value = newValue;
}
},
{ immediate: true }
);
watch(isCompareModeEnabled, (newValue) => {
if (newValue) {
isCommentsOpen.value = false;
isCommentPanelEnabled.value = false;
} else {
isCommentPanelEnabled.value = true;
}
2024-12-17 15:29:26 +01:00
if (!newValue && activeTracks.value.length === 2) {
activeTracks.value.pop();
}
});
2024-12-17 15:08:03 +01:00
function selectTrack(track) {
2024-12-17 15:29:26 +01:00
if (!isCompareModeEnabled.value) {
activeTracks.value = [track];
return;
}
if (activeTracks.value.length === 1 && !activeTracks.value.includes(track)) {
activeTracks.value.push(track);
return;
}
if (activeTracks.value.length === 2) {
2024-12-17 15:08:03 +01:00
if (activeTracks.value.includes(track)) {
2024-12-17 15:29:26 +01:00
removeTrack(track);
2024-12-17 15:08:03 +01:00
} else {
2024-12-17 16:35:32 +01:00
activeTracks.value.pop();
2024-12-17 15:08:03 +01:00
activeTracks.value.push(track);
}
}
}
2024-12-17 15:29:26 +01:00
function removeTrack(track) {
activeTracks.value = activeTracks.value.filter(
(activeTrack) => activeTrack.title !== track.title
);
}
function getCommentsCount(track) {
let count = 0;
for (const file of track.files) {
count += file?.comments?.length || 0;
}
return count > 0 ? count : undefined;
}
</script>
2024-12-16 15:29:54 +01:00
<style>
.track figure {
position: relative;
}
.track .drag-zone {
position: absolute;
inset: 0;
z-index: 2;
}
</style>