This commit is contained in:
2025-11-07 13:34:32 -08:00
commit 1e8c5a972b
436 changed files with 11000 additions and 0 deletions

View File

@@ -0,0 +1,22 @@
export function setCookie(name, value = "", days = 365) {
let expires = ""
const date = new Date()
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000)
expires = `; expires=${date.toUTCString()}`
document.cookie = `${name}=${value}${expires}; path=/`
}
export function readCookie(name) {
const nameEQ = `${name}=`
const ca = document.cookie.split(";")
for (let i = 0; i < ca.length; i++) {
let c = ca[i]
while (c.charAt(0) === " ") c = c.substring(1, c.length)
if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length)
}
return null
}

View File

@@ -0,0 +1,9 @@
import { FetchRequest } from "@rails/request.js"
export async function submitForm(form) {
const request = new FetchRequest(form.method, form.action, {
body: new FormData(form)
})
return await request.perform()
}

View File

@@ -0,0 +1,16 @@
import { setCookie, readCookie } from "helpers/cookie_helpers"
export function getReadingProgress(bookId) {
const progress = readCookie(`reading_progress_${bookId}`)
if (progress) {
const [ leafId, lastReadParagraph ] = progress.split("/")
return [ parseInt(leafId), parseInt(lastReadParagraph) || 0 ]
} else {
return [ undefined, 0 ]
}
}
export function storeReadingProgress(bookId, leafId, lastReadParagraphIndex) {
setCookie(`reading_progress_${bookId}`, `${leafId}/${lastReadParagraphIndex}`)
}

View File

@@ -0,0 +1,39 @@
export function throttle(fn, delay = 1000) {
let timeoutId = null
return (...args) => {
if (!timeoutId) {
fn(...args)
timeoutId = setTimeout(() => timeoutId = null, delay)
}
}
}
export function debounce(fn, delay = 1000) {
let timeoutId = null
return (...args) => {
clearTimeout(timeoutId)
timeoutId = setTimeout(() => fn.apply(this, args), delay)
}
}
export function nextEventLoopTick() {
return delay(0)
}
export function onNextEventLoopTick(callback) {
setTimeout(callback, 0)
}
export function nextFrame() {
return new Promise(requestAnimationFrame)
}
export function nextEventNamed(eventName, element = window) {
return new Promise(resolve => element.addEventListener(eventName, resolve, { once: true }))
}
export function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}