public_flag.gno

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