package web import ( "net/http" "net/url" "sort" "strings" "sourcecraft.dev/bigbes/sr-ht-core/auth" "sourcecraft.dev/bigbes/sr-ht-core/config" "github.com/vaughan0/go-ini" "sourcecraft.dev/bigbes/sr-ht-dolt/authn" ) // serviceName is our own service key in the shared config and nav. const serviceName = "dolt.sr.ht" // networkOrder is upstream core.sr.ht's fixed nav ordering (flask.py // _network_order). Services present in the config but not listed here sort // after these, alphabetically. paste.sr.ht and pages.sr.ht are excluded from // the network entirely (they have no user-facing nav), mirroring _network. var networkOrder = []string{ "hub.sr.ht", "git.sr.ht", "hg.sr.ht", "lists.sr.ht", "todo.sr.ht", "builds.sr.ht", "man.sr.ht", "meta.sr.ht", } var networkExcluded = map[string]bool{ "paste.sr.ht": true, "pages.sr.ht": true, } // navEntry is one service link in the shared nav. type navEntry struct { // Name is the leading segment of the service (e.g. "git" for git.sr.ht), // rendered as the link text exactly as upstream nav.html does. Name string // Site is the full service key (e.g. "git.sr.ht"). Site string // Origin is the external URL for the service. Origin string // Active is true for our own service, which highlights it in the nav. Active bool } // basePage is the chrome model shared by every rendered page. Handler view // structs embed it so templates reference its fields directly (e.g. .SiteName). type basePage struct { Title string Site string SiteLabel string SiteName string Environment string ShowEnvBanner bool Network []navEntry MetaOrigin string SelfOrigin string LoginURL string LogoutURL string StyleHref string // CurrentUser is the authenticated caller, or nil for an anonymous request. CurrentUser *auth.AuthContext } // buildNetwork returns the ordered nav entries for conf: every section ending // ".sr.ht" that is not excluded, ordered by networkOrder then alphabetically // for unknown services. Origins are resolved externally via config.GetOrigin. func buildNetwork(conf ini.File) []navEntry { var sites []string for section := range conf { if !strings.HasSuffix(section, ".sr.ht") || networkExcluded[section] { continue } sites = append(sites, section) } orderIndex := func(s string) int { for i, n := range networkOrder { if n == s { return i } } return len(networkOrder) // unknown services sort after the fixed set } sort.Slice(sites, func(i, j int) bool { oi, oj := orderIndex(sites[i]), orderIndex(sites[j]) if oi != oj { return oi < oj } return sites[i] < sites[j] // stable, alphabetical among unknowns }) entries := make([]navEntry, 0, len(sites)) for _, s := range sites { entries = append(entries, navEntry{ Name: strings.SplitN(s, ".", 2)[0], Site: s, Origin: config.GetOrigin(conf, s, true), Active: s == serviceName, }) } return entries } // newBasePage builds the chrome model for a request. Title is the per-page //