From dd6189378cbc4c8ad22b95951b103880dd39060d Mon Sep 17 00:00:00 2001
From: sageman_ <sageman@anomine.net>
Date: Sat, 3 Jul 2021 14:30:14 +0200
Subject: Implement auto-reload functionality A constant 5 second reload
 interval instead of increasing the reload intervals by 5 seconds every time
 so that the user does not miss any time sensitive posts. This also works with
 the invalid captcha patch.

---
 static/js/timer.js | 38 ++++++++++++++++++++++++++++++++++++++
 static/npost.html  |  2 ++
 2 files changed, 40 insertions(+)
 create mode 100644 static/js/timer.js

(limited to 'static')

diff --git a/static/js/timer.js b/static/js/timer.js
new file mode 100644
index 0000000..8f6516c
--- /dev/null
+++ b/static/js/timer.js
@@ -0,0 +1,38 @@
+var timerCount;
+var timerToggle = false;
+var timer;
+const contentLoadHandler = function(event){
+    timerToggle = !!document.getElementById("autoreload-checkbox").checked;
+    if(timerToggle){
+        timerCount = 5;
+        document.getElementById("autoreload-countdown").innerHTML = "5";
+        document.getElementById("autoreload-countdown").style.visibility = "visible";
+        timer = setInterval(timerFunction, 1000);
+        document.removeEventListener("DOMContentLoaded", contentLoadHandler, false);
+    }
+};
+
+document.addEventListener("DOMContentLoaded", contentLoadHandler, false);
+
+function timerFunction(){
+    timerCount--;
+    document.getElementById("autoreload-countdown").innerHTML = timerCount;
+    if(timerCount <= 0){
+        document.getElementById("autoreload-countdown").innerHTML = "Refreshing...";
+        clearInterval(timer);
+        location.reload();
+    }
+}
+
+function autoTimer(){
+    timerToggle = !timerToggle;
+    if(timerToggle === true){
+        timerCount = 5;
+        document.getElementById("autoreload-countdown").innerHTML = "5";
+        document.getElementById("autoreload-countdown").style.visibility = "visible";
+        timer = setInterval(timerFunction, 1000);
+    }else{
+        clearInterval(timer);
+        document.getElementById("autoreload-countdown").style.visibility = "hidden";
+    }
+}
\ No newline at end of file
diff --git a/static/npost.html b/static/npost.html
index 740018b..3df4090 100644
--- a/static/npost.html
+++ b/static/npost.html
@@ -17,6 +17,7 @@
 {{ end }}
 
 <script src="/static/js/posts.js"></script>
+<script src="/static/js/timer.js"></script>
 {{ end }}
 
 {{ define "content" }}
@@ -39,6 +40,7 @@
   <li style="display: inline"><a href="/{{ $board.Name }}/catalog">[Catalog]</a></li>            
   <li style="display: inline"><a id="bottom" href="#top">[Top]</a></li>
   <li style="display: inline"><a href="javascript:location.reload()">[Refresh]</a></li>
+  <li style="display: inline"><input id="autoreload-checkbox" type="checkbox" onclick="autoTimer()"> Auto refresh <span id="autoreload-countdown" style="visibility: hidden;">0</span></li>
 </ul>
 {{ $replies := (index .Posts 0).Replies }}            
 <span style="float: right;">{{ $replies.TotalItems }} / {{ $replies.TotalImgs }}</span>
-- 
cgit v1.2.3


From 8e3e745c2a8e9f1db6d15a67829b2aa320731c3f Mon Sep 17 00:00:00 2001
From: sageman_ <sageman@anomine.net>
Date: Sat, 3 Jul 2021 16:48:50 +0200
Subject: Preserve reply and report window states Especially important since
 auto-reload gets rid of what you wrote without this patch except for those
 who use the classic reply form. However, this introduces a lot of bloat to
 the code and a lot of data kept on the client-side. Perhaps we could
 implement a no JavaScript version? Also semicolons because apparently
 JavaScript is *this* forgiving.

