From 02bf19aa045de3fd809a3bcf9e92b2e621fb4ae7 Mon Sep 17 00:00:00 2001 From: Michael Bauer <michael-bauer@posteo.de> Date: Fri, 29 Mar 2024 18:20:23 +0100 Subject: [PATCH] Improve intersect handler The state is now in the handler --- .../components/coursebook/Coursebook.vue | 76 +++++++++---------- 1 file changed, 35 insertions(+), 41 deletions(-) diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue b/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue index 22bb509d9..86ca31a65 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue @@ -58,16 +58,13 @@ </template> <template #default="{ items }"> <v-list-item - v-for="{ date, docs, first, last } in groupDocsByDay(items)" + v-for="{ date, docs, idx, lastIdx } in groupDocsByDay(items)" v-intersect="{ - handler: onIntersect, + handler: intersectHandler(date, idx, lastIdx), options: { - threshold: [0, 1] - } + threshold: [0, 1], + }, }" - :data-date="date.toISODate()" - :data-first="first" - :data-last="last" two-line :key="'day-' + date" :id="'documentation_' + date.toISODate()" @@ -240,27 +237,24 @@ export default { // might skip query until both set = atomic }, groupDocsByDay(docs) { - // => {dt: [dt doc ...] ...} + // => {dt: {date: dt, docs: doc ...} ...} const docsByDay = docs.reduce((byDay, doc) => { // This works with dummy. Does actual doc have dateStart instead? const day = DateTime.fromISO(doc.datetimeStart).startOf("day"); - byDay[day] ??= {date: day, docs: [], first: false, last: false}; - byDay[day]['docs'].push(doc); + byDay[day] ??= {date: day, docs: []}; + byDay[day].docs.push(doc); return byDay; }, {}); - // => [[dt doc ...] ...] + // => [{date: dt, docs: doc ..., idx: idx, lastIdx: last-idx} ...] + // sorting is necessary since backend can send docs unordered return Object.keys(docsByDay) .sort() - .map((key, i, {length}) => { + .map((key, idx, {length}) => { const day = docsByDay[key]; - if (i === 0) { - day['first'] = true; - } else if (i === length - 1) { - day['last'] = true; - } + day.idx = idx; + day.lastIdx = length - 1; return day; }); - // sorting is necessary since backend can send docs unordered }, // docsByDay: {dt: [dt doc ...] ...} fetchMore(from, to) { @@ -281,31 +275,31 @@ export default { setDate(date) { this.$router.replace({ hash: date }) }, - onIntersect(entries, observer) { - const entry = entries[0]; - if (entry.isIntersecting) { + intersectHandler(date, idx, lastIdx) { + let waiting = true; + return (entries) => { + const entry = entries[0]; + if (entry.isIntersecting) { - if (entry.boundingClientRect.top <= 0) { - console.log('@', entry.target.dataset.date); - this.setDate(entry.target.dataset.date); - } + if (entry.boundingClientRect.top <= 0) { + console.log('@', date.toISODate()); + this.setDate(date.toISODate()); + } - // load more - if (entry.target.dataset.first) { - console.log('load up'); - entry.target.dataset.first = false; - const date = DateTime.fromISO(entry.target.dataset.date); - this.fetchMore(date.minus({ days: 4 }).toISODate(), - date.minus({ days: 1 }).toISODate()); - } else if (entry.target.dataset.last) { - console.log('load down'); - entry.target.dataset.last = false; - const date = DateTime.fromISO(entry.target.dataset.date); - this.fetchMore(date.plus({ days: 1 }).toISODate(), - date.plus({ days: 5 }).toISODate()); - } - } - }, + if (waiting && idx === 0) { + console.log('load up', date.toISODate()); + this.fetchMore(date.minus({ days: 4 }).toISODate(), + date.minus({ days: 1 }).toISODate()); + waiting = false; + } else if (waiting && idx === lastIdx) { + console.log('load down', date.toISODate()); + this.fetchMore(date.plus({ days: 1 }).toISODate(), + date.plus({ days: 5 }).toISODate()); + waiting = false; + } + } + }; + }, }, created() { this.resetDate(); -- GitLab