Use ThemesSlice instead of Themes in Header struct.

This commit is contained in:
Azareal 2021-05-11 19:25:07 +10:00
parent f54203d54f
commit 67ccca8b4e
3 changed files with 69 additions and 67 deletions

View File

@ -29,7 +29,8 @@ type Header struct {
Widgets PageWidgets Widgets PageWidgets
Site *site Site *site
Settings SettingMap Settings SettingMap
Themes map[string]*Theme // TODO: Use a slice containing every theme instead of the main map for speed? //Themes map[string]*Theme // TODO: Use a slice containing every theme instead of the main map for speed?
ThemesSlice []*Theme
Theme *Theme Theme *Theme
//TemplateName string // TODO: Use this to move template calls to the router rather than duplicating them over and over and over? //TemplateName string // TODO: Use this to move template calls to the router rather than duplicating them over and over and over?
CurrentUser *User // TODO: Deprecate CurrentUser on the page structs and use a pointer here CurrentUser *User // TODO: Deprecate CurrentUser on the page structs and use a pointer here

View File

@ -111,9 +111,10 @@ func cascadeForumPerms(fp *ForumPerms, u *User) {
func panelUserCheck(w http.ResponseWriter, r *http.Request, u *User) (h *Header, stats PanelStats, rerr RouteError) { func panelUserCheck(w http.ResponseWriter, r *http.Request, u *User) (h *Header, stats PanelStats, rerr RouteError) {
theme := GetThemeByReq(r) theme := GetThemeByReq(r)
h = &Header{ h = &Header{
Site: Site, Site: Site,
Settings: SettingBox.Load().(SettingMap), Settings: SettingBox.Load().(SettingMap),
Themes: Themes, //Themes: Themes,
ThemesSlice: ThemesSlice,
Theme: theme, Theme: theme,
CurrentUser: u, CurrentUser: u,
Hooks: GetHookTable(), Hooks: GetHookTable(),
@ -165,8 +166,7 @@ func panelUserCheck(w http.ResponseWriter, r *http.Request, u *User) (h *Header,
// TODO: Optimise this by removing a superfluous string alloc // TODO: Optimise this by removing a superfluous string alloc
var tname string var tname string
if theme.OverridenMap != nil { if theme.OverridenMap != nil {
_, ok := theme.OverridenMap[name] if _, ok := theme.OverridenMap[name]; ok {
if ok {
tname = "_" + theme.Name tname = "_" + theme.Name
} }
} }
@ -193,8 +193,8 @@ func simpleUserCheck(w http.ResponseWriter, r *http.Request, u *User) (lite *Hea
func GetThemeByReq(r *http.Request) *Theme { func GetThemeByReq(r *http.Request) *Theme {
theme := &Theme{Name: ""} theme := &Theme{Name: ""}
cookie, err := r.Cookie("current_theme") cookie, e := r.Cookie("current_theme")
if err == nil { if e == nil {
inTheme, ok := Themes[html.EscapeString(cookie.Value)] inTheme, ok := Themes[html.EscapeString(cookie.Value)]
if ok && !theme.HideFromThemes { if ok && !theme.HideFromThemes {
theme = inTheme theme = inTheme
@ -216,9 +216,10 @@ func userCheck(w http.ResponseWriter, r *http.Request, u *User) (h *Header, rerr
func userCheck2(w http.ResponseWriter, r *http.Request, u *User, nano int64) (h *Header, rerr RouteError) { func userCheck2(w http.ResponseWriter, r *http.Request, u *User, nano int64) (h *Header, rerr RouteError) {
theme := GetThemeByReq(r) theme := GetThemeByReq(r)
h = &Header{ h = &Header{
Site: Site, Site: Site,
Settings: SettingBox.Load().(SettingMap), Settings: SettingBox.Load().(SettingMap),
Themes: Themes, //Themes: Themes,
ThemesSlice: ThemesSlice,
Theme: theme, Theme: theme,
CurrentUser: u, // ! Some things rely on this being a pointer downstream from this function CurrentUser: u, // ! Some things rely on this being a pointer downstream from this function
Hooks: GetHookTable(), Hooks: GetHookTable(),
@ -282,16 +283,15 @@ func PrepResources(u *User, h *Header, theme *Theme) {
addPreScript := func(name string, i int) { addPreScript := func(name string, i int) {
// TODO: Optimise this by removing a superfluous string alloc // TODO: Optimise this by removing a superfluous string alloc
var tname string
if theme.OverridenMap != nil { if theme.OverridenMap != nil {
//fmt.Printf("name %+v\n", name) //fmt.Printf("name %+v\n", name)
//fmt.Printf("theme.OverridenMap %+v\n", theme.OverridenMap) //fmt.Printf("theme.OverridenMap %+v\n", theme.OverridenMap)
if _, ok := theme.OverridenMap[name]; ok { if _, ok := theme.OverridenMap[name]; ok {
tname = "_" + theme.Name tname := "_" + theme.Name
//fmt.Printf("tname %+v\n", tname)
h.AddPreScriptAsync("tmpl_" + name + tname + ".js")
return
} }
//fmt.Printf("tname %+v\n", tname)
h.AddPreScriptAsync("tmpl_" + name + tname + ".js")
return
} }
//fmt.Printf("tname %+v\n", tname) //fmt.Printf("tname %+v\n", tname)
h.AddPreScriptAsync(ucstrs[i]) h.AddPreScriptAsync(ucstrs[i])

View File

@ -24,6 +24,7 @@ type ThemeList map[string]*Theme
var Themes ThemeList = make(map[string]*Theme) // ? Refactor this into a store? var Themes ThemeList = make(map[string]*Theme) // ? Refactor this into a store?
var DefaultThemeBox atomic.Value var DefaultThemeBox atomic.Value
var ChangeDefaultThemeMutex sync.Mutex var ChangeDefaultThemeMutex sync.Mutex
var ThemesSlice []*Theme
// TODO: Fallback to a random theme if this doesn't exist, so admins can remove themes they don't use // TODO: Fallback to a random theme if this doesn't exist, so admins can remove themes they don't use
// TODO: Use this when the default theme doesn't exist // TODO: Use this when the default theme doesn't exist
@ -41,12 +42,12 @@ var themeStmts ThemeStmts
func init() { func init() {
DbInits.Add(func(acc *qgen.Accumulator) error { DbInits.Add(func(acc *qgen.Accumulator) error {
t := "themes" t, cols := "themes", "uname,default"
themeStmts = ThemeStmts{ themeStmts = ThemeStmts{
getAll: acc.Select(t).Columns("uname,default").Prepare(), getAll: acc.Select(t).Columns(cols).Prepare(),
isDefault: acc.Select(t).Columns("default").Where("uname=?").Prepare(), isDefault: acc.Select(t).Columns("default").Where("uname=?").Prepare(),
update: acc.Update(t).Set("default=?").Where("uname=?").Prepare(), update: acc.Update(t).Set("default=?").Where("uname=?").Prepare(),
add: acc.Insert(t).Columns("uname,default").Fields("?,?").Prepare(), add: acc.Insert(t).Columns(cols).Fields("?,?").Prepare(),
} }
return acc.FirstError() return acc.FirstError()
}) })
@ -76,43 +77,43 @@ func NewThemeList() (themes ThemeList, err error) {
return themes, err return themes, err
} }
theme := &Theme{} th := &Theme{}
err = json.Unmarshal(themeFile, theme) err = json.Unmarshal(themeFile, th)
if err != nil { if err != nil {
return themes, err return themes, err
} }
if theme.Name == "" { if th.Name == "" {
return themes, errors.New("Theme " + themePath + " doesn't have a name set in theme.json") return themes, errors.New("Theme " + themePath + " doesn't have a name set in theme.json")
} }
if theme.Name == fallbackTheme { if th.Name == fallbackTheme {
defaultTheme = fallbackTheme defaultTheme = fallbackTheme
} }
lastTheme = theme.Name lastTheme = th.Name
// TODO: Implement the static file part of this and fsnotify // TODO: Implement the static file part of this and fsnotify
if theme.Path != "" { if th.Path != "" {
log.Print("Resolving redirect to " + theme.Path) log.Print("Resolving redirect to " + th.Path)
themeFile, err := ioutil.ReadFile(theme.Path + "/theme.json") themeFile, err := ioutil.ReadFile(th.Path + "/theme.json")
if err != nil { if err != nil {
return themes, err return themes, err
} }
theme = &Theme{Path: theme.Path} th = &Theme{Path: th.Path}
err = json.Unmarshal(themeFile, theme) err = json.Unmarshal(themeFile, th)
if err != nil { if err != nil {
return themes, err return themes, err
} }
} else { } else {
theme.Path = themePath th.Path = themePath
} }
theme.Active = false // Set this to false, just in case someone explicitly overrode this value in the JSON file th.Active = false // Set this to false, just in case someone explicitly overrode this value in the JSON file
// TODO: Let the theme specify where it's resources are via the JSON file? // TODO: Let the theme specify where it's resources are via the JSON file?
// TODO: Let the theme inherit CSS from another theme? // TODO: Let the theme inherit CSS from another theme?
// ? - This might not be too helpful, as it only searches for /public/ and not if /public/ is empty. Still, it might help some people with a slightly less cryptic error // ? - This might not be too helpful, as it only searches for /public/ and not if /public/ is empty. Still, it might help some people with a slightly less cryptic error
log.Print(theme.Path + "/public/") log.Print(th.Path + "/public/")
_, err = os.Stat(theme.Path + "/public/") _, err = os.Stat(th.Path + "/public/")
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return themes, errors.New("We couldn't find this theme's resources. E.g. the /public/ folder.") return themes, errors.New("We couldn't find this theme's resources. E.g. the /public/ folder.")
@ -122,31 +123,31 @@ func NewThemeList() (themes ThemeList, err error) {
} }
} }
if theme.FullImage != "" { if th.FullImage != "" {
DebugLog("Adding theme image") DebugLog("Adding theme image")
err = StaticFiles.Add(theme.Path+"/"+theme.FullImage, themePath) err = StaticFiles.Add(th.Path+"/"+th.FullImage, themePath)
if err != nil { if err != nil {
return themes, err return themes, err
} }
} }
theme.TemplatesMap = make(map[string]string) th.TemplatesMap = make(map[string]string)
theme.TmplPtr = make(map[string]interface{}) th.TmplPtr = make(map[string]interface{})
if theme.Templates != nil { if th.Templates != nil {
for _, themeTmpl := range theme.Templates { for _, themeTmpl := range th.Templates {
theme.TemplatesMap[themeTmpl.Name] = themeTmpl.Source th.TemplatesMap[themeTmpl.Name] = themeTmpl.Source
theme.TmplPtr[themeTmpl.Name] = TmplPtrMap["o_"+themeTmpl.Source] th.TmplPtr[themeTmpl.Name] = TmplPtrMap["o_"+themeTmpl.Source]
} }
} }
theme.IntTmplHandle = DefaultTemplates th.IntTmplHandle = DefaultTemplates
overrides, err := ioutil.ReadDir(theme.Path + "/overrides/") overrides, err := ioutil.ReadDir(th.Path + "/overrides/")
if err != nil && !os.IsNotExist(err) { if err != nil && !os.IsNotExist(err) {
return themes, err return themes, err
} }
if len(overrides) > 0 { if len(overrides) > 0 {
overCount := 0 overCount := 0
theme.OverridenMap = make(map[string]bool) th.OverridenMap = make(map[string]bool)
for _, override := range overrides { for _, override := range overrides {
if override.IsDir() { if override.IsDir() {
continue continue
@ -159,25 +160,25 @@ func NewThemeList() (themes ThemeList, err error) {
} }
overCount++ overCount++
nosuf := strings.TrimSuffix(override.Name(), ext) nosuf := strings.TrimSuffix(override.Name(), ext)
theme.OverridenTemplates = append(theme.OverridenTemplates, nosuf) th.OverridenTemplates = append(th.OverridenTemplates, nosuf)
theme.OverridenMap[nosuf] = true th.OverridenMap[nosuf] = true
//theme.TmplPtr[nosuf] = TmplPtrMap["o_"+nosuf] //th.TmplPtr[nosuf] = TmplPtrMap["o_"+nosuf]
log.Print("succeeded") log.Print("succeeded")
} }
localTmpls := template.New("") localTmpls := template.New("")
err = loadTemplates(localTmpls, theme.Name) err = loadTemplates(localTmpls, th.Name)
if err != nil { if err != nil {
return themes, err return themes, err
} }
theme.IntTmplHandle = localTmpls th.IntTmplHandle = localTmpls
log.Printf("theme.OverridenTemplates: %+v\n", theme.OverridenTemplates) log.Printf("theme.OverridenTemplates: %+v\n", th.OverridenTemplates)
log.Printf("theme.IntTmplHandle: %+v\n", theme.IntTmplHandle) log.Printf("theme.IntTmplHandle: %+v\n", th.IntTmplHandle)
} else { } else {
log.Print("no overrides for " + theme.Name) log.Print("no overrides for " + th.Name)
} }
for i, res := range theme.Resources { for i, res := range th.Resources {
ext := filepath.Ext(res.Name) ext := filepath.Ext(res.Name)
switch ext { switch ext {
case ".css": case ".css":
@ -193,19 +194,19 @@ func NewThemeList() (themes ThemeList, err error) {
case "panel": case "panel":
res.LocID = LocPanel res.LocID = LocPanel
} }
theme.Resources[i] = res th.Resources[i] = res
} }
for _, dock := range theme.Docks { for _, dock := range th.Docks {
id, ok := DockToID[dock] if id, ok := DockToID[dock]; ok {
if ok { th.DocksID = append(th.DocksID, id)
theme.DocksID = append(theme.DocksID, id)
} }
} }
// TODO: Bind the built template, or an interpreted one for any dock overrides this theme has // TODO: Bind the built template, or an interpreted one for any dock overrides this theme has
themes[theme.Name] = theme themes[th.Name] = th
ThemesSlice = append(ThemesSlice, th)
} }
if defaultTheme == "" { if defaultTheme == "" {
defaultTheme = lastTheme defaultTheme = lastTheme
@ -221,18 +222,18 @@ func (t ThemeList) LoadActiveStatus() error {
ChangeDefaultThemeMutex.Lock() ChangeDefaultThemeMutex.Lock()
defer ChangeDefaultThemeMutex.Unlock() defer ChangeDefaultThemeMutex.Unlock()
rows, err := themeStmts.getAll.Query() rows, e := themeStmts.getAll.Query()
if err != nil { if e != nil {
return err return e
} }
defer rows.Close() defer rows.Close()
var uname string var uname string
var defaultThemeSwitch bool var defaultThemeSwitch bool
for rows.Next() { for rows.Next() {
err = rows.Scan(&uname, &defaultThemeSwitch) e = rows.Scan(&uname, &defaultThemeSwitch)
if err != nil { if e != nil {
return err return e
} }
// Was the theme deleted at some point? // Was the theme deleted at some point?
@ -258,8 +259,8 @@ func (t ThemeList) LoadActiveStatus() error {
func (t ThemeList) LoadStaticFiles() error { func (t ThemeList) LoadStaticFiles() error {
for _, theme := range t { for _, theme := range t {
if err := theme.LoadStaticFiles(); err != nil { if e := theme.LoadStaticFiles(); e != nil {
return err return e
} }
} }
return nil return nil