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}