Infinite scroll

This commit is contained in:
Cadence Fish 2020-01-13 04:39:50 +13:00
parent a3b4e2e64e
commit b5f163891c
No known key found for this signature in database
GPG Key ID: 81015DF9AA8607E1
7 changed files with 93 additions and 11 deletions

View File

@ -9,13 +9,13 @@ See also: [Invidious, a front-end for YouTube.](https://github.com/omarroth/invi
## Features
- [x] View profile and timeline
- [x] Infinite scroll
- [x] User memory cache
- [ ] Image disk cache
- [ ] View post
- [ ] Homepage
- [ ] Optimised for mobile
- [ ] Favicon
- [ ] Infinite scroll
- [ ] Settings (e.g. data saving)
- [ ] Galleries
- [ ] List view

View File

@ -10,5 +10,20 @@ module.exports = [
await user.timeline.fetchUpToPage(page - 1)
}
return render(200, "pug/user.pug", {url, user})
}},
{route: "/fragment/user/([\\w.]+)/(\\d+)", methods: ["GET"], code: async ({url, fill}) => {
const user = await fetchUser(fill[0])
const pageNumber = +fill[1]
const pageIndex = pageNumber - 1
await user.timeline.fetchUpToPage(pageIndex)
if (user.timeline.pages[pageIndex]) {
return render(200, "pug/fragments/timeline_page.pug", {page: user.timeline.pages[pageIndex], pageIndex, user, url})
} else {
return {
statusCode: 400,
contentType: "text/html",
content: "That page does not exist"
}
}
}}
]

View File

@ -0,0 +1,56 @@
import {ElemJS, q} from "./elemjs/elemjs.js"
class FreezeWidth extends ElemJS {
freeze(text) {
this.element.style.width = window.getComputedStyle(this.element).width
this.oldText = this.element.textContent
this.text(text)
}
unfreeze() {
this.element.style.width = ""
this.text(this.oldText)
}
}
class NextPage extends FreezeWidth {
constructor(container) {
super(container)
this.clicked = false
this.nextPageNumber = +this.element.getAttribute("data-page")
this.attribute("href", "javascript:void(0)")
this.event("click", event => this.onClick(event))
this.observer = new IntersectionObserver(entries => this.onIntersect(entries), {rootMargin: "-20px", threshold: 1})
this.observer.observe(this.element)
}
onClick(event) {
if (event) event.preventDefault()
if (this.clicked) return
this.clicked = true
this.freeze("Loading...")
fetch(`/fragment/user/${this.element.getAttribute("data-username")}/${this.nextPageNumber}`).then(res => res.text()).then(text => {
q("#next-page-container").remove()
this.observer.disconnect()
q("#timeline").insertAdjacentHTML("beforeend", text)
addNextPageControl()
})
}
/**
* @param {IntersectionObserverEntry[]} entries
*/
onIntersect(entries) {
if (entries.some(entry => entry.isIntersecting && entry.intersectionRatio == 1)) this.onClick()
}
}
function addNextPageControl() {
const nextPage = q("#next-page")
if (nextPage) new NextPage(nextPage)
}
addNextPageControl()

View File

@ -0,0 +1,6 @@
include ../includes/timeline_page.pug
include ../includes/next_page_button.pug
+timeline_page(page, pageIndex)
+next_page_button(user, url)

View File

@ -0,0 +1,10 @@
mixin next_page_button(user, url)
if user.timeline.hasNextPage()
div.next-page-container#next-page-container
-
const nu = new URL(url)
nu.searchParams.set("page", user.timeline.pages.length+1)
a(href=`${nu.search}#page-${user.timeline.pages.length+1}` data-page=(user.timeline.pages.length+1) data-username=(user.data.username))#next-page.next-page Next page
else
div.page-number.no-more-pages
span.number No more posts.

View File

@ -1,4 +1,5 @@
include includes/timeline_page.pug
include includes/next_page_button.pug
- const numberFormat = new Intl.NumberFormat().format
@ -10,6 +11,7 @@ html
title
= `${user.data.full_name} (@${user.data.username}) | Bibliogram`
link(rel="stylesheet" type="text/css" href="/static/css/main.css")
script(src="/static/js/pagination.js" type="module")
body
.main-divider
header.profile-overview
@ -34,16 +36,8 @@ html
|
| followed by
main.timeline
main#timeline.timeline
each page, pageIndex in user.timeline.pages
+timeline_page(page, pageIndex)
if user.timeline.hasNextPage()
div.next-page-container
-
const nu = new URL(url)
nu.searchParams.set("page", user.timeline.pages.length+1)
a(href=`${nu.search}#page-${user.timeline.pages.length+1}` data-cursor=user.timeline.page_info.end_cursor)#next-page.next-page Next page
else
div.page-number.no-more-pages
span.number No more posts.
+next_page_button(user, url)

View File

@ -114,6 +114,7 @@ body
.next-page
@include link-button
font-size: 18px
text-align: center
.timeline-inner
display: flex