diff --git a/common/auth.go b/common/auth.go index e5e5fee0..bedda08b 100644 --- a/common/auth.go +++ b/common/auth.go @@ -182,13 +182,17 @@ func setCookie(w http.ResponseWriter, cookie *http.Cookie, sameSite string) { } } +func deleteCookie(w http.ResponseWriter, cookie *http.Cookie) { + cookie.MaxAge = -1 + http.SetCookie(w, cookie) +} + // Logout logs you out of the computer you requested the logout for, but not the other computers you're logged in with func (auth *DefaultAuth) Logout(w http.ResponseWriter, _ int) { - cookie := http.Cookie{Name: "uid", Value: "", Path: "/", MaxAge: int(Year)} - setCookie(w, &cookie, "lax") - http.SetCookie(w, &cookie) - cookie = http.Cookie{Name: "session", Value: "", Path: "/", MaxAge: int(Year)} - setCookie(w, &cookie, "lax") + cookie := http.Cookie{Name: "uid", Value: "", Path: "/"} + deleteCookie(w, &cookie) + cookie = http.Cookie{Name: "session", Value: "", Path: "/"} + deleteCookie(w, &cookie) } // TODO: Set the cookie domain diff --git a/common/websockets.go b/common/websockets.go index 99a10106..1c007b3e 100644 --- a/common/websockets.go +++ b/common/websockets.go @@ -93,11 +93,13 @@ func (hub *WsHubImpl) Tick() error { //fmt.Println("checking for changes") // TODO: Optimise this by only sniffing the top non-sticky + // TODO: Optimise this by getting back an unsorted list so we don't have to hop around the stickies + // TODO: Add support for new stickies / replies to them if len(tList) == len(hub.lastTopicList) { var hasItem = false for j, tItem := range tList { if !tItem.Sticky { - if tItem.ID != hub.lastTopicList[j].ID { + if tItem.ID != hub.lastTopicList[j].ID || !tItem.LastReplyAt.Equal(hub.lastTopicList[j].LastReplyAt) { hasItem = true } } diff --git a/langs/english.json b/langs/english.json index dc099c07..689cacd0 100644 --- a/langs/english.json +++ b/langs/english.json @@ -424,17 +424,18 @@ "quick_topic.add_file_button":"Add File", "quick_topic.cancel_button":"Cancel", - "topic_list_create_topic_tooltip":"Create Topic", - "topic_list_create_topic_aria":"Create a topic", - "topic_list_moderate_tooltip":"Moderate", - "topic_list_moderate_aria":"Moderate Posts", - "topic_list_what_to_do":"What do you want to do with these 18 topics?", - "topic_list_moderate_delete":"Delete them", - "topic_list_moderate_lock":"Lock them", - "topic_list_moderate_move":"Move them", - "topic_list_moderate_run":"Run", - "topic_list_move_head":"Move these topics to?", - "topic_list_move_button":"Move Topics", + "topic_list.create_topic_tooltip":"Create Topic", + "topic_list.create_topic_aria":"Create a topic", + "topic_list.moderate_tooltip":"Moderate", + "topic_list.moderate_aria":"Moderate Posts", + "topic_list.what_to_do":"What do you want to do with these 18 topics?", + "topic_list.moderate_delete":"Delete them", + "topic_list.moderate_lock":"Lock them", + "topic_list.moderate_move":"Move them", + "topic_list.moderate_run":"Run", + "topic_list.move_head":"Move these topics to?", + "topic_list.move_button":"Move Topics", + "topic_list.changed_topics":"Click to see %d new or changed topics", "status.closed_tooltip":"Status: Closed", "status.pinned_tooltip":"Status: Pinned", diff --git a/misc_test.go b/misc_test.go index 5253cc92..61b4277b 100644 --- a/misc_test.go +++ b/misc_test.go @@ -989,6 +989,11 @@ func TestPreparser(t *testing.T) { msgList = addMETri(msgList, "

", "") msgList = addMETri(msgList, "

