Files
once-campfire/app/javascript/models/scroll_manager.js
Kevin McConnell df76a227dc Hello world
First open source release of Campfire 🎉
2025-08-21 09:31:59 +01:00

58 lines
1.3 KiB
JavaScript

const AUTO_SCROLL_THRESHOLD = 100
export default class ScrollManager {
static #pendingOperations = Promise.resolve()
#container
constructor(container) {
this.#container = container
}
async autoscroll(forceScroll, render = () => {}) {
return this.#appendOperation(async () => {
const wasNearEnd = this.#scrolledNearEnd
await render()
if (wasNearEnd || forceScroll) {
this.#container.scrollTop = this.#container.scrollHeight
return true
} else {
return false
}
})
}
async keepScroll(top, render) {
return this.#appendOperation(async () => {
const scrollTop = this.#container.scrollTop
const scrollHeight = this.#container.scrollHeight
await render()
if (top) {
this.#container.scrollTop = scrollTop + (this.#container.scrollHeight - scrollHeight)
} else {
this.#container.scrollTop = scrollTop
}
})
}
// Private
#appendOperation(operation) {
ScrollManager.#pendingOperations =
ScrollManager.#pendingOperations.then(operation)
return ScrollManager.#pendingOperations
}
get #scrolledNearEnd() {
return this.#distanceScrolledFromEnd <= AUTO_SCROLL_THRESHOLD
}
get #distanceScrolledFromEnd() {
return this.#container.scrollHeight - this.#container.scrollTop - this.#container.clientHeight
}
}