package boards2
import (
"strings"
"gno.land/p/gnoland/boards"
"gno.land/p/jeronimoalbi/mdform"
"gno.land/p/jeronimoalbi/pager"
"gno.land/p/moul/md"
"gno.land/p/nt/mdalert/v0"
"gno.land/p/nt/mux/v0"
)
func renderBoard(res *mux.ResponseWriter, req *mux.Request) {
name := req.GetVar("board")
board, found := gBoards.GetByName(name)
if !found {
res.Write(md.H3("The board you are looking for does not exist"))
res.Write("Do you want to " + md.Link("create a new board", createBoardURI) + "?")
return
}
creatorLink := userLink(board.Creator)
date := board.CreatedAt.Format(dateFormat)
res.Write(md.H1(md.Link("Boards", gRealmPath) + " › " + board.Name))
if board.Readonly {
res.Write(
mdalert.Warning("Info", "Creating new threads and commenting are disabled within this board") + "\n",
)
}
res.Write("Created by " + creatorLink + " on " + date + ", #" + board.ID.String())
res.Write(" \n" + renderBoardMenu(board, req))
res.Write(md.HorizontalRule())
if board.Threads.Size() == 0 {
res.Write(md.H3("This board doesn't have any threads"))
if !board.Readonly {
startConversationLink := md.Link("start a new conversation", makeCreateThreadURI(board))
res.Write("Do you want to " + startConversationLink + " in this board?")
}
return
}
p, err := pager.New(req.RawPath, board.Threads.Size(), pager.WithPageSize(pageSizeDefault))
if err != nil {
panic(err)
}
render := func(thread *boards.Post) bool {
res.Write(renderThreadSummary(thread) + "\n")
return false
}
res.Write("Sort by: ")
r := parseRealmPath(req.RawPath)
sortOrder := r.Query.Get("order")
if sortOrder == "desc" {
r.Query.Set("order", "asc")
res.Write(md.Link("newest first", r.String()) + "\n\n")
} else {
r.Query.Set("order", "desc")
res.Write(md.Link("oldest first", r.String()) + "\n\n")
}
count := p.PageSize()
if sortOrder == "desc" {
count = -count // Reverse iterate
}
board.Threads.Iterate(p.Offset(), count, render)
if p.HasPages() {
res.Write(md.HorizontalRule())
res.Write(pager.Picker(p))
}
}
// renderSubMenu renders a sub-menu with a distinct visual pattern.
func renderSubMenu(items []string) string {
if len(items) == 0 {
return ""
}
return "└─ " + strings.Join(items, " • ") + "\n"
}
func renderBoardMenu(board *boards.Board, req *mux.Request) string {
var (
b strings.Builder
boardMembersURL = makeBoardURI(board) + "/members"
)
if board.Readonly {
b.WriteString(md.Link("List Members", boardMembersURL))
b.WriteString(" • ")
b.WriteString(md.Link("Unfreeze Board", makeUnfreezeBoardURI(board)))
b.WriteString("\n")
} else {
b.WriteString("↳ ")
b.WriteString(md.Link("Create Thread", makeCreateThreadURI(board)))
b.WriteString(" • ")
b.WriteString(md.Link("Request Invite", makeRequestInviteURI(board)))
b.WriteString(" • ")
menu := getCurrentMenu(req.RawPath)
if menu == menuManageBoard {
b.WriteString(md.Bold("Manage Board"))
} else {
b.WriteString(md.Link("Manage Board", menuURL(menuManageBoard)))
}
b.WriteString(" \n")
if menu == menuManageBoard {
subMenuItems := []string{
md.Link("Invite Member", makeInviteMemberURI(board)),
md.Link("List Invite Requests", makeBoardURI(board)+"/invites"),
md.Link("List Members", boardMembersURL),
md.Link("List Banned Users", makeBoardURI(board)+"/banned-users"),
md.Link("Freeze Board", makeFreezeBoardURI(board)),
}
b.WriteString(renderSubMenu(subMenuItems))
}
}
b.WriteString("\n")
return b.String()
}
func renderInviteMember(res *mux.ResponseWriter, req *mux.Request) {
name := req.GetVar("board")
board, found := gBoards.GetByName(name)
if !found {
res.Write("Board not found")
return
}
form := mdform.New("exec", "InviteMember")
form.Input(
"boardID",
"placeholder", "Board ID",
"value", board.ID.String(),
"readonly", "true",
)
form.Input(
"user",
"placeholder", "Address",
"required", "true",
)
form.Select(
"role",
string(RoleOwner),
)
form.Select(
"role",
string(RoleAdmin),
)
form.Select(
"role",
string(RoleModerator),
)
form.Select(
"role",
string(RoleGuest),
"selected", "true",
)
res.Write(md.H1(board.Name + ": Invite Member"))
res.Write(
md.Paragraph(
"Both open and invite only boards can have multiple members with different roles within a "+
"board, where members can have a single role at a time.",
) +
md.Paragraph(
"Boards are independent communities which could apply different permissions per role than "+
"other boards, but generally Boards2 supports four roles, _owner_, _admin_, _moderator_ "+
"and _guest_.",
) +
md.Paragraph(
"Member will be added to "+md.Link(board.Name, makeBoardURI(board))+" board.",
),
)
res.Write(form.String())
}