", "") + msgList = addMETri(msgList, "<", "<") + msgList = addMETri(msgList, ">", ">") + msgList = addMETri(msgList, "", "<meow>") + msgList = addMETri(msgList, "<", "&lt;") + // Note: strings.TrimSpace strips newlines, if there's nothing before or after them msgList = addMETri(msgList, "
", "") msgList = addMETri(msgList, "
", "") diff --git a/public/global.js b/public/global.js index fe211565..f9e53e8f 100644 --- a/public/global.js +++ b/public/global.js @@ -1,9 +1,11 @@ 'use strict'; var formVars = {}; var tmplInits = {}; -var tmplPhrases = []; +var tmplPhrases = []; // [key] array of phrases indexed by order of use +var phraseBox = {}; var alertList = []; var alertCount = 0; +var moreTopicCount = 0; var conn; var selectedTopics = []; var attachItemCallback = function(){} @@ -214,8 +216,8 @@ function runWebSockets() { return; } - // TODO: Fix the data races in this code if ("msg" in data) { + // TODO: Fix the data race where the alert template hasn't been loaded yet wsAlertEvent(data); } else if("Topics" in data) { console.log("topic in data"); @@ -225,11 +227,27 @@ function runWebSockets() { console.log("empty topic list"); return; } + + // TODO: Fix the data race where the function hasn't been loaded yet let renTopic = Template_topics_topic(topic); + $(".topic_row[data-tid='"+topic.ID+"']").addClass("ajax_topic_dupe"); + let node = $(renTopic); - node.addClass("new_item"); + node.addClass("new_item hide_ajax_topic"); console.log("Prepending to topic list"); $(".topic_list").prepend(node); + moreTopicCount++; + + let moreTopicBlocks = document.getElementsByClassName("more_topic_block_initial"); + for(let i = 0; i < moreTopicBlocks.length; i++) { + let moreTopicBlock = moreTopicBlocks[i]; + moreTopicBlock.classList.remove("more_topic_block_initial"); + moreTopicBlock.classList.add("more_topic_block_active"); + + console.log("phraseBox:",phraseBox); + let msgBox = moreTopicBlock.getElementsByClassName("more_topics")[0]; + msgBox.innerText = phraseBox["topic_list"]["topic_list.changed_topics"].replace("%d",moreTopicCount); + } } else { console.log("unknown message"); console.log(data); @@ -278,9 +296,11 @@ function DoNothingButPassBack(item) { } function fetchPhrases() { - fetch("//" +siteURL+"/api/phrases/?query=status") + fetch("//" +siteURL+"/api/phrases/?query=status,topic_list") .then((resp) => resp.json()) .then((data) => { + console.log("loaded phrase endpoint data"); + console.log("data:",data); Object.keys(tmplInits).forEach((key) => { let phrases = []; let tmplInit = tmplInits[key]; @@ -291,7 +311,20 @@ function fetchPhrases() { console.log("key:",key); console.log("phrases:",phrases); tmplPhrases[key] = phrases; - }) + }); + + let prefixes = {}; + Object.keys(data).forEach((key) => { + let prefix = key.split(".")[0]; + if(prefixes[prefix]===undefined) { + prefixes[prefix] = {}; + } + prefixes[prefix][key] = data[key]; + }); + Object.keys(prefixes).forEach((prefix) => { + console.log("adding phrase prefix '"+prefix+"' to box"); + phraseBox[prefix] = prefixes[prefix]; + }); }); } @@ -319,6 +352,21 @@ $(document).ready(function(){ if(window["WebSocket"]) runWebSockets(); else conn = false; + $(".more_topics").click((event) => { + event.preventDefault(); + let moreTopicBlocks = document.getElementsByClassName("more_topic_block_active"); + for(let i = 0; i < moreTopicBlocks.length; i++) { + let moreTopicBlock = moreTopicBlocks[i]; + moreTopicBlock.classList.remove("more_topic_block_active"); + moreTopicBlock.classList.add("more_topic_block_initial"); + } + $(".ajax_topic_dupe").fadeOut("slow", function(){ + $(this).remove(); + }); + $(".hide_ajax_topic").removeClass("hide_ajax_topic"); // TODO: Do Fade + moreTopicCount = 0; + }) + $(".add_like").click(function(event) { event.preventDefault(); let likeButton = this; @@ -596,29 +644,31 @@ $(document).ready(function(){ let reader = new FileReader(); reader.onload = function(e) { - crypto.subtle.digest('SHA-256',e.target.result).then(function(hash) { - const hashArray = Array.from(new Uint8Array(hash)) - return hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join('') - }).then(function(hash) { - console.log("hash",hash); - let content = document.getElementById("input_content") - console.log("content.value", content.value); + crypto.subtle.digest('SHA-256',e.target.result) + .then(function(hash) { + const hashArray = Array.from(new Uint8Array(hash)) + return hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join('') + }).then(function(hash) { + console.log("hash",hash); + let content = document.getElementById("input_content") + console.log("content.value", content.value); + + let attachItem; + if(content.value == "") attachItem = "//" + siteURL + "/attachs/" + hash + "." + ext; + else attachItem = "\r\n//" + siteURL + "/attachs/" + hash + "." + ext; + content.value = content.value + attachItem; + console.log("content.value", content.value); - let attachItem; - if(content.value == "") attachItem = "//" + siteURL + "/attachs/" + hash + "." + ext; - else attachItem = "\r\n//" + siteURL + "/attachs/" + hash + "." + ext; - content.value = content.value + attachItem; - console.log("content.value", content.value); - - // For custom / third party text editors - attachItemCallback(attachItem); - }); + // For custom / third party text editors + attachItemCallback(attachItem); + }); } reader.readAsArrayBuffer(files[i]); } reader.readAsDataURL(files[i]); } if(totalSize>maxRequestSize) { + // TODO: Use a notice instead alert("You can't upload this much data at once, max: " + maxRequestSize); } } diff --git a/templates/forum.html b/templates/forum.html index 8b84492b..c7cf2e97 100644 --- a/templates/forum.html +++ b/templates/forum.html @@ -12,10 +12,10 @@
{{if .CurrentUser.Perms.CreateTopic}}
-
+
{{/** TODO: Add a permissions check for this **/}} -
- +
+
{{else}}
{{end}}
@@ -26,15 +26,15 @@
- {{lang "topic_list_what_to_do"}} + {{lang "topic_list.what_to_do"}}
- +
diff --git a/templates/header.html b/templates/header.html index b6371594..0ff74b7d 100644 --- a/templates/header.html +++ b/templates/header.html @@ -20,8 +20,11 @@ {{if .Header.MetaDesc}}{{end}} + {{/** TODO: Have page / forum / topic level tags and descriptions below as-well **/}} + + {{if not .CurrentUser.IsSuperMod}}{{end}} diff --git a/templates/topics.html b/templates/topics.html index 3b7bcc0b..770e4b9b 100644 --- a/templates/topics.html +++ b/templates/topics.html @@ -7,10 +7,10 @@
{{if .ForumList}}
-
+
{{/** TODO: Add a permissions check for this **/}} -
- +
+
{{else}}
{{end}}
@@ -23,15 +23,15 @@
- {{lang "topic_list_what_to_do"}} + {{lang "topic_list.what_to_do"}}
- +
@@ -43,7 +43,7 @@
-

