feat: mise à jour des règles de configuration pour l'API Platform et ajout de nouveaux composants pour le lecteur, incluant la gestion des pages infinies et des contrôles de lecture

This commit is contained in:
ext.jeremy.guillot@maxicoffee.domains
2025-03-27 10:59:53 +01:00
parent d123166dcb
commit 346fede878
11 changed files with 417 additions and 100 deletions

View File

@@ -0,0 +1,106 @@
<template>
<div class="infinite-reader" ref="containerRef">
<div v-for="(page, index) in pages" :key="index" class="page-wrapper">
<div v-if="page?.loading" class="loading">
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary"></div>
</div>
<div v-else-if="page?.error" class="error">
{{ page.error }}
</div>
<ReaderPage v-else-if="page?.base64Content" :page-data="page" :page-number="index + 1" :zoom="zoom" />
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted, watch } from 'vue';
import { nextTick } from 'vue';
import ReaderPage from './ReaderPage.vue';
const props = defineProps({
pages: {
type: Array,
required: true
},
zoom: {
type: Number,
required: true
}
});
const emit = defineEmits(['pageVisible']);
const containerRef = ref(null);
const observer = ref(null);
const observeIntersection = entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const pageIndex = parseInt(entry.target.getAttribute('data-page-index'));
emit('pageVisible', pageIndex);
}
});
};
const setupIntersectionObserver = () => {
if (observer.value) {
observer.value.disconnect();
}
observer.value = new IntersectionObserver(observeIntersection, {
root: null,
threshold: 0.5
});
nextTick(() => {
const pageElements = containerRef.value?.querySelectorAll('.page-wrapper');
if (pageElements) {
pageElements.forEach((element, index) => {
element.setAttribute('data-page-index', index);
observer.value.observe(element);
});
}
});
};
watch(
() => props.pages,
() => {
setupIntersectionObserver();
},
{ immediate: true }
);
onMounted(() => {
setupIntersectionObserver();
});
onUnmounted(() => {
if (observer.value) {
observer.value.disconnect();
}
});
</script>
<style lang="postcss" scoped>
.infinite-reader {
@apply flex-1 flex flex-col items-center overflow-y-auto py-8;
height: calc(100vh - 8rem);
scroll-behavior: smooth;
}
.page-wrapper {
@apply w-full flex justify-center min-h-[200px] mb-4;
}
.loading,
.error {
@apply flex items-center justify-center;
width: 70vw;
min-height: 400px;
}
.error {
@apply text-red-500 text-xl bg-red-500/10 rounded-lg;
}
</style>