diff --git a/js/lcn/classes.js b/js/lcn/classes.js index 3f4e4cfa..43ebab4b 100644 --- a/js/lcn/classes.js +++ b/js/lcn/classes.js @@ -3,14 +3,6 @@ * @author jonsmy */ -function cont(value_to_test, fn) { - if (value_to_test != null) { - return fn(value_to_test); - } else { - return null; - } -} - globalThis.LCNSite = class LCNSite { static "createAbortable" () { @@ -41,7 +33,7 @@ globalThis.LCNSite = class LCNSite { return null }; - static "constructor" () { + constructor () { this._isModerator = document.body.classList.contains("is-moderator"); this._isThreadPage = document.body.classList.contains("active-thread"); @@ -55,16 +47,18 @@ globalThis.LCNSite = class LCNSite { this._unseen = 0; this._pageTitle = document.title; - this._doTitleUpdate = () => { - document.title = (this._unseen > 0 ? `(${this._unseen}) ` : "") + this._pageTitle; - }; - this._favicon = document.querySelector("head > link[rel=\"shortcut icon\"]"); this._generatedStyle = null; } + "_doTitleUpdate" () { + document.title = (this._unseen > 0 ? `(${this._unseen}) ` : "") + this._pageTitle; + }; + "isModerator" () { return this._isModerator; } - "isThreadPage" () { return this._isThreadPage; } + "isThreadPage" () { + return this._isThreadPage; + } "isBoardPage" () { return this._isBoardPage; } "isCatalogPage" () { return this._isCatalogPage; } @@ -117,7 +111,7 @@ globalThis.LCNSite.INSTANCE = null; globalThis.LCNPostInfo = class LCNPostInfo { - static "constructor" () { + constructor () { this._boardId = null; this._threadId = null; this._postId = null; @@ -202,10 +196,13 @@ LCNPostInfo.selector = ".post:not(.grid-li)"; globalThis.LCNPost = class LCNPost { - static "assign" (post) { return post[this.nodeAttrib] || (post[this.nodeAttrib] = this.from(post)); } + static "assign" (post) { + return post[this.nodeAttrib] || (post[this.nodeAttrib] = this.from(post)); + } + static "from" (post) { return new this(post); } - "constructor" (post) { + constructor (post) { this._parent = null; this._post = null; this._info = null; @@ -218,9 +215,13 @@ globalThis.LCNPost = class LCNPost { this._post = post; this._info = LCNPostInfo.assign(post); this._ipLink = intro.querySelector(".ip-link"); - this._controls = Array.prototype.at.apply(post.querySelectorAll(".controls"), [ -1 ]); - assert.equal(this._info.getParent(), null, "Info should not have parent."); + //this._controls = Array.prototype.at.apply(post.querySelectorAll(".controls"), [ -1 ]); + // the above line fails on older browsers so do this instead: + const elements = Array.prototype.slice.call(post.querySelectorAll(".controls")); + this._controls = elements[elements.length - 1]; + + //assert.equal(this._info.getParent(), null, "Info should not have parent."); this._info.__setParent(this); } @@ -269,17 +270,19 @@ globalThis.LCNPost. NBSP = String.fromCharCode(160); globalThis.LCNThread = class LCNThread { - static "assign" (thread) { return thread[this.nodeAttrib] || (thread[this.nodeAttrib] = this.from(thread)); } + static "assign" (thread) { + return thread[this.nodeAttrib] || (thread[this.nodeAttrib] = this.from(thread)); + } + static "from" (thread) { return new this(thread); } - "constructor" (thread) { + constructor (thread) { this._element = null; this._parent = null; this._op = null; assert.ok(thread.classList.contains("thread"), "Arty must be expected Element.") this._element = thread this._op = LCNPost.assign(this._element.querySelector(".post.op")) - assert.equal(this._op.getParent(), null, "Op should not have parent.") this._op.__setParent(this) } @@ -302,7 +305,7 @@ globalThis.LCNPostContainer = class LCNPostContainer { static "assign" (container) { return container[this.nodeAttrib] || (container[this.nodeAttrib] = this.from(container)); } static "from" (container) { return new this(container); } - "constructor" (container) { + constructor (container) { this._parent = null; this._element = null; this._content = null; @@ -339,7 +342,7 @@ globalThis.LCNPostWrapper = class LCNPostWrapper { static "assign" (wrapper) { return wrapper[this.nodeAttrib] || (wrapper[this.nodeAttrib] = this.from(wrapper)); } static "from" (wrapper) { return new this(wrapper); } - "constructor" (wrapper) { + constructor (wrapper) { this._wrapper = null; this._eitaLink = null; this._eitaId = null; @@ -387,7 +390,7 @@ globalThis.LCNPostWrapper.selector = ".post-wrapper"; globalThis.LCNSetting = class LCNSetting { static "build" (id) { return new this(id); } - "constructor" (id) { + constructor (id) { this._id = null; this._eventId = null; this._label = null; @@ -448,7 +451,6 @@ globalThis.LCNToggleSetting = class LCNToggleSetting extends LCNSetting { } } - globalThis.LCNSettingsSubcategory = class LCNSettingsSubcategory { static "for" (tab_id, id) { @@ -473,7 +475,7 @@ globalThis.LCNSettingsSubcategory = class LCNSettingsSubcategory { } } - "constructor" (tab_id, id, fieldset) { + constructor (tab_id, id, fieldset) { this._tab_id = tab_id this._id = id this._fieldset = fieldset @@ -507,7 +509,7 @@ $().ready(() => { clazz.forEach = (fn, node=document) => clazz.allNodes(node).forEach(elem => fn(clazz.assign(elem))) clazz.filter = (fn, node=document) => clazz.all(node).filter(fn) clazz.find = fn => clazz.all().find(fn) - clazz.first = (node=document) => clazz.assign(node.querySelector(clazz.selector)) + clazz.first = (node=document) => { return clazz.assign(node.querySelector(clazz.selector)); } clazz.last = (node=document) => clazz.assign(Array.prototype.at.apply(clazz.allNodes(node), [ -1 ])) } diff --git a/js/lcn/thread_autoupdater.js b/js/lcn/thread_autoupdater.js index 6c09d245..4ed519b8 100644 --- a/js/lcn/thread_autoupdater.js +++ b/js/lcn/thread_autoupdater.js @@ -4,19 +4,19 @@ */ $().ready(() => { - const kIsEnabled = LCNToggleSetting.build("enabled") //const kIsBellEnabled = LCNToggleSetting.build("bellEnabled") void LCNSettingsSubcategory.for("general", "threadUpdater") .setLabel("Thread Updater") .addSetting(kIsEnabled .setLabel(_("Fetch new replies in the background")) - .setDefaultValue(true)) + .setDefaultValue(true)); /*.addSetting(kIsBellEnabled .setLabel(_("Play an audible chime when new replies are found")) .setDefaultValue(false))*/; if (LCNSite.INSTANCE.isThreadPage()) { + console.log("LCNSite.INSTANCE.isThreadPage() is true"); let threadUpdateStatus = null let secondsCounter = 0 let threadState = null @@ -30,7 +30,7 @@ $().ready(() => { const abortable = LCNSite.createAbortable() const threadStatsItems = [] const updateDOMStatus = () => { - const text = threadState ?? (secondsCounter >= 0 ? `${secondsCounter}s` : "…") + const text = threadState || (secondsCounter >= 0 ? `${secondsCounter}s` : "…") threadUpdateStatus.innerText = text } @@ -59,7 +59,7 @@ $().ready(() => { } const findMissingReplies = (thread_op, thread_dom, thread_latest) => { - const lastPostTs = (thread_dom.at(-1)?.getInfo() ?? thread_op).getCreatedAt().getTime() + const lastPostTs = (cont(thread_dom.at(-1), x => x.getInfo()) || thread_op).getCreatedAt().getTime() const missing = [] for (const pc of thread_latest.reverse()) { @@ -122,33 +122,48 @@ $().ready(() => { let onTickId = null const onTickFn = async () => { + console.log("tick function"); + void secondsCounter--; + console.log(secondsCounter); onTickClean() updateDOMStatus() + console.log("tick function2"); if (threadState == null) { + console.log("tick function3"); + console.log(secondsCounter); + if (secondsCounter < 0) { + console.log("tick function3.5"); const thread = LCNThread.first() + + console.log("tick function4"); try { await updateStatsFn(thread) if (threadState == null && threadStats.last_modified > (thread.getReplies().at(-1).getInfo().getCreatedAt().getTime() / 1000)) { updateThreadFn(thread, await fetchThreadFn()) } + console.log("tick function5"); + const threadEl = thread.getElement() statUniqueIPs.innerText = threadStats.unique_ips statReplies.innerText = thread.getReplies().length statFiles.innerText = threadEl.querySelectorAll(".files .file").length - threadEl.querySelectorAll(".files .file .post-image.deleted").length statPage.innerText = threadStats.page + 1 updateSecondsByTSLP(thread.getReplies().at(-1).getInfo()) + console.log("tick function6"); } catch (error) { console.error("threadAutoUpdater: Failed while processing update. Probably a network error", error) secondsCounter = 60 } } - onTickId = setTimeout(onTickFn, 1000) + //onTickId = setTimeout(onTickFn, 1000) } + + console.log("bottom of tick function"); } $(document).on("ajax_after_post", (_, xhr_body) => { @@ -167,15 +182,18 @@ $().ready(() => { $(document).on("thread_manual_refresh", () => { if (kIsEnabled.getValue() && secondsCounter >= 0) { secondsCounter = 0 + console.log("thread_manual_refresh handler"); onTickFn() } }) let floaterLinkBox = null const onStateChangeFn = v => { + console.log("onStateChangeFn"); onTickClean() if (v) { + console.log("v is true"); _domsetup_btn: { const container = LCNSite.INSTANCE.getFloaterLContainer() floaterLinkBox = document.createElement("span") @@ -231,9 +249,11 @@ $().ready(() => { } } + console.log("thread_manual_refresh trigger"); $(document).trigger("thread_manual_refresh") } else { - floaterLinkBox?.remove() + console.log("v is false"); + cont(floaterLinkBox, x => x.remove()) floaterLinkBox = null statReplies = null statFiles = null @@ -247,5 +267,6 @@ $().ready(() => { kIsEnabled.onChange(onStateChangeFn) onStateChangeFn(kIsEnabled.getValue()) + console.log("Bottom of if block"); } }) diff --git a/js/lcn/utils.js b/js/lcn/utils.js index 250f5bf9..b6309b7b 100644 --- a/js/lcn/utils.js +++ b/js/lcn/utils.js @@ -3,6 +3,54 @@ * @author jonsmy */ +function cont(value_to_test, fn) { + if (value_to_test != null) { + return fn(value_to_test); + } else { + return null; + } +} + +function text(s) { + return document.createTextNode(s); +} + +function prepend(elem, children) { + var child = elem.firstChild; + + if (child) { + elem.insertBefore(children, child); + } else { + elem.appendChild(children); + } +} + + +function _log() { + for (var arg of arguments) { + if (arg == null) { + continue; + } + + var pre = document.createElement('pre'); + pre.appendChild(text(arg.toString())); + document.body.appendChild(pre); + try { + prepend(document.body, pre); + } catch (e) { + var pre = document.createElement('pre'); + pre.appendChild(text(e.toString())); + document.body.appendChild(pre); + } + + } +} + +var console = { + log: _log, + error: _log +}; + const assert = { "equal": (actual, expected, message="No message set") => { if (actual !== expected) { @@ -41,3 +89,15 @@ if (AbortSignal.any == null) { return controller.signal; } } + +// polyfill for replaceChildren +if( Node.prototype.replaceChildren === undefined) { + Node.prototype.replaceChildren = function(addNodes) { + while(this.lastChild) { + this.removeChild(this.lastChild); + } + if (addNodes !== undefined) { + this.append(addNodes); + } + } +}