Compare commits
5 Commits
e9228892fa
...
ebb7cb8cfb
Author | SHA1 | Date |
---|---|---|
|
ebb7cb8cfb | |
|
ba120d32f7 | |
|
07db8e2db4 | |
|
c5cf671929 | |
|
733aad3bf2 |
|
@ -35,7 +35,7 @@ $().ready(() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateSecondsByTSLP = post_info => {
|
const updateSecondsByTSLP = post_info => {
|
||||||
secondsCounter = Math.floor(((Date.now() - post_info.getCreatedAt().getTime()) / 30000))
|
secondsCounter = Math.floor(((Date.now() - post_info.getCreatedAt().getTime()) / 120000))
|
||||||
secondsCounter = secondsCounter > 1000 ? 1000 : secondsCounter
|
secondsCounter = secondsCounter > 1000 ? 1000 : secondsCounter
|
||||||
secondsCounter = secondsCounter < 11 ? 11 : secondsCounter
|
secondsCounter = secondsCounter < 11 ? 11 : secondsCounter
|
||||||
}
|
}
|
||||||
|
@ -58,43 +58,24 @@ $().ready(() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleThreadUpdate = async (thread) => {
|
const findMissingReplies = (thread_op, thread_dom, thread_latest) => {
|
||||||
const threadPost = thread.getContent()
|
const lastPostTs = (thread_dom.at(-1)?.getInfo() ?? thread_op).getCreatedAt().getTime()
|
||||||
|
const missing = []
|
||||||
|
|
||||||
const res = await fetch(location.href, {
|
for (const pc of thread_latest.reverse()) {
|
||||||
"signal": abortable.signal
|
|
||||||
})
|
|
||||||
|
|
||||||
if (res.ok) {
|
|
||||||
const dom = parser.parseFromString(await res.text(), "text/html")
|
|
||||||
const livePCList = Array.prototype.map.apply(dom.querySelectorAll(`#thread_${threadPost.getInfo().getThreadId()} > .postcontainer`), [ pc => LCNPostContainer.assign(pc) ])
|
|
||||||
updateThreadFn(thread, livePCList);
|
|
||||||
} else if (res.status == 404) {
|
|
||||||
threadState = String(res.status)
|
|
||||||
} else {
|
|
||||||
throw new Error(`Server responded with non-OK status '${res.status}'`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateThreadFn(thread, lcn_pc_list) {
|
|
||||||
const threadPost = thread.getContent()
|
|
||||||
const threadReplies = thread.getReplies()
|
|
||||||
const lastPostC = threadReplies.at(-1).getParent()
|
|
||||||
const lastPostTs = lastPostC.getContent().getInfo().getCreatedAt().getTime()
|
|
||||||
|
|
||||||
const livePCList = lcn_pc_list;
|
|
||||||
const documentPCList = [ threadPost, ...threadReplies.map(p => p.getParent()) ]
|
|
||||||
const missingPCList = []
|
|
||||||
|
|
||||||
for (const pc of livePCList.reverse()) {
|
|
||||||
if (pc.getContent().getInfo().getCreatedAt().getTime() > lastPostTs) {
|
if (pc.getContent().getInfo().getCreatedAt().getTime() > lastPostTs) {
|
||||||
missingPCList.unshift(pc)
|
missing.unshift(pc)
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return missing
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateRepliesFn = (thread, missingPCList) => {
|
||||||
if (missingPCList.length) {
|
if (missingPCList.length) {
|
||||||
|
const documentPCList = [ thread.getContent(), ...(thread.getReplies()).map(p => p.getParent()) ]
|
||||||
|
|
||||||
for (const pc of missingPCList) {
|
for (const pc of missingPCList) {
|
||||||
documentPCList.at(-1).getElement().after(pc.getElement())
|
documentPCList.at(-1).getElement().after(pc.getElement())
|
||||||
documentPCList.push(pc)
|
documentPCList.push(pc)
|
||||||
|
@ -106,7 +87,29 @@ $().ready(() => {
|
||||||
|
|
||||||
LCNSite.INSTANCE.setUnseen(LCNSite.INSTANCE.getUnseen() + missingPCList.length)
|
LCNSite.INSTANCE.setUnseen(LCNSite.INSTANCE.getUnseen() + missingPCList.length)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateThreadFn = async (thread, dom) => {
|
||||||
|
const threadPost = thread.getContent()
|
||||||
|
const threadReplies = thread.getReplies()
|
||||||
|
const missingPCList = findMissingReplies(
|
||||||
|
threadPost,
|
||||||
|
threadReplies,
|
||||||
|
LCNPostContainer.all(dom.querySelector(`#thread_${threadPost.getInfo().getThreadId()}`)))
|
||||||
|
|
||||||
|
updateRepliesFn(thread, missingPCList)
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchThreadFn = async () => {
|
||||||
|
const res = await fetch(location.href, { "signal": abortable.signal })
|
||||||
|
if (res.ok) {
|
||||||
|
return parser.parseFromString(await res.text(), "text/html")
|
||||||
|
} else {
|
||||||
|
if (res.status == 404) {
|
||||||
|
threadState = String(res.status)
|
||||||
|
}
|
||||||
|
throw new Error(`Server responded with non-OK status '${res.status}'`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onTickClean = () => {
|
const onTickClean = () => {
|
||||||
|
@ -129,7 +132,7 @@ $().ready(() => {
|
||||||
try {
|
try {
|
||||||
await updateStatsFn(thread)
|
await updateStatsFn(thread)
|
||||||
if (threadState == null && threadStats.last_modified > (thread.getReplies().at(-1).getInfo().getCreatedAt().getTime() / 1000)) {
|
if (threadState == null && threadStats.last_modified > (thread.getReplies().at(-1).getInfo().getCreatedAt().getTime() / 1000)) {
|
||||||
await handleThreadUpdate(thread)
|
updateThreadFn(thread, await fetchThreadFn())
|
||||||
}
|
}
|
||||||
|
|
||||||
const threadEl = thread.getElement()
|
const threadEl = thread.getElement()
|
||||||
|
@ -148,6 +151,26 @@ $().ready(() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$(document).on("ajax_after_post", (_, xhr_body) => {
|
||||||
|
if (kIsEnabled.getValue() && xhr_body != null) {
|
||||||
|
if (!xhr_body.mod) {
|
||||||
|
const thread = LCNThread.first()
|
||||||
|
const dom = parser.parseFromString(xhr_body.thread, "text/html")
|
||||||
|
updateThreadFn(thread, dom)
|
||||||
|
updateSecondsByTSLP(thread.getReplies().at(-1).getInfo())
|
||||||
|
} else {
|
||||||
|
$(document).trigger("thread_manual_refresh")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
$(document).on("thread_manual_refresh", () => {
|
||||||
|
if (kIsEnabled.getValue() && secondsCounter >= 0) {
|
||||||
|
secondsCounter = 0
|
||||||
|
onTickFn()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
let floaterLinkBox = null
|
let floaterLinkBox = null
|
||||||
const onStateChangeFn = v => {
|
const onStateChangeFn = v => {
|
||||||
onTickClean()
|
onTickClean()
|
||||||
|
@ -164,10 +187,7 @@ $().ready(() => {
|
||||||
threadUpdateStatus.innerText = "…"
|
threadUpdateStatus.innerText = "…"
|
||||||
threadUpdateLink.addEventListener("click", e => {
|
threadUpdateLink.addEventListener("click", e => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if (secondsCounter >= 0) {
|
$(document).trigger("thread_manual_refresh")
|
||||||
secondsCounter = 0
|
|
||||||
onTickFn()
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
threadUpdateLink.href = "#"
|
threadUpdateLink.href = "#"
|
||||||
threadUpdateLink.appendChild(new Text("Refresh: "))
|
threadUpdateLink.appendChild(new Text("Refresh: "))
|
||||||
|
@ -211,8 +231,7 @@ $().ready(() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
secondsCounter = 0
|
$(document).trigger("thread_manual_refresh")
|
||||||
setTimeout(onTickFn, 1)
|
|
||||||
} else {
|
} else {
|
||||||
floaterLinkBox?.remove()
|
floaterLinkBox?.remove()
|
||||||
floaterLinkBox = null
|
floaterLinkBox = null
|
||||||
|
@ -228,26 +247,5 @@ $().ready(() => {
|
||||||
|
|
||||||
kIsEnabled.onChange(onStateChangeFn)
|
kIsEnabled.onChange(onStateChangeFn)
|
||||||
onStateChangeFn(kIsEnabled.getValue())
|
onStateChangeFn(kIsEnabled.getValue())
|
||||||
$(document).on("ajax_after_post", onNewPost);
|
|
||||||
|
|
||||||
function onNewPost(_, post_response) {
|
|
||||||
if (post_response == null) {
|
|
||||||
console.log("onNewPost data is null, can't do anything.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const thread_dom = parser.parseFromString(
|
|
||||||
post_response['thread'],
|
|
||||||
"text/html");
|
|
||||||
|
|
||||||
const thread_id_sel = "#thread_" + post_response['thread_id'];
|
|
||||||
const post_containers = [...thread_dom.querySelectorAll(`${thread_id_sel} > .postcontainer`)]
|
|
||||||
.map(elem => LCNPostContainer.assign(elem));
|
|
||||||
|
|
||||||
const thread_elem = document.querySelector(thread_id_sel);
|
|
||||||
const lcn_thread = new LCNThread(thread_elem);
|
|
||||||
|
|
||||||
updateThreadFn(lcn_thread, post_containers);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -8,8 +8,7 @@ const assert = {
|
||||||
if (actual !== expected) {
|
if (actual !== expected) {
|
||||||
const err = new Error(`Assertion Failed. ${message}`)
|
const err = new Error(`Assertion Failed. ${message}`)
|
||||||
err.data = { actual, expected}
|
err.data = { actual, expected}
|
||||||
// Seems like there's no such thing as captureStackTrace in firefox?
|
Error.captureStackTrace?.(err, assert.equal)
|
||||||
//Error.captureStackTrace(err, assert.equal)
|
|
||||||
debugger
|
debugger
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
|
@ -18,7 +17,7 @@ const assert = {
|
||||||
if (!actual) {
|
if (!actual) {
|
||||||
const err = new Error(`Assertion Failed. ${message}`)
|
const err = new Error(`Assertion Failed. ${message}`)
|
||||||
err.data = { actual }
|
err.data = { actual }
|
||||||
// Error.captureStackTrace(err, assert.ok)
|
Error.captureStackTrace?.(err, assert.ok)
|
||||||
debugger
|
debugger
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue