diff --git a/common/alerts.go b/common/alerts.go index 417c8f3a..d4406d6b 100644 --- a/common/alerts.go +++ b/common/alerts.go @@ -1,7 +1,7 @@ /* * * Gosora Alerts System -* Copyright Azareal 2017 - 2019 +* Copyright Azareal 2017 - 2020 * */ package common diff --git a/common/site.go b/common/site.go index 5d6d15e7..6431a37b 100644 --- a/common/site.go +++ b/common/site.go @@ -96,6 +96,8 @@ type config struct { LoosePort bool DisableServerPush bool EnableCDNPush bool + DisableNoavatarRange bool + DisableDefaultNoavatar bool Noavatar string // ? - Move this into the settings table? ItemsPerPage int // ? - Move this into the settings table? diff --git a/common/user.go b/common/user.go index 36607e3e..f6997b9c 100644 --- a/common/user.go +++ b/common/user.go @@ -1,7 +1,7 @@ /* * * Gosora User File -* Copyright Azareal 2017 - 2019 +* Copyright Azareal 2017 - 2020 * */ package common @@ -456,27 +456,45 @@ type GuestAvatar struct { } func buildNoavatar(uid int, width int) string { + if !Config.DisableNoavatarRange { + // TODO: Find a faster algorithm + if uid > 50000 { + uid -= 50000 + } + if uid > 5000 { + uid -= 5000 + } + if uid > 500 { + uid -= 500 + } + for uid > 50 { + uid -= 50 + } + } + if !Config.DisableDefaultNoavatar && uid < 5 { + return "/static/n"+strconv.Itoa(uid)+"-"+strconv.Itoa(width)+".png?i=0" + } return strings.Replace(strings.Replace(Config.Noavatar, "{id}", strconv.Itoa(uid), 1), "{width}", strconv.Itoa(width), 1) } // ? Make this part of *User? // TODO: Write tests for this func BuildAvatar(uid int, avatar string) (normalAvatar string, microAvatar string) { - if avatar != "" { - if avatar[0] == '.' { - if avatar[1] == '.' { - normalAvatar = "/uploads/avatar_" + strconv.Itoa(uid) + "_tmp" + avatar[1:] - return normalAvatar, normalAvatar - } - normalAvatar = "/uploads/avatar_" + strconv.Itoa(uid) + avatar + if avatar == "" { + if uid == 0 { + return guestAvatar.Normal, guestAvatar.Micro + } + return buildNoavatar(uid, 200), buildNoavatar(uid, 48) + } + if avatar[0] == '.' { + if avatar[1] == '.' { + normalAvatar = "/uploads/avatar_" + strconv.Itoa(uid) + "_tmp" + avatar[1:] return normalAvatar, normalAvatar } - return avatar, avatar + normalAvatar = "/uploads/avatar_" + strconv.Itoa(uid) + avatar + return normalAvatar, normalAvatar } - if uid == 0 { - return guestAvatar.Normal, guestAvatar.Micro - } - return buildNoavatar(uid, 200), buildNoavatar(uid, 48) + return avatar, avatar } // TODO: Move this to *User diff --git a/docs/configuration.md b/docs/configuration.md index 4c3582e8..32cec701 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -92,6 +92,10 @@ DisableServerPush - This switch lets you disable the HTTP/2 server push feature. EnableCDNPush - This switch lets you enable the HTTP/2 CDN Server Push feature. This operates by sending a Link header on every request and may also work with reverse-proxies like Nginx for doing HTTP/2 server pushes. +DisableNoavatarRange - This switch lets you disable the noavatar algorithm which maps IDs to a set ranging from 0 to 50 for better cacheability. Default: false + +DisableDefaultNoavatar - This switch lets you disable the default noavatar algorithm which may intercept noavatars for increased efficiency. Default: false + NoAvatar - The default avatar to use for users when they don't have their own. The default for this may change in the near future to better utilise HTTP/2. Example: https://api.adorable.io/avatars/{width}/{id}.png ItemsPerPage - The number of posts, topics, etc. you want on each page. diff --git a/langs/english.json b/langs/english.json index f3a4408b..f8f70c2d 100644 --- a/langs/english.json +++ b/langs/english.json @@ -960,6 +960,7 @@ "panel_themes_menus_head":"Menus", "panel_themes_menus_main":"Main Menu", + "panel_themes_menus_items_suffix":" items", "panel_themes_menus_items_head":"Menu Items", "panel_themes_menus_items_edit_button_aria":"Edit menu item", "panel_themes_menus_items_delete_button_aria":"Delete menu item", diff --git a/public/analytics.js b/public/analytics.js index 6b8ea95e..90ee0d4b 100644 --- a/public/analytics.js +++ b/public/analytics.js @@ -8,13 +8,20 @@ const Gigabyte = Megabyte * 1024; const Terabyte = Gigabyte * 1024; const Petabyte = Terabyte * 1024; -function convertByteUnit(bytes) { - if(bytes >= Petabyte) return Math.ceil(bytes / Petabyte) + "PB"; - else if(bytes >= Terabyte) return Math.ceil(bytes / Terabyte) + "TB"; - else if(bytes >= Gigabyte) return Math.ceil(bytes / Gigabyte) + "GB"; - else if(bytes >= Megabyte) return Math.ceil(bytes / Megabyte) + "MB"; - else if(bytes >= Kilobyte) return Math.ceil(bytes / Kilobyte) + "KB"; - return bytes; +function convertByteUnit(bytes, places = 0) { + let out; + if(bytes >= Petabyte) out = [bytes / Petabyte, "PB"]; + else if(bytes >= Terabyte) out = [bytes / Terabyte, "TB"]; + else if(bytes >= Gigabyte) out = [bytes / Gigabyte, "GB"]; + else if(bytes >= Megabyte) out = [bytes / Megabyte, "MB"]; + else if(bytes >= Kilobyte) out = [bytes / Kilobyte, "KB"]; + else out = [bytes,"b"]; + + if(places==0) return Math.ceil(out[0]) + out[1]; + else { + let ex = Math.pow(10, places); + return (Math.round(out[0], ex) / ex) + out[1]; + } } // TODO: Fully localise this diff --git a/public/n1-200.png b/public/n1-200.png new file mode 100644 index 00000000..1335aa37 Binary files /dev/null and b/public/n1-200.png differ diff --git a/public/n1-48.png b/public/n1-48.png new file mode 100644 index 00000000..fe6f8b44 Binary files /dev/null and b/public/n1-48.png differ diff --git a/public/n2-200.png b/public/n2-200.png new file mode 100644 index 00000000..56d35bca Binary files /dev/null and b/public/n2-200.png differ diff --git a/public/n2-48.png b/public/n2-48.png new file mode 100644 index 00000000..1d89fec3 Binary files /dev/null and b/public/n2-48.png differ diff --git a/public/n3-200.png b/public/n3-200.png new file mode 100644 index 00000000..4194121d Binary files /dev/null and b/public/n3-200.png differ diff --git a/public/n3-48.png b/public/n3-48.png new file mode 100644 index 00000000..cd1726fe Binary files /dev/null and b/public/n3-48.png differ diff --git a/public/n4-200.png b/public/n4-200.png new file mode 100644 index 00000000..25ce6d77 Binary files /dev/null and b/public/n4-200.png differ diff --git a/public/n4-48.png b/public/n4-48.png new file mode 100644 index 00000000..19f60483 Binary files /dev/null and b/public/n4-48.png differ diff --git a/routes/misc.go b/routes/misc.go index 016c5d9c..b1b69fe1 100644 --- a/routes/misc.go +++ b/routes/misc.go @@ -14,6 +14,7 @@ import ( ) var cacheControlMaxAge = "max-age=" + strconv.Itoa(int(c.Day)) // TODO: Make this a c.Config value +var cacheControlMaxAgeWeek = "max-age=" + strconv.Itoa(int(c.Week)) // TODO: Make this a c.Config value // GET functions func StaticFile(w http.ResponseWriter, r *http.Request) { @@ -33,7 +34,11 @@ func StaticFile(w http.ResponseWriter, r *http.Request) { } h.Set("Last-Modified", file.FormattedModTime) h.Set("Content-Type", file.Mimetype) - h.Set("Cache-Control", cacheControlMaxAge) //Cache-Control: max-age=31536000 + if len(file.Sha256) != 0 { + h.Set("Cache-Control", cacheControlMaxAgeWeek) + } else { + h.Set("Cache-Control", cacheControlMaxAge) //Cache-Control: max-age=31536000 + } h.Set("Vary", "Accept-Encoding") if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") && file.GzipLength > 0 { diff --git a/routes/panel/backups.go b/routes/panel/backups.go index 07ecf3af..89494020 100644 --- a/routes/panel/backups.go +++ b/routes/panel/backups.go @@ -57,6 +57,5 @@ func Backups(w http.ResponseWriter, r *http.Request, user c.User, backupURL stri backupList = append(backupList, c.BackupItem{backupFile.Name(), backupFile.ModTime()}) } - pi := c.PanelBackupPage{basePage, backupList} - return renderTemplate("panel_backups", w, r, basePage.Header, &pi) + return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_backups", c.PanelBackupPage{basePage, backupList}}) } diff --git a/routes/panel/debug.go b/routes/panel/debug.go index fb411174..fa112320 100644 --- a/routes/panel/debug.go +++ b/routes/panel/debug.go @@ -42,5 +42,5 @@ func Debug(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { runtime.ReadMemStats(&memStats) pi := c.PanelDebugPage{basePage, goVersion, dbVersion, uptime, openConnCount, qgen.Builder.GetAdapter().GetName(), goroutines, cpus, memStats} - return renderTemplate("panel_debug", w, r, basePage.Header, &pi) + return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"panel_dashboard_right","","panel_debug", pi}) } diff --git a/routes/panel/logs.go b/routes/panel/logs.go index 4d2acc6a..8d0ded09 100644 --- a/routes/panel/logs.go +++ b/routes/panel/logs.go @@ -34,7 +34,7 @@ func LogsRegs(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError pageList := c.Paginate(logCount, perPage, 5) pi := c.PanelRegLogsPage{basePage, llist, c.Paginator{pageList, page, lastPage}} - return renderTemplate("panel_reglogs", w, r, basePage.Header, &pi) + return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_reglogs", pi}) } // TODO: Log errors when something really screwy is going on? @@ -125,7 +125,7 @@ func LogsMod(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { pageList := c.Paginate(logCount, perPage, 5) pi := c.PanelLogsPage{basePage, llist, c.Paginator{pageList, page, lastPage}} - return renderTemplate("panel_modlogs", w, r, basePage.Header, &pi) + return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_modlogs", pi}) } func LogsAdmin(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { @@ -152,5 +152,5 @@ func LogsAdmin(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError pageList := c.Paginate(logCount, perPage, 5) pi := c.PanelLogsPage{basePage, llist, c.Paginator{pageList, page, lastPage}} - return renderTemplate("panel_adminlogs", w, r, basePage.Header, &pi) + return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_adminlogs", pi}) } diff --git a/routes/panel/plugins.go b/routes/panel/plugins.go index ed834d57..af6f77e3 100644 --- a/routes/panel/plugins.go +++ b/routes/panel/plugins.go @@ -22,8 +22,7 @@ func Plugins(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { pluginList = append(pluginList, plugin) } - pi := c.PanelPage{basePage, pluginList, nil} - return renderTemplate("panel_plugins", w, r, basePage.Header, &pi) + return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_plugins", c.PanelPage{basePage, pluginList, nil}}) } // TODO: Abstract more of the plugin activation / installation / deactivation logic, so we can test all that more reliably and easily diff --git a/routes/panel/themes.go b/routes/panel/themes.go index 0b055d73..f5e6ab05 100644 --- a/routes/panel/themes.go +++ b/routes/panel/themes.go @@ -34,7 +34,7 @@ func Themes(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { } pi := c.PanelThemesPage{basePage, pThemeList, vThemeList} - return renderTemplate("panel_themes", w, r, basePage.Header, &pi) + return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"panel_themes","","panel_themes",&pi}) } func ThemesSetDefault(w http.ResponseWriter, r *http.Request, user c.User, uname string) c.RouteError { @@ -85,8 +85,7 @@ func ThemesMenus(w http.ResponseWriter, r *http.Request, user c.User) c.RouteErr }) } - pi := c.PanelMenuListPage{basePage, menuList} - return renderTemplate("panel_themes_menus", w, r, basePage.Header, &pi) + return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_themes_menus", &c.PanelMenuListPage{basePage, menuList}}) } func ThemesMenusEdit(w http.ResponseWriter, r *http.Request, user c.User, smid string) c.RouteError { @@ -133,8 +132,7 @@ func ThemesMenusEdit(w http.ResponseWriter, r *http.Request, user c.User, smid s menuList = append(menuList, item) } - pi := c.PanelMenuPage{basePage, mid, menuList} - return renderTemplate("panel_themes_menus_items", w, r, basePage.Header, &pi) + return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_themes_menus_items", &c.PanelMenuPage{basePage, mid, menuList}}) } func ThemesMenuItemEdit(w http.ResponseWriter, r *http.Request, user c.User, sitemID string) c.RouteError { @@ -159,8 +157,7 @@ func ThemesMenuItemEdit(w http.ResponseWriter, r *http.Request, user c.User, sit return c.InternalError(err, w, r) } - pi := c.PanelMenuItemPage{basePage, menuItem} - return renderTemplate("panel_themes_menus_item_edit", w, r, basePage.Header, &pi) + return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_themes_menus_item_edit", &c.PanelMenuItemPage{basePage, menuItem}}) } func themesMenuItemSetters(r *http.Request, menuItem c.MenuItem) c.MenuItem { @@ -362,7 +359,7 @@ func ThemesWidgets(w http.ResponseWriter, r *http.Request, user c.User) c.RouteE } pi := c.PanelWidgetListPage{basePage, docks, c.WidgetEdit{&c.Widget{ID: 0, Type: "simple"}, make(map[string]string)}} - return renderTemplate("panel_themes_widgets", w, r, basePage.Header, &pi) + return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_themes_widgets", pi}) } func widgetsParseInputs(r *http.Request, widget *c.Widget) (*c.WidgetEdit, error) { diff --git a/templates/panel_adminlogs.html b/templates/panel_adminlogs.html index c9fbc462..149690b2 100644 --- a/templates/panel_adminlogs.html +++ b/templates/panel_adminlogs.html @@ -1,8 +1,3 @@ -{{template "header.html" . }} -