basic behavior of filtering users added
This commit is contained in:
+28
-3
@@ -405,6 +405,15 @@ func templateAttachmentInfo(args jet.Arguments) reflect.Value {
|
|||||||
return reflect.ValueOf(rc)
|
return reflect.ValueOf(rc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// templateBozo returns true if the post's creator user has been filtered by the current one.
|
||||||
|
func templateBozo(args jet.Arguments) reflect.Value {
|
||||||
|
post := args.Get(0).Convert(reflect.TypeFor[*database.PostHeader]()).Interface().(*database.PostHeader)
|
||||||
|
topic := args.Get(1).Convert(reflect.TypeFor[*database.Topic]()).Interface().(*database.Topic)
|
||||||
|
ctxt := args.Get(2).Convert(reflect.TypeFor[ui.AmContext]()).Interface().(ui.AmContext)
|
||||||
|
rc, _ := topic.IsBozo(ctxt.Ctx(), ctxt.CurrentUser(), post.CreatorUid)
|
||||||
|
return reflect.ValueOf(rc)
|
||||||
|
}
|
||||||
|
|
||||||
/* ReadPosts displays posts in a topic.
|
/* ReadPosts displays posts in a topic.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* ctxt - The AmContext for the request.
|
* ctxt - The AmContext for the request.
|
||||||
@@ -450,6 +459,7 @@ func ReadPosts(ctxt ui.AmContext) (string, any, error) {
|
|||||||
conf := ctxt.GetScratch("currentConference").(*database.Conference)
|
conf := ctxt.GetScratch("currentConference").(*database.Conference)
|
||||||
myLevel := ctxt.GetScratch("levelInConference").(uint16)
|
myLevel := ctxt.GetScratch("levelInConference").(uint16)
|
||||||
topic := ctxt.GetScratch("currentTopic").(*database.Topic)
|
topic := ctxt.GetScratch("currentTopic").(*database.Topic)
|
||||||
|
ctxt.VarMap().Set("post_topic", topic)
|
||||||
|
|
||||||
// Determine the range of posts to display. The "pin" is the post number after which we display the horizontal line separating old and new posts.
|
// Determine the range of posts to display. The "pin" is the post number after which we display the horizontal line separating old and new posts.
|
||||||
lastRead, err := topic.GetLastRead(ctxt.Ctx(), ctxt.CurrentUser())
|
lastRead, err := topic.GetLastRead(ctxt.Ctx(), ctxt.CurrentUser())
|
||||||
@@ -544,6 +554,13 @@ func ReadPosts(ctxt ui.AmContext) (string, any, error) {
|
|||||||
// Set advanced controls.
|
// Set advanced controls.
|
||||||
advancedControls := ctxt.HasParameter("ac") && (len(posts) == 1)
|
advancedControls := ctxt.HasParameter("ac") && (len(posts) == 1)
|
||||||
if advancedControls {
|
if advancedControls {
|
||||||
|
nbozo := ctxt.QueryParamInt("bozo", -1)
|
||||||
|
if nbozo >= 0 {
|
||||||
|
err = topic.SetBozo(ctxt.Ctx(), ctxt.CurrentUser(), posts[0].CreatorUid, nbozo != 0)
|
||||||
|
if err != nil {
|
||||||
|
return ui.ErrorPage(ctxt, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
isMyPost := (posts[0].CreatorUid == ctxt.CurrentUserId()) && !ctxt.CurrentUser().IsAnon
|
isMyPost := (posts[0].CreatorUid == ctxt.CurrentUserId()) && !ctxt.CurrentUser().IsAnon
|
||||||
isScribbled := posts[0].IsScribbled()
|
isScribbled := posts[0].IsScribbled()
|
||||||
canHide := !isScribbled && (isMyPost || confHidePerm)
|
canHide := !isScribbled && (isMyPost || confHidePerm)
|
||||||
@@ -560,9 +577,6 @@ func ReadPosts(ctxt ui.AmContext) (string, any, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctxt.VarMap().Set("canPublish", canPublish)
|
ctxt.VarMap().Set("canPublish", canPublish)
|
||||||
if !canHide && !canScribble && !confNukePerm && !canPublish {
|
|
||||||
advancedControls = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ctxt.VarMap().Set("advancedControls", advancedControls)
|
ctxt.VarMap().Set("advancedControls", advancedControls)
|
||||||
|
|
||||||
@@ -588,6 +602,7 @@ func ReadPosts(ctxt ui.AmContext) (string, any, error) {
|
|||||||
ctxt.VarMap().SetFunc("post_getText", templatePostText)
|
ctxt.VarMap().SetFunc("post_getText", templatePostText)
|
||||||
ctxt.VarMap().SetFunc("post_getUserName", templateExtractUserName)
|
ctxt.VarMap().SetFunc("post_getUserName", templateExtractUserName)
|
||||||
ctxt.VarMap().SetFunc("post_getAttachmentInfo", templateAttachmentInfo)
|
ctxt.VarMap().SetFunc("post_getAttachmentInfo", templateAttachmentInfo)
|
||||||
|
ctxt.VarMap().SetFunc("post_isBozo", templateBozo)
|
||||||
ctxt.VarMap().Set("post_stem", fmt.Sprintf("%s/r/%d", urlStem, topic.Number))
|
ctxt.VarMap().Set("post_stem", fmt.Sprintf("%s/r/%d", urlStem, topic.Number))
|
||||||
ctxt.VarMap().Set("post_max", topic.TopMessage)
|
ctxt.VarMap().Set("post_max", topic.TopMessage)
|
||||||
ctxt.VarMap().Set("posts", posts)
|
ctxt.VarMap().Set("posts", posts)
|
||||||
@@ -605,12 +620,21 @@ func ReadPosts(ctxt ui.AmContext) (string, any, error) {
|
|||||||
return "framed_template", "posts.jet", nil
|
return "framed_template", "posts.jet", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* PostInTopic adds a new post to a topic.
|
||||||
|
* Parameters:
|
||||||
|
* ctxt - The AmContext for the request.
|
||||||
|
* Returns:
|
||||||
|
* Command string dictating what to be rendered.
|
||||||
|
* Data as a parameter for the command string.
|
||||||
|
* Standard Go error status.
|
||||||
|
*/
|
||||||
func PostInTopic(ctxt ui.AmContext) (string, any, error) {
|
func PostInTopic(ctxt ui.AmContext) (string, any, error) {
|
||||||
// Locate community, conference, and topic.
|
// Locate community, conference, and topic.
|
||||||
comm := ctxt.CurrentCommunity()
|
comm := ctxt.CurrentCommunity()
|
||||||
conf := ctxt.GetScratch("currentConference").(*database.Conference)
|
conf := ctxt.GetScratch("currentConference").(*database.Conference)
|
||||||
level := ctxt.GetScratch("levelInConference").(uint16)
|
level := ctxt.GetScratch("levelInConference").(uint16)
|
||||||
topic := ctxt.GetScratch("currentTopic").(*database.Topic)
|
topic := ctxt.GetScratch("currentTopic").(*database.Topic)
|
||||||
|
ctxt.VarMap().Set("post_topic", topic)
|
||||||
|
|
||||||
urlStem := fmt.Sprintf("/comm/%s/conf/%s/r/%d", comm.Alias, ctxt.GetScratch("currentAlias"), topic.Number)
|
urlStem := fmt.Sprintf("/comm/%s/conf/%s/r/%d", comm.Alias, ctxt.GetScratch("currentAlias"), topic.Number)
|
||||||
if ctxt.FormFieldIsSet("cancel") {
|
if ctxt.FormFieldIsSet("cancel") {
|
||||||
@@ -711,6 +735,7 @@ func PostInTopic(ctxt ui.AmContext) (string, any, error) {
|
|||||||
ctxt.VarMap().SetFunc("post_getText", templatePostText)
|
ctxt.VarMap().SetFunc("post_getText", templatePostText)
|
||||||
ctxt.VarMap().SetFunc("post_getUserName", templateExtractUserName)
|
ctxt.VarMap().SetFunc("post_getUserName", templateExtractUserName)
|
||||||
ctxt.VarMap().SetFunc("post_getAttachmentInfo", templateAttachmentInfo)
|
ctxt.VarMap().SetFunc("post_getAttachmentInfo", templateAttachmentInfo)
|
||||||
|
ctxt.VarMap().SetFunc("post_isBozo", templateBozo)
|
||||||
ctxt.VarMap().Set("post_stem", fmt.Sprintf("/comm/%s/conf/%s/r/%d", comm.Alias, ctxt.GetScratch("currentAlias"), topic.Number))
|
ctxt.VarMap().Set("post_stem", fmt.Sprintf("/comm/%s/conf/%s/r/%d", comm.Alias, ctxt.GetScratch("currentAlias"), topic.Number))
|
||||||
ctxt.VarMap().Set("post_max", topic.TopMessage)
|
ctxt.VarMap().Set("post_max", topic.TopMessage)
|
||||||
ctxt.VarMap().Set("posts", posts)
|
ctxt.VarMap().Set("posts", posts)
|
||||||
|
|||||||
@@ -129,6 +129,74 @@ func (t *Topic) SetHidden(ctx context.Context, u *User, hidden bool) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsBozo returns true if the specified test UID is filtered for the specified user.
|
||||||
|
func (t *Topic) IsBozo(ctx context.Context, u *User, testUid int32) (bool, error) {
|
||||||
|
if u.IsAnon {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
row := amdb.QueryRowContext(ctx, "SELECT bozo_uid FROM topicbozo WHERE topicid = ? AND uid = ? AND bozo_uid = ?", t.TopicId, u.Uid, testUid)
|
||||||
|
var tmp int32
|
||||||
|
err := row.Scan(&tmp)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return true, nil
|
||||||
|
case sql.ErrNoRows:
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBozo adds or removes a filter of a subject UID for the specified user.
|
||||||
|
func (t *Topic) SetBozo(ctx context.Context, u *User, subjectUid int32, bozo bool) error {
|
||||||
|
var err error = nil
|
||||||
|
if !u.IsAnon {
|
||||||
|
if bozo { // Flipping the bozo bit!
|
||||||
|
row := amdb.QueryRowContext(ctx, "SELECT bozo_uid FROM topicbozo WHERE topicid = ? AND uid = ? AND bozo_uid = ?", t.TopicId, u.Uid, subjectUid)
|
||||||
|
var tmp int32
|
||||||
|
err = row.Scan(&tmp)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return nil
|
||||||
|
case sql.ErrNoRows:
|
||||||
|
_, err = amdb.ExecContext(ctx, "INSERT INTO topicbozo (topicid, uid, bozo_uid) VALUES (?, ?, ?)", t.TopicId, u.Uid, subjectUid)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_, err = amdb.ExecContext(ctx, "DELETE FROM topicbozo WHERE topicid = ? AND uid = ? AND bozo_uid = ?", t.TopicId, u.Uid, subjectUid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TopicBozo is a structure that returns all information about a filtered user.
|
||||||
|
type TopicBozo struct {
|
||||||
|
Uid int32
|
||||||
|
Username string
|
||||||
|
GivenName string
|
||||||
|
FamilyName string
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBozos returns all filtered users for a given user on the topic.
|
||||||
|
func (t *Topic) GetBozos(ctx context.Context, u *User) ([]TopicBozo, error) {
|
||||||
|
if u.IsAnon {
|
||||||
|
return make([]TopicBozo, 0), nil
|
||||||
|
}
|
||||||
|
rs, err := amdb.QueryContext(ctx, `SELECT b.bozo_uid, u.username, c.given_name, c.family_name
|
||||||
|
FROM topicbozo b, users u, contacts c WHERE b.topicid = ? AND b.uid = ? AND b.bozo_uid = u.uid AND u.contactid = c.contactid`, t.TopicId, u.Uid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rc := make([]TopicBozo, 0)
|
||||||
|
for rs.Next() {
|
||||||
|
var tb TopicBozo
|
||||||
|
err = rs.Scan(&(tb.Uid), &(tb.Username), &(tb.GivenName), &(tb.FamilyName))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rc = append(rc, tb)
|
||||||
|
}
|
||||||
|
return rc, nil
|
||||||
|
}
|
||||||
|
|
||||||
// TopicSettings contains per-user settings for topics, including the "last read" message pointer.
|
// TopicSettings contains per-user settings for topics, including the "last read" message pointer.
|
||||||
type TopicSettings struct {
|
type TopicSettings struct {
|
||||||
TopicId int32 `db:"topicid"` // unique ID of the topic
|
TopicId int32 `db:"topicid"` // unique ID of the topic
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ _(italicized items can be deferred)_
|
|||||||
- Delete
|
- Delete
|
||||||
- ~~Post Scribble~~
|
- ~~Post Scribble~~
|
||||||
- ~~Post Nuke~~
|
- ~~Post Nuke~~
|
||||||
- Post Filter User
|
- ~~Post Filter User~~
|
||||||
- Post Move
|
- Post Move
|
||||||
- Post Publish
|
- Post Publish
|
||||||
- Manage Communities on communities sidebox
|
- Manage Communities on communities sidebox
|
||||||
|
|||||||
+4
-2
@@ -109,6 +109,7 @@
|
|||||||
{{ post_overrideLine := "" }}
|
{{ post_overrideLine := "" }}
|
||||||
{{ post_overrideLink := "" }}
|
{{ post_overrideLink := "" }}
|
||||||
{{ post_attach := nil }}
|
{{ post_attach := nil }}
|
||||||
|
{{ post_bozo := false }}
|
||||||
{{ range i, p := posts }}
|
{{ range i, p := posts }}
|
||||||
{{ post_cur = p }}
|
{{ post_cur = p }}
|
||||||
{{ post_userName = post_getUserName(p, .) }}
|
{{ post_userName = post_getUserName(p, .) }}
|
||||||
@@ -116,6 +117,7 @@
|
|||||||
{{ post_overrideLine = post_getOverrideLine(p, .) }}
|
{{ post_overrideLine = post_getOverrideLine(p, .) }}
|
||||||
{{ post_overrideLink = post_getOverrideLink(p, post_topicPermalink) }}
|
{{ post_overrideLink = post_getOverrideLink(p, post_topicPermalink) }}
|
||||||
{{ post_attach = post_getAttachmentInfo(p, .) }}
|
{{ post_attach = post_getAttachmentInfo(p, .) }}
|
||||||
|
{{ post_bozo = post_isBozo(p, post_topic, .) }}
|
||||||
{{ include "singlepost.jet" }}
|
{{ include "singlepost.jet" }}
|
||||||
{{ if advancedControls }}
|
{{ if advancedControls }}
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
@@ -129,8 +131,8 @@
|
|||||||
<a href="{{ topicListLink }}/op/{{ topicNum }}/scribble/{{ p.Num }}"
|
<a href="{{ topicListLink }}/op/{{ topicNum }}/scribble/{{ p.Num }}"
|
||||||
class="bg-yellow-600 hover:bg-yellow-700 text-white px-3 py-2 rounded text-sm font-medium transition-colors whitespace-nowrap">Scribble</a>
|
class="bg-yellow-600 hover:bg-yellow-700 text-white px-3 py-2 rounded text-sm font-medium transition-colors whitespace-nowrap">Scribble</a>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ if false }}{* TODO *}
|
{{ if !isAnon }}
|
||||||
<a href="/TODO"
|
<a href="{{ post_stem }}?r={{ p.Num }}&ac=1&bozo=1"
|
||||||
class="bg-blue-600 hover:bg-blue-700 text-white px-3 py-2 rounded text-sm font-medium transition-colors whitespace-nowrap">Filter User</a>
|
class="bg-blue-600 hover:bg-blue-700 text-white px-3 py-2 rounded text-sm font-medium transition-colors whitespace-nowrap">Filter User</a>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ if canNuke }}
|
{{ if canNuke }}
|
||||||
|
|||||||
@@ -15,6 +15,13 @@
|
|||||||
title="Permalink to this post">🔗<{{ post_confRef }}.{{ post_cur.Num }}></a>
|
title="Permalink to this post">🔗<{{ post_confRef }}.{{ post_cur.Num }}></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{ if post_bozo }}
|
||||||
|
<div class="mt-4 mb-2">
|
||||||
|
<span class="italic font-bold">
|
||||||
|
(User filtered; <a class="text-blue-700 hover:text-blue-900" href="{{ post_stem }}?r={{ post_cur.Num }}&ac=1&bozo=0">remove filter</a>)
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{{ else }}
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<strong class="text-lg">{{ post_cur.Pseud | raw }}</strong>
|
<strong class="text-lg">{{ post_cur.Pseud | raw }}</strong>
|
||||||
<span class="text-gray-600 text-sm ml-2">(<em>
|
<span class="text-gray-600 text-sm ml-2">(<em>
|
||||||
@@ -40,4 +47,5 @@
|
|||||||
{{ else }}
|
{{ else }}
|
||||||
<pre class="amsPost font-mono text-sm whitespace-pre-wrap bg-gray-50 p-4 rounded border border-gray-200">{{ post_text | postRewrite | raw }}</pre>
|
<pre class="amsPost font-mono text-sm whitespace-pre-wrap bg-gray-50 p-4 rounded border border-gray-200">{{ post_text | postRewrite | raw }}</pre>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -25,15 +25,15 @@
|
|||||||
{{ post_overrideLine := "" }}
|
{{ post_overrideLine := "" }}
|
||||||
{{ post_overrideLink := "" }}
|
{{ post_overrideLink := "" }}
|
||||||
{{ post_attach := nil }}
|
{{ post_attach := nil }}
|
||||||
|
{{ post_bozo := false }}
|
||||||
{{ range i, p := posts }}
|
{{ range i, p := posts }}
|
||||||
{{ m = map("post_cur", p, "post_userName", post_getUserName(p, .), "post_text", post_getText(p, .),
|
|
||||||
"post_overrideLine", post_getOverrideLine(p, .), "post_overrideLink", post_getOverrideLink(p, post_topicPermalink)) }}
|
|
||||||
{{ post_cur = p }}
|
{{ post_cur = p }}
|
||||||
{{ post_userName = post_getUserName(p, .) }}
|
{{ post_userName = post_getUserName(p, .) }}
|
||||||
{{ post_text = post_getText(p, .) }}
|
{{ post_text = post_getText(p, .) }}
|
||||||
{{ post_overrideLine = post_getOverrideLine(p, .) }}
|
{{ post_overrideLine = post_getOverrideLine(p, .) }}
|
||||||
{{ post_overrideLink = post_getOverrideLink(p, post_topicPermalink) }}
|
{{ post_overrideLink = post_getOverrideLink(p, post_topicPermalink) }}
|
||||||
{{ post_attach = post_getAttachmentInfo(p, .) }}
|
{{ post_attach = post_getAttachmentInfo(p, .) }}
|
||||||
|
{{ post_bozo = post_isBozo(p, post_topic, .) }}
|
||||||
{{ include "singlepost.jet" }}
|
{{ include "singlepost.jet" }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user