{{lang "topic_list_move_head"}}

+

{{lang "topic_list.move_head"}}

@@ -51,7 +51,7 @@
- +
@@ -101,6 +101,9 @@
{{end}} {{end}} +
+
+
{{range .TopicList}}{{template "topics_topic.html" . }}{{else}}
{{lang "topics_no_topics"}}{{if .CurrentUser.Perms.CreateTopic}} {{lang "topics_start_one"}}{{end}}
{{end}}
diff --git a/themes/cosora/public/main.css b/themes/cosora/public/main.css index c9af11f9..1b0e4def 100644 --- a/themes/cosora/public/main.css +++ b/themes/cosora/public/main.css @@ -698,9 +698,16 @@ textarea { background-color: rgb(239, 255, 255); border: 1px solid rgb(187, 217, 217); border-bottom: 2px solid rgb(187, 217, 217); - border-left: none; +} +.topic_row.new_item .topic_left { border-right: none; } +.topic_row.new_item .topic_right { + border-left: none; +} +.hide_ajax_topic { + display: none !important; +} .topic_middle { display: none; } @@ -896,6 +903,13 @@ textarea { } } +.more_topic_block_initial { + display: none; +} +.more_topic_block_active { + display: block; +} + .forum_list, .post_container { border: none; } diff --git a/themes/nox/public/main.css b/themes/nox/public/main.css index 2beb5b6a..2b92cecc 100644 --- a/themes/nox/public/main.css +++ b/themes/nox/public/main.css @@ -236,6 +236,14 @@ h1, h3 { display: none; } +/* TODO: Make a generic version of this so that we can have more blocks which are initially hidden but flip over to visible under certain conditions */ +.more_topic_block_initial { + display: none; +} +.more_topic_block_active { + display: block; +} + input, select, button, .formbutton, textarea { border-radius: 3px; background: rgb(90,90,90); diff --git a/themes/nox/theme.json b/themes/nox/theme.json index 05a7dcd5..9ddd6fc6 100644 --- a/themes/nox/theme.json +++ b/themes/nox/theme.json @@ -1,12 +1,16 @@ { "Name": "nox", - "FriendlyName": "Nox", + "FriendlyName": "Nox (Incomplete)", "Version": "0.0.1", "Creator": "Azareal", "URL": "github.com/Azareal/Gosora", "Tag": "WIP", - "HideFromThemes":true, "Docks":["topMenu","rightSidebar","footer"], + "MapTmplToDock": { + "rightOfNav": { + "File": "./templates/userDock.html" + } + }, "Templates": [ { "Name": "topic", diff --git a/themes/shadow/public/main.css b/themes/shadow/public/main.css index 173e6f3e..8f388d8e 100644 --- a/themes/shadow/public/main.css +++ b/themes/shadow/public/main.css @@ -841,6 +841,13 @@ input[type=checkbox]:checked + label.poll_option_label .sel { display: none; } +.more_topic_block_initial { + display: none; +} +.more_topic_block_active { + display: block; +} + .topic_name_input { width: 100%; margin-right: 10px; diff --git a/themes/tempra-conflux/public/main.css b/themes/tempra-conflux/public/main.css index c4235cff..9b8495ec 100644 --- a/themes/tempra-conflux/public/main.css +++ b/themes/tempra-conflux/public/main.css @@ -489,6 +489,13 @@ li a { display: none; } +.more_topic_block_initial { + display: none; +} +.more_topic_block_active { + display: block; +} + .postImage { max-width: 100%; max-height: 200px; diff --git a/themes/tempra-simple/public/main.css b/themes/tempra-simple/public/main.css index 5409d3f8..b42d0a33 100644 --- a/themes/tempra-simple/public/main.css +++ b/themes/tempra-simple/public/main.css @@ -498,6 +498,13 @@ input, select { display: none; } +.more_topic_block_initial { + display: none; +} +.more_topic_block_active { + display: block; +} + .postImage { max-width: 100%; max-height: 200px;