package boards2
import (
"chain/runtime"
"strings"
"gno.land/p/gnoland/boards"
"gno.land/p/gnoland/boards/exts/permissions"
"gno.land/p/moul/realmpath"
"gno.land/p/moul/txlink"
"gno.land/p/nt/avl/v0"
)
// TODO: Refactor globals in favor of a cleaner pattern
var (
gRealmLink txlink.Realm
gNotice string
gHelp string
gListedBoardsByID avl.Tree // string(id) -> *boards.Board
gInviteRequests avl.Tree // string(board id) -> *avl.Tree(address -> time.Time)
gBannedUsers avl.Tree // string(board id) -> *avl.Tree(address -> time.Time)
gLocked struct {
realm bool
realmMembers bool
}
)
var (
gBoards = boards.NewStorage()
gBoardsSequence = boards.NewIdentifierGenerator()
gRealmPath = strings.TrimPrefix(runtime.CurrentRealm().PkgPath(), "gno.land")
gPerms = initRealmPermissions(
"g16jpf0puufcpcjkph5nxueec8etpcldz7zwgydq",
"g1rp7cmetn27eqlpjpc4vuusf8kaj746tysc0qgh", // govdao t1 multisig
)
// TODO: Allow updating open account amount though a proposal (GovDAO, CommonDAO?)
gOpenAccountAmount = int64(3_000_000_000) // ugnot required for open board actions
)
func init() {
// Save current realm path so it's available during render calls
gRealmLink = txlink.Realm(runtime.CurrentRealm().PkgPath())
}
// initRealmPermissions returns the default realm permissions.
func initRealmPermissions(owners ...address) boards.Permissions {
perms := permissions.New(
permissions.UseSingleUserRole(),
permissions.WithSuperRole(RoleOwner),
)
perms.AddRole(RoleAdmin, PermissionBoardCreate)
for _, owner := range owners {
perms.SetUserRoles(owner, RoleOwner)
}
perms.ValidateFunc(PermissionBoardCreate, validateBasicBoardCreate)
perms.ValidateFunc(PermissionMemberInvite, validateBasicMemberInvite)
perms.ValidateFunc(PermissionRoleChange, validateBasicRoleChange)
return perms
}
// getInviteRequests returns invite requests for a board.
func getInviteRequests(boardID boards.ID) (_ *avl.Tree, found bool) {
v, exists := gInviteRequests.Get(boardID.Key())
if !exists {
return nil, false
}
return v.(*avl.Tree), true
}
// getBannedUsers returns banned users within a board.
func getBannedUsers(boardID boards.ID) (_ *avl.Tree, found bool) {
v, exists := gBannedUsers.Get(boardID.Key())
if !exists {
return nil, false
}
return v.(*avl.Tree), true
}
// mustGetBoardByName returns a board or panics when it's not found.
func mustGetBoardByName(name string) *boards.Board {
board, found := gBoards.GetByName(name)
if !found {
panic("board does not exist with name: " + name)
}
return board
}
// mustGetBoard returns a board or panics when it's not found.
func mustGetBoard(id boards.ID) *boards.Board {
board, found := gBoards.Get(id)
if !found {
panic("board does not exist with ID: " + id.String())
}
return board
}
// getThread returns a board thread.
func getThread(board *boards.Board, threadID boards.ID) (*boards.Post, bool) {
thread, found := board.Threads.Get(threadID)
if !found {
// When thread is not found search it within hidden threads
meta := board.Meta.(*BoardMeta)
thread, found = meta.HiddenThreads.Get(threadID)
}
return thread, found
}
// getReply returns a thread comment or reply.
func getReply(thread *boards.Post, replyID boards.ID) (*boards.Post, bool) {
meta := thread.Meta.(*ThreadMeta)
return meta.AllReplies.Get(replyID)
}
// mustGetThread returns a thread or panics when it's not found.
func mustGetThread(board *boards.Board, threadID boards.ID) *boards.Post {
thread, found := getThread(board, threadID)
if !found {
panic("thread does not exist with ID: " + threadID.String())
}
return thread
}
// mustGetReply returns a reply or panics when it's not found.
func mustGetReply(thread *boards.Post, replyID boards.ID) *boards.Post {
reply, found := getReply(thread, replyID)
if !found {
panic("reply does not exist with ID: " + replyID.String())
}
return reply
}
func mustGetPermissions(bid boards.ID) boards.Permissions {
if bid != 0 {
board := mustGetBoard(bid)
return board.Permissions
}
return gPerms
}
func parseRealmPath(path string) *realmpath.Request {
// Make sure request is using current realm path so paths can be parsed during Render
r := realmpath.Parse(path)
r.Realm = string(gRealmLink)
return r
}