---
 static/bottom.html        |   4 +-
 static/js/footerscript.js |  24 ++--
 static/js/posts.js        | 273 +++++++++++++++++++++++++++++++++-------------
 3 files changed, 209 insertions(+), 92 deletions(-)

(limited to 'static')

diff --git a/static/bottom.html b/static/bottom.html
index db9606d..994ad89 100644
--- a/static/bottom.html
+++ b/static/bottom.html
@@ -4,7 +4,7 @@
   <form id="reply-post" action="/post" method="post" enctype="multipart/form-data">
     <input id="reply-name" name="name" size="43" type="text" placeholder="Name" maxlength="100">
     <input id="reply-options" name="options" size="43" type="text" placeholder="Options" maxlength="100">
-    <textarea id="reply-comment" name="comment" rows="12" cols="54" style="width: 396px;" maxlength="2000"></textarea>
+    <textarea id="reply-comment" name="comment" rows="12" cols="54" style="width: 396px;" maxlength="2000" oninput="sessionStorage.setItem('element-reply-comment', document.getElementById('reply-comment').value)"></textarea>
     <input id="reply-file" name="file" type="file">
     <input id="reply-submit" type="submit" value="Reply" style="float: right;"><br><br>
     <input type="hidden" id="inReplyTo-box" name="inReplyTo" value="{{ .Board.InReplyTo }}">
@@ -27,7 +27,7 @@
   <div id="report-header" style="text-align: center; display: inline-block; width: 370px; z-index: 0; cursor: move;"></div><div id="report-close" style="display: inline-block; float: right;"><a href="javascript:closeReport()">[X]</a></div>
   <form id="report-post" action="/report" method="post">
     <label for="comment">Reason:</label>
-    <textarea id="report-comment" name="comment" rows="12" cols="54" style="width: 396px;" maxlength="100"></textarea>
+    <textarea id="report-comment" name="comment" rows="12" cols="54" style="width: 396px;" maxlength="100" oninput="sessionStorage.setItem('element-report-comment', document.getElementById('report-comment').value)"></textarea>
     <input id="report-submit" type="submit" value="Report" style="float: right;">
     <input type="hidden" id="report-inReplyTo-box" name="id" value="{{ .Board.InReplyTo }}">
     <input type="hidden" id="sendTo" name="sendTo" value="{{ .Board.To }}">
diff --git a/static/js/footerscript.js b/static/js/footerscript.js
index a63f422..69e56e7 100644
--- a/static/js/footerscript.js
+++ b/static/js/footerscript.js
@@ -3,34 +3,34 @@ var imgArray = [].slice.call(imgs);
 
 imgArray.forEach(function(img, i){
     img.addEventListener("click", function(e){
-        var id = img.getAttribute("id")
-        var media = document.getElementById("media-" + id)
-        var sensitive = document.getElementById("sensitive-" + id)        
+        var id = img.getAttribute("id");
+        var media = document.getElementById("media-" + id);
+        var sensitive = document.getElementById("sensitive-" + id);     
         
         if(img.getAttribute("enlarge") == "0")
         {
-            var attachment = img.getAttribute("attachment")
+            var attachment = img.getAttribute("attachment");
             img.setAttribute("enlarge", "1");
             img.setAttribute("style", "float: left; margin-right: 10px; cursor: pointer;");
-            img.src = attachment
+            img.src = attachment;
         }
         else
         {
-            var preview = img.getAttribute("preview")
+            var preview = img.getAttribute("preview");
             img.setAttribute("enlarge", "0");
             if(img.getAttribute("main") == 1)
             {
                 img.setAttribute("style", "float: left; margin-right: 10px; max-width: 250px; max-height: 250px; cursor: pointer;");
-                img.src = preview
+                img.src = preview;
             }
             else
             {
                 img.setAttribute("style", "float: left; margin-right: 10px; max-width: 125px; max-height: 125px; cursor: pointer;");
-                img.src = preview                
+                img.src = preview;
             }
         }
     });
-})
+});
 
 
 function viewLink(board, actor) {
@@ -38,7 +38,7 @@ function viewLink(board, actor) {
     var postsArray = [].slice.call(posts);
 
     postsArray.forEach(function(p, i){
-        var id = p.getAttribute("post")
-        p.href = "/" + board + "/" + shortURL(actor, id)
-    })  
+        var id = p.getAttribute("post");
+        p.href = "/" + board + "/" + shortURL(actor, id);
+    });
 }
