Search Apps Documentation Source Content File Folder Download Copy Actions Download

public_flag.gno

3.61 Kb ยท 138 lines
  1package boards2
  2
  3import (
  4	"chain"
  5	"chain/runtime"
  6	"strconv"
  7
  8	"gno.land/p/gnoland/boards"
  9)
 10
 11// SetFlaggingThreshold sets the number of flags required to hide a thread or comment.
 12//
 13// Threshold is only applicable within the board where it's setted.
 14func SetFlaggingThreshold(_ realm, boardID boards.ID, threshold int) {
 15	if threshold < 1 {
 16		panic("invalid flagging threshold")
 17	}
 18
 19	assertRealmIsNotLocked()
 20
 21	board := mustGetBoard(boardID)
 22	assertBoardIsNotFrozen(board)
 23
 24	caller := runtime.PreviousRealm().Address()
 25	args := boards.Args{board.ID, threshold}
 26	board.Permissions.WithPermission(cross, caller, PermissionBoardFlaggingUpdate, args, func(realm) {
 27		assertRealmIsNotLocked()
 28
 29		gFlaggingThresholds.Set(boardID.String(), threshold)
 30
 31		chain.Emit(
 32			"FlaggingThresholdUpdated",
 33			"caller", caller.String(),
 34			"boardID", board.ID.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 boards.ID) 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, threadID boards.ID, reason string) {
 51	caller := runtime.PreviousRealm().Address()
 52	board := mustGetBoard(boardID)
 53	isRealmOwner := gPerms.HasRole(caller, RoleOwner)
 54	if !isRealmOwner {
 55		assertRealmIsNotLocked()
 56		assertBoardIsNotFrozen(board)
 57	}
 58
 59	thread, found := board.Threads.Get(threadID)
 60	if !found {
 61		panic("thread not found")
 62	}
 63
 64	assertThreadIsNotFrozen(thread)
 65
 66	flagThread := func() {
 67		hide := flagItem(thread, caller, reason, getFlaggingThreshold(board.ID))
 68		if hide || isRealmOwner {
 69			// Realm owners can hide with a single flag
 70			thread.Hidden = true
 71		}
 72
 73		chain.Emit(
 74			"ThreadFlagged",
 75			"caller", caller.String(),
 76			"boardID", board.ID.String(),
 77			"threadID", thread.ID.String(),
 78			"reason", reason,
 79		)
 80	}
 81
 82	// Realm owners should be able to flag without permissions even when board is frozen
 83	if isRealmOwner {
 84		flagThread()
 85		return
 86	}
 87
 88	args := boards.Args{caller, board.ID, thread.ID, reason}
 89	board.Permissions.WithPermission(cross, caller, PermissionThreadFlag, args, func(realm) {
 90		flagThread()
 91	})
 92}
 93
 94// FlagReply adds a new flag to a comment or reply.
 95//
 96// Flagging requires special permissions and hides the comment or reply
 97// when the number of flags reaches a pre-defined flagging threshold.
 98func FlagReply(_ realm, boardID, threadID, replyID boards.ID, reason string) {
 99	caller := runtime.PreviousRealm().Address()
100	board := mustGetBoard(boardID)
101	isRealmOwner := gPerms.HasRole(caller, RoleOwner)
102	if !isRealmOwner {
103		assertRealmIsNotLocked()
104		assertBoardIsNotFrozen(board)
105	}
106
107	thread := mustGetThread(board, threadID)
108	assertThreadIsNotFrozen(thread)
109
110	reply := mustGetReply(thread, replyID)
111	flagReply := func() {
112		hide := flagItem(reply, caller, reason, getFlaggingThreshold(board.ID))
113		if hide || isRealmOwner {
114			// Realm owners can hide with a single flag
115			reply.Hidden = true
116		}
117
118		chain.Emit(
119			"ReplyFlagged",
120			"caller", caller.String(),
121			"boardID", board.ID.String(),
122			"threadID", thread.ID.String(),
123			"replyID", reply.ID.String(),
124			"reason", reason,
125		)
126	}
127
128	// Realm owners should be able to flag without permissions even when board is frozen
129	if isRealmOwner {
130		flagReply()
131		return
132	}
133
134	args := boards.Args{caller, board.ID, thread.ID, reply.ID, reason}
135	board.Permissions.WithPermission(cross, caller, PermissionReplyFlag, args, func(realm) {
136		flagReply()
137	})
138}