From 08996db8b21702e918af82a2ec0968822ff6003e Mon Sep 17 00:00:00 2001 From: Ryan Stafford Date: Sun, 3 Sep 2023 12:48:04 -0400 Subject: [PATCH] post/user blocking --- main.go | 2 +- public/style.css | 29 ++++++++++++++----- public/utils.js | 64 ++++++++++++++++++++++++++++++++++++++++-- routes.go | 41 ++++++++++++++++++++++++++- state.go | 12 ++++++++ templates/block.html | 23 +++++++++++++++ templates/comment.html | 11 ++++++-- templates/footer.html | 7 +++++ templates/header.html | 11 ++++++++ templates/nav.html | 9 +++--- templates/post.html | 6 +++- templates/sidebar.html | 30 ++++++++++++-------- 12 files changed, 216 insertions(+), 29 deletions(-) create mode 100644 templates/block.html create mode 100644 templates/footer.html create mode 100644 templates/header.html diff --git a/main.go b/main.go index 95e0f3d..d778a8b 100644 --- a/main.go +++ b/main.go @@ -56,7 +56,7 @@ func init() { )) templates = make(map[string]*template.Template) if !*watch { - for _, name := range []string{"index.html", "login.html", "frontpage.html", "root.html", "settings.html", "xhr.html", "create_comment.html"} { + for _, name := range []string{"index.html", "login.html", "frontpage.html", "root.html", "settings.html", "xhr.html", "create_comment.html", "block.html"} { t := template.New(name).Funcs(funcMap) glob, err := t.ParseGlob("templates/*") if err != nil { diff --git a/public/style.css b/public/style.css index 7522f61..6de8ae4 100644 --- a/public/style.css +++ b/public/style.css @@ -408,9 +408,12 @@ form.nsfw div { .gray { color: #808080; } -.loading { +.morecomments .loading { color: red !important; } +.blockpopup .loading { + padding: 2px; +} .error { color: red; font-size: 13px; @@ -462,7 +465,7 @@ form.nsfw div { .buttons li { display: inline; } -.buttons, .buttons input { +.buttons, .buttons > form input, .buttons li form input { font-weight: bold; font-size: 10px; padding: 0; @@ -481,20 +484,32 @@ form.nsfw div { border-left: 2px solid #c5c1ad; padding: 0 8px; } -.buttons a, .buttons form input, .comment .buttons form input { +.buttons a, .buttons > form input, .comment .buttons form input { text-decoration: none; color: #888; display: inline-block; margin-right: 5px !important; } -.buttons a:hover, .title a:hover, .buttons form input:hover, .comment .buttons form input:hover { +.buttons a:hover, .title a:hover, .buttons > form input:hover, .comment .buttons form input:hover { text-decoration: underline; } .entry { - overflow: hidden; color: #888; + overflow:hidden; +} +.entry .buttons .blockpopup { + display: inline-block; + position: absolute; + border: 1px solid #888; + z-index: 100; + background-color: white; +} +form.blockpost { + margin: 2px; +} +.blockpost div:last-child input { + margin: 4px 2px 4px 4px; } - .expando-button { width: 23px; height: 23px; @@ -816,7 +831,7 @@ h1, h2 { .dark .moderators a { color: #6a98af; } -.community { +main > .community { margin: 20px 50px; max-width: 840px; position: relative; diff --git a/public/utils.js b/public/utils.js index df8c22a..a07028b 100644 --- a/public/utils.js +++ b/public/utils.js @@ -51,13 +51,23 @@ function commentClick(e) { if (e.target.value == "preview") { targ = form } - console.log("ok") } else if (("c"+data.get("parentid")) == targ.id) { targ = form } else { return } e.target.disabled = "disabled" request(targ.action || "", data, function(res){ + if (data.get("op") == "block_user") { + var submitter = targ.getElementsByClassName("creator")[0].href + var comments = Array.prototype.slice.call(document.getElementsByClassName("comment")) + for (var i = 0; i < comments.length; i++) { + var submitter2 = comments[i].getElementsByClassName("creator")[0].href + if (submitter2 == submitter) { + comments[i].remove() + } + } + return + } targ.outerHTML = res setup() }, @@ -223,6 +233,10 @@ function formSubmit(e) { var data = new FormData(targ) data.set(e.submitter.name, e.submitter.value) data.set("xhr", "1") + if (data.get("submit") == "cancel") { + targ.remove() + return + } e.submitter.disabled = "disabled" request(targ.target, data, function(res){ @@ -230,6 +244,24 @@ function formSubmit(e) { document.getElementById("p"+data.get("postid")).remove() return } + if (data.get("op") == "block_post") { + var post = document.getElementById("p"+data.get("postid")) + var user = post.getElementsByClassName("submitter")[0].href + var community = post.getElementsByClassName("community")[0].href + var posts = Array.prototype.slice.call(document.getElementsByClassName("post")) + for (var i = 0; i < posts.length; i++) { + var user2 = posts[i].getElementsByClassName("submitter")[0].href + var community2 = posts[i].getElementsByClassName("community")[0].href + if (data.get("blockcommunity") != null && community2 == community) { + posts[i].remove() + } + if (data.get("blockuser") != null && user2 == user) { + posts[i].remove() + } + } + targ.remove() + return + } targ.outerHTML = res setup() }, @@ -388,7 +420,7 @@ function setup() { var posts = document.getElementsByClassName("post") for (var i = 0; i < posts.length; i++) { posts[i].addEventListener("click", postClick) - var forms = posts[i].getElementsByClassName("link-btn") + var forms = posts[i].getElementsByTagName("form") for (var f = 0; f < forms.length; f++) { forms[f].addEventListener("submit", formSubmit) } @@ -406,6 +438,34 @@ function setup() { for (var i = 0; i < comments.length; i++) { comments[i].addEventListener("click", commentClick) } + var links = document.getElementsByTagName("a") + for (var i = 0; i < links.length; i++) { + if (links[i].rel == "xhr") { + links[i].addEventListener("click", xhrLink) + } + } +} +function xhrLink(e) { + e = e || window.event; + e.preventDefault(); + var targ = e.currentTarget || e.srcElement || e; + var t = [] + if (targ.target != "") { + t = document.getElementsByName(targ.target) + } + if (t.length) { + t[0].innerHTML = '
loading
' + } + request(targ.href+"?xhr", "", + function(res){ + if (t.length) { + t[0].innerHTML = res + } + setup() + }, + function(res){ + }) + return false; } setup() diff --git a/routes.go b/routes.go index d72d653..032582a 100644 --- a/routes.go +++ b/routes.go @@ -295,7 +295,7 @@ func GetTemplate(name string) (*template.Template, error) { } t, ok := templates[name] if !ok { - return nil, errors.New("template not found") + return nil, errors.New("template not found: " + name) } return t, nil } @@ -493,6 +493,7 @@ func GetPost(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { Render(w, "index.html", state) return } + // redirect /post/remote_id@instance to /post/local_id if path := strings.Split(ps.ByName("postid"), "@"); len(path) > 1 { apid := ResolveId(r, "post", path[0], path[1]) if apid != "" { @@ -529,6 +530,11 @@ func GetPost(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { } postid, _ := strconv.Atoi(ps.ByName("postid")) state.GetPost(postid) + if ps.ByName("op") == "block" { + state.Op = "block" + Render(w, "block.html", state) + return + } state.GetComments() Render(w, "index.html", state) } @@ -597,6 +603,9 @@ func GetUser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { return } state.GetUser(ps.ByName("username")) + if state.Site == nil { + state.GetSite() + } Render(w, "index.html", state) } func GetMessageForm(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { @@ -931,6 +940,20 @@ func UserOp(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { CommunityID: communityid, Block: false, }) + case "block_user": + personId, _ := strconv.Atoi(r.FormValue("user_id")) + if personId == 0 { + state.GetUser(ps.ByName("username")) + personId = state.User.PersonView.Person.ID + } + state.Client.BlockPerson(context.Background(), types.BlockPerson{ + PersonID: personId, + Block: r.FormValue("submit") == "block", + }) + if r.FormValue("xhr") == "1" { + w.Write([]byte{}) + return + } case "logout": deleteCookie(w, state.Host, "jwt") deleteCookie(w, state.Host, "user") @@ -1166,6 +1189,21 @@ func UserOp(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { r.URL.Path = "/" + state.Host + "/c/" + resp.PostView.Community.Name r.URL.RawQuery = "" } + case "block_post": + postid, _ := strconv.Atoi(r.FormValue("postid")) + state.GetPost(postid) + if r.FormValue("blockcommunity") != "" && len(state.Posts) > 0 { + state.Client.BlockCommunity(context.Background(), types.BlockCommunity{ + CommunityID: state.Posts[0].Post.CommunityID, + Block: true, + }) + } + if r.FormValue("blockuser") != "" && len(state.Posts) > 0 { + state.Client.BlockPerson(context.Background(), types.BlockPerson{ + PersonID: state.Posts[0].Post.CreatorID, + Block: true, + }) + } case "read_post": postid, _ := strconv.Atoi(r.FormValue("postid")) post := types.MarkPostAsRead{ @@ -1399,6 +1437,7 @@ func GetRouter() *httprouter.Router { router.GET("/:host/c/:community/edit", middleware(GetCreateCommunity)) router.GET("/:host/post/:postid", middleware(GetPost)) router.POST("/:host/post/:postid", middleware(UserOp)) + router.GET("/:host/post/:postid/:op", middleware(GetPost)) router.GET("/:host/comment/:commentid", middleware(GetComment)) router.GET("/:host/comment/:commentid/:op", middleware(GetComment)) router.POST("/:host/comment/:commentid", middleware(UserOp)) diff --git a/state.go b/state.go index 1e2085a..8f49caa 100644 --- a/state.go +++ b/state.go @@ -107,6 +107,18 @@ type State struct { HideThumbnails bool } +func (s State) UserBlocked() bool { + if s.User == nil || s.Site == nil || !s.Site.MyUser.IsValid() { + return false + } + for _, p := range s.Site.MyUser.MustValue().PersonBlocks { + if p.Target.ID == s.User.PersonView.Person.ID { + return true + } + } + return false +} + func (s State) Unknown() string { fmt.Println(fmt.Sprintf("%v", s.Error)) re := regexp.MustCompile(`(.*?)@(.*?)@`) diff --git a/templates/block.html b/templates/block.html new file mode 100644 index 0000000..311634c --- /dev/null +++ b/templates/block.html @@ -0,0 +1,23 @@ +{{ if not .XHR }} + {{ template "header.html" . }} + {{ template "nav.html" . }} +{{ end }} +
+
+ + +
+
+ + +
+
+ + + + +
+
+{{ if not .XHR }} + {{ template "footer.html" . }} +{{ end }} diff --git a/templates/comment.html b/templates/comment.html index c33d77a..befaee6 100644 --- a/templates/comment.html +++ b/templates/comment.html @@ -21,7 +21,7 @@ [-] {{- end -}} - + {{- if .State.HideInstanceNames -}} {{ .P.Creator.Name }} {{- else -}} @@ -77,10 +77,17 @@ {{ else }} - {{ end }} +
  • + +
  • reply diff --git a/templates/footer.html b/templates/footer.html new file mode 100644 index 0000000..588a3b5 --- /dev/null +++ b/templates/footer.html @@ -0,0 +1,7 @@ + + {{ if .Watch }} + + {{ end }} + + + diff --git a/templates/header.html b/templates/header.html new file mode 100644 index 0000000..16667b9 --- /dev/null +++ b/templates/header.html @@ -0,0 +1,11 @@ + + + {{if and .Posts .PostID }}{{ (index .Posts 0).Post.Name}} : {{.CommunityName}}{{else if and .Community (ne .Community.CommunityView.Community.Title "")}}{{.Community.CommunityView.Community.Title}}{{else if ne .CommunityName ""}}/c/{{.CommunityName}}{{ else if .User}}overview for {{.User.PersonView.Person.Name}}{{else}}{{ host .Host }}{{end}} + + + + + + diff --git a/templates/nav.html b/templates/nav.html index f455ace..bb83b8d 100644 --- a/templates/nav.html +++ b/templates/nav.html @@ -33,7 +33,7 @@ |
    {{else}} -
    log in or sign up + log in or sign up | settings {{end}} @@ -41,11 +41,11 @@
    {{- if .Community }} - {{fullcname .Community.CommunityView.Community}} + {{fullcname .Community.CommunityView.Community}} {{ else if .User }} {{fullname .User.PersonView.Person}} {{ else }} @@ -60,7 +60,8 @@ : search {{ end }}