diff --git a/static/js/posts.js b/static/js/posts.js
index 79fb7c4..d91fadd 100644
--- a/static/js/posts.js
+++ b/static/js/posts.js
@@ -1,33 +1,44 @@
+function startNewPost(){
+    var el = document.getElementById("newpostbtn");
+    el.style="display:none;";
+    el.setAttribute("state", "1");
+    document.getElementById("newpost").style = "display: block;";  
+}
+
+function stopNewPost(){
+    var el = document.getElementById("newpostbtn");
+    el.style="display:block;";
+    el.setAttribute("state", "0");
+    document.getElementById("newpost").style = "display: hidden;"; 
+}
+
 function newpost()
 {
-    var el = document.getElementById("newpostbtn")
-    var state = el.getAttribute("state")
-    if(state = "0")
+    var state = document.getElementById("newpostbtn").getAttribute("state");
+    if(state === "0")
     {
-        el.style="display:none;"
-        el.setAttribute("state", "1")
-        document.getElementById("newpost").style = "display: block;";        
+        startNewPost();
+        sessionStorage.setItem("newpostState", true);    
     }
     else
     {
-        el.style="display:block;"
-        el.setAttribute("state", "0")
-        document.getElementById("newpost").style = "display: hidden;";        
+        stopNewPost();
+        sessionStorage.setItem("newpostState", false);      
     }
 }
 
 function getMIMEType(type)
 {
-    re = /\/.+/g
-    return type.replace(re, "")
+    re = /\/.+/g;
+    return type.replace(re, "");
 }
 
 function shortURL(actorName, url)
 {
     re = /.+\//g;
-    temp = re.exec(url)
+    temp = re.exec(url);
 
-    var output
+    var output;
     
     if(stripTransferProtocol(temp[0]) == stripTransferProtocol(actorName) + "/")
     {
@@ -55,18 +66,18 @@ function shortURL(actorName, url)
 
         u =  re.exec(short);
 
-        str = short.replace(/\/+/g, " ")
+        str = short.replace(/\/+/g, " ");
 
-        str = str.replace(u, " ").trim()
+        str = str.replace(u, " ").trim();
 
         re = /(\w|[!@#$%^&*<>])+$/;
         
-        v = re.exec(str)
+        v = re.exec(str);
 
         output = "f" + v[0] + "-" + u
     }
 
-    return output
+    return output;
 }
 
 function shortImg(url)
@@ -92,22 +103,22 @@ function convertSize(size)
     var convert = size / 1024.0;
     if(convert > 1024)
     {
-        convert = convert / 1024.0
-        convert = convert.toFixed(2) + " MB"
+        convert = convert / 1024.0;
+        convert = convert.toFixed(2) + " MB";
     }
     else
     {
-        convert = convert.toFixed(2) + " KB"
+        convert = convert.toFixed(2) + " KB";
     }
 
-    return convert
+    return convert;
 }
 
 function getBoardId(url)
 {
-    var re = /\/([^/\n]+)(.+)?/gm
+    var re = /\/([^/\n]+)(.+)?/gm;
     var matches = re.exec(url);
-    return matches[1]
+    return matches[1];
 }
 
 function convertContent(actorName, content, opid)
@@ -118,24 +129,24 @@ function convertContent(actorName, content, opid)
     if(match)
     {
         match.forEach(function(quote, i){
-            var link = quote.replace('>>', '')
-            var isOP = ""
+            var link = quote.replace('>>', '');
+            var isOP = "";
             if(link == opid)
             {
                 isOP = " (OP)";
             }
             
-            var q = link
+            var q = link;
             
             if(document.getElementById(link + "-content") != null) {
                 q = document.getElementById(link + "-content").innerText;
-                q = q.replaceAll('>', '/\>')
-                q = q.replaceAll('"', '')
-                q = q.replaceAll("'", "")                                
+                q = q.replaceAll('>', '/\>');
+                q = q.replaceAll('"', '');
+                q = q.replaceAll("'", "");                       
             }
             newContent = newContent.replace(quote, '<a class="reply" title="' + q +  '" href="'+ (actorName) + "/" + shortURL(actorName, opid)  +  '#' + shortURL(actorName, link) + '";">>>' + shortURL(actorName, link)  + isOP + '</a>');
 
-        })            
+        });           
     }
     
     re =  /^(\s+)?>.+/gm;
