hub.gno
5.28 Kb · 201 lines
1// The `hub.gno` file exposes safe, read-only views over the realm's
2// persistent state.
3//
4// Note for future maintainers: these reads perform no caller
5// authorization, so do not graft user-identity gating onto them.
6
7package boards2
8
9import (
10 hubexts "gno.land/p/g1gsarxwyhnxfuug3lsys58rcpg7myrgmw3wuc2u/boards/exts/hub"
11 "gno.land/p/gnoland/boards"
12)
13
14// Safe view types are defined in the hub extensions package and
15// re-exported here so callers can keep using them via this realm.
16type (
17 Board = hubexts.Board
18 Comment = hubexts.Comment
19 Flag = hubexts.Flag
20 Member = hubexts.Member
21 Thread = hubexts.Thread
22)
23
24// GetBoard returns a safe board.
25func GetBoard(id uint64) (Board, bool) {
26 b, found := gBoards.Get(boards.ID(id))
27 if !found {
28 return Board{}, false
29 }
30 return hubexts.NewSafeBoard(b), true
31}
32
33// GetThread returns a safe board thread.
34func GetThread(boardID, threadID uint64) (Thread, bool) {
35 t, found := getBoardThread(boardID, threadID)
36 if !found {
37 return Thread{}, false
38 }
39 return hubexts.NewSafeThread(t), true
40}
41
42// GetComment returns a safe thread comment.
43func GetComment(boardID, threadID, commentID uint64) (Comment, bool) {
44 c, found := getComment(boardID, threadID, commentID)
45 if !found {
46 return Comment{}, false
47 }
48 return hubexts.NewSafeComment(c), true
49}
50
51// GetBoards returns a list with all boards.
52// To reverse iterate use a negative count.
53func GetBoards(start, count int) []Board {
54 var boards_ []Board
55 gBoards.Iterate(start, count, func(b *boards.Board) bool {
56 boards_ = append(boards_, hubexts.NewSafeBoard(b))
57 return false
58 })
59 return boards_
60}
61
62// GetThreads returns a list with threads of a board.
63// To reverse iterate use a negative count.
64func GetThreads(boardID uint64, start, count int) []Thread {
65 b, found := gBoards.Get(boards.ID(boardID))
66 if !found {
67 return nil
68 }
69
70 var threads []Thread
71 b.Threads.Iterate(start, count, func(thread *boards.Post) bool {
72 threads = append(threads, hubexts.NewSafeThread(thread))
73 return false
74 })
75 return threads
76}
77
78// GetMembers returns a list with the members of a board.
79// To reverse iterate use a negative count.
80func GetMembers(boardID uint64, start, count int) []Member {
81 b, found := gBoards.Get(boards.ID(boardID))
82 if !found {
83 return nil
84 }
85
86 var members []Member
87 b.Permissions.IterateUsers(start, count, func(u boards.User) bool {
88 var roles []string
89 for _, r := range u.Roles {
90 roles = append(roles, string(r))
91 }
92
93 members = append(members, Member{
94 Address: u.Address,
95 Roles: roles,
96 })
97 return false
98 })
99 return members
100}
101
102// GetReposts returns a list with repost of a board thread.
103// To reverse iterate use a negative count.
104func GetReposts(boardID, threadID uint64, start, count int) []Thread {
105 t, found := getBoardThread(boardID, threadID)
106 if !found {
107 return nil
108 }
109
110 var reposts []Thread
111 t.Reposts.Iterate(start, count, func(rBoardID, rRepostID boards.ID) bool {
112 r, found := getBoardThread(uint64(rBoardID), uint64(rRepostID))
113 if found {
114 reposts = append(reposts, hubexts.NewSafeThread(r))
115 }
116 return false
117 })
118 return reposts
119}
120
121// GetFlags returns a list with thread or comment moderation flags.
122// To reverse iterate use a negative count.
123// Thread flags are returned when `commentID` is zero, or comment flags are returned otherwise.
124func GetFlags(boardID, threadID, commentID uint64, start, count int) []Flag {
125 var storage boards.FlagStorage
126 if commentID == 0 {
127 t, found := getBoardThread(boardID, threadID)
128 if !found {
129 return nil
130 }
131
132 storage = t.Flags
133 } else {
134 c, found := getComment(boardID, threadID, commentID)
135 if !found {
136 return nil
137 }
138
139 storage = c.Flags
140 }
141
142 var flags []Flag
143 storage.Iterate(start, count, func(f boards.Flag) bool {
144 flags = append(flags, hubexts.NewSafeFlag(f))
145 return false
146 })
147 return flags
148}
149
150// GetComments returns a list with all thread comments and replies.
151// To reverse iterate use a negative count.
152// Top level comments can be filtered by checking `Comment.ParentID`, replies
153// always have a parent comment or reply, while comments have no parent.
154func GetComments(boardID, threadID uint64, start, count int) []Comment {
155 t, found := getBoardThread(boardID, threadID)
156 if !found {
157 return nil
158 }
159
160 var comments []Comment
161 t.Replies.Iterate(start, count, func(comment *boards.Post) bool {
162 comments = append(comments, hubexts.NewSafeComment(comment))
163 return false
164 })
165 return comments
166}
167
168// GetReplies returns a list with top level comment replies.
169// To reverse iterate use a negative count.
170func GetReplies(boardID, threadID, commentID uint64, start, count int) []Comment {
171 c, found := getComment(boardID, threadID, commentID)
172 if !found {
173 return nil
174 }
175
176 var replies []Comment
177 c.Replies.Iterate(start, count, func(comment *boards.Post) bool {
178 replies = append(replies, hubexts.NewSafeComment(comment))
179 return false
180 })
181 return replies
182}
183
184// getBoardThread returns a board thread from their IDs.
185func getBoardThread(boardID, threadID uint64) (*boards.Post, bool) {
186 b, found := gBoards.Get(boards.ID(boardID))
187 if !found {
188 return nil, false
189 }
190 return getThread(b, boards.ID(threadID))
191}
192
193// getComment returns a thread comment from their IDs.
194func getComment(boardID, threadID, commentID uint64) (*boards.Post, bool) {
195 t, found := getBoardThread(boardID, threadID)
196 if !found {
197 return nil, false
198 }
199
200 return t.Replies.Get(boards.ID(commentID))
201}