boards.gno
3.90 Kb ยท 143 lines
1package boards2
2
3import (
4 "chain/runtime"
5 "strings"
6
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 gPerms Permissions
15 gRealmLink txlink.Realm
16 gNotice string
17 gHelp string
18 gLastReservedID BoardID
19 gBoardsByID avl.Tree // string(id) -> *Board
20 gListedBoardsByID avl.Tree // string(id) -> *Board
21 gBoardsByName avl.Tree // string(lowercase name) -> *Board
22 gInviteRequests avl.Tree // string(board id) -> *avl.Tree(address -> time.Time)
23 gBannedUsers avl.Tree // string(board id) -> *avl.Tree(address -> time.Time)
24 gLocked struct {
25 realm bool
26 realmMembers bool
27 }
28)
29
30func init() {
31 // Save current realm path so it's available during render calls
32 gRealmLink = txlink.Realm(runtime.CurrentRealm().PkgPath())
33
34 // Initialize default realm permissions
35 gPerms = initRealmPermissions(
36 "g16jpf0puufcpcjkph5nxueec8etpcldz7zwgydq", // @devx
37 "g1manfred47kzduec920z88wfr64ylksmdcedlf5", // @moul
38 "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", // @test1
39 )
40}
41
42// initRealmPermissions returns the default realm permissions.
43func initRealmPermissions(owners ...address) *BasicPermissions {
44 perms := createBasicPermissions(owners...)
45 perms.ValidateFunc(PermissionBoardCreate, validateBoardCreate)
46 perms.ValidateFunc(PermissionMemberInvite, validateMemberInvite)
47 perms.ValidateFunc(PermissionRoleChange, validateRoleChange)
48 return perms
49}
50
51// reserveBoardID returns a new board ID which won't be used by another board.
52// Reserving IDs is necessary because boards can be created asynchronically.
53func reserveBoardID() BoardID {
54 gLastReservedID++
55 return gLastReservedID
56}
57
58// getBoard returns a board for a specific ID.
59func getBoard(id BoardID) (_ *Board, found bool) {
60 v, exists := gBoardsByID.Get(id.Key())
61 if !exists {
62 return nil, false
63 }
64 return v.(*Board), true
65}
66
67// getInvitesRequests returns invite requests for a board.
68func getInviteRequests(boardID BoardID) (_ *avl.Tree, found bool) {
69 v, exists := gInviteRequests.Get(boardID.Key())
70 if !exists {
71 return nil, false
72 }
73 return v.(*avl.Tree), true
74}
75
76// getBannedUsers returns banned users within a board.
77func getBannedUsers(boardID BoardID) (_ *avl.Tree, found bool) {
78 v, exists := gBannedUsers.Get(boardID.Key())
79 if !exists {
80 return nil, false
81 }
82 return v.(*avl.Tree), true
83}
84
85// getBoardByName returns a board that matches a name.
86func getBoardByName(name string) (_ *Board, found bool) {
87 name = strings.ToLower(name)
88 if v, found := gBoardsByName.Get(name); found {
89 return v.(*Board), true
90 }
91 return nil, false
92}
93
94// mustGetBoardByName returns a board or panics when it's not found.
95func mustGetBoardByName(name string) *Board {
96 board, found := getBoardByName(name)
97 if !found {
98 panic("board does not exist with name: " + name)
99 }
100 return board
101}
102
103// mustGetBoard returns a board or panics when it's not found.
104func mustGetBoard(id BoardID) *Board {
105 board, found := getBoard(id)
106 if !found {
107 panic("board does not exist with ID: " + id.String())
108 }
109 return board
110}
111
112// mustGetThread returns a thread or panics when it's not found.
113func mustGetThread(board *Board, threadID PostID) *Post {
114 thread, found := board.GetThread(threadID)
115 if !found {
116 panic("thread does not exist with ID: " + threadID.String())
117 }
118 return thread
119}
120
121// mustGetReply returns a reply or panics when it's not found.
122func mustGetReply(thread *Post, replyID PostID) *Post {
123 reply, found := thread.GetReply(replyID)
124 if !found {
125 panic("reply does not exist with ID: " + replyID.String())
126 }
127 return reply
128}
129
130func mustGetPermissions(bid BoardID) Permissions {
131 if bid != 0 {
132 board := mustGetBoard(bid)
133 return board.perms
134 }
135 return gPerms
136}
137
138func parseRealmPath(path string) *realmpath.Request {
139 // Make sure request is using current realm path so paths can be parsed during Render
140 r := realmpath.Parse(path)
141 r.Realm = string(gRealmLink)
142 return r
143}