@@ -146,10 +157,10 @@ function convertContent(actorName, content, opid)
         match.forEach(function(quote, i) {
     
             newContent = newContent.replace(quote, '<span class="quote">' + quote + '</span>');
-        })
+        });
     }
     
-    return newContent.replaceAll('/\>', '>')
+    return newContent.replaceAll('/\>', '>');
 }
 
 function convertContentNoLink(actorName, content, opid)
@@ -160,36 +171,40 @@ function convertContentNoLink(actorName, content, opid)
     if(match)
     {
         match.forEach(function(quote, i){
-            var link = quote.replace('>>', '')
-            var isOP = ""
+            var link = quote.replace('>>', '');
+            var isOP = "";
             if(link == opid)
             {
                 isOP = " (OP)";
             }
             
-            var q = link
+            var q = link;
             
             if(document.getElementById(link + "-content") != null) {
                 q = document.getElementById(link + "-content").innerText;
             }
             
             newContent = newContent.replace(quote, '>>' + shortURL(actorName, link)  + isOP);
-        })            
+        });   
     }
-    newContent = newContent.replaceAll("'", "")
-    return newContent.replaceAll('"', '')
+    newContent = newContent.replaceAll("'", "");
+    return newContent.replaceAll('"', '');
 }
 
 function closeReply()
 {
     document.getElementById("reply-box").style.display = "none";
-    document.getElementById("reply-comment").value = "";        
+    document.getElementById("reply-comment").value = "";      
+      
+    sessionStorage.setItem("element-closed-reply", true);
 }
 
 function closeReport()
 {
     document.getElementById("report-box").style.display = "none";
     document.getElementById("report-comment").value = "";        
+
+    sessionStorage.setItem("element-closed-report", true);
 }
 
 
