avoid sending the same bytes over and over when the alert list hasn't changed

save bytes in activity feed queries
save bytes in scripts
This commit is contained in:
Azareal 2020-04-04 11:25:59 +10:00
parent e2293b3495
commit 943ab18761
3 changed files with 154 additions and 156 deletions

View File

@ -12,7 +12,7 @@ import (
"log" "log"
c "github.com/Azareal/Gosora/common" c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/query_gen" qgen "github.com/Azareal/Gosora/query_gen"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -60,19 +60,19 @@ func initMySQL() (err error) {
}*/ }*/
log.Print("Preparing getActivityFeedByWatcher statement.") log.Print("Preparing getActivityFeedByWatcher statement.")
stmts.getActivityFeedByWatcher, err = db.Prepare("SELECT activity_stream_matches.asid, activity_stream.actor, activity_stream.targetUser, activity_stream.event, activity_stream.elementType, activity_stream.elementID, activity_stream.createdAt FROM `activity_stream_matches` INNER JOIN `activity_stream` ON activity_stream_matches.asid = activity_stream.asid AND activity_stream_matches.watcher != activity_stream.actor WHERE `watcher` = ? ORDER BY activity_stream.asid DESC LIMIT ?") stmts.getActivityFeedByWatcher, err = db.Prepare("SELECT activity_stream_matches.asid, activity_stream.actor, activity_stream.targetUser, activity_stream.event, activity_stream.elementType, activity_stream.elementID, activity_stream.createdAt FROM activity_stream_matches INNER JOIN activity_stream ON activity_stream_matches.asid = activity_stream.asid AND activity_stream_matches.watcher != activity_stream.actor WHERE watcher=? ORDER BY activity_stream.asid DESC LIMIT ?")
if err != nil { if err != nil {
return errors.WithStack(err) return errors.WithStack(err)
} }
/*log.Print("Preparing getActivityFeedByWatcherAfter statement.") /*log.Print("Preparing getActivityFeedByWatcherAfter statement.")
stmts.getActivityFeedByWatcherAfter, err = db.Prepare("SELECT activity_stream_matches.asid, activity_stream.actor, activity_stream.targetUser, activity_stream.event, activity_stream.elementType, activity_stream.elementID, activity_stream.createdAt FROM `activity_stream_matches` INNER JOIN `activity_stream` ON activity_stream_matches.asid = activity_stream.asid AND activity_stream_matches.watcher != activity_stream.actor WHERE `watcher` = ? AND createdAt => ? ORDER BY activity_stream.asid DESC LIMIT ?") stmts.getActivityFeedByWatcherAfter, err = db.Prepare("SELECT activity_stream_matches.asid, activity_stream.actor, activity_stream.targetUser, activity_stream.event, activity_stream.elementType, activity_stream.elementID, activity_stream.createdAt FROM activity_stream_matches INNER JOIN activity_stream ON activity_stream_matches.asid = activity_stream.asid AND activity_stream_matches.watcher != activity_stream.actor WHERE watcher=? AND asid => ? ORDER BY activity_stream.asid DESC LIMIT ?")
if err != nil { if err != nil {
return errors.WithStack(err) return errors.WithStack(err)
}*/ }*/
log.Print("Preparing getActivityCountByWatcher statement.") log.Print("Preparing getActivityCountByWatcher statement.")
stmts.getActivityCountByWatcher, err = db.Prepare("SELECT count(*) FROM `activity_stream_matches` INNER JOIN `activity_stream` ON activity_stream_matches.asid = activity_stream.asid AND activity_stream_matches.watcher != activity_stream.actor WHERE `watcher` = ?") stmts.getActivityCountByWatcher, err = db.Prepare("SELECT count(*) FROM activity_stream_matches INNER JOIN activity_stream ON activity_stream_matches.asid = activity_stream.asid AND activity_stream_matches.watcher != activity_stream.actor WHERE watcher=?")
if err != nil { if err != nil {
return errors.WithStack(err) return errors.WithStack(err)
} }

View File

