Search Apps Documentation Source Content File Folder Download Copy Actions Download

public_flag.gno

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