public_flag.gno
3.24 Kb ยท 119 lines
1package boards2
2
3import (
4 "chain"
5 "chain/runtime"
6 "strconv"
7)
8
9// SetFlaggingThreshold sets the number of flags required to hide a thread or comment.
10//
11// Threshold is only applicable within the board where it's setted.
12func SetFlaggingThreshold(_ realm, boardID BoardID, threshold int) {
13 if threshold < 1 {
14 panic("invalid flagging threshold")
15 }
16
17 assertRealmIsNotLocked()
18
19 board := mustGetBoard(boardID)
20 assertBoardIsNotFrozen(board)
21
22 caller := runtime.PreviousRealm().Address()
23 args := Args{boardID, threshold}
24 board.perms.WithPermission(caller, PermissionBoardFlaggingUpdate, args, func(Args) {
25 assertRealmIsNotLocked()
26
27 board := mustGetBoard(boardID)
28 assertBoardIsNotFrozen(board)
29
30 gFlaggingThresholds.Set(boardID.String(), threshold)
31 chain.Emit(
32 "FlaggingThresholdUpdated",
33 "caller", caller.String(),
34 "boardID", boardID.String(),
35 "threshold", strconv.Itoa(threshold),
36 )
37 })
38}
39
40// GetFlaggingThreshold returns the number of flags required to hide a thread or comment within a board.
41func GetFlaggingThreshold(boardID BoardID) int {
42 assertBoardExists(boardID)
43 return getFlaggingThreshold(boardID)
44}
45
46// FlagThread adds a new flag to a thread.
47//
48// Flagging requires special permissions and hides the thread when
49// the number of flags reaches a pre-defined flagging threshold.
50func FlagThread(_ realm, boardID BoardID, threadID PostID, reason string) {
51 board := mustGetBoard(boardID)
52
53 // Realm owners should be able to flag without permissions even when board is frozen
54 caller := runtime.PreviousRealm().Address()
55 isRealmOwner := gPerms.HasRole(caller, RoleOwner)
56 if !isRealmOwner {
57 assertRealmIsNotLocked()
58 assertBoardIsNotFrozen(board)
59 assertHasPermission(board.perms, caller, PermissionThreadFlag)
60 }
61
62 t, ok := board.GetThread(threadID)
63 if !ok {
64 panic("post doesn't exist")
65 }
66 assertThreadIsNotFrozen(t)
67
68 // Realm owners can hide with a single flag
69 hide := flagItem(t, caller, reason, getFlaggingThreshold(boardID))
70 if hide || isRealmOwner {
71 t.Hidden = true
72 }
73
74 chain.Emit(
75 "ThreadFlagged",
76 "caller", caller.String(),
77 "boardID", boardID.String(),
78 "threadID", threadID.String(),
79 "reason", reason,
80 )
81}
82
83// FlagReply adds a new flag to a comment or reply.
84//
85// Flagging requires special permissions and hides the comment or reply
86// when the number of flags reaches a pre-defined flagging threshold.
87func FlagReply(_ realm, boardID BoardID, threadID, replyID PostID, reason string) {
88 board := mustGetBoard(boardID)
89
90 // Realm owners should be able to flag without permissions even when board is frozen
91 caller := runtime.PreviousRealm().Address()
92 isRealmOwner := gPerms.HasRole(caller, RoleOwner)
93 if !isRealmOwner {
94 assertRealmIsNotLocked()
95 assertBoardIsNotFrozen(board)
96 assertHasPermission(board.perms, caller, PermissionReplyFlag)
97 }
98
99 thread := mustGetThread(board, threadID)
100 assertThreadIsNotFrozen(thread)
101
102 reply := mustGetReply(thread, replyID)
103 assertReplyIsNotFrozen(thread)
104
105 // Realm owners can hide with a single flag
106 hide := flagItem(reply, caller, reason, getFlaggingThreshold(boardID))
107 if hide || isRealmOwner {
108 reply.Hidden = true
109 }
110
111 chain.Emit(
112 "ReplyFlagged",
113 "caller", caller.String(),
114 "boardID", boardID.String(),
115 "threadID", threadID.String(),
116 "replyID", replyID.String(),
117 "reason", reason,
118 )
119}