did stick/unstick, freeze/unfreeze, and archive/unarchive topic for three quick wins
This commit is contained in:
@@ -202,6 +202,75 @@ func HideTopic(ctxt ui.AmContext) (string, any, error) {
|
|||||||
return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number), nil
|
return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FreezeTopic freezes or unfreezes the current 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 FreezeTopic(ctxt ui.AmContext) (string, any, error) {
|
||||||
|
conf := ctxt.GetScratch("currentConference").(*database.Conference)
|
||||||
|
myLevel := ctxt.GetScratch("levelInConference").(uint16)
|
||||||
|
topic := ctxt.GetScratch("currentTopic").(*database.Topic)
|
||||||
|
if !conf.TestPermission("Conference.Hide", myLevel) {
|
||||||
|
ctxt.SetRC(http.StatusForbidden)
|
||||||
|
return ui.ErrorPage(ctxt, ENOPERM)
|
||||||
|
}
|
||||||
|
err := topic.SetFrozen(ctxt.Ctx(), !topic.Frozen, ctxt.CurrentUser(), ctxt.RemoteIP())
|
||||||
|
if err != nil {
|
||||||
|
return ui.ErrorPage(ctxt, err)
|
||||||
|
}
|
||||||
|
return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ArchiveTopic archives or unarchives the current 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 ArchiveTopic(ctxt ui.AmContext) (string, any, error) {
|
||||||
|
conf := ctxt.GetScratch("currentConference").(*database.Conference)
|
||||||
|
myLevel := ctxt.GetScratch("levelInConference").(uint16)
|
||||||
|
topic := ctxt.GetScratch("currentTopic").(*database.Topic)
|
||||||
|
if !conf.TestPermission("Conference.Hide", myLevel) {
|
||||||
|
ctxt.SetRC(http.StatusForbidden)
|
||||||
|
return ui.ErrorPage(ctxt, ENOPERM)
|
||||||
|
}
|
||||||
|
err := topic.SetArchived(ctxt.Ctx(), !topic.Archived, ctxt.CurrentUser(), ctxt.RemoteIP())
|
||||||
|
if err != nil {
|
||||||
|
return ui.ErrorPage(ctxt, err)
|
||||||
|
}
|
||||||
|
return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/* StickTopic sticks or unsticks the current 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 StickTopic(ctxt ui.AmContext) (string, any, error) {
|
||||||
|
conf := ctxt.GetScratch("currentConference").(*database.Conference)
|
||||||
|
myLevel := ctxt.GetScratch("levelInConference").(uint16)
|
||||||
|
topic := ctxt.GetScratch("currentTopic").(*database.Topic)
|
||||||
|
if !conf.TestPermission("Conference.Hide", myLevel) {
|
||||||
|
ctxt.SetRC(http.StatusForbidden)
|
||||||
|
return ui.ErrorPage(ctxt, ENOPERM)
|
||||||
|
}
|
||||||
|
err := topic.SetSticky(ctxt.Ctx(), !topic.Sticky, ctxt.CurrentUser(), ctxt.RemoteIP())
|
||||||
|
if err != nil {
|
||||||
|
return ui.ErrorPage(ctxt, err)
|
||||||
|
}
|
||||||
|
return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number), nil
|
||||||
|
}
|
||||||
|
|
||||||
/* HideMessage hides or shows a topic message.
|
/* HideMessage hides or shows a topic message.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* ctxt - The AmContext for the request.
|
* ctxt - The AmContext for the request.
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Amsterdam Web Communities System
|
* Amsterdam Web Communities System
|
||||||
* Copyright (c) 2025 Erbosoft Metaverse Design Solutions, All Rights Reserved
|
* Copyright (c) 2025-2026 Erbosoft Metaverse Design Solutions, All Rights Reserved
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@@ -66,7 +66,7 @@ const (
|
|||||||
AuditConferenceMembership = 305
|
AuditConferenceMembership = 305
|
||||||
AuditConferenceCreateTopic = 306
|
AuditConferenceCreateTopic = 306
|
||||||
AuditConferenceDeleteTopic = 307
|
AuditConferenceDeleteTopic = 307
|
||||||
AudotConferenceFreezeTopic = 308
|
AuditConferenceFreezeTopic = 308
|
||||||
AuditConferenceArchiveTopic = 309
|
AuditConferenceArchiveTopic = 309
|
||||||
AuditConferencePostMessage = 310
|
AuditConferencePostMessage = 310
|
||||||
AuditConferenceHideMessage = 311
|
AuditConferenceHideMessage = 311
|
||||||
|
|||||||
@@ -129,6 +129,48 @@ func (t *Topic) SetHidden(ctx context.Context, u *User, hidden bool) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetFrozen sets a topic's "frozen" state.
|
||||||
|
func (t *Topic) SetFrozen(ctx context.Context, frozen bool, u *User, ipaddr string) error {
|
||||||
|
var ar *AuditRecord = nil
|
||||||
|
defer func() {
|
||||||
|
AmStoreAudit(ar)
|
||||||
|
}()
|
||||||
|
_, err := amdb.ExecContext(ctx, "UPDATE topics SET frozen = ? WHERE topicid = ?", frozen, t.TopicId)
|
||||||
|
if err == nil {
|
||||||
|
t.Frozen = frozen
|
||||||
|
ar = AmNewAudit(AuditConferenceFreezeTopic, u.Uid, ipaddr, fmt.Sprintf("topic=%d", t.TopicId), fmt.Sprintf("frozen=%t", frozen))
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetArchived sets a topic's "archived" state.
|
||||||
|
func (t *Topic) SetArchived(ctx context.Context, archived bool, u *User, ipaddr string) error {
|
||||||
|
var ar *AuditRecord = nil
|
||||||
|
defer func() {
|
||||||
|
AmStoreAudit(ar)
|
||||||
|
}()
|
||||||
|
_, err := amdb.ExecContext(ctx, "UPDATE topics SET archived = ? WHERE topicid = ?", archived, t.TopicId)
|
||||||
|
if err == nil {
|
||||||
|
t.Archived = archived
|
||||||
|
ar = AmNewAudit(AuditConferenceArchiveTopic, u.Uid, ipaddr, fmt.Sprintf("topic=%d", t.TopicId), fmt.Sprintf("archived=%t", archived))
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSticky sets a topic's "sticky" state.
|
||||||
|
func (t *Topic) SetSticky(ctx context.Context, sticky bool, u *User, ipaddr string) error {
|
||||||
|
var ar *AuditRecord = nil
|
||||||
|
defer func() {
|
||||||
|
AmStoreAudit(ar)
|
||||||
|
}()
|
||||||
|
_, err := amdb.ExecContext(ctx, "UPDATE topics SET sticky = ? where topicid = ?", sticky, t.TopicId)
|
||||||
|
if err == nil {
|
||||||
|
t.Sticky = sticky
|
||||||
|
ar = AmNewAudit(AuditConferenceStickyTopic, u.Uid, ipaddr, fmt.Sprintf("topic=%d", t.TopicId), fmt.Sprintf("sticky=%t", sticky))
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// IsBozo returns true if the specified test UID is filtered for the specified user.
|
// 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) {
|
func (t *Topic) IsBozo(ctx context.Context, u *User, testUid int32) (bool, error) {
|
||||||
if u.IsAnon {
|
if u.IsAnon {
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ _(italicized items can be deferred)_
|
|||||||
- Subscribe to Topic
|
- Subscribe to Topic
|
||||||
- Send invite
|
- Send invite
|
||||||
- ~~Filtered Users (list/remove)~~
|
- ~~Filtered Users (list/remove)~~
|
||||||
- Stick/Unstick
|
- ~~Stick/Unstick~~
|
||||||
- Freeze/Unfreeze
|
- ~~Freeze/Unfreeze~~
|
||||||
- Archive/Unarchive
|
- ~~Archive/Unarchive~~
|
||||||
- Delete
|
- Delete
|
||||||
- ~~Post Scribble~~
|
- ~~Post Scribble~~
|
||||||
- ~~Post Nuke~~
|
- ~~Post Nuke~~
|
||||||
|
|||||||
@@ -107,6 +107,9 @@ func setupEcho() *echo.Echo {
|
|||||||
confGroup.POST("/r/:topic", ui.AmWrap(PostInTopic), ui.SetTopic)
|
confGroup.POST("/r/:topic", ui.AmWrap(PostInTopic), ui.SetTopic)
|
||||||
opsGroup := confGroup.Group("/op/:topic", ui.SetTopic)
|
opsGroup := confGroup.Group("/op/:topic", ui.SetTopic)
|
||||||
opsGroup.GET("/hide", ui.AmWrap(HideTopic))
|
opsGroup.GET("/hide", ui.AmWrap(HideTopic))
|
||||||
|
opsGroup.GET("/freeze", ui.AmWrap(FreezeTopic))
|
||||||
|
opsGroup.GET("/archive", ui.AmWrap(ArchiveTopic))
|
||||||
|
opsGroup.GET("/stick", ui.AmWrap(StickTopic))
|
||||||
opsGroup.GET("/hide/:msg", ui.AmWrap(HideMessage))
|
opsGroup.GET("/hide/:msg", ui.AmWrap(HideMessage))
|
||||||
opsGroup.GET("/scribble/:msg", ui.AmWrap(ScribbleMessage))
|
opsGroup.GET("/scribble/:msg", ui.AmWrap(ScribbleMessage))
|
||||||
opsGroup.GET("/nuke/:msg", ui.AmWrap(NukeMessage))
|
opsGroup.GET("/nuke/:msg", ui.AmWrap(NukeMessage))
|
||||||
|
|||||||
+3
-3
@@ -43,19 +43,19 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2 flex-wrap">
|
<div class="flex gap-2 flex-wrap">
|
||||||
{{ if canStick }}
|
{{ if canStick }}
|
||||||
<a href="/TODO"
|
<a href="{{ topicListLink }}/op/{{ topicNum }}/stick"
|
||||||
class="bg-purple-600 hover:bg-purple-700 text-white px-4 py-2 rounded text-sm font-medium transition-colors">
|
class="bg-purple-600 hover:bg-purple-700 text-white px-4 py-2 rounded text-sm font-medium transition-colors">
|
||||||
{{ if isSticky }}Unstick Topic{{ else }}Stick Topic{{ end }}
|
{{ if isSticky }}Unstick Topic{{ else }}Stick Topic{{ end }}
|
||||||
</a>
|
</a>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ if canFreeze }}
|
{{ if canFreeze }}
|
||||||
<a href="/TODO"
|
<a href="{{ topicListLink }}/op/{{ topicNum }}/freeze"
|
||||||
class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded text-sm font-medium transition-colors">
|
class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded text-sm font-medium transition-colors">
|
||||||
{{ if isFrozen }}Unfreeze Topic{{ else }}Freeze Topic{{ end }}
|
{{ if isFrozen }}Unfreeze Topic{{ else }}Freeze Topic{{ end }}
|
||||||
</a>
|
</a>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ if canArchive }}
|
{{ if canArchive }}
|
||||||
<a href="/TODO"
|
<a href="{{ topicListLink }}/op/{{ topicNum }}/archive"
|
||||||
class="bg-yellow-600 hover:bg-yellow-700 text-white px-4 py-2 rounded text-sm font-medium transition-colors">
|
class="bg-yellow-600 hover:bg-yellow-700 text-white px-4 py-2 rounded text-sm font-medium transition-colors">
|
||||||
{{ if isArchived }}Unarchive Topic{{ else }}Archive Topic{{ end }}
|
{{ if isArchived }}Unarchive Topic{{ else }}Archive Topic{{ end }}
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
Reference in New Issue
Block a user