mirror of
https://github.com/rystaf/mlmym.git
synced 2024-11-21 13:17:13 +00:00
post/user blocking
This commit is contained in:
parent
a96b5b1cd2
commit
08996db8b2
2
main.go
2
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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 = '<div class="loading">loading</div>'
|
||||
}
|
||||
request(targ.href+"?xhr", "",
|
||||
function(res){
|
||||
if (t.length) {
|
||||
t[0].innerHTML = res
|
||||
}
|
||||
setup()
|
||||
},
|
||||
function(res){
|
||||
})
|
||||
return false;
|
||||
}
|
||||
setup()
|
||||
|
||||
|
|
41
routes.go
41
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))
|
||||
|
|
12
state.go
12
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(`(.*?)@(.*?)@`)
|
||||
|
|
23
templates/block.html
Normal file
23
templates/block.html
Normal file
|
@ -0,0 +1,23 @@
|
|||
{{ if not .XHR }}
|
||||
{{ template "header.html" . }}
|
||||
{{ template "nav.html" . }}
|
||||
{{ end }}
|
||||
<form method="POST" class="blockpost"{{ if not .XHR }} action="./"{{ end }}>
|
||||
<div>
|
||||
<input type="checkbox" id="blockuser" name="blockuser" checked>
|
||||
<label for="blockuser">u/{{ fullname (index .Posts 0).Creator }}</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" id="blockcommunity" name="blockcommunity">
|
||||
<label for="blockcommunity">c/{{ fullcname .Community.CommunityView.Community }}</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="hidden" name="op" value="block_post">
|
||||
<input type="hidden" name="postid" value="{{(index .Posts 0).Post.ID}}">
|
||||
<input type="submit" value="block" name="submit">
|
||||
<input type="submit" value="cancel" name="submit">
|
||||
</div>
|
||||
</form>
|
||||
{{ if not .XHR }}
|
||||
{{ template "footer.html" . }}
|
||||
{{ end }}
|
|
@ -21,7 +21,7 @@
|
|||
[-]
|
||||
{{- end -}}
|
||||
</a>
|
||||
<a {{ if .P.Comment.Distinguished}}class="{{if .P.Creator.Admin}}admin {{end}}distinguished"{{ else if .Submitter }}class="submitter"{{end}} href="/{{.State.Host}}/u/{{fullname .P.Creator}}">
|
||||
<a class="creator{{ if .P.Comment.Distinguished}}{{if .P.Creator.Admin}} admin{{end}} distinguished{{ else if .Submitter }} submitter{{end}}" href="/{{.State.Host}}/u/{{fullname .P.Creator}}">
|
||||
{{- if .State.HideInstanceNames -}}
|
||||
{{ .P.Creator.Name }}
|
||||
{{- else -}}
|
||||
|
@ -77,10 +77,17 @@
|
|||
<input type="submit" name="submit" value="unsave">
|
||||
{{ else }}
|
||||
<input type="submit" name="submit" value="save">
|
||||
|
||||
{{ end }}
|
||||
</form>
|
||||
</li>
|
||||
<li>
|
||||
<form class="link-btn" method="POST">
|
||||
<input type="hidden" name="commentid" value="{{.P.Comment.ID}}">
|
||||
<input type="hidden" name="op" value="block_user">
|
||||
<input type="hidden" name="user_id" value="{{.P.Creator.ID}}">
|
||||
<input type="submit" name="submit" value="block">
|
||||
</form>
|
||||
</li>
|
||||
<li>
|
||||
<a class="reply" for="c{{.P.Comment.ID}}" href="/{{.State.Host}}/comment/{{.P.Comment.ID}}?reply">
|
||||
reply
|
||||
|
|
7
templates/footer.html
Normal file
7
templates/footer.html
Normal file
|
@ -0,0 +1,7 @@
|
|||
<script src="/_/static/utils.js?v={{ .Version }}"></script>
|
||||
{{ if .Watch }}
|
||||
<script src="/_/static/ws.js"></script>
|
||||
{{ end }}
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
11
templates/header.html
Normal file
11
templates/header.html
Normal file
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
<title>{{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}}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="shortcut icon" href="/{{.Host}}/icon.jpg">
|
||||
<link rel="stylesheet" href="/_/static/style.css?v={{ .Version }}">
|
||||
</head>
|
||||
<body{{ if .Dark }} class="dark"{{end}}>
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="/_/static/noscript.css?v={{ .Version }}">
|
||||
</noscript>
|
|
@ -33,7 +33,7 @@
|
|||
|
|
||||
<form method="POST"><input type="submit" name="op" value="logout"></form>
|
||||
{{else}}
|
||||
<a href="/{{.Host}}/login">log in</a> or <a href="/{{.Host}}/login">sign up</a>
|
||||
<a href="/{{.Host}}/login">log in</a> or <a href="/{{.Host}}/login">sign up</a>
|
||||
|
|
||||
<a id="opensettings" href="/{{.Host}}/settings">settings</a>
|
||||
{{end}}
|
||||
|
@ -41,11 +41,11 @@
|
|||
<div id="settingspopup"></div>
|
||||
<div class="spacer">
|
||||
<a href="/{{ .Host}}/">
|
||||
<img class="icon" src="{{ if .Site }}{{ .Site.SiteView.Site.Icon.String }}{{else}}/{{ .Host}}/icon.jpg{{end}}">
|
||||
<img class="icon" src="{{ if and .Site .Site.SiteView.Site.Icon.IsValid }}{{ .Site.SiteView.Site.Icon.String }}{{else}}/{{ .Host}}/icon.jpg{{end}}">
|
||||
</a>
|
||||
</div>
|
||||
{{- if .Community }}
|
||||
<a class="title" href="/{{ .Host}}//c/{{fullcname .Community.CommunityView.Community}}">{{fullcname .Community.CommunityView.Community}}</a>
|
||||
<a class="title" href="/{{ .Host}}/c/{{fullcname .Community.CommunityView.Community}}">{{fullcname .Community.CommunityView.Community}}</a>
|
||||
{{ else if .User }}
|
||||
<a class="title" href="/{{ .Host}}/u/{{fullname .User.PersonView.Person}}">{{fullname .User.PersonView.Person}}</a>
|
||||
{{ else }}
|
||||
|
@ -60,7 +60,8 @@
|
|||
<span>: search</span>
|
||||
{{ end }}
|
||||
<ul>
|
||||
{{ if and .User (not .Query)}}
|
||||
{{- if eq .Op "block" }}<li class="selected"><a href="/{{ .Host }}/post/{{ (index .Posts 0).Post.ID}}">block</a></li>
|
||||
{{ else if and .User (not .Query)}}
|
||||
<li {{if eq .Op "" }}class="selected"{{end}}><a href="?">overview</a></li>
|
||||
{{ if and .Session (eq .User.PersonView.Person.ID .Session.UserID) }}
|
||||
<li {{if eq .Op "Saved"}}class="selected"{{end}}><a href="?view=Saved">saved</a></li>
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
{{- end -}}
|
||||
</a>
|
||||
to
|
||||
<a href="/{{ .State.Host }}/c/{{ fullcname .Community }}">
|
||||
<a class="community" href="/{{ .State.Host }}/c/{{ fullcname .Community }}">
|
||||
c/{{ if .State.HideInstanceNames -}}
|
||||
{{ .Community.Name }}
|
||||
{{ else -}}
|
||||
|
@ -63,6 +63,10 @@
|
|||
{{ if .Post.NSFW }}<span class="nsfw">NSFW</span>{{end}}
|
||||
<a href="/{{ .State.Host }}/post/{{ .Post.ID }}">{{ .Counts.Comments }} comments</a>
|
||||
<a href="{{ .Post.ApID}}">fedilink</a>
|
||||
{{ if .State.Session }}
|
||||
<a href="/{{ .State.Host }}/post/{{ .Post.ID }}/block" rel="xhr" target="block{{ .Post.ID }}">block</a>
|
||||
{{ end }}
|
||||
<span class="blockpopup" name="block{{.Post.ID}}"></span>
|
||||
{{ if and .State.Session (eq .State.Session.UserID .Post.CreatorID) }}
|
||||
{{ if not .Post.Deleted }}<a href="/{{ .State.Host }}/post/{{ .Post.ID }}?edit">edit</a>{{end}}
|
||||
<form class="link-btn" method="POST">
|
||||
|
|
|
@ -11,8 +11,26 @@
|
|||
<input type="hidden" name="sort" value="New">
|
||||
</form>
|
||||
|
||||
{{ if not .Session -}}
|
||||
<form class="login" method="post">
|
||||
<input name="username" type="text" placeholder="username" maxlength="20">
|
||||
<input name="password" type="password" placeholder="password">
|
||||
<div>
|
||||
<input type="submit" name="op" value="login">
|
||||
</div>
|
||||
</form>
|
||||
{{ end }}
|
||||
|
||||
{{ if .User }}
|
||||
<h1>{{ .User.PersonView.Person.Name }}</h1>
|
||||
{{ if .Session }}
|
||||
<div>
|
||||
<form method="POST" class="block {{ if .UserBlocked }}unblock{{end}}">
|
||||
<input name="submit" type="submit" value="{{ if .UserBlocked}}unblock{{else}}block{{end}}">
|
||||
<input type="hidden" name="op" value="block_user">
|
||||
</form>
|
||||
</div>
|
||||
{{ end }}
|
||||
<b>{{ .User.PersonView.Counts.PostScore}}</b> post score <br>
|
||||
<b>{{ .User.PersonView.Counts.CommentScore}}</b> comment score <br>
|
||||
<div class="age">
|
||||
|
@ -29,16 +47,6 @@
|
|||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ if not .Session -}}
|
||||
<form class="login" method="post">
|
||||
<input name="username" type="text" placeholder="username" maxlength="20">
|
||||
<input name="password" type="password" placeholder="password">
|
||||
<div>
|
||||
<input type="submit" name="op" value="login">
|
||||
</div>
|
||||
</form>
|
||||
{{ end }}
|
||||
|
||||
{{ if and .PostID .Posts }}
|
||||
<div class="stats">
|
||||
this post was submitted on {{ (index .Posts 0).Post.Published.Time.Format "01 Jan 2006" }}
|
||||
|
@ -55,7 +63,7 @@
|
|||
</div>
|
||||
{{ end }}
|
||||
|
||||
{{ if and .Site (not .Community) }}
|
||||
{{ if and .Site (not .Community) (not .User) }}
|
||||
{{ if .Site.SiteView.Site.Banner.IsValid }}
|
||||
<div class="banner" style="background-image: url({{ .Site.SiteView.Site.Banner }})"></div>
|
||||
{{ else if .Site.SiteView.Site.Icon.IsValid }}
|
||||
|
|
Loading…
Reference in a new issue