Skip to content

Commit

Permalink
feat: add infinite scroll
Browse files Browse the repository at this point in the history
  • Loading branch information
joaquimds committed Nov 8, 2023
1 parent a172769 commit 99dccaf
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 1 deletion.
2 changes: 1 addition & 1 deletion web/app/themes/awasqa/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
// WPML logic
require_once(__DIR__ . '/src/wpml.php');

$ver = "1.8";
$ver = "1.9";
add_action('wp_enqueue_scripts', function () use ($ver) {
wp_enqueue_style(
'awasqa',
Expand Down
5 changes: 5 additions & 0 deletions web/app/themes/awasqa/pre-script.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@
const style = document.createElement("style")
style.innerText = "body { visibility: hidden; }"
document.head.appendChild(style)

// Fallback in case of errors - display page after 5 seconds
setTimeout(() => {
document.head.removeChild(style);
}, 5000);
105 changes: 105 additions & 0 deletions web/app/themes/awasqa/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,5 +153,110 @@ document.querySelectorAll(
query.previousElementSibling.style.display = "none"
})

// Set up infinite scroll
function isElementInViewport(el) {
const rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}

/**
* Pass an <a> element, and return the key and value of
* the ?query-N-page=M query parameter. Used for pagination.
*/
function getLinkPageParam(a) {
let href = a.getAttribute('href')
if (!href) {
return {}
}
if (!href.startsWith('http')) {
href = `${window.location.protocol}//${window.location.host}${href}`
}
const parsedHref = new URL(href)
const queryParams = parsedHref.searchParams
let pageParam = null;
for (const param of queryParams.keys()) {
if (param.match(/query-[0-9]+-page+/)) {
pageParam = param
}
}
if (!pageParam) {
return {}
}
let page = queryParams.get(pageParam)
return {
href: href,
param: pageParam,
value: page
}
}

document.querySelectorAll('body.single .wp-block-query-pagination').forEach(pagination => {
const loading = document.createElement("div")
loading.setAttribute('class', 'awasqa-infinite-scroll-loading')
pagination.appendChild(loading)
pagination.querySelectorAll("*").forEach(el => { el.style.visibility = "hidden" })

const queryLoopWrapper = pagination.closest('.wp-block-query')
const queryLoop = queryLoopWrapper.querySelector('.wp-block-post-template')
const next = pagination.querySelector('.wp-block-query-pagination-next')
if (!next) {
return
}

let { href: nextHref, param: paginationParam } = getLinkPageParam(next)

let pagesFetched = []

function doInfiniteScroll() {
if (!nextHref) {
return
}
if (!isElementInViewport(pagination)) {
return
}
if (pagesFetched.includes(nextHref)) {
return
}
loading.style.visibility = "visible"
pagesFetched.push(nextHref)
window.fetch(nextHref).then(response => response.text()).then(html => {
let body = html.split(/<body[^>]*>/)[1]
body = body.split('</body>')[0]
const dummy = document.createElement('div')
dummy.innerHTML = body
dummy.querySelectorAll('.wp-block-query-pagination a').forEach(pageLink => {
const { param } = getLinkPageParam(pageLink)
let appended = false
if (!appended && param === paginationParam) {
const fetchedQueryLoop = pageLink.closest('.wp-block-query')
fetchedQueryLoop.querySelectorAll('.wp-block-post').forEach(post => {
queryLoop.appendChild(post)
})
const next = fetchedQueryLoop.querySelector('.wp-block-query-pagination-next')
if (next) {
nextHref = getLinkPageParam(next).href
} else {
nextHref = null
window.removeEventListener('scroll', doInfiniteScroll)
}
appended = true
}
})
loading.style.visibility = "hidden"
// In case the pagination is still visible after load, load again
doInfiniteScroll()
})
}

window.addEventListener('scroll', doInfiniteScroll)

doInfiniteScroll()
})

// Display content (hidden by pre-script.js)
document.body.style.visibility = "visible"
15 changes: 15 additions & 0 deletions web/app/themes/awasqa/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,21 @@ h6::after {
border-top: 1px solid var(--color-orange);
flex-grow: 1;
}
.awasqa-infinite-scroll-loading {
animation: spin 1s linear infinite;
height: 25px;
border: 2px solid var(--color-green);
border-left: 0;
border-top: 0;
border-radius: 100%;
visibility: visible;
width: 25px;
}
@keyframes spin {
100% {
transform: rotate(360deg);
}
}
.page-join-us-steps ol {
counter-reset: li;
list-style: none;
Expand Down
1 change: 1 addition & 0 deletions web/app/themes/awasqa/styles/awasqa.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
@import "gravity-forms.css";
@import "header.css";
@import "headings.css";
@import "infinite-scroll.css";
@import "join-us.css";
@import "util.css";
@import "wp.css";
Expand Down
16 changes: 16 additions & 0 deletions web/app/themes/awasqa/styles/infinite-scroll.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.awasqa-infinite-scroll-loading {
animation: spin 1s linear infinite;
height: 25px;
border: 2px solid var(--color-green);
border-left: 0;
border-top: 0;
border-radius: 100%;
visibility: visible;
width: 25px;
}

@keyframes spin {
100% {
transform: rotate(360deg);
}
}

0 comments on commit 99dccaf

Please sign in to comment.