hover styling for topic list moderation

add megaindex user agent
reduce boilerplate and save bytes
hide elapsed on nox mobile
This commit is contained in:
Azareal 2020-04-09 18:35:43 +10:00
parent 709b0d5541
commit f6c5109fc7
7 changed files with 81 additions and 77 deletions

View File

@ -228,6 +228,7 @@
"dotbot":"DotBot", "dotbot":"DotBot",
"ahrefs":"Ahrefs", "ahrefs":"Ahrefs",
"proximic":"Comscore", "proximic":"Comscore",
"megaindex":"MegaIndex",
"majestic":"MJ12bot", "majestic":"MJ12bot",
"netcraft":"Netcraft", "netcraft":"Netcraft",
"blexbot":"BLEXBot", "blexbot":"BLEXBot",

View File

@ -1,5 +1,5 @@
// TODO: Push ImageFileExts to the client from the server in some sort of gen.js? // TODO: Push ImageFileExts to the client from the server in some sort of gen.js?
var imageExts = ["png", "jpg", "jpe","jpeg","jif","jfi","jfif", "svg", "bmp", "gif", "tiff","tif", "webp"]; var imageExts = ["png","jpg","jpe","jpeg","jif","jfi","jfif","svg","bmp","gif","tiff","tif","webp"];
(() => { (() => {
function copyToClipboard(str) { function copyToClipboard(str) {
@ -16,32 +16,32 @@ var imageExts = ["png", "jpg", "jpe","jpeg","jif","jfi","jfif", "svg", "bmp", "g
function uploadFileHandler(fileList, maxFiles = 5, step1 = () => {}, step2 = () => {}) { function uploadFileHandler(fileList, maxFiles = 5, step1 = () => {}, step2 = () => {}) {
let files = []; let files = [];
for(var i = 0; i < fileList.length && i < 5; i++) files[i] = fileList[i]; for(var i=0; i<fileList.length && i<5; i++) files[i] = fileList[i];
let totalSize = 0; let totalSize = 0;
for(let i = 0; i < files.length; i++) { for(let i=0; i<files.length; i++) {
console.log("files[" + i + "]",files[i]); console.log("file "+i,files[i]);
totalSize += files[i]["size"]; totalSize += files[i]["size"];
} }
if(totalSize > me.Site.MaxRequestSize) throw("You can't upload this much at once, max: " + me.Site.MaxRequestSize); if(totalSize > me.Site.MaxRequestSize) throw("You can't upload this much at once, max: "+me.Site.MaxRequestSize);
for(let i = 0; i < files.length; i++) { for(let i=0; i<files.length; i++) {
let filename = files[i]["name"]; let fname = files[i]["name"];
let f = (e) => { let f = e => {
step1(e,filename) step1(e,fname)
let reader = new FileReader(); let reader = new FileReader();
reader.onload = (e2) => { reader.onload = e2 => {
crypto.subtle.digest('SHA-256',e2.target.result) crypto.subtle.digest('SHA-256',e2.target.result)
.then((hash) => { .then(hash => {
const hashArray = Array.from(new Uint8Array(hash)) const hashArray = Array.from(new Uint8Array(hash))
return hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join('') return hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join('')
}).then(hash => step2(e,hash,filename)); }).then(hash => step2(e,hash,fname));
} }
reader.readAsArrayBuffer(files[i]); reader.readAsArrayBuffer(files[i]);
}; };
let ext = getExt(filename); let ext = getExt(fname);
// TODO: Push ImageFileExts to the client from the server in some sort of gen.js? // TODO: Push ImageFileExts to the client from the server in some sort of gen.js?
let isImage = imageExts.includes(ext); let isImage = imageExts.includes(ext);
if(isImage) { if(isImage) {
@ -58,11 +58,11 @@ var imageExts = ["png", "jpg", "jpe","jpeg","jif","jfi","jfif", "svg", "bmp", "g
let fileDock = this.closest(".attach_edit_bay"); let fileDock = this.closest(".attach_edit_bay");
try { try {
uploadFileHandler(this.files, 5, () => {}, uploadFileHandler(this.files, 5, () => {},
(e,hash,filename) => { (e,hash,fname) => {
console.log("hash",hash); console.log("hash",hash);
let formData = new FormData(); let formData = new FormData();
formData.append("s",me.User.S); formData.append("s",me.User.S);
for(let i = 0; i < this.files.length; i++) formData.append("upload_files",this.files[i]); for(let i=0; i<this.files.length; i++) formData.append("upload_files",this.files[i]);
bindAttachManager(); bindAttachManager();
let req = new XMLHttpRequest(); let req = new XMLHttpRequest();
@ -70,12 +70,12 @@ var imageExts = ["png", "jpg", "jpe","jpeg","jif","jfi","jfif", "svg", "bmp", "g
let data = JSON.parse(req.responseText); let data = JSON.parse(req.responseText);
//console.log("rdata",data); //console.log("rdata",data);
let fileItem = document.createElement("div"); let fileItem = document.createElement("div");
let ext = getExt(filename); let ext = getExt(fname);
// TODO: Push ImageFileExts to the client from the server in some sort of gen.js? // TODO: Push ImageFileExts to the client from the server in some sort of gen.js?
let isImage = imageExts.includes(ext); let isImage = imageExts.includes(ext);
let c = ""; let c = "";
if(isImage) c = " attach_image_holder" if(isImage) c = " attach_image_holder"
fileItem.className = "attach_item attach_item_item" + c; fileItem.className = "attach_item attach_item_item"+c;
fileItem.innerHTML = Tmpl_topic_c_attach_item({ fileItem.innerHTML = Tmpl_topic_c_attach_item({
ID: data.elems[hash+"."+ext], ID: data.elems[hash+"."+ext],
ImgSrc: isImage ? e.target.result : "", ImgSrc: isImage ? e.target.result : "",
@ -100,32 +100,32 @@ var imageExts = ["png", "jpg", "jpe","jpeg","jif","jfi","jfif", "svg", "bmp", "g
// Quick Topic / Quick Reply // Quick Topic / Quick Reply
function uploadAttachHandler() { function uploadAttachHandler() {
try { try {
uploadFileHandler(this.files, 5, (e,filename) => { uploadFileHandler(this.files, 5, (e,fname) => {
// TODO: Use client templates here // TODO: Use client templates here
let fileDock = document.getElementById("upload_file_dock"); let fileDock = document.getElementById("upload_file_dock");
let fileItem = document.createElement("label"); let fileItem = document.createElement("label");
console.log("fileItem",fileItem); console.log("fileItem",fileItem);
let ext = getExt(filename); let ext = getExt(fname);
// TODO: Push ImageFileExts to the client from the server in some sort of gen.js? // TODO: Push ImageFileExts to the client from the server in some sort of gen.js?
let isImage = imageExts.includes(ext); let isImage = imageExts.includes(ext);
fileItem.innerText = "." + ext; fileItem.innerText = "."+ext;
fileItem.className = "formbutton uploadItem"; fileItem.className = "formbutton uploadItem";
// TODO: Check if this is actually an image // TODO: Check if this is actually an image
if(isImage) fileItem.style.backgroundImage = "url("+e.target.result+")"; if(isImage) fileItem.style.backgroundImage = "url("+e.target.result+")";
fileDock.appendChild(fileItem); fileDock.appendChild(fileItem);
},(e,hash,filename) => { },(e,hash,fname) => {
console.log("hash",hash); console.log("hash",hash);
let ext = getExt(filename) let ext = getExt(fname)
let content = document.getElementById("input_content") let con = document.getElementById("input_content")
console.log("content.value", content.value); console.log("con.value",con.value);
let attachItem; let attachItem;
if(content.value=="") attachItem = "//" + window.location.host + "/attachs/" + hash + "." + ext; if(con.value=="") attachItem = "//"+window.location.host+"/attachs/"+hash+"."+ext;
else attachItem = "\r\n//" + window.location.host + "/attachs/" + hash + "." + ext; else attachItem = "\r\n//"+window.location.host+"/attachs/"+hash+"."+ext;
content.value = content.value + attachItem; con.value = con.value + attachItem;
console.log("content.value", content.value); console.log("con.value",con.value);
// For custom / third party text editors // For custom / third party text editors
attachItemCallback(attachItem); attachItemCallback(attachItem);
@ -140,7 +140,7 @@ var imageExts = ["png", "jpg", "jpe","jpeg","jif","jfi","jfif", "svg", "bmp", "g
function bindAttachManager() { function bindAttachManager() {
let uploadFiles = document.getElementsByClassName("upload_files_post"); let uploadFiles = document.getElementsByClassName("upload_files_post");
if(uploadFiles==null) return; if(uploadFiles==null) return;
for(let i = 0; i < uploadFiles.length; i++) { for(let i=0; i<uploadFiles.length; i++) {
let uploader = uploadFiles[i]; let uploader = uploadFiles[i];
uploader.value = ""; uploader.value = "";
uploader.removeEventListener("change", uploadAttachHandler2, false); uploader.removeEventListener("change", uploadAttachHandler2, false);
@ -192,7 +192,7 @@ var imageExts = ["png", "jpg", "jpe","jpeg","jif","jfi","jfif", "svg", "bmp", "g
for(let i = 0; i < elems.length; i++) { for(let i = 0; i < elems.length; i++) {
let pathNode = elems[i].querySelector(".attach_item_path"); let pathNode = elems[i].querySelector(".attach_item_path");
console.log("pathNode",pathNode); console.log("pathNode",pathNode);
aidList += pathNode.getAttribute("aid") + ","; aidList += pathNode.getAttribute("aid")+",";
elems[i].remove(); elems[i].remove();
} }
if(aidList.length > 0) aidList = aidList.slice(0, -1); if(aidList.length > 0) aidList = aidList.slice(0, -1);
@ -219,6 +219,7 @@ var imageExts = ["png", "jpg", "jpe","jpeg","jif","jfi","jfif", "svg", "bmp", "g
ev.preventDefault(); ev.preventDefault();
$(".pre_opt").removeClass("auto_hide"); $(".pre_opt").removeClass("auto_hide");
$(".moderate_link").addClass("moderate_open"); $(".moderate_link").addClass("moderate_open");
$("#topicsItemList,#forumItemList").addClass("topics_moderate");
$(".topic_row").each(function(){ $(".topic_row").each(function(){
$(this).click(function(){ $(this).click(function(){
selectedTopics.push(parseInt($(this).attr("data-tid"),10)); selectedTopics.push(parseInt($(this).attr("data-tid"),10));
@ -233,10 +234,9 @@ var imageExts = ["png", "jpg", "jpe","jpeg","jif","jfi","jfif", "svg", "bmp", "g
}); });
}); });
let bulkActionSender = function(action,selectedTopics,fragBit) { let bulkActionSender = (action,selectedTopics,fragBit) => {
let url = "/topic/"+action+"/submit/"+fragBit+"?s="+me.User.S;
$.ajax({ $.ajax({
url: url, url: "/topic/"+action+"/submit/"+fragBit+"?s="+me.User.S,
type: "POST", type: "POST",
data: JSON.stringify(selectedTopics), data: JSON.stringify(selectedTopics),
contentType: "application/json", contentType: "application/json",
@ -262,7 +262,7 @@ var imageExts = ["png", "jpg", "jpe","jpeg","jif","jfi","jfif", "svg", "bmp", "g
$("#mod_topic_mover .pane_row").click(function(){ $("#mod_topic_mover .pane_row").click(function(){
modTopicMover.find(".pane_row").removeClass("pane_selected"); modTopicMover.find(".pane_row").removeClass("pane_selected");
let fid = this.getAttribute("data-fid"); let fid = this.getAttribute("data-fid");
if (fid==null) return; if(fid==null) return;
this.classList.add("pane_selected"); this.classList.add("pane_selected");
console.log("fid",fid); console.log("fid",fid);
forumToMoveTo = fid; forumToMoveTo = fid;

View File

@ -11,39 +11,38 @@ import (
) )
// TODO: Retire this in favour of an alias for /topics/? // TODO: Retire this in favour of an alias for /topics/?
func ViewForum(w http.ResponseWriter, r *http.Request, user *c.User, header *c.Header, sfid string) c.RouteError { func ViewForum(w http.ResponseWriter, r *http.Request, u *c.User, h *c.Header, sfid string) c.RouteError {
page, _ := strconv.Atoi(r.FormValue("page")) page, _ := strconv.Atoi(r.FormValue("page"))
_, fid, err := ParseSEOURL(sfid) _, fid, err := ParseSEOURL(sfid)
if err != nil { if err != nil {
return c.SimpleError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, header) return c.SimpleError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, h)
} }
ferr := c.ForumUserCheck(header, w, r, user, fid) ferr := c.ForumUserCheck(h, w, r, u, fid)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
if !user.Perms.ViewTopic { if !u.Perms.ViewTopic {
return c.NoPermissions(w, r, user) return c.NoPermissions(w, r, u)
} }
header.Path = "/forums/" h.Path = "/forums/"
// TODO: Fix this double-check // TODO: Fix this double-check
forum, err := c.Forums.Get(fid) forum, err := c.Forums.Get(fid)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return c.NotFound(w, r, header) return c.NotFound(w, r, h)
} else if err != nil { } else if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
header.Title = forum.Name h.Title = forum.Name
header.OGDesc = forum.Desc h.OGDesc = forum.Desc
topicList, pagi, err := c.TopicList.GetListByForum(forum, page, 0) topicList, pagi, err := c.TopicList.GetListByForum(forum, page, 0)
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
h.Zone = "view_forum"
header.Zone = "view_forum" h.ZoneID = forum.ID
header.ZoneID = forum.ID
// TODO: Reduce the amount of boilerplate here // TODO: Reduce the amount of boilerplate here
if r.FormValue("js") == "1" { if r.FormValue("js") == "1" {
@ -56,15 +55,15 @@ func ViewForum(w http.ResponseWriter, r *http.Request, user *c.User, header *c.H
} }
//pageList := c.Paginate(page, lastPage, 5) //pageList := c.Paginate(page, lastPage, 5)
pi := c.ForumPage{header, topicList, forum, pagi} pi := c.ForumPage{h, topicList, forum, pagi}
tmpl := forum.Tmpl tmpl := forum.Tmpl
if tmpl == "" { if tmpl == "" {
ferr = renderTemplate("forum", w, r, header, pi) ferr = renderTemplate("forum", w, r, h, pi)
} else { } else {
tmpl = "forum_" + tmpl tmpl = "forum_" + tmpl
err = renderTemplate3(tmpl, tmpl, w, r, header, pi) err = renderTemplate3(tmpl, tmpl, w, r, h, pi)
if err != nil { if err != nil {
ferr = renderTemplate("forum", w, r, header, pi) ferr = renderTemplate("forum", w, r, h, pi)
} }
} }
counters.ForumViewCounter.Bump(forum.ID) counters.ForumViewCounter.Bump(forum.ID)

View File

@ -1,11 +1,11 @@
{{template "header.html" . }} {{template "header.html" . }}
<main id="forumsItemList" itemscope itemtype="http://schema.org/ItemList"> <main id="forumsItemList"itemscope itemtype="http://schema.org/ItemList">
<div class="rowblock opthead"> <div class="rowblock opthead">
<div class="rowitem"><h1 itemprop="name">{{lang "forums_head"}}</h1></div> <div class="rowitem"><h1 itemprop="name">{{lang "forums_head"}}</h1></div>
</div> </div>
<div class="rowblock forum_list"> <div class="rowblock forum_list">
{{range .ItemList}}<div id="forum_{{.ID}}" class="rowitem{{if (.Desc) or (.LastTopic.Title)}} datarow{{end}}"itemprop="itemListElement" itemscope {{range .ItemList}}<div id="forum_{{.ID}}"class="rowitem{{if (.Desc) or (.LastTopic.Title)}} datarow{{end}}"itemprop="itemListElement" itemscope
itemtype="http://schema.org/ListItem"> itemtype="http://schema.org/ListItem">
<span class="forum_left shift_left"> <span class="forum_left shift_left">
<a href="{{.Link}}"itemprop="item">{{.Name}}</a><br> <a href="{{.Link}}"itemprop="item">{{.Name}}</a><br>

View File

@ -13,7 +13,6 @@
--light-text-color: hsl(0,0%,55%); --light-text-color: hsl(0,0%,55%);
--lighter-text-color: hsl(0,0%,65%); --lighter-text-color: hsl(0,0%,65%);
/*background-color: hsl(0,0%,97%);*/
--tinted-background-color: hsl(0,0%,98%); --tinted-background-color: hsl(0,0%,98%);
} }
@ -908,6 +907,9 @@ textarea {
.topic_sticky .topic_left, .topic_sticky .topic_right { .topic_sticky .topic_left, .topic_sticky .topic_right {
border-bottom: 2px solid hsl(51, 60%, 70%); border-bottom: 2px solid hsl(51, 60%, 70%);
} }
.topics_moderate .topic_row:hover .topic_left, .topics_moderate .topic_row:hover .topic_right {
background-color: hsl(81, 60%, 97%);
}
.topic_selected .topic_left, .topic_selected .topic_right { .topic_selected .topic_left, .topic_selected .topic_right {
background-color: hsl(81, 60%, 95%); background-color: hsl(81, 60%, 95%);
} }

View File

@ -228,6 +228,9 @@ li a {
.sidebar .rowblock:not(.topic_list):not(.rowhead):not(.opthead) .rowitem, .sidebar .search { .sidebar .rowblock:not(.topic_list):not(.rowhead):not(.opthead) .rowitem, .sidebar .search {
margin-left: 12px; margin-left: 12px;
} }
.topics_moderate .topic_row:hover {
background-color: rgb(78, 78, 98);
}
.widget_search:first-child { .widget_search:first-child {
margin-top: 36px; margin-top: 36px;
} }
@ -264,8 +267,8 @@ h1, h2, h3, h4, h5 {
margin-block-end:0; margin-block-end:0;
margin-top:0; margin-top:0;
margin-bottom:0; margin-bottom:0;
font-weight: normal; font-weight:normal;
white-space: nowrap; white-space:nowrap;
} }
/* new */ /* new */
@ -782,9 +785,8 @@ button, .formbutton, .panel_right_button:not(.has_inner_button) {
margin-right: 10px; margin-right: 10px;
margin-bottom: 0px; margin-bottom: 0px;
margin-left: 0px; margin-left: 0px;
margin-left: 0px;
} }
.topic_item .submit_edit { sp.topic_item .submit_edit {
/*margin-right: 16px;*/ /*margin-right: 16px;*/
} }
.zone_view_topic button, .zone_view_topic .formbutton { .zone_view_topic button, .zone_view_topic .formbutton {
@ -1021,23 +1023,23 @@ input[type=checkbox]:not(:checked):hover + label .sel {
} }
.add_like:before, .remove_like:before { .add_like:before, .remove_like:before {
content: "{{lang "topic.plus_one" . }}"; content:"{{lang "topic.plus_one" . }}";
} }
.remove_like:before { .remove_like:before {
content: "{{lang "topic.minus_one" . }}"; content:"{{lang "topic.minus_one" . }}";
} }
.button_container .open_edit:after, .edit_item:after { .button_container .open_edit:after, .edit_item:after {
content: "{{lang "topic.edit_button_text" . }}"; content:"{{lang "topic.edit_button_text" . }}";
} }
.ip_item_button:after { .ip_item_button:after {
content: "{{lang "topic.ip_button_text" . }}"; content:"{{lang "topic.ip_button_text" . }}";
}{{$p := .}} }{{$p := .}}
{{range (toArr "quote" "delete" "lock" "unlock" "pin" "unpin" "report")}} {{range (toArr "quote" "delete" "lock" "unlock" "pin" "unpin" "report")}}
.{{.}}_item:after { .{{.}}_item:after {
content: "{{lang (concat "topic." . "_button_text") ($p) }}"; content:"{{lang (concat "topic." . "_button_text") ($p) }}";
}{{end}} }{{end}}
.like_count:after { .like_count:after {
content: "{{lang "topic.like_count_suffix" . }}"; content:"{{lang "topic.like_count_suffix" . }}";
} }
.attach_item { .attach_item {
@ -1425,7 +1427,7 @@ input[type=checkbox]:not(:checked):hover + label .sel {
width: auto; width: auto;
padding: 0px; padding: 0px;
} }
.user_box { .user_box, .elapsed {
display: none; display: none;
} }
#back { #back {
@ -1442,9 +1444,6 @@ input[type=checkbox]:not(:checked):hover + label .sel {
font-size: 17px; font-size: 17px;
line-height: 28px; line-height: 28px;
} }
.elapsed {
display: none;
}
} }
@media(min-width: 751px) { @media(min-width: 751px) {

View File

@ -848,6 +848,9 @@ input[type=checkbox]:checked + label.poll_option_label .sel {
.topic_list .topic_row { .topic_list .topic_row {
display: flex; display: flex;
} }
.topics_moderate .topic_row:hover .rowitem {
background-color: hsla(0, 0%, 27%, 1);
}
.topic_selected .rowitem { .topic_selected .rowitem {
background-color: hsla(0, 0%, 29%, 1); background-color: hsla(0, 0%, 29%, 1);
} }