feat: ajout de la gestion des doubles pages pour le lecteur, incluant des paramètres de détection automatique, des modes d'affichage et des préférences sauvegardées. Amélioration de l'interface utilisateur pour intégrer ces nouvelles fonctionnalités.

This commit is contained in:
ext.jeremy.guillot@maxicoffee.domains
2025-07-06 15:55:55 +02:00
parent a6ca8a2c9a
commit 5a5569cf2c
9 changed files with 1150 additions and 63 deletions

View File

@@ -12,7 +12,7 @@
<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" />
<ReaderPage v-else-if="page?.base64Content" :page-data="page" :page-number="index + 1" :zoom="zoom" :double-page-mode="doublePageMode" />
</div>
<!-- Navigation en bas -->
@@ -30,7 +30,7 @@
leave-to-class="opacity-0 translate-y-5 scale-75"
>
<button
v-show="showScrollToTop"
v-show="showFloatingButtons"
@click="scrollToTop"
class="fixed bottom-6 right-6 z-[9999] bg-blue-600 hover:bg-blue-700 text-white w-12 h-12 rounded-full shadow-lg hover:shadow-xl flex items-center justify-center transition-all duration-200 hover:scale-110 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
title="Revenir en haut"
@@ -58,18 +58,23 @@ import ReaderPage from './ReaderPage.vue';
zoom: {
type: Number,
required: true
},
doublePageMode: {
type: String,
required: true
}
});
const emit = defineEmits(['pageVisible']);
const emit = defineEmits(['pageVisible', 'buttonsVisibilityChange']);
const headerStore = useHeaderStore();
const containerRef = ref(null);
const observer = ref(null);
const windowWidth = ref(window.innerWidth);
// État pour le bouton scroll to top
const showScrollToTop = ref(false);
// État unique pour tous les boutons flottants avec timer de 3 secondes
const showFloatingButtons = ref(false);
let buttonsTimer = null;
// Variables pour détecter la direction du scroll
let lastScrollTop = 0;
@@ -105,7 +110,38 @@ import ReaderPage from './ReaderPage.vue';
});
};
// Gestion du scroll pour le bouton "revenir en haut" et le header
// Fonction unique pour gérer la visibilité de tous les boutons flottants
const showButtonsWithTimer = () => {
showFloatingButtons.value = true;
emit('buttonsVisibilityChange', true);
// Réinitialiser le timer à chaque fois
clearTimeout(buttonsTimer);
buttonsTimer = setTimeout(() => {
showFloatingButtons.value = false;
emit('buttonsVisibilityChange', false);
}, 3000); // 3 secondes
};
const hideButtonsImmediately = () => {
showFloatingButtons.value = false;
emit('buttonsVisibilityChange', false);
clearTimeout(buttonsTimer);
};
// Fonction exposée pour réinitialiser le timer depuis l'extérieur
const resetButtonsTimer = () => {
if (showFloatingButtons.value) {
clearTimeout(buttonsTimer);
buttonsTimer = setTimeout(() => {
showFloatingButtons.value = false;
emit('buttonsVisibilityChange', false);
}, 3000);
} else {
showButtonsWithTimer();
}
};
// Gestion du scroll pour tous les boutons flottants et le header
const handleScroll = () => {
let scrollTop = 0;
@@ -141,23 +177,26 @@ import ReaderPage from './ReaderPage.vue';
headerStore.updateScrollDirection(scrollTop);
}
// Mise à jour de la visibilité du bouton
// Afficher si on scroll vers le bas et qu'on est à plus de 300px
// Masquer si on scroll vers le haut ou qu'on est en haut de page
if (scrollDirection === 'down' && scrollTop > 300) {
showScrollToTop.value = true;
} else if (scrollDirection === 'up' || scrollTop <= 100) {
showScrollToTop.value = false;
// Gestion de la visibilité des boutons flottants (même condition pour tous)
// Afficher si on scroll et qu'on est à plus de 300px
if (scrollTop > 300) {
showButtonsWithTimer();
} else if (scrollTop <= 100) {
// Masquer immédiatement si on est en haut de page
hideButtonsImmediately();
}
// Sauvegarder la position actuelle pour la prochaine comparaison
lastScrollTop = scrollTop;
};
// Fonction pour revenir en haut de la page
// Fonction pour revenir en haut de la page
const scrollToTop = () => {
console.log('scrollToTop appelée'); // Debug
// Réinitialiser le timer lors du clic
resetButtonsTimer();
// Stratégie 1: Scroll sur le conteneur direct
if (containerRef.value) {
console.log('containerRef trouvé, scrollTop actuel:', containerRef.value.scrollTop); // Debug
@@ -195,6 +234,12 @@ import ReaderPage from './ReaderPage.vue';
});
};
// Exposer la fonction pour le parent
defineExpose({
resetButtonsTimer,
showButtonsWithTimer
});
watch(
() => props.pages,
() => {
@@ -244,6 +289,9 @@ import ReaderPage from './ReaderPage.vue';
// Désactiver l'auto-hide du header en quittant
headerStore.disableAutoHide();
// Nettoyer les timers
clearTimeout(buttonsTimer);
// Nettoyer l'écouteur de scroll du conteneur
if (containerRef.value) {
containerRef.value.removeEventListener('scroll', handleScroll);