Skip to content

Commit

Permalink
feat(boards2): add core flagging logic
Browse files Browse the repository at this point in the history
  • Loading branch information
x1unix committed Dec 19, 2024
1 parent 251a107 commit 88a7e5c
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 3 deletions.
47 changes: 47 additions & 0 deletions examples/gno.land/r/demo/boards2/flag.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package boards2

import (
"std"
"strconv"
)

var flagThreshold = 3

type Flag struct {
User std.Address
Reason string
}

func NewFlag(creator std.Address, reason string) Flag {
return Flag{
User: creator,
Reason: reason,
}
}

type Flaggable interface {
// AddFlag adds a new flag to an entry.
//
// Returns false if item was already flagged by user.
AddFlag(flag Flag) bool

// FlagsCount returns number of times entry was flagged.
FlagsCount() int
}

// flagItem adds a flag to a flaggable item (post, thread, etc).
//
// Returns whether flag count threshold is reached and item can be hidden.
//
// Panics if flag count threshold was already reached.
func flagItem(item Flaggable, flag Flag) bool {
if item.FlagsCount() >= flagThreshold {
panic("item flag count threshold exceeded: " + strconv.Itoa(flagThreshold))
}

if !item.AddFlag(flag) {
panic("item has been already flagged by a user")
}

return item.FlagsCount() == flagThreshold
}
2 changes: 2 additions & 0 deletions examples/gno.land/r/demo/boards2/permission.gno
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ const (
PermissionThreadCreate = "thread:create"
PermissionThreadEdit = "thread:edit"
PermissionThreadDelete = "thread:delete"
PermissionThreadFlag = "thread:flag"
PermissionThreadRepost = "thread:repost"
PermissionReplyDelete = "reply:delete"
PermissionReplyFlag = "reply:flag"
PermissionMemberInvite = "member:invite"
PermissionMemberRemove = "member:remove"
)
Expand Down
32 changes: 29 additions & 3 deletions examples/gno.land/r/demo/boards2/post.gno
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@ type Post struct {
creator std.Address
title string // optional
body string
isHidden bool
replies avl.Tree // Post.id -> *Post
repliesAll avl.Tree // Post.id -> *Post (all replies, for top-level posts)
reposts avl.Tree // Board.id -> Post.id
threadID PostID // original Post.id
parentID PostID // parent Post.id (if reply or repost)
repostBoardID BoardID // original Board.id (if repost)
flags []Flag
threadID PostID // original Post.id
parentID PostID // parent Post.id (if reply or repost)
repostBoardID BoardID // original Board.id (if repost)
createdAt time.Time
updatedAt time.Time
}
Expand Down Expand Up @@ -97,6 +99,30 @@ func (post *Post) GetUpdatedAt() time.Time {
return post.updatedAt
}

func (post *Post) AddFlag(flag Flag) bool {
// TODO: sort flags for fast search in case of big thresholds
for _, v := range post.flags {
if v.User == flag.User {
return false
}
}

post.flags = append(post.flags, flag)
return true
}

func (post *Post) FlagsCount() int {
return len(post.flags)
}

func (post *Post) SetVisibility(isVisible bool) {
post.isHidden = !isVisible
}

func (post *Post) Hidden() bool {
return post.isHidden
}

func (post *Post) AddReply(creator std.Address, body string) *Post {
board := post.board
pid := board.incGetPostID()
Expand Down
28 changes: 28 additions & 0 deletions examples/gno.land/r/demo/boards2/public.gno
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,21 @@ func CreateBoard(name string) BoardID {
return id
}

func FlagThread(bid BoardID, postID PostID, reason string) {
caller := std.GetOrigCaller()
assertHasPermission(caller, PermissionThreadFlag)

board := mustGetBoard(bid)
t, ok := board.GetThread(postID)
if !ok {
panic("post doesn't exist")
}

if flagItem(t, NewFlag(caller, reason)) {
t.SetVisibility(false)
}
}

func CreateThread(bid BoardID, title, body string) PostID {
assertIsUserCall()

Expand Down Expand Up @@ -75,6 +90,19 @@ func CreateReply(bid BoardID, threadID, replyID PostID, body string) PostID {
return reply.id
}

func FlagReply(bid BoardID, threadID, replyID PostID, reason string) {
caller := std.GetOrigCaller()
assertHasPermission(caller, PermissionThreadFlag)

board := mustGetBoard(bid)
thread := mustGetThread(board, threadID)
reply := mustGetReply(thread, replyID)

if flagItem(reply, NewFlag(caller, reason)) {
reply.SetVisibility(false)
}
}

func CreateRepost(bid BoardID, threadID PostID, title, body string, dstBoardID BoardID) PostID {
assertIsUserCall()

Expand Down

0 comments on commit 88a7e5c

Please sign in to comment.