@ -1,34 +1,34 @@
'use strict'; 'use strict';
var formVars = {}; var formVars={};
var alertMapping = {}; var alertMapping={};
var alertList = []; var alertList=[];
var alertCount = 0; var alertCount=0;
var moreTopicCount = 0; var moreTopicCount=0;
var conn = false; var conn=false;
var selectedTopics = []; var selectedTopics=[];
var attachItemCallback = function(){} var attachItemCallback=function(){}
var quoteItemCallback = function(){} var quoteItemCallback=function(){}
var baseTitle = document.title; var baseTitle=document.title;
var wsBackoff = 0; var wsBackoff=0;
var noAlerts = false; var noAlerts=false;
// Topic move // Topic move
var forumToMoveTo = 0; var forumToMoveTo=0;
function pushNotice(msg) { function pushNotice(msg) {
let aBox = document.getElementsByClassName("alertbox")[0]; let aBox = document.getElementsByClassName("alertbox")[0];
let div = document.createElement('div'); let n = document.createElement('div');
div.innerHTML = Tmpl_notice(msg).trim(); n.innerHTML = Tmpl_notice(msg).trim();
aBox.appendChild(div); aBox.appendChild(n);
runInitHook("after_notice"); runInitHook("after_notice");
} }
// TODO: Write a friendlier error handler which uses a .notice or something, we could have a specialised one for alerts // TODO: Write a friendlier error handler which uses a .notice or something, we could have a specialised one for alerts
function ajaxError(xhr,status,errstr) { function ajaxError(xhr,status,er) {
console.log("The AJAX request failed"); console.log("The AJAX request failed");
console.log("xhr",xhr); console.log("xhr",xhr);
console.log("status",status); console.log("status",status);
console.log("err",errstr); console.log("er",er);
if(status=="parsererror") console.log("The server didn't respond with a valid JSON response"); if(status=="parsererror") console.log("The server didn't respond with a valid JSON response");
console.trace(); console.trace();
} }
@ -58,11 +58,11 @@ function bindToAlerts() {
}); });
} }
function addAlert(msg, notice=false) { function addAlert(msg,notice=false) {
var mmsg = msg.msg; var mmsg = msg.msg;
if(mmsg[0]==".") mmsg = phraseBox["alerts"]["alerts"+mmsg]; if(mmsg[0]==".") mmsg = phraseBox["alerts"]["alerts"+mmsg];
if("sub" in msg) { if("sub" in msg) {
for(var i = 0; i < msg.sub.length; i++) mmsg = mmsg.replace("\{"+i+"\}", msg.sub[i]); for(var i=0; i<msg.sub.length; i++) mmsg = mmsg.replace("\{"+i+"\}", msg.sub[i]);
} }
let aItem = Tmpl_alert({ let aItem = Tmpl_alert({
@ -80,12 +80,12 @@ function addAlert(msg, notice=false) {
if(notice) { if(notice) {
// TODO: Add some sort of notification queue to avoid flooding the end-user with notices? // TODO: Add some sort of notification queue to avoid flooding the end-user with notices?
// TODO: Use the site name instead of "Something Happened" // TODO: Use the site name instead of "Something Happened"
if(Notification.permission === "granted") { if(Notification.permission==="granted") {
var n = new Notification("Something Happened",{ var n = new Notification("Something Happened",{
body: mmsg, body: mmsg,
icon: msg.img, icon: msg.img,
}); });
setTimeout(n.close.bind(n), 8000); setTimeout(n.close.bind(n),8000);
} }
} }
@ -100,7 +100,7 @@ function updateAlertList(menuAlerts) {
alertListNode.innerHTML = ""; alertListNode.innerHTML = "";
let any = false; let any = false;
let j = 0; let j = 0;
for(var i = 0; i < alertList.length && j < 8; i++) { for(var i=0; i<alertList.length && j<8; i++) {
any = true; any = true;
alertListNode.appendChild(alertMapping[alertList[i]]); alertListNode.appendChild(alertMapping[alertList[i]]);
//outList += alertMapping[alertList[i]]; //outList += alertMapping[alertList[i]];
@ -108,7 +108,7 @@ function updateAlertList(menuAlerts) {
} }
if(!any) alertListNode.innerHTML = "<div class='alertItem'>"+phraseBox["alerts"]["alerts.no_alerts"]+"</div>"; if(!any) alertListNode.innerHTML = "<div class='alertItem'>"+phraseBox["alerts"]["alerts.no_alerts"]+"</div>";
if(alertCount != 0) { if(alertCount!=0) {
alertCounterNode.textContent = alertCount; alertCounterNode.textContent = alertCount;
menuAlerts.classList.add("has_alerts"); menuAlerts.classList.add("has_alerts");
let nTitle = "("+alertCount+") "+baseTitle; let nTitle = "("+alertCount+") "+baseTitle;
@ -120,7 +120,7 @@ function updateAlertList(menuAlerts) {
bindToAlerts(); bindToAlerts();
console.log("alertCount",alertCount) console.log("alertCount",alertCount)
runInitHook("after_update_alert_list", alertCount); runInitHook("after_update_alert_list",alertCount);
} }
function setAlertError(menuAlerts,msg) { function setAlertError(menuAlerts,msg) {
@ -133,21 +133,23 @@ var lastTc = 0;
function loadAlerts(menuAlerts,eTc=false) { function loadAlerts(menuAlerts,eTc=false) {
if(!alertsInitted) return; if(!alertsInitted) return;
let tc = ""; let tc = "";
if(eTc && lastTc != 0) tc = "&t=" + lastTc + "&c=" + alertCount; if(eTc && lastTc!=0) tc = "&t="+lastTc+"&c="+alertCount;
$.ajax({ $.ajax({
type:'get', type:'get',
dataType:'json', dataType:'json',
url:'/api/?m=alerts' + tc, url:'/api/?m=alerts'+tc,
success: data => { success: data => {
if("errmsg" in data) { if("errmsg" in data) {
setAlertError(menuAlerts,data.errmsg) setAlertError(menuAlerts,data.errmsg)
return; return;
} }
alertList = []; if(!eTc) {
alertMapping = {}; alertList=[];
alertMapping={};
}
if(!data.hasOwnProperty("msgs")) data = {"msgs":[],"count":alertCount,"tc":lastTc}; if(!data.hasOwnProperty("msgs")) data = {"msgs":[],"count":alertCount,"tc":lastTc};
/*else if(data.count != (alertCount + data.msgs.length)) tc = false; /*else if(data.count != (alertCount + data.msgs.length)) tc = false;
if(eTc && lastTc != 0) { if(eTc && lastTc!=0) {
for(var i in data.msgs) wsAlertEvent(data.msgs[i]); for(var i in data.msgs) wsAlertEvent(data.msgs[i]);
} else {*/ } else {*/
console.log("data",data); console.log("data",data);
@ -157,54 +159,54 @@ function loadAlerts(menuAlerts,eTc=false) {
//} //}
lastTc = data.tc; lastTc = data.tc;
}, },
error: (magic,theStatus,err) => { error: (magic,status,er) => {
let errtxt = "Unable to get the alerts"; let errtxt = "Unable to get the alerts";
try { try {
var data = JSON.parse(magic.responseText); let dat = JSON.parse(magic.responseText);
if("errmsg" in data) errtxt = data.errmsg; if("errmsg" in dat) errtxt = dat.errmsg;
} catch(err) { } catch(e) {
console.log(magic.responseText); console.log(magic.responseText);
console.log(err); console.log(e);
} }
console.log("err", err); console.log("er",er);
setAlertError(menuAlerts,errtxt); setAlertError(menuAlerts,errtxt);
} }
}); });
} }
function SplitN(data,ch,n) { function SplitN(data,ch,n) {
var out = []; var o = [];
if(data.length === 0) return out; if(data.length===0) return o;
var lastI = 0; var lastI = 0;
var j = 0; var j = 0;
var lastN = 1; var lastN = 1;
for(let i = 0; i < data.length; i++) { for(let i=0; i<data.length; i++) {
if(data[i] === ch) { if(data[i] === ch) {
out[j++] = data.substring(lastI,i); o[j++] = data.substring(lastI,i);
lastI = i; lastI = i;
if(lastN === n) break; if(lastN === n) break;
lastN++; lastN++;
} }
} }
if(data.length > lastI) out[out.length - 1] += data.substring(lastI); if(data.length > lastI) o[o.length - 1] += data.substring(lastI);
return out; return o;
} }
function wsAlertEvent(data) { function wsAlertEvent(dat) {
console.log("wsAlertEvent",data) console.log("wsAlertEvent",dat)
addAlert(data, true); addAlert(dat,true);
alertCount++; alertCount++;
let aTmp = alertList; let aTmp = alertList;
alertList = [alertList[alertList.length-1]]; alertList = [alertList[alertList.length-1]];
aTmp = aTmp.slice(0,-1); aTmp = aTmp.slice(0,-1);
for(let i = 0; i < aTmp.length; i++) alertList.push(aTmp[i]); for(let i=0; i<aTmp.length; i++) alertList.push(aTmp[i]);
// TODO: Add support for other alert feeds like PM Alerts // TODO: Add support for other alert feeds like PM Alerts
var generalAlerts = document.getElementById("general_alerts"); let n = document.getElementById("general_alerts");
// TODO: Make sure we update alertCount here // TODO: Make sure we update alertCount here
lastTc = 0; lastTc = 0;
updateAlertList(generalAlerts/*, alist*/); updateAlertList(n/*,alist*/);
} }
function runWebSockets(resume=false) { function runWebSockets(resume=false) {
@ -212,7 +214,7 @@ function runWebSockets(resume=false) {
if(window.location.protocol == "https:") s = "s"; if(window.location.protocol == "https:") s = "s";
conn = new WebSocket("ws"+s+"://" + document.location.host + "/ws/"); conn = new WebSocket("ws"+s+"://" + document.location.host + "/ws/");
conn.onerror = (err) => { conn.onerror = err => {
console.log(err); console.log(err);
} }
@ -236,8 +238,8 @@ function runWebSockets(resume=false) {
setTimeout(() => { setTimeout(() => {
if(!noAlerts) { if(!noAlerts) {
let alertMenuList = document.getElementsByClassName("menu_alerts"); let nl = document.getElementsByClassName("menu_alerts");
for(var i=0; i < alertMenuList.length; i++) loadAlerts(alertMenuList[i]); for(var i=0; i < nl.length; i++) loadAlerts(nl[i],true);
} }
runWebSockets(true); runWebSockets(true);
}, backoff * 60 * 1000); }, backoff * 60 * 1000);
@ -260,9 +262,9 @@ function runWebSockets(resume=false) {
return; return;
} }
if ("msg" in data) wsAlertEvent(data); if("msg" in data) wsAlertEvent(data);
else if("event" in data) { else if("event" in data) {
if(data.event == "dismiss-alert"){ if(data.event=="dismiss-alert"){
Object.keys(alertMapping).forEach((key) => { Object.keys(alertMapping).forEach((key) => {
if(key!=data.id) return; if(key!=data.id) return;
alertCount--; alertCount--;
@ -275,15 +277,13 @@ function runWebSockets(resume=false) {
} }
if(index==-1) return; if(index==-1) return;
for(var i = index; (i+1) < alertList.length; i++) { for(var i = index; (i+1) < alertList.length; i++) alertList[i] = alertList[i+1];
alertList[i] = alertList[i+1];
}
alertList.splice(alertList.length-1,1); alertList.splice(alertList.length-1,1);
delete alertMapping[key]; delete alertMapping[key];
// TODO: Add support for other alert feeds like PM Alerts // TODO: Add support for other alert feeds like PM Alerts
let generalAlerts = document.getElementById("general_alerts"); let generalAlerts = document.getElementById("general_alerts");
if(alertList.length < 8) loadAlerts(generalAlerts); if(alertList.length < 8) loadAlerts(generalAlerts,true);
else updateAlertList(generalAlerts); else updateAlertList(generalAlerts);
}); });
} }
@ -305,23 +305,21 @@ function runWebSockets(resume=false) {
$(".topic_list").prepend(node); $(".topic_list").prepend(node);
moreTopicCount++; moreTopicCount++;
let moreTopicBlocks = document.getElementsByClassName("more_topic_block_initial"); let blocks = document.getElementsByClassName("more_topic_block_initial");
for(let i=0; i < moreTopicBlocks.length; i++) { for(let i=0; i < blocks.length; i++) {
let moreTopicBlock = moreTopicBlocks[i]; let block = blocks[i];
moreTopicBlock.classList.remove("more_topic_block_initial"); block.classList.remove("more_topic_block_initial");
moreTopicBlock.classList.add("more_topic_block_active"); block.classList.add("more_topic_block_active");
console.log("phraseBox",phraseBox); console.log("phraseBox",phraseBox);
let msgBox = moreTopicBlock.getElementsByClassName("more_topics")[0]; let msgBox = block.getElementsByClassName("more_topics")[0];
msgBox.innerText = phraseBox["topic_list"]["topic_list.changed_topics"].replace("%d",moreTopicCount); msgBox.innerText = phraseBox["topic_list"]["topic_list.changed_topics"].replace("%d",moreTopicCount);
} }
} else { } else console.log("unknown message",data);
console.log("unknown message", data);
}
} }
let messages = event.data.split('\r'); let messages = event.data.split('\r');
for(var i=0; i < messages.length; i++) { for(var i=0; i<messages.length; i++) {
let message = messages[i]; let message = messages[i];
//console.log("message",message); //console.log("message",message);
let msgblocks = SplitN(message," ",3); let msgblocks = SplitN(message," ",3);
@ -360,8 +358,8 @@ function getExt(name) {
// TODO: The load part of loadAlerts could be done asynchronously while the update of the DOM could be deferred // TODO: The load part of loadAlerts could be done asynchronously while the update of the DOM could be deferred
$(document).ready(() => { $(document).ready(() => {
alertsInitted = true; alertsInitted = true;
var alertMenuList = document.getElementsByClassName("menu_alerts"); let alertMenuList = document.getElementsByClassName("menu_alerts");
for(var i = 0; i < alertMenuList.length; i++) loadAlerts(alertMenuList[i]); for(var i=0; i<alertMenuList.length; i++) loadAlerts(alertMenuList[i]);
if(window["WebSocket"]) runWebSockets(); if(window["WebSocket"]) runWebSockets();
}); });
}); });
@ -391,7 +389,7 @@ function PageOffset(count,page,perPage) {
// We don't want the offset to overflow the slices, if everything's in memory // We don't want the offset to overflow the slices, if everything's in memory
//if(offset >= (count - 1)) offset = 0; //if(offset >= (count - 1)) offset = 0;
return {Offset:offset, Page:page, LastPage:lastPage}; return {Offset:offset,Page:page,LastPage:lastPage};
} }
function LastPage(count,perPage) { function LastPage(count,perPage) {
return (count / perPage) + 1 return (count / perPage) + 1
@ -403,12 +401,12 @@ function Paginate(currentPage,lastPage,maxPages) {
let page = currentPage - pre; let page = currentPage - pre;
if(page < 0) page = 0; if(page < 0) page = 0;
let out = []; let o = [];
while(out.length < maxPages && page < lastPage){ while(o.length < maxPages && page < lastPage){
page++; page++;
out.push(page); o.push(page);
} }
return out; return o;
} }
function mainInit(){ function mainInit(){
@ -416,9 +414,9 @@ function mainInit(){
$(".more_topics").click(ev => { $(".more_topics").click(ev => {
ev.preventDefault(); ev.preventDefault();
let moreTopicBlocks = document.getElementsByClassName("more_topic_block_active"); let blocks = document.getElementsByClassName("more_topic_block_active");
for(let i = 0; i < moreTopicBlocks.length; i++) { for(let i=0; i<blocks.length; i++) {
let block = moreTopicBlocks[i]; let block = blocks[i];
block.classList.remove("more_topic_block_active"); block.classList.remove("more_topic_block_active");
block.classList.add("more_topic_block_initial"); block.classList.add("more_topic_block_initial");
} }
@ -443,29 +441,29 @@ function mainInit(){
this.classList.remove("add_like"); this.classList.remove("add_like");
this.classList.add("remove_like"); this.classList.add("remove_like");
if(!hadLikes) controls.classList.add("has_likes"); if(!hadLikes) controls.classList.add("has_likes");
this.closest("a").setAttribute("href", target.replace("like","unlike")); this.closest("a").setAttribute("href",target.replace("like","unlike"));
likeCountNode.innerHTML = parseInt(likeCountNode.innerHTML) + 1; likeCountNode.innerHTML = parseInt(likeCountNode.innerHTML) + 1;
} else { } else {
this.classList.remove("remove_like"); this.classList.remove("remove_like");
this.classList.add("add_like"); this.classList.add("add_like");
let likeCount = parseInt(likeCountNode.innerHTML); let likeCount = parseInt(likeCountNode.innerHTML);
if(likeCount==1) controls.classList.remove("has_likes"); if(likeCount==1) controls.classList.remove("has_likes");
this.closest("a").setAttribute("href", target.replace("unlike","like")); this.closest("a").setAttribute("href",target.replace("unlike","like"));
likeCountNode.innerHTML = parseInt(likeCountNode.innerHTML) - 1; likeCountNode.innerHTML = parseInt(likeCountNode.innerHTML) - 1;
} }
//let likeButton = this; //let likeButton = this;
$.ajax({ $.ajax({
url: target, url:target,
type: "POST", type:"POST",
dataType: "json", dataType:"json",
data: { js: 1 }, data: { js: 1 },
error: ajaxError, error: ajaxError,
success: function (data,status,xhr) { success: function (dat,status,xhr) {
if("success" in data && data["success"] == "1") return; if("success" in dat && dat["success"] == "1") return;
// addNotice("Failed to add a like: {err}") // addNotice("Failed to add a like: {err}")
//likeCountNode.innerHTML = parseInt(likeCountNode.innerHTML)-1; //likeCountNode.innerHTML = parseInt(likeCountNode.innerHTML)-1;
console.log("data",data); console.log("data",dat);
console.log("status",status); console.log("status",status);
console.log("xhr",xhr); console.log("xhr",xhr);
} }
@ -474,10 +472,10 @@ function mainInit(){
$(".link_label").click(function(ev) { $(".link_label").click(function(ev) {
ev.preventDefault(); ev.preventDefault();
let linkSelect = $('#'+$(this).attr("data-for")); let linkSel = $('#'+$(this).attr("data-for"));
if(!linkSelect.hasClass("link_opened")) { if(!linkSel.hasClass("link_opened")) {
ev.stopPropagation(); ev.stopPropagation();
linkSelect.addClass("link_opened"); linkSel.addClass("link_opened");
} }
}); });
@ -513,23 +511,23 @@ function mainInit(){
.then(resp => { .then(resp => {
if(!resp.ok) throw(url+q+"&js=1 failed to load"); if(!resp.ok) throw(url+q+"&js=1 failed to load");
return resp.json(); return resp.json();
}).then(data => { }).then(dat => {
if(!"Topics" in data) throw("no Topics in data"); if(!"Topics" in dat) throw("no Topics in data");
let topics = data["Topics"]; let topics = dat["Topics"];
console.log("ajax navigated to different page"); console.log("ajax navigated to different page");
// TODO: Fix the data race where the function hasn't been loaded yet // TODO: Fix the data race where the function hasn't been loaded yet
let out = ""; let out = "";
for(let i = 0; i < topics.length;i++) out += Tmpl_topics_topic(topics[i]); for(let i=0; i<topics.length;i++) out += Tmpl_topics_topic(topics[i]);
$(".topic_list").html(out); $(".topic_list").html(out);
let obj = {Title: document.title, Url: url+q}; let obj = {Title:document.title, Url:url+q};
history.pushState(obj, obj.Title, obj.Url); history.pushState(obj,obj.Title,obj.Url);
rebuildPaginator(data.LastPage); rebuildPaginator(dat.LastPage);
rebindPaginator(); rebindPaginator();
}).catch(ex => { }).catch(e => {
console.log("Unable to get script '"+url+q+"&js=1"+"'"); console.log("Unable to get script '"+url+q+"&js=1"+"'");
console.log("ex",ex); console.log("e",e);
console.trace(); console.trace();
}); });
}); });
@ -544,19 +542,19 @@ function mainInit(){
// TODO: Take mostviewed into account // TODO: Take mostviewed into account
let url = "//"+window.location.host+"/topics/?fids="+fid; let url = "//"+window.location.host+"/topics/?fids="+fid;
fetch(url+"&js=1", {credentials: "same-origin"}) fetch(url+"&js=1",{credentials: "same-origin"})
.then(resp => { .then(resp => {
if(!resp.ok) throw(url+"&js=1 failed to load"); if(!resp.ok) throw(url+"&js=1 failed to load");
return resp.json(); return resp.json();
}).then(data => { }).then(dat => {
console.log("data",data); console.log("data",dat);
if(!"Topics" in data) throw("no Topics in data"); if(!"Topics" in dat) throw("no Topics in data");
let topics = data["Topics"]; let topics = dat["Topics"];
console.log("ajax navigated to "+that.innerText); console.log("ajax navigated to "+that.innerText);
// TODO: Fix the data race where the function hasn't been loaded yet // TODO: Fix the data race where the function hasn't been loaded yet
let out = ""; let out = "";
for(let i = 0; i < topics.length;i++) out += Tmpl_topics_topic(topics[i]); for(let i=0;i<topics.length;i++) out += Tmpl_topics_topic(topics[i]);
$(".topic_list").html(out); $(".topic_list").html(out);
//$(".topic_list").addClass("single_forum"); //$(".topic_list").addClass("single_forum");
@ -565,7 +563,7 @@ function mainInit(){
else document.title = baseTitle; else document.title = baseTitle;
let obj = {Title: document.title, Url: url}; let obj = {Title: document.title, Url: url};
history.pushState(obj, obj.Title, obj.Url); history.pushState(obj, obj.Title, obj.Url);
rebuildPaginator(data.LastPage) rebuildPaginator(dat.LastPage)
rebindPaginator(); rebindPaginator();
$(".filter_item").each(function(){ $(".filter_item").each(function(){
@ -573,9 +571,9 @@ function mainInit(){
}); });
that.classList.add("filter_selected"); that.classList.add("filter_selected");
$(".topic_list_title h1").text(that.innerText); $(".topic_list_title h1").text(that.innerText);
}).catch(ex => { }).catch(e => {
console.log("Unable to get script '"+url+"&js=1"+"'"); console.log("Unable to get script '"+url+"&js=1"+"'");
console.log("ex",ex); console.log("e",e);
console.trace(); console.trace();
}); });
}); });
@ -596,7 +594,7 @@ function mainInit(){
if(q.length>1) q = q.slice(0,-1); if(q.length>1) q = q.slice(0,-1);
// TODO: Try to de-duplicate some of these fetch calls // TODO: Try to de-duplicate some of these fetch calls
fetch(url+q+"&js=1", {credentials: "same-origin"}) fetch(url+q+"&js=1",{credentials:"same-origin"})
.then(resp => { .then(resp => {
if(!resp.ok) throw(url+q+"&js=1 failed to load"); if(!resp.ok) throw(url+q+"&js=1 failed to load");
return resp.json(); return resp.json();
@ -607,7 +605,7 @@ function mainInit(){
// TODO: Fix the data race where the function hasn't been loaded yet // TODO: Fix the data race where the function hasn't been loaded yet
let out = ""; let out = "";
for(let i = 0; i < topics.length;i++) out += Tmpl_topics_topic(topics[i]); for(let i=0; i < topics.length;i++) out += Tmpl_topics_topic(topics[i]);
$(".topic_list").html(out); $(".topic_list").html(out);
baseTitle = phraseBox["topic_list"]["topic_list.search_head"]; baseTitle = phraseBox["topic_list"]["topic_list.search_head"];
@ -618,9 +616,9 @@ function mainInit(){
history.pushState(obj, obj.Title, obj.Url); history.pushState(obj, obj.Title, obj.Url);
rebuildPaginator(data.LastPage); rebuildPaginator(data.LastPage);
rebindPaginator(); rebindPaginator();
}).catch(ex => { }).catch(e => {
console.log("Unable to get script '"+url+q+"&js=1"+"'"); console.log("Unable to get script '"+url+q+"&js=1"+"'");
console.log("ex",ex); console.log("e",e);
console.trace(); console.trace();
}); });
}); });
@ -643,8 +641,8 @@ function mainInit(){
let formAction = $(this).closest('a').attr("href"); let formAction = $(this).closest('a').attr("href");
$.ajax({ $.ajax({
url: formAction + "?s=" + me.User.S, url: formAction + "?s=" + me.User.S,
type: "POST", type:"POST",
dataType: "json", dataType:"json",
error: ajaxError, error: ajaxError,
data: { js: 1, edit_item: content } data: { js: 1, edit_item: content }
}); });
@ -655,11 +653,11 @@ function mainInit(){
ev.preventDefault(); ev.preventDefault();
if($(this).find("input").length!==0) return; if($(this).find("input").length!==0) return;
//console.log("clicked .edit_fields"); //console.log("clicked .edit_fields");
var blockParent = $(this).closest('.editable_parent'); var bp = $(this).closest('.editable_parent');
blockParent.find('.hide_on_edit').addClass("edit_opened"); bp.find('.hide_on_edit').addClass("edit_opened");
blockParent.find('.show_on_edit').addClass("edit_opened"); bp.find('.show_on_edit').addClass("edit_opened");
blockParent.find('.editable_block').show(); bp.find('.editable_block').show();
blockParent.find('.editable_block').each(function(){ bp.find('.editable_block').each(function(){
var fieldName = this.getAttribute("data-field"); var fieldName = this.getAttribute("data-field");
var fieldType = this.getAttribute("data-type"); var fieldType = this.getAttribute("data-type");
if(fieldType=="list") { if(fieldType=="list") {
@ -668,11 +666,11 @@ function mainInit(){
else var it = ['No','Yes']; else var it = ['No','Yes'];
var itLen = it.length; var itLen = it.length;
var out = ""; var out = "";
for (var i = 0; i < itLen; i++) { for (var i=0; i<itLen; i++) {
var sel = ""; var sel = "";
if(fieldValue == i || fieldValue == it[i]) { if(fieldValue == i || fieldValue == it[i]) {
sel = "selected "; sel = "selected ";
this.classList.remove(fieldName + '_' + it[i]); this.classList.remove(fieldName+'_'+it[i]);
this.innerHTML = ""; this.innerHTML = "";
} }
out += "<option "+sel+"value='"+i+"'>"+it[i]+"</option>"; out += "<option "+sel+"value='"+i+"'>"+it[i]+"</option>";
@ -707,10 +705,10 @@ function mainInit(){
outData[fieldName] = newContent; outData[fieldName] = newContent;
}); });
var formAction = $(this).closest('a').attr("href"); let href = $(this).closest('a').attr("href");
//console.log("Form Action", formAction); //console.log("href",href);
//console.log(outData); //console.log(outData);
$.ajax({ url: formAction + "?s=" + me.User.S, type:"POST", dataType:"json", data: outData, error: ajaxError }); $.ajax({ url: href + "?s=" + me.User.S, type:"POST", dataType:"json", data: outData, error: ajaxError });
bp.find('.hide_on_edit').removeClass("edit_opened"); bp.find('.hide_on_edit').removeClass("edit_opened");
bp.find('.show_on_edit').removeClass("edit_opened"); bp.find('.show_on_edit').removeClass("edit_opened");
}); });
@ -723,7 +721,7 @@ function mainInit(){
}); });
$(".alert_bell").click(function(){ $(".alert_bell").click(function(){
var menuAlerts = $(this).parent(); let menuAlerts = $(this).parent();
if(menuAlerts.hasClass("selectedAlert")) { if(menuAlerts.hasClass("selectedAlert")) {
event.stopPropagation(); event.stopPropagation();
menuAlerts.removeClass("selectedAlert"); menuAlerts.removeClass("selectedAlert");
@ -733,7 +731,7 @@ function mainInit(){
$(".menu_alerts").click(function(ev) { $(".menu_alerts").click(function(ev) {
ev.stopPropagation(); ev.stopPropagation();
if($(this).hasClass("selectedAlert")) return; if($(this).hasClass("selectedAlert")) return;
if(!conn) loadAlerts(this); if(!conn) loadAlerts(this,true);
this.className += " selectedAlert"; this.className += " selectedAlert";
document.getElementById("back").className += " alertActive" document.getElementById("back").className += " alertActive"
}); });
@ -751,16 +749,16 @@ function mainInit(){
}); });
$("#themeSelectorSelect").change(function(){ $("#themeSelectorSelect").change(function(){
console.log("Changing the theme to " + this.options[this.selectedIndex].getAttribute("value")); console.log("Changing the theme to "+this.options[this.selectedIndex].getAttribute("value"));
$.ajax({ $.ajax({
url: this.form.getAttribute("action") + "?s=" + me.User.S, url: this.form.getAttribute("action") + "?s=" + me.User.S,
type: "POST", type:"POST",
dataType: "json", dataType:"json",
data: { "theme": this.options[this.selectedIndex].getAttribute("value"), js: 1 }, data: { "theme": this.options[this.selectedIndex].getAttribute("value"), js: 1 },
error: ajaxError, error: ajaxError,
success: function (data,status,xhr) { success: function (dat,status,xhr) {
console.log("Theme successfully switched"); console.log("Theme successfully switched");
console.log("data",data); console.log("dat",dat);
console.log("status",status); console.log("status",status);
console.log("xhr",xhr); console.log("xhr",xhr);
window.location.reload(); window.location.reload();
@ -879,9 +877,9 @@ function mainInit(){
$(".elapsed").remove(); $(".elapsed").remove();
let obj = {Title: document.title, Url: base}; let obj = {Title: document.title, Url: base};
history.pushState(obj, obj.Title, obj.Url); history.pushState(obj, obj.Title, obj.Url);
}).catch(ex => { }).catch(e => {
console.log("Unable to get script '"+href+""+"'"); console.log("Unable to get script '"+href+""+"'");
console.log("ex",ex); console.log("e",e);
console.trace(); console.trace();
}); });
@ -934,8 +932,8 @@ function bindTopic() {
js: 1 js: 1
}, },
error: ajaxError, error: ajaxError,
success: (data,status,xhr) => { success: (dat,status,xhr) => {
if("Content" in data) $(".topic_content").html(data["Content"]); if("Content" in dat) $(".topic_content").html(dat["Content"]);
} }
}); });
}); });
@ -1003,8 +1001,8 @@ function bindTopic() {
dataType:"json", dataType:"json",
data: { js: 1, edit_item: content }, data: { js: 1, edit_item: content },
error: ajaxError, error: ajaxError,
success: (data,status,xhr) => { success: (dat,status,xhr) => {
if("Content" in data) block.innerHTML = data["Content"]; if("Content" in dat) block.innerHTML = dat["Content"];
} }
}); });
}); });
@ -1018,8 +1016,8 @@ function bindTopic() {
console.log("content.value",content.value); console.log("content.value",content.value);
let item; let item;
if(content.value=="") item = "<blockquote>" + src.innerHTML + "</blockquote>" if(content.value=="") item = "<blockquote>"+src.innerHTML+"</blockquote>"
else item = "\r\n<blockquote>" + src.innerHTML + "</blockquote>"; else item = "\r\n<blockquote>"+src.innerHTML+"</blockquote>";
content.value = content.value + item; content.value = content.value + item;
console.log("content.value",content.value); console.log("content.value",content.value);
@ -1027,18 +1025,18 @@ function bindTopic() {
quoteItemCallback(src.innerHTML,item); quoteItemCallback(src.innerHTML,item);
}); });
//id="poll_results_{{.Poll.ID}}" class="poll_results auto_hide" //id="poll_results_{pollid}" class="poll_results auto_hide"
$(".poll_results_button").click(function(){ $(".poll_results_button").click(function(){
let pollID = $(this).attr("data-poll-id"); let pollID = $(this).attr("data-poll-id");
$("#poll_results_" + pollID).removeClass("auto_hide"); $("#poll_results_"+pollID).removeClass("auto_hide");
fetch("/poll/results/" + pollID, { fetch("/poll/results/"+pollID, {
credentials: 'same-origin' credentials: 'same-origin'
}).then(resp => resp.text()).catch(err => console.error("err",err)).then(rawData => { }).then(resp => resp.text()).catch(er => console.error("er",er)).then(rawData => {
// TODO: Make sure the received data is actually a list of integers // TODO: Make sure the received data is actually a list of integers
let data = JSON.parse(rawData); let data = JSON.parse(rawData);
let allZero = true; let allZero = true;
for(let i = 0; i < data.length; i++) { for(let i=0; i<data.length; i++) {
if(data[i] != "0") allZero = false; if(data[i]!="0") allZero = false;
} }
if(allZero) { if(allZero) {
$("#poll_results_"+pollID+" .poll_no_results").removeClass("auto_hide"); $("#poll_results_"+pollID+" .poll_no_results").removeClass("auto_hide");

View File

@ -7,7 +7,7 @@ formVars = {
}; };
var forums = {}; var forums = {};
let items = document.getElementsByClassName("panel_forum_item"); let items = document.getElementsByClassName("panel_forum_item");
for(let i = 0; item = items[i]; i++) forums[i] = item.getAttribute("data-fid"); for(let i=0; item=items[i]; i++) forums[i] = item.getAttribute("data-fid");
console.log("forums",forums); console.log("forums",forums);
Sortable.create(document.getElementById("panel_forums"), { Sortable.create(document.getElementById("panel_forums"), {
@ -37,12 +37,12 @@ document.getElementById("panel_forums_order_button").addEventListener("click", (
if(req.status!==200) return; if(req.status!==200) return;
let resp = JSON.parse(req.responseText); let resp = JSON.parse(req.responseText);
console.log("resp", resp); console.log("resp",resp);
// TODO: Should we move other notices into TmplPhrases like this one? // TODO: Should we move other notices into TmplPhrases like this one?
pushNotice(phraseBox["panel"]["panel.forums_order_updated"]); pushNotice(phraseBox["panel"]["panel.forums_order_updated"]);
if(resp.success==1) return; if(resp.success==1) return;
} catch(ex) { } catch(e) {
console.error("ex", ex) console.error("e",e)
} }
console.trace(); console.trace();
} }
@ -50,7 +50,7 @@ document.getElementById("panel_forums_order_button").addEventListener("click", (
req.open("POST","/panel/forums/order/edit/submit/?s=" + encodeURIComponent(me.User.S)); req.open("POST","/panel/forums/order/edit/submit/?s=" + encodeURIComponent(me.User.S));
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
let items = ""; let items = "";
for(let i = 0; item = forums[i];i++) items += item+","; for(let i=0;item=forums[i];i++) items += item+",";
if(items.length > 0) items = items.slice(0,-1); if(items.length > 0) items = items.slice(0,-1);
req.send("js=1&amp;items={"+items+"}"); req.send("js=1&amp;items={"+items+"}");
}); });