frontend: desperate attempt to fix fullpage issues when switching views

Signed-off-by: Nicolas Froger <nicolas@kektus.xyz>
This commit is contained in:
Nicolas Froger 2024-07-25 19:26:20 +02:00
commit b115ee3d5e
No known key found for this signature in database
2 changed files with 65 additions and 25 deletions

View file

@ -15,13 +15,15 @@ export const usePostsStore = defineStore('posts', () => {
.then((response) => {
return response.json()
})
.then((data) => {
.then(async (data) => {
posts.value = data.sort((a, b) => b.id - a.id) // highest ID (more recent) first
for (const post of posts.value) {
const postDate = new Date(post.date)
post.formatedDate = formatRelative(postDate, new Date(), { locale: fr })
post.formatedDescription = marked.parse(post.description)
}
return posts.value
})
.catch((error) => {
console.log('post list parsing failed with error: ' + error)

View file

@ -1,7 +1,7 @@
<script setup>
import PostComponent from '@/components/PostComponent.vue'
import { usePostsStore } from '@/stores/posts.js'
import { onMounted, ref } from 'vue'
import { nextTick, onBeforeUnmount, onMounted, ref } from 'vue'
import WelcomeComponent from '@/components/WelcomeComponent.vue'
const postsStore = usePostsStore()
@ -14,46 +14,80 @@ const fullpageOptions = ref({
normalScrollElements: '.scrollable-element',
scrollOverflow: false,
onLeave: onLeave,
afterLoad: afterLoad,
credits: { enabled: false }
})
const menu = ref(null)
const menuItems = ref([])
let fullPageInit = false;
let fullPageInit = false
const fullpageEnable = ref(false)
const fullpageKey = ref(Math.floor(Math.random() * 1000))
/*
There is a huge mess in this code because I couldn't find a way to make fullpage.js work well when
changing views.
At this point I've tried so many things that in the end I don't know which attempt worked best, so
I'm leaving this as is because reloading the page is the only way I could make the app work for the
users. How come after every ***** hack I've tried to completely destroy and rebuild the fullpage
instance it still finds a way to be alive and break when changing views????
*/
async function initFullpage() {
if (fullPageInit)
return
fullpageKey.value += 5
fullpageEnable.value = true
await nextTick()
try {
fullpage.value.init()
} catch (e) {
console.log('failed to reload fullpage.js because it sucks with vue, reloading page as last resort')
window.location.reload()
return
}
fullPageInit = true
}
onMounted(() => {
console.log('post view mounted')
postsStore.fetchPosts().then(() => {
if (!fullPageInit) {
fullpage.value.init();
fullPageInit = true;
} else {
fullpage.value.build();
}
});
initFullpage()
})
})
onBeforeUnmount(async () => {
console.log('caught post view unmount')
if (typeof window.fullpage_api !== 'undefined' && typeof window.fullpage_api.destroy !== 'undefined') {
window.fullpage_api.destroy('all')
}
fullpageKey.value++
fullpageEnable.value = false
await nextTick()
fullPageInit = false
})
// eslint-disable-next-line no-unused-vars
function onLeave(origin, destination, direction, trigger) {
if (destination.anchor === 'welcome-section') {
menu.value.classList.add('opacity-0')
menu.value.classList.remove('scrollable-element')
} else {
menu.value.classList.remove('opacity-0')
menu.value.classList.add('scrollable-element')
// Disgusting way to make the menu automatically scroll when changing slide.
// For some reason this doesn't work on Chrome, I love web dev
for (const menuItem of menuItems.value) {
if (menuItem.dataset.menuanchor === destination.anchor) {
menuItem.scrollIntoView({
behavior: "smooth",
inline: "center"
});
break;
behavior: 'smooth',
inline: 'center'
})
break
}
}
}
}
function afterLoad(origin, destination, direction, trigger) {
if (destination.anchor === 'welcome-section') {
menu.value.classList.add('opacity-0')
}
}
</script>
<template>
@ -63,11 +97,14 @@ function afterLoad(origin, destination, direction, trigger) {
>
<ul
id="menu"
class="scrollable-element col-start-1 col-span-full row-start-1 max-h-52 h-fit mt-16 lg:m-0 lg:col-start-5 lg:col-span-1 lg:row-start-3 lg:row-span-1 pointer-events-auto overflow-y-scroll transition-opacity duration-1000 opacity-0"
class="col-start-1 col-span-full row-start-1 max-h-52 h-fit mt-28 sm:mt-16 lg:m-0 lg:col-start-5 lg:col-span-1 lg:row-start-3 lg:row-span-1 pointer-events-auto overflow-y-scroll transition-opacity duration-1000 opacity-0"
ref="menu"
>
<li :data-menuanchor="'post-' + post.id" v-for="post in postsStore.posts" :key="post.id" class="m-2 backdrop-blur-sm rounded-lg bg-black/10 hover:bg-gray-500/10 transition-colors duration-200" ref="menuItems">
<a :href="'#post-' + post.id" class="block text-right px-4 py-3 transition-all duration-300">{{ post.formatedDate }}</a>
<li :data-menuanchor="'post-' + post.id" v-for="post in postsStore.posts" :key="post.id"
class="m-2 backdrop-blur-sm rounded-lg bg-black/10 hover:bg-gray-500/10 transition-colors duration-200"
ref="menuItems">
<a :href="'#post-' + post.id"
class="block text-right px-4 py-3 transition-all duration-300">{{ post.formatedDate }}</a>
</li>
</ul>
</div>
@ -76,8 +113,9 @@ function afterLoad(origin, destination, direction, trigger) {
ref="fullpage"
:options="fullpageOptions"
@on-leave="onLeave"
@after-load="afterLoad"
:skip-init="true"
:key="fullpageKey"
v-if="fullpageEnable"
>
<WelcomeComponent />
<PostComponent class="section" v-for="post in postsStore.posts" :key="post.id" :post="post" />