@@ -211,10 +226,11 @@ function next(actorName, totalPage, page)
 
 function quote(actorName, opid, id)
 {
+    sessionStorage.setItem("element-closed-reply", false);
     var box = document.getElementById("reply-box");
     var header = document.getElementById("reply-header");
     var comment = document.getElementById("reply-comment");
-    var inReplyTo = document.getElementById("inReplyTo-box");      
+    var inReplyTo = document.getElementById("inReplyTo-box");
 
     var w = window.innerWidth / 2 - 200;
     if(id == "reply") {
@@ -223,8 +239,11 @@ function quote(actorName, opid, id)
         var h = document.getElementById(id + "-content").offsetTop - 348;
     }
 
-
-    box.setAttribute("style", "display: block; position: absolute; width: 400px; height: 600px; z-index: 9; top: " + h + "px; left: " + w + "px; padding: 5px;");
+    const boxStyle = "display: block; position: absolute; width: 400px; height: 600px; z-index: 9; top: " + h + "px; left: " + w + "px; padding: 5px;";
+    box.setAttribute("style", boxStyle);
+    sessionStorage.setItem("element-reply-style", boxStyle);
+    sessionStorage.setItem("reply-top", h);
+    sessionStorage.setItem("reply-left", w);
 
 
     if (inReplyTo.value != opid)
@@ -232,9 +251,12 @@ function quote(actorName, opid, id)
     
     header.innerText = "Replying to Thread No. " + shortURL(actorName, opid);
     inReplyTo.value = opid;
+    sessionStorage.setItem("element-reply-actor", actorName);
+    sessionStorage.setItem("element-reply-id", inReplyTo.value);
 
     if(id != "reply")
         comment.value += ">>" + id + "\n";
+    sessionStorage.setItem("element-reply-comment", comment.value);
 
     dragElement(header);            
 
@@ -242,66 +264,161 @@ function quote(actorName, opid, id)
 
 function report(actorName, id)
 {
+    sessionStorage.setItem("element-closed-report", false);
     var box = document.getElementById("report-box");
     var header = document.getElementById("report-header");
     var comment = document.getElementById("report-comment");
-    var inReplyTo = document.getElementById("report-inReplyTo-box");      
+    var inReplyTo = document.getElementById("report-inReplyTo-box");    
 
     var w = window.innerWidth / 2 - 200;
     var h = document.getElementById(id + "-content").offsetTop - 348;
 
-    box.setAttribute("style", "display: block; position: absolute; width: 400px; height: 480px; z-index: 9; top: " + h + "px; left: " + w + "px; padding: 5px;");
+    const boxStyle = "display: block; position: absolute; width: 400px; height: 480px; z-index: 9; top: " + h + "px; left: " + w + "px; padding: 5px;";
+    box.setAttribute("style", boxStyle);
+    sessionStorage.setItem("element-report-style", boxStyle);
+    sessionStorage.setItem("report-top", h);
+    sessionStorage.setItem("report-left", w);
 
     header.innerText = "Report Post No. " + shortURL(actorName, id);
     inReplyTo.value = id;
+    sessionStorage.setItem("element-report-actor", actorName);
+    sessionStorage.setItem("element-report-id", id);
 
     dragElement(header);            
 }  
 
+var pos1, pos2, pos3, pos4;
+var elmnt;
+
+function closeDragElement(e) {
+    // stop moving when mouse button is released:
+    document.onmouseup = null;
+    document.onmousemove = null;
+    sessionStorage.setItem("eventhandler", false);
+}
+
+function elementDrag(e) {
+    e = e || window.event;
+    e.preventDefault();
+    // calculate the new cursor position:
+    pos1 = pos3 - e.clientX;
+    pos2 = pos4 - e.clientY;
+    pos3 = e.clientX;
+    pos4 = e.clientY;
+    sessionStorage.setItem("pos1", pos1);
+    sessionStorage.setItem("pos2", pos2);
+    sessionStorage.setItem("pos3", pos3);
+    sessionStorage.setItem("pos4", pos4);
+
+    // set the element's new position:
+    elmnt.parentElement.style.top = (elmnt.parentElement.offsetTop - pos2) + "px";
+    elmnt.parentElement.style.left = (elmnt.parentElement.offsetLeft - pos1) + "px";
+    if(elmnt.id.startsWith("report")){
+        sessionStorage.setItem("report-top", elmnt.parentElement.style.top);
+        sessionStorage.setItem("report-left", elmnt.parentElement.style.left);
+    }else if(elmnt.id.startsWith("reply")){
+        sessionStorage.setItem("reply-top", elmnt.parentElement.style.top);
+        sessionStorage.setItem("reply-left", elmnt.parentElement.style.left);
+    }
+}
+
+function dragMouseDown(e) {
+    e = e || window.event;
+    e.preventDefault();
+
+    // get the mouse cursor position at startup:
+    pos3 = e.clientX;
+    pos4 = e.clientY;
+    sessionStorage.setItem("pos3", pos3);
+    sessionStorage.setItem("pos4", pos4);
+
+    elmnt = e.currentTarget;
+
+    // call a function whenever the cursor moves:
+    document.onmouseup = closeDragElement;
+    document.onmousemove = elementDrag;
+    sessionStorage.setItem("eventhandler", true);
+
+}
+
 function dragElement(elmnt) {
-    var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
-    
     elmnt.onmousedown = dragMouseDown;
+}
 
-    function dragMouseDown(e) {
-        e = e || window.event;
-        e.preventDefault();
-        // get the mouse cursor position at startup:
-        pos3 = e.clientX;
-        pos4 = e.clientY;
-        document.onmouseup = closeDragElement;
-        // call a function whenever the cursor moves:
-        document.onmousemove = elementDrag;
-    }
+const stateLoadHandler = function(event){
+    pos1 = parseInt(sessionStorage.getItem("pos1"));
+    pos2 = parseInt(sessionStorage.getItem("pos2"));
+    pos3 = parseInt(sessionStorage.getItem("pos3"));
+    pos4 = parseInt(sessionStorage.getItem("pos4"));
 
-    function elementDrag(e) {
-        e = e || window.event;
-        e.preventDefault();
-        // calculate the new cursor position:
-        pos1 = pos3 - e.clientX;
-        pos2 = pos4 - e.clientY;
-        pos3 = e.clientX;
-        pos4 = e.clientY;
-        // set the element's new position:
-        elmnt.parentElement.style.top = (elmnt.parentElement.offsetTop - pos2) + "px";
-        elmnt.parentElement.style.left = (elmnt.parentElement.offsetLeft - pos1) + "px";
-    }
+    if(sessionStorage.getItem("element-closed-report") === "false"){
+        var box = document.getElementById("report-box");
+        var header = document.getElementById("report-header");
+        var comment = document.getElementById("report-comment");
+        var inReplyTo = document.getElementById("report-inReplyTo-box");
 
-    function closeDragElement() {
-        // stop moving when mouse button is released:
-        document.onmouseup = null;
-        document.onmousemove = null;
+        header.onmousedown = dragMouseDown;
+        inReplyTo.value = parseInt(sessionStorage.getItem("element-report-id"));
+        header.innerText = "Report Post No. " + shortURL(sessionStorage.getItem("element-report-actor"), sessionStorage.getItem("element-report-id"));
+        comment.value = sessionStorage.getItem("element-report-comment");
+
+        box.setAttribute("style", sessionStorage.getItem("element-report-style"));
+            
+        box.style.top = sessionStorage.getItem("report-top");
+        box.style.left = sessionStorage.getItem("report-left");
+
+        if(sessionStorage.getItem("eventhandler") === "true"){
+            elmnt = header;
+            document.onmouseup = closeDragElement;
+            document.onmousemove = elementDrag;
+        }else{
+            document.onmouseup = null;
+            document.onmousemove = null;
+        }
     }
-}
+    if(sessionStorage.getItem("element-closed-reply") === "false"){
+        var box = document.getElementById("reply-box");
+        var header = document.getElementById("reply-header");
+        var comment = document.getElementById("reply-comment");
+        var inReplyTo = document.getElementById("inReplyTo-box");
+
+        header.onmousedown = dragMouseDown;
+        inReplyTo.value = parseInt(sessionStorage.getItem("element-reply-id"));
+        header.innerText = "Replying to Thread No. " + shortURL(sessionStorage.getItem("element-reply-actor"), sessionStorage.getItem("element-reply-id"));
+        comment.value = sessionStorage.getItem("element-reply-comment");
+
+        pos1 = parseInt(sessionStorage.getItem("pos1"));
+        pos2 = parseInt(sessionStorage.getItem("pos2"));
+        pos3 = parseInt(sessionStorage.getItem("pos3"));
+        pos4 = parseInt(sessionStorage.getItem("pos4"));
+
+        box.setAttribute("style", sessionStorage.getItem("element-reply-style"));
+            
+        box.style.top = sessionStorage.getItem("reply-top");
+        box.style.left = sessionStorage.getItem("reply-left");
+
+        if(sessionStorage.getItem("eventhandler") === "true"){
+            elmnt = header;
+            document.onmouseup = closeDragElement;
+            document.onmousemove = elementDrag;
+        }else{
+            document.onmouseup = null;
+            document.onmousemove = null;
+        }
+    }
+};
+
+document.addEventListener("DOMContentLoaded", stateLoadHandler, false);
 
 function stripTransferProtocol(value){
-    var re = /(https:\/\/|http:\/\/)?(www.)?/
-    return value.replace(re, "")
+    var re = /(https:\/\/|http:\/\/)?(www.)?/;
+    return value.replace(re, "");
 }
 
 function isOnion(value){
-    var re = /\.onion/
+    var re = /\.onion/;
     if(value.match(re) != null)
-        return true
-    return false
+        return true;
+    return false;
 }
+
-- 
cgit v1.2.3