The rest of the Control Panel (exc. the Group Editor) now uses dyntmpl.
Improved the noavatar cacheability by constraining them in a range. Improved the noavatar cacheability by serving a small subset from Gosora. Improved the formatting of bytes in the memory analytics pane. Static resources with checksums will now have their caches expire in a week rather than a day. Tweaked the padding on the sub_heads on Nox. Moved a block of CSS out of a template and into panel.css in Tempra Simple and Shadow. Added the panel_themes_menus_items_suffix phrase. Added the DisableNoavatarRange config setting. Added the DisableDefaultNoavatar config setting.
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Gosora Alerts System
|
* Gosora Alerts System
|
||||||
* Copyright Azareal 2017 - 2019
|
* Copyright Azareal 2017 - 2020
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
package common
|
package common
|
||||||
|
|
|
@ -96,6 +96,8 @@ type config struct {
|
||||||
LoosePort bool
|
LoosePort bool
|
||||||
DisableServerPush bool
|
DisableServerPush bool
|
||||||
EnableCDNPush bool
|
EnableCDNPush bool
|
||||||
|
DisableNoavatarRange bool
|
||||||
|
DisableDefaultNoavatar bool
|
||||||
|
|
||||||
Noavatar string // ? - Move this into the settings table?
|
Noavatar string // ? - Move this into the settings table?
|
||||||
ItemsPerPage int // ? - Move this into the settings table?
|
ItemsPerPage int // ? - Move this into the settings table?
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Gosora User File
|
* Gosora User File
|
||||||
* Copyright Azareal 2017 - 2019
|
* Copyright Azareal 2017 - 2020
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
package common
|
package common
|
||||||
|
@ -456,13 +456,36 @@ type GuestAvatar struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildNoavatar(uid int, width int) string {
|
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)
|
return strings.Replace(strings.Replace(Config.Noavatar, "{id}", strconv.Itoa(uid), 1), "{width}", strconv.Itoa(width), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ? Make this part of *User?
|
// ? Make this part of *User?
|
||||||
// TODO: Write tests for this
|
// TODO: Write tests for this
|
||||||
func BuildAvatar(uid int, avatar string) (normalAvatar string, microAvatar string) {
|
func BuildAvatar(uid int, avatar string) (normalAvatar string, microAvatar string) {
|
||||||
if avatar != "" {
|
if avatar == "" {
|
||||||
|
if uid == 0 {
|
||||||
|
return guestAvatar.Normal, guestAvatar.Micro
|
||||||
|
}
|
||||||
|
return buildNoavatar(uid, 200), buildNoavatar(uid, 48)
|
||||||
|
}
|
||||||
if avatar[0] == '.' {
|
if avatar[0] == '.' {
|
||||||
if avatar[1] == '.' {
|
if avatar[1] == '.' {
|
||||||
normalAvatar = "/uploads/avatar_" + strconv.Itoa(uid) + "_tmp" + avatar[1:]
|
normalAvatar = "/uploads/avatar_" + strconv.Itoa(uid) + "_tmp" + avatar[1:]
|
||||||
|
@ -473,11 +496,6 @@ func BuildAvatar(uid int, avatar string) (normalAvatar string, microAvatar strin
|
||||||
}
|
}
|
||||||
return avatar, avatar
|
return avatar, avatar
|
||||||
}
|
}
|
||||||
if uid == 0 {
|
|
||||||
return guestAvatar.Normal, guestAvatar.Micro
|
|
||||||
}
|
|
||||||
return buildNoavatar(uid, 200), buildNoavatar(uid, 48)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Move this to *User
|
// TODO: Move this to *User
|
||||||
func SetPassword(uid int, password string) error {
|
func SetPassword(uid int, password string) error {
|
||||||
|
|
|
@ -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.
|
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
|
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.
|
ItemsPerPage - The number of posts, topics, etc. you want on each page.
|
||||||
|
|
|
@ -960,6 +960,7 @@
|
||||||
|
|
||||||
"panel_themes_menus_head":"Menus",
|
"panel_themes_menus_head":"Menus",
|
||||||
"panel_themes_menus_main":"Main Menu",
|
"panel_themes_menus_main":"Main Menu",
|
||||||
|
"panel_themes_menus_items_suffix":" items",
|
||||||
"panel_themes_menus_items_head":"Menu Items",
|
"panel_themes_menus_items_head":"Menu Items",
|
||||||
"panel_themes_menus_items_edit_button_aria":"Edit menu item",
|
"panel_themes_menus_items_edit_button_aria":"Edit menu item",
|
||||||
"panel_themes_menus_items_delete_button_aria":"Delete menu item",
|
"panel_themes_menus_items_delete_button_aria":"Delete menu item",
|
||||||
|
|
|
@ -8,13 +8,20 @@ const Gigabyte = Megabyte * 1024;
|
||||||
const Terabyte = Gigabyte * 1024;
|
const Terabyte = Gigabyte * 1024;
|
||||||
const Petabyte = Terabyte * 1024;
|
const Petabyte = Terabyte * 1024;
|
||||||
|
|
||||||
function convertByteUnit(bytes) {
|
function convertByteUnit(bytes, places = 0) {
|
||||||
if(bytes >= Petabyte) return Math.ceil(bytes / Petabyte) + "PB";
|
let out;
|
||||||
else if(bytes >= Terabyte) return Math.ceil(bytes / Terabyte) + "TB";
|
if(bytes >= Petabyte) out = [bytes / Petabyte, "PB"];
|
||||||
else if(bytes >= Gigabyte) return Math.ceil(bytes / Gigabyte) + "GB";
|
else if(bytes >= Terabyte) out = [bytes / Terabyte, "TB"];
|
||||||
else if(bytes >= Megabyte) return Math.ceil(bytes / Megabyte) + "MB";
|
else if(bytes >= Gigabyte) out = [bytes / Gigabyte, "GB"];
|
||||||
else if(bytes >= Kilobyte) return Math.ceil(bytes / Kilobyte) + "KB";
|
else if(bytes >= Megabyte) out = [bytes / Megabyte, "MB"];
|
||||||
return bytes;
|
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
|
// TODO: Fully localise this
|
||||||
|
|
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 9.8 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 1.9 KiB |
|
@ -14,6 +14,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var cacheControlMaxAge = "max-age=" + strconv.Itoa(int(c.Day)) // TODO: Make this a c.Config value
|
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
|
// GET functions
|
||||||
func StaticFile(w http.ResponseWriter, r *http.Request) {
|
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("Last-Modified", file.FormattedModTime)
|
||||||
h.Set("Content-Type", file.Mimetype)
|
h.Set("Content-Type", file.Mimetype)
|
||||||
|
if len(file.Sha256) != 0 {
|
||||||
|
h.Set("Cache-Control", cacheControlMaxAgeWeek)
|
||||||
|
} else {
|
||||||
h.Set("Cache-Control", cacheControlMaxAge) //Cache-Control: max-age=31536000
|
h.Set("Cache-Control", cacheControlMaxAge) //Cache-Control: max-age=31536000
|
||||||
|
}
|
||||||
h.Set("Vary", "Accept-Encoding")
|
h.Set("Vary", "Accept-Encoding")
|
||||||
|
|
||||||
if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") && file.GzipLength > 0 {
|
if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") && file.GzipLength > 0 {
|
||||||
|
|
|
@ -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()})
|
backupList = append(backupList, c.BackupItem{backupFile.Name(), backupFile.ModTime()})
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := c.PanelBackupPage{basePage, backupList}
|
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_backups", c.PanelBackupPage{basePage, backupList}})
|
||||||
return renderTemplate("panel_backups", w, r, basePage.Header, &pi)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,5 +42,5 @@ func Debug(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
runtime.ReadMemStats(&memStats)
|
runtime.ReadMemStats(&memStats)
|
||||||
|
|
||||||
pi := c.PanelDebugPage{basePage, goVersion, dbVersion, uptime, openConnCount, qgen.Builder.GetAdapter().GetName(), goroutines, cpus, 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})
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ func LogsRegs(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError
|
||||||
|
|
||||||
pageList := c.Paginate(logCount, perPage, 5)
|
pageList := c.Paginate(logCount, perPage, 5)
|
||||||
pi := c.PanelRegLogsPage{basePage, llist, c.Paginator{pageList, page, lastPage}}
|
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?
|
// 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)
|
pageList := c.Paginate(logCount, perPage, 5)
|
||||||
pi := c.PanelLogsPage{basePage, llist, c.Paginator{pageList, page, lastPage}}
|
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 {
|
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)
|
pageList := c.Paginate(logCount, perPage, 5)
|
||||||
pi := c.PanelLogsPage{basePage, llist, c.Paginator{pageList, page, lastPage}}
|
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})
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,7 @@ func Plugins(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
pluginList = append(pluginList, plugin)
|
pluginList = append(pluginList, plugin)
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := c.PanelPage{basePage, pluginList, nil}
|
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_plugins", c.PanelPage{basePage, pluginList, nil}})
|
||||||
return renderTemplate("panel_plugins", w, r, basePage.Header, &pi)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Abstract more of the plugin activation / installation / deactivation logic, so we can test all that more reliably and easily
|
// TODO: Abstract more of the plugin activation / installation / deactivation logic, so we can test all that more reliably and easily
|
||||||
|
|
|
@ -34,7 +34,7 @@ func Themes(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := c.PanelThemesPage{basePage, pThemeList, vThemeList}
|
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 {
|
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", w, r, basePage.Header, c.Panel{basePage,"","","panel_themes_menus", &c.PanelMenuListPage{basePage, menuList}})
|
||||||
return renderTemplate("panel_themes_menus", w, r, basePage.Header, &pi)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThemesMenusEdit(w http.ResponseWriter, r *http.Request, user c.User, smid string) c.RouteError {
|
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)
|
menuList = append(menuList, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := c.PanelMenuPage{basePage, mid, menuList}
|
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_themes_menus_items", &c.PanelMenuPage{basePage, mid, menuList}})
|
||||||
return renderTemplate("panel_themes_menus_items", w, r, basePage.Header, &pi)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThemesMenuItemEdit(w http.ResponseWriter, r *http.Request, user c.User, sitemID string) c.RouteError {
|
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)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := c.PanelMenuItemPage{basePage, menuItem}
|
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_themes_menus_item_edit", &c.PanelMenuItemPage{basePage, menuItem}})
|
||||||
return renderTemplate("panel_themes_menus_item_edit", w, r, basePage.Header, &pi)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func themesMenuItemSetters(r *http.Request, menuItem c.MenuItem) c.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)}}
|
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) {
|
func widgetsParseInputs(r *http.Request, widget *c.Widget) (*c.WidgetEdit, error) {
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
{{template "header.html" . }}
|
|
||||||
<div class="colstack panel_stack">
|
|
||||||
{{template "panel_menu.html" . }}
|
|
||||||
<main class="colstack_right">
|
|
||||||
{{template "panel_before_head.html" . }}
|
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{lang "panel_logs_administration_head"}}</h1></div>
|
<div class="rowitem"><h1>{{lang "panel_logs_administration_head"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -21,6 +16,3 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{template "paginator.html" . }}
|
{{template "paginator.html" . }}
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
{{template "footer.html" . }}
|
|
||||||
|
|
|
@ -48,15 +48,33 @@
|
||||||
options = Chartist.extend({}, {}, options);
|
options = Chartist.extend({}, {}, options);
|
||||||
|
|
||||||
return function byteUnits(chart) {
|
return function byteUnits(chart) {
|
||||||
if (chart instanceof Chartist.Line) {
|
if(!chart instanceof Chartist.Line) return;
|
||||||
|
|
||||||
chart.on('created', function() {
|
chart.on('created', function() {
|
||||||
console.log("running created")
|
console.log("running created")
|
||||||
let vbits = document.getElementsByClassName("ct-vertical");
|
const vbits = document.getElementsByClassName("ct-vertical");
|
||||||
|
if(vbits==null) return;
|
||||||
|
|
||||||
|
let tbits = [];
|
||||||
for(let i = 0; i < vbits.length; i++) {
|
for(let i = 0; i < vbits.length; i++) {
|
||||||
vbits[i].innerHTML = convertByteUnit(vbits[i].innerHTML);
|
tbits[i] = vbits[i].innerHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const calc = (places) => {
|
||||||
|
if(places==3) return;
|
||||||
|
|
||||||
|
const matcher = vbits[0].innerHTML;
|
||||||
|
let allMatch = true;
|
||||||
|
for(let i = 0; i < tbits.length; i++) {
|
||||||
|
let val = convertByteUnit(tbits[i], places);
|
||||||
|
if(val!=matcher) allMatch = false;
|
||||||
|
vbits[i].innerHTML = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(allMatch) calc(places + 1);
|
||||||
|
}
|
||||||
|
calc(0);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<div id="panel_analytics_posts_table" class="colstack_item rowlist" aria-label="{{lang "panel_statistics_post_counts_table_aria"}}">
|
<div id="panel_analytics_posts_table" class="colstack_item rowlist" aria-label="{{lang "panel_statistics_post_counts_table_aria"}}">
|
||||||
{{range .ViewItems}}
|
{{range .ViewItems}}
|
||||||
<div class="rowitem panel_compactrow editable_parent">
|
<div class="rowitem panel_compactrow editable_parent">
|
||||||
<a class="panel_upshift {{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}unix_to_24_hour_time{{else}}unix_to_date{{end}}">{{.Time}}</a>
|
<a class="panel_upshift unix_{{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}to_24_hour_time{{else}}to_date{{end}}">{{.Time}}</a>
|
||||||
<span class="panel_compacttext to_right">{{.Count}}{{lang "panel_statistics_posts_suffix"}}</span>
|
<span class="panel_compacttext to_right">{{.Count}}{{lang "panel_statistics_posts_suffix"}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{else}}<div class="rowitem passive rowmsg">{{lang "panel_statistics_post_counts_no_post_counts"}}</div>{{end}}
|
{{else}}<div class="rowitem passive rowmsg">{{lang "panel_statistics_post_counts_no_post_counts"}}</div>{{end}}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<div id="panel_analytics_topics_table" class="colstack_item rowlist" aria-label="{{lang "panel_statistics_topic_counts_table_aria"}}">
|
<div id="panel_analytics_topics_table" class="colstack_item rowlist" aria-label="{{lang "panel_statistics_topic_counts_table_aria"}}">
|
||||||
{{range .ViewItems}}
|
{{range .ViewItems}}
|
||||||
<div class="rowitem panel_compactrow editable_parent">
|
<div class="rowitem panel_compactrow editable_parent">
|
||||||
<a class="panel_upshift {{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}unix_to_24_hour_time{{else}}unix_to_date{{end}}">{{.Time}}</a>
|
<a class="panel_upshift unix_{{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}to_24_hour_time{{else}}to_date{{end}}">{{.Time}}</a>
|
||||||
<span class="panel_compacttext to_right">{{.Count}}{{lang "panel_statistics_topics_suffix"}}</span>
|
<span class="panel_compacttext to_right">{{.Count}}{{lang "panel_statistics_topics_suffix"}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<div id="panel_analytics_views_table" class="colstack_item rowlist" aria-label="{{lang "panel_statistics_requests_table_aria"}}">
|
<div id="panel_analytics_views_table" class="colstack_item rowlist" aria-label="{{lang "panel_statistics_requests_table_aria"}}">
|
||||||
{{range .ViewItems}}
|
{{range .ViewItems}}
|
||||||
<div class="rowitem panel_compactrow editable_parent">
|
<div class="rowitem panel_compactrow editable_parent">
|
||||||
<a class="panel_upshift {{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}unix_to_24_hour_time{{else}}unix_to_date{{end}}">{{.Time}}</a>
|
<a class="panel_upshift unix_{{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}to_24_hour_time{{else}}to_date{{end}}">{{.Time}}</a>
|
||||||
<span class="panel_compacttext to_right">{{.Count}}{{lang "panel_statistics_views_suffix"}}</span>
|
<span class="panel_compacttext to_right">{{.Count}}{{lang "panel_statistics_views_suffix"}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
{{template "header.html" . }}
|
|
||||||
<div class="colstack panel_stack">
|
|
||||||
{{template "panel_menu.html" . }}
|
|
||||||
<main class="colstack_right">
|
|
||||||
{{template "panel_before_head.html" . }}
|
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{lang "panel_backups_head"}}</h1></div>
|
<div class="rowitem"><h1>{{lang "panel_backups_head"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -18,6 +13,3 @@
|
||||||
<div class="rowitem rowmsg">{{lang "panel_backups_no_backups"}}</div>
|
<div class="rowitem rowmsg">{{lang "panel_backups_no_backups"}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
{{template "footer.html" . }}
|
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
{{template "header.html" . }}
|
|
||||||
<div class="colstack panel_stack">
|
|
||||||
{{template "panel_menu.html" . }}
|
|
||||||
<main id="panel_dashboard_right" class="colstack_right">
|
|
||||||
{{template "panel_before_head.html" . }}
|
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{lang "panel_debug_head"}}</h1></div>
|
<div class="rowitem"><h1>{{lang "panel_debug_head"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -49,6 +44,3 @@
|
||||||
<div class="grid_item grid_stat"><span>?</span></div>
|
<div class="grid_item grid_stat"><span>?</span></div>
|
||||||
<div class="grid_item grid_stat"><span>{{.MemStats.StackInuse}}</span></div>
|
<div class="grid_item grid_stat"><span>{{.MemStats.StackInuse}}</span></div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
{{template "footer.html" . }}
|
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
{{template "header.html" . }}
|
|
||||||
<div class="colstack panel_stack">
|
|
||||||
{{template "panel_menu.html" . }}
|
|
||||||
<main class="colstack_right">
|
|
||||||
{{template "panel_before_head.html" . }}
|
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{lang "panel_logs_moderation_head"}}</h1></div>
|
<div class="rowitem"><h1>{{lang "panel_logs_moderation_head"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -21,6 +16,3 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{template "paginator.html" . }}
|
{{template "paginator.html" . }}
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
{{template "footer.html" . }}
|
|
||||||
|
|
|
@ -1,9 +1,3 @@
|
||||||
{{template "header.html" . }}
|
|
||||||
<div class="colstack panel_stack">
|
|
||||||
|
|
||||||
{{template "panel_menu.html" . }}
|
|
||||||
<main class="colstack_right">
|
|
||||||
{{template "panel_before_head.html" . }}
|
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{lang "panel_plugins_head"}}</h1></div>
|
<div class="rowitem"><h1>{{lang "panel_plugins_head"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -25,7 +19,3 @@
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
{{template "footer.html" . }}
|
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
{{template "header.html" . }}
|
|
||||||
<div class="colstack panel_stack">
|
|
||||||
{{template "panel_menu.html" . }}
|
|
||||||
<main class="colstack_right">
|
|
||||||
{{template "panel_before_head.html" . }}
|
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{lang "panel_logs_registration_head"}}</h1></div>
|
<div class="rowitem"><h1>{{lang "panel_logs_registration_head"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -21,6 +16,3 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{template "paginator.html" . }}
|
{{template "paginator.html" . }}
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
{{template "footer.html" . }}
|
|
||||||
|
|
|
@ -1,17 +1,3 @@
|
||||||
{{template "header.html" . }}
|
|
||||||
<div class="colstack panel_stack">
|
|
||||||
{{template "panel_menu.html" . }}
|
|
||||||
{{/** Stop inlining this x.x **/}}
|
|
||||||
<style type="text/css">
|
|
||||||
.rowitem::after {
|
|
||||||
content: "";
|
|
||||||
display: block;
|
|
||||||
clear: both;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<main class="colstack_right">
|
|
||||||
{{template "panel_before_head.html" . }}
|
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{lang "panel_themes_primary_themes"}}</h1></div>
|
<div class="rowitem"><h1>{{lang "panel_themes_primary_themes"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -50,7 +36,3 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</main>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
{{template "footer.html" . }}
|
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
{{template "header.html" . }}
|
|
||||||
<div class="colstack panel_stack">
|
|
||||||
{{template "panel_menu.html" . }}
|
|
||||||
<main class="colstack_right">
|
|
||||||
{{template "panel_before_head.html" . }}
|
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{lang "panel_themes_menus_head"}}</h1></div>
|
<div class="rowitem"><h1>{{lang "panel_themes_menus_head"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -10,10 +5,7 @@
|
||||||
{{range .ItemList}}
|
{{range .ItemList}}
|
||||||
<div class="rowitem panel_compactrow editable_parent">
|
<div class="rowitem panel_compactrow editable_parent">
|
||||||
<a href="/panel/themes/menus/edit/{{.ID}}" class="editable_block panel_upshift">{{if .Name}}{{.Name}} - {{end}}#{{.ID}}</a>
|
<a href="/panel/themes/menus/edit/{{.ID}}" class="editable_block panel_upshift">{{if .Name}}{{.Name}} - {{end}}#{{.ID}}</a>
|
||||||
<a class="panel_compacttext to_right">{{.ItemCount}} items</a>
|
<a class="panel_compacttext to_right">{{.ItemCount}}{{lang "panel_themes_menus_items_suffix"}}</a>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
{{template "footer.html" . }}
|
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
{{template "header.html" . }}
|
|
||||||
<div class="colstack panel_stack">
|
|
||||||
{{/** TODO: Set the order based on the order here **/}}
|
{{/** TODO: Set the order based on the order here **/}}
|
||||||
{{/** TODO: Write the backend code and JS code for saving this menu **/}}
|
{{/** TODO: Write the backend code and JS code for saving this menu **/}}
|
||||||
{{template "panel_menu.html" . }}
|
|
||||||
<main class="colstack_right">
|
|
||||||
{{template "panel_before_head.html" . }}
|
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{lang "panel_themes_menus_edit_head"}}</h1></div>
|
<div class="rowitem"><h1>{{lang "panel_themes_menus_edit_head"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -59,11 +54,9 @@
|
||||||
</select></div>
|
</select></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<div class="formitem"><button name="panel-button" class="formbutton">{{lang "panel_themes_menus_edit_update_button"}}</button></div>
|
<div class="formitem">
|
||||||
|
<button name="panel-button" class="formbutton">{{lang "panel_themes_menus_edit_update_button"}}</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</main>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
{{template "footer.html" . }}
|
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
{{template "header.html" . }}
|
|
||||||
<div class="colstack panel_stack">
|
|
||||||
{{template "panel_menu.html" . }}
|
|
||||||
<main class="colstack_right">
|
|
||||||
{{template "panel_before_head.html" . }}
|
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem">
|
<div class="rowitem">
|
||||||
<h1>{{lang "panel_themes_menus_items_head"}}</h1>
|
<h1>{{lang "panel_themes_menus_items_head"}}</h1>
|
||||||
|
@ -78,6 +73,3 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
{{template "footer.html" . }}
|
|
|
@ -9,11 +9,6 @@ type Widget struct {
|
||||||
Literal bool
|
Literal bool
|
||||||
}
|
}
|
||||||
**/}}
|
**/}}
|
||||||
{{template "header.html" . }}
|
|
||||||
<div class="colstack panel_stack">
|
|
||||||
{{template "panel_menu.html" . }}
|
|
||||||
<main class="colstack_right">
|
|
||||||
{{template "panel_before_head.html" . }}
|
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{lang "panel_themes_widgets_head"}}</h1></div>
|
<div class="rowitem"><h1>{{lang "panel_themes_widgets_head"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -56,6 +51,3 @@ type Widget struct {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
{{template "footer.html" . }}
|
|
|
@ -87,7 +87,7 @@
|
||||||
background-color: #444444;
|
background-color: #444444;
|
||||||
}
|
}
|
||||||
.colstack_right .colstack_head.colstack_sub_head:not(:first-child) {
|
.colstack_right .colstack_head.colstack_sub_head:not(:first-child) {
|
||||||
margin-top: 6px;
|
margin-top: 12px;
|
||||||
}
|
}
|
||||||
.colstack_head + .colstack_head.colstack_sub_head:not(:first-child) {
|
.colstack_head + .colstack_head.colstack_sub_head:not(:first-child) {
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
|
|
|
@ -81,6 +81,12 @@
|
||||||
padding-right: 2px;
|
padding-right: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#panel_themes .rowitem::after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
.panel_submitrow .rowitem {
|
.panel_submitrow .rowitem {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,3 +188,9 @@
|
||||||
.wtype_about .w_about, .wtype_simple .w_simple, .wtype_wol .w_wol, .wtype_default .w_default {
|
.wtype_about .w_about, .wtype_simple .w_simple, .wtype_wol .w_wol, .wtype_default .w_default {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#panel_themes .rowitem::after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
clear: both;
|
||||||
|
}
|