simpleadmin-web/internal/web/site.go

89 lines
2.7 KiB
Go

package web
import (
"encoding/json"
"fmt"
"os"
"strings"
)
// Site holds display settings SimpleAdmin has no place for: rank labels, colours and the plain
// descriptions on the public staff page. Ranks are keyed by SimpleAdmin group name.
type Site struct {
Title string `json:"title"`
Ranks map[string]Rank `json:"ranks"`
}
type Rank struct {
Label string `json:"label"`
Color string `json:"color"`
About string `json:"about"`
// Supporter ranks (VIPs) are listed apart from staff and don't count as staff online.
Supporter bool `json:"supporter"`
}
func defaultSite() Site {
return Site{
Title: "zio.sh",
Ranks: map[string]Rank{
"#rank/owner": {Label: "Owner", Color: "#fe113d", About: "Runs the server."},
"#rank/senioradmin": {Label: "Senior admin", Color: "#ff7a45", About: "Manages the staff team and server settings."},
"#rank/admin": {Label: "Admin", Color: "#f0a63a", About: "Handles appeals and longer bans."},
"#rank/trialadmin": {Label: "Trial admin", Color: "#e8d25a", About: "Admins on trial."},
"#rank/mod": {Label: "Moderator", Color: "#37c58f", About: "Keeps matches fair. Can kick, gag and issue short bans."},
"#rank/trialmod": {Label: "Trial mod", Color: "#4fb3d9", About: "Moderators on trial."},
"#rank/helper": {Label: "Helper", Color: "#7c8cf5", About: "Answers questions and handles chat."},
"#rank/guardian": {Label: "Guardian", Color: "#c77dff", About: "Supporters of the server. Not staff, and can't punish anyone.", Supporter: true},
},
}
}
func loadSite(path string) (Site, error) {
s := defaultSite()
if path == "" {
return s, nil
}
data, err := os.ReadFile(path)
if err != nil {
return s, err
}
var file Site
if err := json.Unmarshal(data, &file); err != nil {
return s, fmt.Errorf("%s: %w", path, err)
}
if file.Title != "" {
s.Title = file.Title
}
if file.Ranks != nil {
s.Ranks = file.Ranks
}
return s, nil
}
var fallbackColors = []string{"#7c8cf5", "#4fb3d9", "#37c58f", "#e8d25a", "#f0a63a", "#ff7a45", "#c77dff"}
// rank returns display settings for a group, deriving a label ("#rank/mod" -> "Mod") and a colour
// for groups the site config doesn't list.
func (s Site) rank(group string, index int) Rank {
if r, ok := s.Ranks[group]; ok {
if r.Label == "" {
r.Label = defaultLabel(group)
}
if r.Color == "" {
r.Color = fallbackColors[index%len(fallbackColors)]
}
return r
}
return Rank{Label: defaultLabel(group), Color: fallbackColors[index%len(fallbackColors)]}
}
func defaultLabel(group string) string {
name := strings.TrimPrefix(group, "#")
if i := strings.LastIndex(name, "/"); i >= 0 {
name = name[i+1:]
}
if name == "" {
return group
}
return strings.ToUpper(name[:1]) + name[1:]
}