Search Apps Documentation Source Content File Folder Download Copy Actions Download

render_board.gno

4.42 Kb · 176 lines
  1package boards2
  2
  3import (
  4	"strings"
  5
  6	"gno.land/p/gnoland/boards"
  7	"gno.land/p/jeronimoalbi/mdform"
  8	"gno.land/p/jeronimoalbi/pager"
  9	"gno.land/p/moul/md"
 10	"gno.land/p/nt/mdalert/v0"
 11	"gno.land/p/nt/mux/v0"
 12)
 13
 14func renderBoard(res *mux.ResponseWriter, req *mux.Request) {
 15	name := req.GetVar("board")
 16	board, found := gBoards.GetByName(name)
 17	if !found {
 18		res.Write(md.H3("The board you are looking for does not exist"))
 19		res.Write("Do you want to " + md.Link("create a new board", createBoardURI) + "?")
 20		return
 21	}
 22
 23	creatorLink := userLink(board.Creator)
 24	date := board.CreatedAt.Format(dateFormat)
 25
 26	res.Write(md.H1(md.Link("Boards", gRealmPath) + " › " + board.Name))
 27	if board.Readonly {
 28		res.Write(
 29			mdalert.Warning("Info", "Creating new threads and commenting are disabled within this board") + "\n",
 30		)
 31	}
 32
 33	res.Write("Created by " + creatorLink + " on " + date + ", #" + board.ID.String())
 34	res.Write("  \n" + renderBoardMenu(board, req))
 35	res.Write(md.HorizontalRule())
 36
 37	if board.Threads.Size() == 0 {
 38		res.Write(md.H3("This board doesn't have any threads"))
 39		if !board.Readonly {
 40			startConversationLink := md.Link("start a new conversation", makeCreateThreadURI(board))
 41			res.Write("Do you want to " + startConversationLink + " in this board?")
 42		}
 43		return
 44	}
 45
 46	p := newClampedPager(req.RawPath, board.Threads.Size(), pageSizeDefault)
 47
 48	render := func(thread *boards.Post) bool {
 49		res.Write(renderThreadSummary(thread) + "\n")
 50		return false
 51	}
 52
 53	res.Write("Sort by: ")
 54
 55	link, desc := sortToggleLink(req.RawPath)
 56	res.Write(link + "\n\n")
 57
 58	count := p.PageSize()
 59	if desc {
 60		count = -count // Reverse iterate
 61	}
 62
 63	board.Threads.Iterate(p.Offset(), count, render)
 64
 65	if p.HasPages() {
 66		res.Write(md.HorizontalRule())
 67		res.Write(pager.Picker(p))
 68	}
 69}
 70
 71// renderSubMenu renders a sub-menu with a distinct visual pattern.
 72func renderSubMenu(items []string) string {
 73	if len(items) == 0 {
 74		return ""
 75	}
 76	return "└─ " + strings.Join(items, " • ") + "\n"
 77}
 78
 79func renderBoardMenu(board *boards.Board, req *mux.Request) string {
 80	var (
 81		b               strings.Builder
 82		boardMembersURL = makeBoardURI(board) + "/members"
 83	)
 84
 85	if board.Readonly {
 86		b.WriteString(md.Link("List Members", boardMembersURL))
 87		b.WriteString(" • ")
 88		b.WriteString(md.Link("Unfreeze Board", makeUnfreezeBoardURI(board)))
 89		b.WriteString("\n")
 90	} else {
 91		b.WriteString("↳ ")
 92		b.WriteString(md.Link("Create Thread", makeCreateThreadURI(board)))
 93		b.WriteString(" • ")
 94		b.WriteString(md.Link("Request Invite", makeRequestInviteURI(board)))
 95		b.WriteString(" • ")
 96
 97		menu := getCurrentMenu(req.RawPath)
 98		if menu == menuManageBoard {
 99			b.WriteString(md.Bold("Manage Board"))
100		} else {
101			b.WriteString(md.Link("Manage Board", menuURL(menuManageBoard)))
102		}
103
104		b.WriteString("  \n")
105
106		if menu == menuManageBoard {
107			subMenuItems := []string{
108				md.Link("Invite Member", makeInviteMemberURI(board)),
109				md.Link("List Invite Requests", makeBoardURI(board)+"/invites"),
110				md.Link("List Members", boardMembersURL),
111				md.Link("List Banned Users", makeBoardURI(board)+"/banned-users"),
112				md.Link("Freeze Board", makeFreezeBoardURI(board)),
113			}
114			b.WriteString(renderSubMenu(subMenuItems))
115		}
116	}
117
118	b.WriteString("\n")
119	return b.String()
120}
121
122func renderInviteMember(res *mux.ResponseWriter, req *mux.Request) {
123	name := req.GetVar("board")
124	board, found := gBoards.GetByName(name)
125	if !found {
126		res.Write("Board not found")
127		return
128	}
129
130	form := mdform.New("exec", "InviteMember")
131	form.Input(
132		"boardID",
133		"placeholder", "Board ID",
134		"value", board.ID.String(),
135		"readonly", "true",
136	)
137	form.Input(
138		"user",
139		"placeholder", "Address",
140		"required", "true",
141	)
142	form.Select(
143		"role",
144		string(RoleOwner),
145	)
146	form.Select(
147		"role",
148		string(RoleAdmin),
149	)
150	form.Select(
151		"role",
152		string(RoleModerator),
153	)
154	form.Select(
155		"role",
156		string(RoleGuest),
157		"selected", "true",
158	)
159
160	res.Write(md.H1(board.Name + ": Invite Member"))
161	res.Write(
162		md.Paragraph(
163			"Both open and invite only boards can have multiple members with different roles within a "+
164				"board, where members can have a single role at a time.",
165		) +
166			md.Paragraph(
167				"Boards are independent communities which could apply different permissions per role than "+
168					"other boards, but generally Boards2 supports four roles, _owner_, _admin_, _moderator_ "+
169					"and _guest_.",
170			) +
171			md.Paragraph(
172				"Member will be added to "+md.Link(board.Name, makeBoardURI(board))+" board.",
173			),
174	)
175	res.Write(form.String())
176}