boards.gno
3.33 Kb ยท 122 lines
1package boards2
2
3import (
4 "chain/runtime"
5
6 "gno.land/p/gnoland/boards"
7 "gno.land/p/moul/realmpath"
8 "gno.land/p/moul/txlink"
9 "gno.land/p/nt/avl"
10)
11
12// TODO: Refactor globals in favor of a cleaner pattern
13var (
14 gRealmLink txlink.Realm
15 gNotice string
16 gHelp string
17 gListedBoardsByID avl.Tree // string(id) -> *boards.Board
18 gInviteRequests avl.Tree // string(board id) -> *avl.Tree(address -> time.Time)
19 gBannedUsers avl.Tree // string(board id) -> *avl.Tree(address -> time.Time)
20 gLocked struct {
21 realm bool
22 realmMembers bool
23 }
24)
25
26var (
27 gBoards = boards.NewStorage()
28 gBoardsSequence = boards.NewIdentifierGenerator()
29 gPerms = initRealmPermissions(
30 "g16jpf0puufcpcjkph5nxueec8etpcldz7zwgydq", // @devx
31 "g1manfred47kzduec920z88wfr64ylksmdcedlf5", // @moul
32 )
33)
34
35func init() {
36 // Save current realm path so it's available during render calls
37 gRealmLink = txlink.Realm(runtime.CurrentRealm().PkgPath())
38}
39
40// initRealmPermissions returns the default realm permissions.
41func initRealmPermissions(owners ...address) boards.Permissions {
42 perms := NewBasicPermissions()
43 perms.SetSuperRole(RoleOwner)
44 perms.AddRole(RoleAdmin, PermissionBoardCreate)
45 for _, owner := range owners {
46 perms.SetUserRoles(cross, owner, RoleOwner)
47 }
48
49 perms.ValidateFunc(PermissionBoardCreate, validateBoardCreate)
50 perms.ValidateFunc(PermissionMemberInvite, validateMemberInvite)
51 perms.ValidateFunc(PermissionRoleChange, validateRoleChange)
52 return perms
53}
54
55// getInvitesRequests returns invite requests for a board.
56func getInviteRequests(boardID boards.ID) (_ *avl.Tree, found bool) {
57 v, exists := gInviteRequests.Get(boardID.Key())
58 if !exists {
59 return nil, false
60 }
61 return v.(*avl.Tree), true
62}
63
64// getBannedUsers returns banned users within a board.
65func getBannedUsers(boardID boards.ID) (_ *avl.Tree, found bool) {
66 v, exists := gBannedUsers.Get(boardID.Key())
67 if !exists {
68 return nil, false
69 }
70 return v.(*avl.Tree), true
71}
72
73// mustGetBoardByName returns a board or panics when it's not found.
74func mustGetBoardByName(name string) *boards.Board {
75 board, found := gBoards.GetByName(name)
76 if !found {
77 panic("board does not exist with name: " + name)
78 }
79 return board
80}
81
82// mustGetBoard returns a board or panics when it's not found.
83func mustGetBoard(id boards.ID) *boards.Board {
84 board, found := gBoards.Get(id)
85 if !found {
86 panic("board does not exist with ID: " + id.String())
87 }
88 return board
89}
90
91// mustGetThread returns a thread or panics when it's not found.
92func mustGetThread(board *boards.Board, threadID boards.ID) *boards.Post {
93 thread, found := board.Threads.Get(threadID)
94 if !found {
95 panic("thread does not exist with ID: " + threadID.String())
96 }
97 return thread
98}
99
100// mustGetReply returns a reply or panics when it's not found.
101func mustGetReply(thread *boards.Post, replyID boards.ID) *boards.Post {
102 reply, found := thread.Replies.Get(replyID)
103 if !found {
104 panic("reply does not exist with ID: " + replyID.String())
105 }
106 return reply
107}
108
109func mustGetPermissions(bid boards.ID) boards.Permissions {
110 if bid != 0 {
111 board := mustGetBoard(bid)
112 return board.Permissions
113 }
114 return gPerms
115}
116
117func parseRealmPath(path string) *realmpath.Request {
118 // Make sure request is using current realm path so paths can be parsed during Render
119 r := realmpath.Parse(path)
120 r.Realm = string(gRealmLink)
121 return r
122}