Renamed the pre_render_panel_mod_log pre-render hook to pre_render_panel_modlogs.
Added the half-second task type, you'll why later ;) Reduced the amount of code duplication in the panel routes (saved a hundred lines). Added the two day time range option for graphs. We now track the discord, lynx and blank user agents. Renamed some template files for consistency and to help stamp out some duplicate code. Began work on topic move.
This commit is contained in:
parent
5f5994726e
commit
5ba7aa74f7
|
@ -112,7 +112,7 @@ var PreRenderHooks = map[string][]func(http.ResponseWriter, *http.Request, *User
|
||||||
"pre_render_panel_edit_group": nil,
|
"pre_render_panel_edit_group": nil,
|
||||||
"pre_render_panel_edit_group_perms": nil,
|
"pre_render_panel_edit_group_perms": nil,
|
||||||
"pre_render_panel_themes": nil,
|
"pre_render_panel_themes": nil,
|
||||||
"pre_render_panel_mod_log": nil,
|
"pre_render_panel_modlogs": nil,
|
||||||
|
|
||||||
"pre_render_error": nil, // Note: This hook isn't run for a few errors whose templates are computed at startup and reused, such as InternalError. This hook is also not available in JS mode.
|
"pre_render_error": nil, // Note: This hook isn't run for a few errors whose templates are computed at startup and reused, such as InternalError. This hook is also not available in JS mode.
|
||||||
"pre_render_security_error": nil,
|
"pre_render_security_error": nil,
|
||||||
|
|
|
@ -19,6 +19,7 @@ type TaskStmts struct {
|
||||||
getSync *sql.Stmt
|
getSync *sql.Stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ScheduledHalfSecondTasks []func() error
|
||||||
var ScheduledSecondTasks []func() error
|
var ScheduledSecondTasks []func() error
|
||||||
var ScheduledFifteenMinuteTasks []func() error
|
var ScheduledFifteenMinuteTasks []func() error
|
||||||
var ShutdownTasks []func() error
|
var ShutdownTasks []func() error
|
||||||
|
@ -37,6 +38,11 @@ func init() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddScheduledHalfSecondTask is not concurrency safe
|
||||||
|
func AddScheduledHalfSecondTask(task func() error) {
|
||||||
|
ScheduledHalfSecondTasks = append(ScheduledHalfSecondTasks, task)
|
||||||
|
}
|
||||||
|
|
||||||
// AddScheduledSecondTask is not concurrency safe
|
// AddScheduledSecondTask is not concurrency safe
|
||||||
func AddScheduledSecondTask(task func() error) {
|
func AddScheduledSecondTask(task func() error) {
|
||||||
ScheduledSecondTasks = append(ScheduledSecondTasks, task)
|
ScheduledSecondTasks = append(ScheduledSecondTasks, task)
|
||||||
|
|
|
@ -15,6 +15,7 @@ type Stmts struct {
|
||||||
isThemeDefault *sql.Stmt
|
isThemeDefault *sql.Stmt
|
||||||
getModlogs *sql.Stmt
|
getModlogs *sql.Stmt
|
||||||
getModlogsOffset *sql.Stmt
|
getModlogsOffset *sql.Stmt
|
||||||
|
getAdminlogsOffset *sql.Stmt
|
||||||
getReplyTID *sql.Stmt
|
getReplyTID *sql.Stmt
|
||||||
getTopicFID *sql.Stmt
|
getTopicFID *sql.Stmt
|
||||||
getUserReplyUID *sql.Stmt
|
getUserReplyUID *sql.Stmt
|
||||||
|
@ -122,6 +123,13 @@ func _gen_mssql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Print("Preparing getAdminlogsOffset statement.")
|
||||||
|
stmts.getAdminlogsOffset, err = db.Prepare("SELECT [action],[elementID],[elementType],[ipaddress],[actorID],[doneAt] FROM [administration_logs] ORDER BY doneAt DESC OFFSET ?1 ROWS FETCH NEXT ?2 ROWS ONLY")
|
||||||
|
if err != nil {
|
||||||
|
log.Print("Bad Query: ","SELECT [action],[elementID],[elementType],[ipaddress],[actorID],[doneAt] FROM [administration_logs] ORDER BY doneAt DESC OFFSET ?1 ROWS FETCH NEXT ?2 ROWS ONLY")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
log.Print("Preparing getReplyTID statement.")
|
log.Print("Preparing getReplyTID statement.")
|
||||||
stmts.getReplyTID, err = db.Prepare("SELECT [tid] FROM [replies] WHERE [rid] = ?1")
|
stmts.getReplyTID, err = db.Prepare("SELECT [tid] FROM [replies] WHERE [rid] = ?1")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -17,6 +17,7 @@ type Stmts struct {
|
||||||
isThemeDefault *sql.Stmt
|
isThemeDefault *sql.Stmt
|
||||||
getModlogs *sql.Stmt
|
getModlogs *sql.Stmt
|
||||||
getModlogsOffset *sql.Stmt
|
getModlogsOffset *sql.Stmt
|
||||||
|
getAdminlogsOffset *sql.Stmt
|
||||||
getReplyTID *sql.Stmt
|
getReplyTID *sql.Stmt
|
||||||
getTopicFID *sql.Stmt
|
getTopicFID *sql.Stmt
|
||||||
getUserReplyUID *sql.Stmt
|
getUserReplyUID *sql.Stmt
|
||||||
|
@ -118,6 +119,12 @@ func _gen_mysql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Print("Preparing getAdminlogsOffset statement.")
|
||||||
|
stmts.getAdminlogsOffset, err = db.Prepare("SELECT `action`,`elementID`,`elementType`,`ipaddress`,`actorID`,`doneAt` FROM `administration_logs` ORDER BY doneAt DESC LIMIT ?,?")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
log.Print("Preparing getReplyTID statement.")
|
log.Print("Preparing getReplyTID statement.")
|
||||||
stmts.getReplyTID, err = db.Prepare("SELECT `tid` FROM `replies` WHERE `rid` = ?")
|
stmts.getReplyTID, err = db.Prepare("SELECT `tid` FROM `replies` WHERE `rid` = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -233,6 +233,9 @@ var agentMapEnum = map[string]int{
|
||||||
"bing": 9,
|
"bing": 9,
|
||||||
"baidu": 10,
|
"baidu": 10,
|
||||||
"duckduckgo": 11,
|
"duckduckgo": 11,
|
||||||
|
"discord": 12,
|
||||||
|
"lynx": 13,
|
||||||
|
"blank": 14,
|
||||||
}
|
}
|
||||||
var reverseAgentMapEnum = map[int]string{
|
var reverseAgentMapEnum = map[int]string{
|
||||||
0: "unknown",
|
0: "unknown",
|
||||||
|
@ -247,6 +250,9 @@ var reverseAgentMapEnum = map[int]string{
|
||||||
9: "bing",
|
9: "bing",
|
||||||
10: "baidu",
|
10: "baidu",
|
||||||
11: "duckduckgo",
|
11: "duckduckgo",
|
||||||
|
12: "discord",
|
||||||
|
13: "lynx",
|
||||||
|
14: "blank",
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Stop spilling these into the package scope?
|
// TODO: Stop spilling these into the package scope?
|
||||||
|
@ -344,7 +350,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
// Track the user agents. Unfortunately, everyone pretends to be Mozilla, so this'll be a little less efficient than I would like.
|
// Track the user agents. Unfortunately, everyone pretends to be Mozilla, so this'll be a little less efficient than I would like.
|
||||||
// TODO: Add a setting to disable this?
|
// TODO: Add a setting to disable this?
|
||||||
// TODO: Use a more efficient detector instead of smashing every possible combination in
|
// TODO: Use a more efficient detector instead of smashing every possible combination in
|
||||||
ua := strings.TrimSuffix(strings.TrimPrefix(req.UserAgent(),"Mozilla/5.0 ")," Safari/537.36") // Noise, no one's going to be running this and it complicates implementing an efficient UA parser, particularly the more efficient right-to-left one I have in mind
|
ua := strings.TrimSpace(strings.TrimSuffix(strings.TrimPrefix(req.UserAgent(),"Mozilla/5.0 ")," Safari/537.36")) // Noise, no one's going to be running this and it complicates implementing an efficient UA parser, particularly the more efficient right-to-left one I have in mind
|
||||||
switch {
|
switch {
|
||||||
case strings.Contains(ua,"Google"):
|
case strings.Contains(ua,"Google"):
|
||||||
common.AgentViewCounter.Bump(7)
|
common.AgentViewCounter.Bump(7)
|
||||||
|
@ -368,6 +374,12 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
common.AgentViewCounter.Bump(10)
|
common.AgentViewCounter.Bump(10)
|
||||||
case strings.Contains(ua,"DuckDuckBot"):
|
case strings.Contains(ua,"DuckDuckBot"):
|
||||||
common.AgentViewCounter.Bump(11)
|
common.AgentViewCounter.Bump(11)
|
||||||
|
case strings.Contains(ua,"Discordbot"):
|
||||||
|
common.AgentViewCounter.Bump(12)
|
||||||
|
case strings.Contains(ua,"Lynx"):
|
||||||
|
common.AgentViewCounter.Bump(13)
|
||||||
|
case ua == "":
|
||||||
|
common.AgentViewCounter.Bump(14)
|
||||||
default:
|
default:
|
||||||
common.AgentViewCounter.Bump(0)
|
common.AgentViewCounter.Bump(0)
|
||||||
if common.Dev.DebugMode {
|
if common.Dev.DebugMode {
|
||||||
|
|
|
@ -69,23 +69,24 @@
|
||||||
"register":"Registration",
|
"register":"Registration",
|
||||||
"ip-search":"IP Search",
|
"ip-search":"IP Search",
|
||||||
|
|
||||||
"panel-dashboard":"Control Panel Dashboard",
|
"panel_dashboard":"Control Panel Dashboard",
|
||||||
"panel-forums":"Forum Manager",
|
"panel_forums":"Forum Manager",
|
||||||
"panel-delete-forum":"Delete Forum",
|
"panel_delete_forum":"Delete Forum",
|
||||||
"panel-edit-forum":"Forum Editor",
|
"panel_edit_forum":"Forum Editor",
|
||||||
"panel-analytics":"Analytics",
|
"panel_analytics":"Analytics",
|
||||||
"panel-settings":"Setting Manager",
|
"panel_settings":"Setting Manager",
|
||||||
"panel-edit-setting":"Edit Setting",
|
"panel_edit_setting":"Edit Setting",
|
||||||
"panel-word-filters":"Word Filter Manager",
|
"panel_word_filters":"Word Filter Manager",
|
||||||
"panel-edit-word-filter":"Edit Word Filter",
|
"panel_edit_word_filter":"Edit Word Filter",
|
||||||
"panel-plugins":"Plugin Manager",
|
"panel_plugins":"Plugin Manager",
|
||||||
"panel-users":"User Manager",
|
"panel_users":"User Manager",
|
||||||
"panel-edit-user":"User Editor",
|
"panel_edit_user":"User Editor",
|
||||||
"panel-groups":"Group Manager",
|
"panel_groups":"Group Manager",
|
||||||
"panel-edit-group":"Group Editor",
|
"panel_edit_group":"Group Editor",
|
||||||
"panel-themes":"Theme Manager",
|
"panel_themes":"Theme Manager",
|
||||||
"panel-backups":"Backups",
|
"panel_backups":"Backups",
|
||||||
"panel-mod-logs":"Moderation Logs",
|
"panel_mod_logs":"Moderation Logs",
|
||||||
"panel-debug":"Debug"
|
"panel_admin_logs":"Administration Logs",
|
||||||
|
"panel_debug":"Debug"
|
||||||
}
|
}
|
||||||
}
|
}
|
13
main.go
13
main.go
|
@ -246,13 +246,18 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run this goroutine once a second
|
// Run this goroutine once every half second
|
||||||
|
halfSecondTicker := time.NewTicker(time.Second / 2)
|
||||||
secondTicker := time.NewTicker(1 * time.Second)
|
secondTicker := time.NewTicker(1 * time.Second)
|
||||||
fifteenMinuteTicker := time.NewTicker(15 * time.Minute)
|
fifteenMinuteTicker := time.NewTicker(15 * time.Minute)
|
||||||
//hourTicker := time.NewTicker(1 * time.Hour)
|
//hourTicker := time.NewTicker(1 * time.Hour)
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
case <-halfSecondTicker.C:
|
||||||
|
// TODO: Add a plugin hook here
|
||||||
|
runTasks(common.ScheduledHalfSecondTasks)
|
||||||
|
// TODO: Add a plugin hook here
|
||||||
case <-secondTicker.C:
|
case <-secondTicker.C:
|
||||||
// TODO: Add a plugin hook here
|
// TODO: Add a plugin hook here
|
||||||
runTasks(common.ScheduledSecondTasks)
|
runTasks(common.ScheduledSecondTasks)
|
||||||
|
@ -291,13 +296,14 @@ func main() {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
// TODO: Move these routes into the new routes list
|
||||||
log.Print("Initialising the router")
|
log.Print("Initialising the router")
|
||||||
router = NewGenRouter(http.FileServer(http.Dir("./uploads")))
|
router = NewGenRouter(http.FileServer(http.Dir("./uploads")))
|
||||||
router.HandleFunc("/topic/create/submit/", routeTopicCreateSubmit)
|
router.HandleFunc("/topic/create/submit/", routeTopicCreateSubmit)
|
||||||
router.HandleFunc("/topic/", routeTopicID)
|
router.HandleFunc("/topic/", routeTopicID)
|
||||||
router.HandleFunc("/reply/create/", routeCreateReply)
|
router.HandleFunc("/reply/create/", routeCreateReply)
|
||||||
//router.HandleFunc("/reply/edit/", routeReplyEdit)
|
//router.HandleFunc("/reply/edit/", routeReplyEdit) // No js fallback
|
||||||
//router.HandleFunc("/reply/delete/", routeReplyDelete)
|
//router.HandleFunc("/reply/delete/", routeReplyDelete) // No js confirmation page? We could have a confirmation modal for the JS case
|
||||||
router.HandleFunc("/reply/edit/submit/", routeReplyEditSubmit)
|
router.HandleFunc("/reply/edit/submit/", routeReplyEditSubmit)
|
||||||
router.HandleFunc("/reply/delete/submit/", routeReplyDeleteSubmit)
|
router.HandleFunc("/reply/delete/submit/", routeReplyDeleteSubmit)
|
||||||
router.HandleFunc("/reply/like/submit/", routeReplyLikeSubmit)
|
router.HandleFunc("/reply/like/submit/", routeReplyLikeSubmit)
|
||||||
|
@ -307,6 +313,7 @@ func main() {
|
||||||
router.HandleFunc("/topic/unstick/submit/", routeUnstickTopic)
|
router.HandleFunc("/topic/unstick/submit/", routeUnstickTopic)
|
||||||
router.HandleFunc("/topic/lock/submit/", routeLockTopic)
|
router.HandleFunc("/topic/lock/submit/", routeLockTopic)
|
||||||
router.HandleFunc("/topic/unlock/submit/", routeUnlockTopic)
|
router.HandleFunc("/topic/unlock/submit/", routeUnlockTopic)
|
||||||
|
router.HandleFunc("/topic/move/submit/", routeMoveTopic)
|
||||||
router.HandleFunc("/topic/like/submit/", routeLikeTopic)
|
router.HandleFunc("/topic/like/submit/", routeLikeTopic)
|
||||||
|
|
||||||
// Accounts
|
// Accounts
|
||||||
|
|
|
@ -312,6 +312,48 @@ func routeUnlockTopic(w http.ResponseWriter, r *http.Request, user common.User)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func routeMoveTopic(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
|
return common.NoPermissions(w, r, user)
|
||||||
|
|
||||||
|
tid, err := strconv.Atoi(r.URL.Path[len("/topic/move/submit/"):])
|
||||||
|
if err != nil {
|
||||||
|
return common.PreError("The provided TopicID is not a valid number.", w, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
topic, err := common.Topics.Get(tid)
|
||||||
|
if err == ErrNoRows {
|
||||||
|
return common.PreError("The topic you tried to move doesn't exist.", w, r)
|
||||||
|
} else if err != nil {
|
||||||
|
return common.InternalError(err, w, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add hooks to make use of headerLite
|
||||||
|
_, ferr := common.SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
||||||
|
if ferr != nil {
|
||||||
|
return ferr
|
||||||
|
}
|
||||||
|
if !user.Perms.ViewTopic { // TODO: MoveTopic permission?
|
||||||
|
return common.NoPermissions(w, r, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = topic.Unlock()
|
||||||
|
if err != nil {
|
||||||
|
return common.InternalError(err, w, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = common.ModLogs.Create("move", tid, "topic", user.LastIP, user.ID)
|
||||||
|
if err != nil {
|
||||||
|
return common.InternalError(err, w, r)
|
||||||
|
}
|
||||||
|
err = topic.CreateActionReply("move", user.LastIP, user)
|
||||||
|
if err != nil {
|
||||||
|
return common.InternalError(err, w, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Disable stat updates in posts handled by plugin_guilds
|
// TODO: Disable stat updates in posts handled by plugin_guilds
|
||||||
// TODO: Update the stats after edits so that we don't under or over decrement stats during deletes
|
// TODO: Update the stats after edits so that we don't under or over decrement stats during deletes
|
||||||
func routeReplyEditSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func routeReplyEditSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
|
|
289
panel_routes.go
289
panel_routes.go
|
@ -30,20 +30,18 @@ func panelSuccessRedirect(dest string, w http.ResponseWriter, r *http.Request, i
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
func panelRenderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, user common.User, pi interface{}) common.RouteError {
|
||||||
// TODO: Implement this properly
|
|
||||||
/*func panelRenderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, user common.User, pi interface{}) common.RouteError {
|
|
||||||
if common.PreRenderHooks["pre_render_"+tmplName] != nil {
|
if common.PreRenderHooks["pre_render_"+tmplName] != nil {
|
||||||
if common.RunPreRenderHook("pre_render_"+tmplName, w, r, &user, &pi) {
|
if common.RunPreRenderHook("pre_render_"+tmplName, w, r, &user, pi) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = common.Templates.ExecuteTemplate(w, tmplName+".html", pi)
|
err := common.Templates.ExecuteTemplate(w, tmplName+".html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}*/
|
}
|
||||||
|
|
||||||
func routePanel(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func routePanel(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
headerVars, stats, ferr := common.PanelUserCheck(w, r, &user)
|
headerVars, stats, ferr := common.PanelUserCheck(w, r, &user)
|
||||||
|
@ -170,18 +168,8 @@ func routePanel(w http.ResponseWriter, r *http.Request, user common.User) common
|
||||||
gridElements = append(gridElements, common.GridElement{"dash-postsperuser", "5 posts / user / week", 14, "grid_stat stat_disabled", "", "", "Coming Soon!" /*"The average number of posts made by each active user over the past week"*/})
|
gridElements = append(gridElements, common.GridElement{"dash-postsperuser", "5 posts / user / week", 14, "grid_stat stat_disabled", "", "", "Coming Soon!" /*"The average number of posts made by each active user over the past week"*/})
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelDashboardPage{common.GetTitlePhrase("panel-dashboard"), user, headerVars, stats, "dashboard", gridElements}
|
pi := common.PanelDashboardPage{common.GetTitlePhrase("panel_dashboard"), user, headerVars, stats, "dashboard", gridElements}
|
||||||
if common.PreRenderHooks["pre_render_panel_dashboard"] != nil {
|
return panelRenderTemplate("panel_dashboard", w, r, user, &pi)
|
||||||
if common.RunPreRenderHook("pre_render_panel_dashboard", w, r, &user, &pi) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = common.Templates.ExecuteTemplate(w, "panel_dashboard.html", pi)
|
|
||||||
if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
//return panelRenderTemplate("panel_dashboard",w,r,user,pi)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func routePanelForums(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func routePanelForums(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
|
@ -210,18 +198,8 @@ func routePanelForums(w http.ResponseWriter, r *http.Request, user common.User)
|
||||||
forumList = append(forumList, fadmin)
|
forumList = append(forumList, fadmin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pi := common.PanelPage{common.GetTitlePhrase("panel-forums"), user, headerVars, stats, "forums", forumList, nil}
|
pi := common.PanelPage{common.GetTitlePhrase("panel_forums"), user, headerVars, stats, "forums", forumList, nil}
|
||||||
if common.PreRenderHooks["pre_render_panel_forums"] != nil {
|
return panelRenderTemplate("panel_forums", w, r, user, &pi)
|
||||||
if common.RunPreRenderHook("pre_render_panel_forums", w, r, &user, &pi) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = common.Templates.ExecuteTemplate(w, "panel-forums.html", pi)
|
|
||||||
if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func routePanelForumsCreateSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func routePanelForumsCreateSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
|
@ -274,7 +252,7 @@ func routePanelForumsDelete(w http.ResponseWriter, r *http.Request, user common.
|
||||||
confirmMsg := "Are you sure you want to delete the '" + forum.Name + "' forum?"
|
confirmMsg := "Are you sure you want to delete the '" + forum.Name + "' forum?"
|
||||||
yousure := common.AreYouSure{"/panel/forums/delete/submit/" + strconv.Itoa(fid), confirmMsg}
|
yousure := common.AreYouSure{"/panel/forums/delete/submit/" + strconv.Itoa(fid), confirmMsg}
|
||||||
|
|
||||||
pi := common.PanelPage{common.GetTitlePhrase("panel-delete-forum"), user, headerVars, stats, "forums", tList, yousure}
|
pi := common.PanelPage{common.GetTitlePhrase("panel_delete_forum"), user, headerVars, stats, "forums", tList, yousure}
|
||||||
if common.PreRenderHooks["pre_render_panel_delete_forum"] != nil {
|
if common.PreRenderHooks["pre_render_panel_delete_forum"] != nil {
|
||||||
if common.RunPreRenderHook("pre_render_panel_delete_forum", w, r, &user, &pi) {
|
if common.RunPreRenderHook("pre_render_panel_delete_forum", w, r, &user, &pi) {
|
||||||
return nil
|
return nil
|
||||||
|
@ -351,7 +329,7 @@ func routePanelForumsEdit(w http.ResponseWriter, r *http.Request, user common.Us
|
||||||
gplist = append(gplist, common.GroupForumPermPreset{group, common.ForumPermsToGroupForumPreset(group.Forums[fid])})
|
gplist = append(gplist, common.GroupForumPermPreset{group, common.ForumPermsToGroupForumPreset(group.Forums[fid])})
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelEditForumPage{common.GetTitlePhrase("panel-edit-forum"), user, headerVars, stats, "forums", forum.ID, forum.Name, forum.Desc, forum.Active, forum.Preset, gplist}
|
pi := common.PanelEditForumPage{common.GetTitlePhrase("panel_edit_forum"), user, headerVars, stats, "forums", forum.ID, forum.Name, forum.Desc, forum.Active, forum.Preset, gplist}
|
||||||
if common.PreRenderHooks["pre_render_panel_edit_forum"] != nil {
|
if common.PreRenderHooks["pre_render_panel_edit_forum"] != nil {
|
||||||
if common.RunPreRenderHook("pre_render_panel_edit_forum", w, r, &user, &pi) {
|
if common.RunPreRenderHook("pre_render_panel_edit_forum", w, r, &user, &pi) {
|
||||||
return nil
|
return nil
|
||||||
|
@ -513,7 +491,7 @@ func routePanelForumsEditPermsAdvance(w http.ResponseWriter, r *http.Request, us
|
||||||
addNameLangToggle("PinTopic", forumPerms.PinTopic)
|
addNameLangToggle("PinTopic", forumPerms.PinTopic)
|
||||||
addNameLangToggle("CloseTopic", forumPerms.CloseTopic)
|
addNameLangToggle("CloseTopic", forumPerms.CloseTopic)
|
||||||
|
|
||||||
pi := common.PanelEditForumGroupPage{common.GetTitlePhrase("panel-edit-forum"), user, headerVars, stats, "forums", forum.ID, gid, forum.Name, forum.Desc, forum.Active, forum.Preset, formattedPermList}
|
pi := common.PanelEditForumGroupPage{common.GetTitlePhrase("panel_edit_forum"), user, headerVars, stats, "forums", forum.ID, gid, forum.Name, forum.Desc, forum.Active, forum.Preset, formattedPermList}
|
||||||
if common.PreRenderHooks["pre_render_panel_edit_forum"] != nil {
|
if common.PreRenderHooks["pre_render_panel_edit_forum"] != nil {
|
||||||
if common.RunPreRenderHook("pre_render_panel_edit_forum", w, r, &user, &pi) {
|
if common.RunPreRenderHook("pre_render_panel_edit_forum", w, r, &user, &pi) {
|
||||||
return nil
|
return nil
|
||||||
|
@ -596,6 +574,12 @@ func routePanelAnalyticsViews(w http.ResponseWriter, r *http.Request, user commo
|
||||||
var timeRange = "six-hours"
|
var timeRange = "six-hours"
|
||||||
|
|
||||||
switch r.FormValue("timeRange") {
|
switch r.FormValue("timeRange") {
|
||||||
|
case "two-days": // Two days is experimental
|
||||||
|
timeQuantity = 2
|
||||||
|
timeUnit = "day"
|
||||||
|
timeSlices = 24
|
||||||
|
sliceWidth = 60 * 60 * 2
|
||||||
|
timeRange = "two-days"
|
||||||
case "one-day":
|
case "one-day":
|
||||||
timeQuantity = 1
|
timeQuantity = 1
|
||||||
timeUnit = "day"
|
timeUnit = "day"
|
||||||
|
@ -668,7 +652,7 @@ func routePanelAnalyticsViews(w http.ResponseWriter, r *http.Request, user commo
|
||||||
graph := common.PanelTimeGraph{Series: viewList, Labels: labelList}
|
graph := common.PanelTimeGraph{Series: viewList, Labels: labelList}
|
||||||
log.Printf("graph: %+v\n", graph)
|
log.Printf("graph: %+v\n", graph)
|
||||||
|
|
||||||
pi := common.PanelAnalyticsPage{common.GetTitlePhrase("panel-analytics"), user, headerVars, stats, "analytics", graph, viewItems, timeRange}
|
pi := common.PanelAnalyticsPage{common.GetTitlePhrase("panel_analytics"), user, headerVars, stats, "analytics", graph, viewItems, timeRange}
|
||||||
if common.PreRenderHooks["pre_render_panel_analytics"] != nil {
|
if common.PreRenderHooks["pre_render_panel_analytics"] != nil {
|
||||||
if common.RunPreRenderHook("pre_render_panel_analytics", w, r, &user, &pi) {
|
if common.RunPreRenderHook("pre_render_panel_analytics", w, r, &user, &pi) {
|
||||||
return nil
|
return nil
|
||||||
|
@ -696,6 +680,12 @@ func routePanelAnalyticsRouteViews(w http.ResponseWriter, r *http.Request, user
|
||||||
var timeRange = "six-hours"
|
var timeRange = "six-hours"
|
||||||
|
|
||||||
switch r.FormValue("timeRange") {
|
switch r.FormValue("timeRange") {
|
||||||
|
case "two-days": // Two days is experimental
|
||||||
|
timeQuantity = 2
|
||||||
|
timeUnit = "day"
|
||||||
|
timeSlices = 24
|
||||||
|
sliceWidth = 60 * 60 * 2
|
||||||
|
timeRange = "two-days"
|
||||||
case "one-day":
|
case "one-day":
|
||||||
timeQuantity = 1
|
timeQuantity = 1
|
||||||
timeUnit = "day"
|
timeUnit = "day"
|
||||||
|
@ -767,17 +757,8 @@ func routePanelAnalyticsRouteViews(w http.ResponseWriter, r *http.Request, user
|
||||||
graph := common.PanelTimeGraph{Series: viewList, Labels: labelList}
|
graph := common.PanelTimeGraph{Series: viewList, Labels: labelList}
|
||||||
log.Printf("graph: %+v\n", graph)
|
log.Printf("graph: %+v\n", graph)
|
||||||
|
|
||||||
pi := common.PanelAnalyticsRoutePage{common.GetTitlePhrase("panel-analytics"), user, headerVars, stats, "analytics", html.EscapeString(route), graph, timeRange}
|
pi := common.PanelAnalyticsRoutePage{common.GetTitlePhrase("panel_analytics"), user, headerVars, stats, "analytics", html.EscapeString(route), graph, timeRange}
|
||||||
if common.PreRenderHooks["pre_render_panel_analytics_route_views"] != nil {
|
return panelRenderTemplate("panel_analytics_route_views", w, r, user, &pi)
|
||||||
if common.RunPreRenderHook("pre_render_panel_analytics_route_views", w, r, &user, &pi) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = common.Templates.ExecuteTemplate(w, "panel-analytics-route-views.html", pi)
|
|
||||||
if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func routePanelAnalyticsAgentViews(w http.ResponseWriter, r *http.Request, user common.User, agent string) common.RouteError {
|
func routePanelAnalyticsAgentViews(w http.ResponseWriter, r *http.Request, user common.User, agent string) common.RouteError {
|
||||||
|
@ -795,6 +776,12 @@ func routePanelAnalyticsAgentViews(w http.ResponseWriter, r *http.Request, user
|
||||||
var timeRange = "six-hours"
|
var timeRange = "six-hours"
|
||||||
|
|
||||||
switch r.FormValue("timeRange") {
|
switch r.FormValue("timeRange") {
|
||||||
|
case "two-days": // Two days is experimental
|
||||||
|
timeQuantity = 2
|
||||||
|
timeUnit = "day"
|
||||||
|
timeSlices = 24
|
||||||
|
sliceWidth = 60 * 60 * 2
|
||||||
|
timeRange = "two-days"
|
||||||
case "one-day":
|
case "one-day":
|
||||||
timeQuantity = 1
|
timeQuantity = 1
|
||||||
timeUnit = "day"
|
timeUnit = "day"
|
||||||
|
@ -866,17 +853,8 @@ func routePanelAnalyticsAgentViews(w http.ResponseWriter, r *http.Request, user
|
||||||
graph := common.PanelTimeGraph{Series: viewList, Labels: labelList}
|
graph := common.PanelTimeGraph{Series: viewList, Labels: labelList}
|
||||||
log.Printf("graph: %+v\n", graph)
|
log.Printf("graph: %+v\n", graph)
|
||||||
|
|
||||||
pi := common.PanelAnalyticsAgentPage{common.GetTitlePhrase("panel-analytics"), user, headerVars, stats, "analytics", html.EscapeString(agent), graph, timeRange}
|
pi := common.PanelAnalyticsAgentPage{common.GetTitlePhrase("panel_analytics"), user, headerVars, stats, "analytics", html.EscapeString(agent), graph, timeRange}
|
||||||
if common.PreRenderHooks["pre_render_panel_analytics_agent_views"] != nil {
|
return panelRenderTemplate("panel_analytics_agent_views", w, r, user, &pi)
|
||||||
if common.RunPreRenderHook("pre_render_panel_analytics_agent_views", w, r, &user, &pi) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = common.Templates.ExecuteTemplate(w, "panel-analytics-agent-views.html", pi)
|
|
||||||
if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func routePanelAnalyticsRoutes(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func routePanelAnalyticsRoutes(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
|
@ -919,17 +897,8 @@ func routePanelAnalyticsRoutes(w http.ResponseWriter, r *http.Request, user comm
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelAnalyticsRoutesPage{common.GetTitlePhrase("panel-analytics"), user, headerVars, stats, "analytics", routeItems}
|
pi := common.PanelAnalyticsRoutesPage{common.GetTitlePhrase("panel_analytics"), user, headerVars, stats, "analytics", routeItems}
|
||||||
if common.PreRenderHooks["pre_render_panel_analytics_routes"] != nil {
|
return panelRenderTemplate("panel_analytics_routes", w, r, user, &pi)
|
||||||
if common.RunPreRenderHook("pre_render_panel_analytics_routes", w, r, &user, &pi) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = common.Templates.ExecuteTemplate(w, "panel-analytics-routes.html", pi)
|
|
||||||
if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func routePanelAnalyticsAgents(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func routePanelAnalyticsAgents(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
|
@ -972,17 +941,8 @@ func routePanelAnalyticsAgents(w http.ResponseWriter, r *http.Request, user comm
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelAnalyticsAgentsPage{common.GetTitlePhrase("panel-analytics"), user, headerVars, stats, "analytics", agentItems}
|
pi := common.PanelAnalyticsAgentsPage{common.GetTitlePhrase("panel_analytics"), user, headerVars, stats, "analytics", agentItems}
|
||||||
if common.PreRenderHooks["pre_render_panel_analytics_agents"] != nil {
|
return panelRenderTemplate("panel_analytics_agents", w, r, user, &pi)
|
||||||
if common.RunPreRenderHook("pre_render_panel_analytics_agents", w, r, &user, &pi) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = common.Templates.ExecuteTemplate(w, "panel-analytics-agents.html", pi)
|
|
||||||
if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func routePanelSettings(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func routePanelSettings(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
|
@ -1021,17 +981,8 @@ func routePanelSettings(w http.ResponseWriter, r *http.Request, user common.User
|
||||||
settingList[setting.Name] = setting.Content
|
settingList[setting.Name] = setting.Content
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelPage{common.GetTitlePhrase("panel-settings"), user, headerVars, stats, "settings", tList, settingList}
|
pi := common.PanelPage{common.GetTitlePhrase("panel_settings"), user, headerVars, stats, "settings", tList, settingList}
|
||||||
if common.PreRenderHooks["pre_render_panel_settings"] != nil {
|
return panelRenderTemplate("panel_settings", w, r, user, &pi)
|
||||||
if common.RunPreRenderHook("pre_render_panel_settings", w, r, &user, &pi) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = common.Templates.ExecuteTemplate(w, "panel-settings.html", pi)
|
|
||||||
if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func routePanelSettingEdit(w http.ResponseWriter, r *http.Request, user common.User, sname string) common.RouteError {
|
func routePanelSettingEdit(w http.ResponseWriter, r *http.Request, user common.User, sname string) common.RouteError {
|
||||||
|
@ -1067,17 +1018,8 @@ func routePanelSettingEdit(w http.ResponseWriter, r *http.Request, user common.U
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelPage{common.GetTitlePhrase("panel-edit-setting"), user, headerVars, stats, "settings", itemList, setting}
|
pi := common.PanelPage{common.GetTitlePhrase("panel_edit_setting"), user, headerVars, stats, "settings", itemList, setting}
|
||||||
if common.PreRenderHooks["pre_render_panel_setting"] != nil {
|
return panelRenderTemplate("panel_setting", w, r, user, &pi)
|
||||||
if common.RunPreRenderHook("pre_render_panel_setting", w, r, &user, &pi) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = common.Templates.ExecuteTemplate(w, "panel-setting.html", pi)
|
|
||||||
if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func routePanelSettingEditSubmit(w http.ResponseWriter, r *http.Request, user common.User, sname string) common.RouteError {
|
func routePanelSettingEditSubmit(w http.ResponseWriter, r *http.Request, user common.User, sname string) common.RouteError {
|
||||||
|
@ -1112,17 +1054,8 @@ func routePanelWordFilters(w http.ResponseWriter, r *http.Request, user common.U
|
||||||
}
|
}
|
||||||
|
|
||||||
var filterList = common.WordFilterBox.Load().(common.WordFilterMap)
|
var filterList = common.WordFilterBox.Load().(common.WordFilterMap)
|
||||||
pi := common.PanelPage{common.GetTitlePhrase("panel-word-filters"), user, headerVars, stats, "word-filters", tList, filterList}
|
pi := common.PanelPage{common.GetTitlePhrase("panel_word_filters"), user, headerVars, stats, "word-filters", tList, filterList}
|
||||||
if common.PreRenderHooks["pre_render_panel_word_filters"] != nil {
|
return panelRenderTemplate("panel_word_filters", w, r, user, &pi)
|
||||||
if common.RunPreRenderHook("pre_render_panel_word_filters", w, r, &user, &pi) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err := common.Templates.ExecuteTemplate(w, "panel-word-filters.html", pi)
|
|
||||||
if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func routePanelWordFiltersCreate(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func routePanelWordFiltersCreate(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
|
@ -1156,6 +1089,7 @@ func routePanelWordFiltersCreate(w http.ResponseWriter, r *http.Request, user co
|
||||||
return panelSuccessRedirect("/panel/settings/word-filters/", w, r, isJs)
|
return panelSuccessRedirect("/panel/settings/word-filters/", w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Implement this as a non-JS fallback
|
||||||
func routePanelWordFiltersEdit(w http.ResponseWriter, r *http.Request, user common.User, wfid string) common.RouteError {
|
func routePanelWordFiltersEdit(w http.ResponseWriter, r *http.Request, user common.User, wfid string) common.RouteError {
|
||||||
headerVars, stats, ferr := common.PanelUserCheck(w, r, &user)
|
headerVars, stats, ferr := common.PanelUserCheck(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
|
@ -1167,17 +1101,8 @@ func routePanelWordFiltersEdit(w http.ResponseWriter, r *http.Request, user comm
|
||||||
|
|
||||||
_ = wfid
|
_ = wfid
|
||||||
|
|
||||||
pi := common.PanelPage{common.GetTitlePhrase("panel-edit-word-filter"), user, headerVars, stats, "word-filters", tList, nil}
|
pi := common.PanelPage{common.GetTitlePhrase("panel_edit_word_filter"), user, headerVars, stats, "word-filters", tList, nil}
|
||||||
if common.PreRenderHooks["pre_render_panel_word_filters_edit"] != nil {
|
return panelRenderTemplate("panel_word_filters_edit", w, r, user, &pi)
|
||||||
if common.RunPreRenderHook("pre_render_panel_word_filters_edit", w, r, &user, &pi) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err := common.Templates.ExecuteTemplate(w, "panel-word-filters-edit.html", pi)
|
|
||||||
if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func routePanelWordFiltersEditSubmit(w http.ResponseWriter, r *http.Request, user common.User, wfid string) common.RouteError {
|
func routePanelWordFiltersEditSubmit(w http.ResponseWriter, r *http.Request, user common.User, wfid string) common.RouteError {
|
||||||
|
@ -1260,17 +1185,8 @@ func routePanelPlugins(w http.ResponseWriter, r *http.Request, user common.User)
|
||||||
pluginList = append(pluginList, plugin)
|
pluginList = append(pluginList, plugin)
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelPage{common.GetTitlePhrase("panel-plugins"), user, headerVars, stats, "plugins", pluginList, nil}
|
pi := common.PanelPage{common.GetTitlePhrase("panel_plugins"), user, headerVars, stats, "plugins", pluginList, nil}
|
||||||
if common.PreRenderHooks["pre_render_panel_plugins"] != nil {
|
return panelRenderTemplate("panel_plugins", w, r, user, &pi)
|
||||||
if common.RunPreRenderHook("pre_render_panel_plugins", w, r, &user, &pi) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err := common.Templates.ExecuteTemplate(w, "panel-plugins.html", pi)
|
|
||||||
if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func routePanelPluginsActivate(w http.ResponseWriter, r *http.Request, user common.User, uname string) common.RouteError {
|
func routePanelPluginsActivate(w http.ResponseWriter, r *http.Request, user common.User, uname string) common.RouteError {
|
||||||
|
@ -1481,17 +1397,8 @@ func routePanelUsers(w http.ResponseWriter, r *http.Request, user common.User) c
|
||||||
}
|
}
|
||||||
|
|
||||||
pageList := common.Paginate(stats.Users, perPage, 5)
|
pageList := common.Paginate(stats.Users, perPage, 5)
|
||||||
pi := common.PanelUserPage{common.GetTitlePhrase("panel-users"), user, headerVars, stats, "users", userList, pageList, page, lastPage}
|
pi := common.PanelUserPage{common.GetTitlePhrase("panel_users"), user, headerVars, stats, "users", userList, pageList, page, lastPage}
|
||||||
if common.PreRenderHooks["pre_render_panel_users"] != nil {
|
return panelRenderTemplate("panel_users", w, r, user, &pi)
|
||||||
if common.RunPreRenderHook("pre_render_panel_users", w, r, &user, &pi) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = common.Templates.ExecuteTemplate(w, "panel-users.html", pi)
|
|
||||||
if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func routePanelUsersEdit(w http.ResponseWriter, r *http.Request, user common.User, suid string) common.RouteError {
|
func routePanelUsersEdit(w http.ResponseWriter, r *http.Request, user common.User, suid string) common.RouteError {
|
||||||
|
@ -1536,7 +1443,7 @@ func routePanelUsersEdit(w http.ResponseWriter, r *http.Request, user common.Use
|
||||||
groupList = append(groupList, group)
|
groupList = append(groupList, group)
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelPage{common.GetTitlePhrase("panel-edit-user"), user, headerVars, stats, "users", groupList, targetUser}
|
pi := common.PanelPage{common.GetTitlePhrase("panel_edit_user"), user, headerVars, stats, "users", groupList, targetUser}
|
||||||
if common.PreRenderHooks["pre_render_panel_edit_user"] != nil {
|
if common.PreRenderHooks["pre_render_panel_edit_user"] != nil {
|
||||||
if common.RunPreRenderHook("pre_render_panel_edit_user", w, r, &user, &pi) {
|
if common.RunPreRenderHook("pre_render_panel_edit_user", w, r, &user, &pi) {
|
||||||
return nil
|
return nil
|
||||||
|
@ -1679,18 +1586,8 @@ func routePanelGroups(w http.ResponseWriter, r *http.Request, user common.User)
|
||||||
//log.Printf("groupList: %+v\n", groupList)
|
//log.Printf("groupList: %+v\n", groupList)
|
||||||
|
|
||||||
pageList := common.Paginate(stats.Groups, perPage, 5)
|
pageList := common.Paginate(stats.Groups, perPage, 5)
|
||||||
pi := common.PanelGroupPage{common.GetTitlePhrase("panel-groups"), user, headerVars, stats, "groups", groupList, pageList, page, lastPage}
|
pi := common.PanelGroupPage{common.GetTitlePhrase("panel_groups"), user, headerVars, stats, "groups", groupList, pageList, page, lastPage}
|
||||||
if common.PreRenderHooks["pre_render_panel_groups"] != nil {
|
return panelRenderTemplate("panel_groups", w, r, user, &pi)
|
||||||
if common.RunPreRenderHook("pre_render_panel_groups", w, r, &user, &pi) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err := common.Templates.ExecuteTemplate(w, "panel-groups.html", pi)
|
|
||||||
if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func routePanelGroupsEdit(w http.ResponseWriter, r *http.Request, user common.User, sgid string) common.RouteError {
|
func routePanelGroupsEdit(w http.ResponseWriter, r *http.Request, user common.User, sgid string) common.RouteError {
|
||||||
|
@ -1738,7 +1635,7 @@ func routePanelGroupsEdit(w http.ResponseWriter, r *http.Request, user common.Us
|
||||||
|
|
||||||
disableRank := !user.Perms.EditGroupGlobalPerms || (group.ID == 6)
|
disableRank := !user.Perms.EditGroupGlobalPerms || (group.ID == 6)
|
||||||
|
|
||||||
pi := common.PanelEditGroupPage{common.GetTitlePhrase("panel-edit-group"), user, headerVars, stats, "groups", group.ID, group.Name, group.Tag, rank, disableRank}
|
pi := common.PanelEditGroupPage{common.GetTitlePhrase("panel_edit_group"), user, headerVars, stats, "groups", group.ID, group.Name, group.Tag, rank, disableRank}
|
||||||
if common.PreRenderHooks["pre_render_panel_edit_group"] != nil {
|
if common.PreRenderHooks["pre_render_panel_edit_group"] != nil {
|
||||||
if common.RunPreRenderHook("pre_render_panel_edit_group", w, r, &user, &pi) {
|
if common.RunPreRenderHook("pre_render_panel_edit_group", w, r, &user, &pi) {
|
||||||
return nil
|
return nil
|
||||||
|
@ -1825,7 +1722,7 @@ func routePanelGroupsEditPerms(w http.ResponseWriter, r *http.Request, user comm
|
||||||
addGlobalPerm("ViewIPs", group.Perms.ViewIPs)
|
addGlobalPerm("ViewIPs", group.Perms.ViewIPs)
|
||||||
addGlobalPerm("UploadFiles", group.Perms.UploadFiles)
|
addGlobalPerm("UploadFiles", group.Perms.UploadFiles)
|
||||||
|
|
||||||
pi := common.PanelEditGroupPermsPage{common.GetTitlePhrase("panel-edit-group"), user, headerVars, stats, "groups", group.ID, group.Name, localPerms, globalPerms}
|
pi := common.PanelEditGroupPermsPage{common.GetTitlePhrase("panel_edit_group"), user, headerVars, stats, "groups", group.ID, group.Name, localPerms, globalPerms}
|
||||||
if common.PreRenderHooks["pre_render_panel_edit_group_perms"] != nil {
|
if common.PreRenderHooks["pre_render_panel_edit_group_perms"] != nil {
|
||||||
if common.RunPreRenderHook("pre_render_panel_edit_group_perms", w, r, &user, &pi) {
|
if common.RunPreRenderHook("pre_render_panel_edit_group_perms", w, r, &user, &pi) {
|
||||||
return nil
|
return nil
|
||||||
|
@ -2055,17 +1952,8 @@ func routePanelThemes(w http.ResponseWriter, r *http.Request, user common.User)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelThemesPage{common.GetTitlePhrase("panel-themes"), user, headerVars, stats, "themes", pThemeList, vThemeList}
|
pi := common.PanelThemesPage{common.GetTitlePhrase("panel_themes"), user, headerVars, stats, "themes", pThemeList, vThemeList}
|
||||||
if common.PreRenderHooks["pre_render_panel_themes"] != nil {
|
return panelRenderTemplate("panel_themes", w, r, user, &pi)
|
||||||
if common.RunPreRenderHook("pre_render_panel_themes", w, r, &user, &pi) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err := common.Templates.ExecuteTemplate(w, "panel-themes.html", pi)
|
|
||||||
if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func routePanelThemesSetDefault(w http.ResponseWriter, r *http.Request, user common.User, uname string) common.RouteError {
|
func routePanelThemesSetDefault(w http.ResponseWriter, r *http.Request, user common.User, uname string) common.RouteError {
|
||||||
|
@ -2172,12 +2060,8 @@ func routePanelBackups(w http.ResponseWriter, r *http.Request, user common.User,
|
||||||
backupList = append(backupList, common.BackupItem{backupFile.Name(), backupFile.ModTime()})
|
backupList = append(backupList, common.BackupItem{backupFile.Name(), backupFile.ModTime()})
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelBackupPage{common.GetTitlePhrase("panel-backups"), user, headerVars, stats, "backups", backupList}
|
pi := common.PanelBackupPage{common.GetTitlePhrase("panel_backups"), user, headerVars, stats, "backups", backupList}
|
||||||
err = common.Templates.ExecuteTemplate(w, "panel-backups.html", pi)
|
return panelRenderTemplate("panel_backups", w, r, user, &pi)
|
||||||
if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Log errors when something really screwy is going on?
|
// TODO: Log errors when something really screwy is going on?
|
||||||
|
@ -2270,17 +2154,48 @@ func routePanelLogsMod(w http.ResponseWriter, r *http.Request, user common.User)
|
||||||
}
|
}
|
||||||
|
|
||||||
pageList := common.Paginate(logCount, perPage, 5)
|
pageList := common.Paginate(logCount, perPage, 5)
|
||||||
pi := common.PanelLogsPage{common.GetTitlePhrase("panel-mod-logs"), user, headerVars, stats, "logs", logs, pageList, page, lastPage}
|
pi := common.PanelLogsPage{common.GetTitlePhrase("panel_mod_logs"), user, headerVars, stats, "logs", logs, pageList, page, lastPage}
|
||||||
if common.PreRenderHooks["pre_render_panel_mod_log"] != nil {
|
return panelRenderTemplate("panel_modlogs", w, r, user, &pi)
|
||||||
if common.RunPreRenderHook("pre_render_panel_mod_log", w, r, &user, &pi) {
|
}
|
||||||
return nil
|
|
||||||
|
func routePanelLogsAdmin(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
|
headerVars, stats, ferr := common.PanelUserCheck(w, r, &user)
|
||||||
|
if ferr != nil {
|
||||||
|
return ferr
|
||||||
}
|
}
|
||||||
}
|
|
||||||
err = common.Templates.ExecuteTemplate(w, "panel-modlogs.html", pi)
|
logCount := common.ModLogs.GlobalCount()
|
||||||
|
page, _ := strconv.Atoi(r.FormValue("page"))
|
||||||
|
perPage := 10
|
||||||
|
offset, page, lastPage := common.PageOffset(logCount, page, perPage)
|
||||||
|
|
||||||
|
rows, err := stmts.getAdminlogsOffset.Query(offset, perPage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
return nil
|
defer rows.Close()
|
||||||
|
|
||||||
|
var logs []common.LogItem
|
||||||
|
var action, elementType, ipaddress, doneAt string
|
||||||
|
var elementID, actorID int
|
||||||
|
for rows.Next() {
|
||||||
|
err := rows.Scan(&action, &elementID, &elementType, &ipaddress, &actorID, &doneAt)
|
||||||
|
if err != nil {
|
||||||
|
return common.InternalError(err, w, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
actor := handleUnknownUser(common.Users.Get(actorID))
|
||||||
|
action = modlogsElementType(action, elementType, elementID, actor)
|
||||||
|
logs = append(logs, common.LogItem{Action: template.HTML(action), IPAddress: ipaddress, DoneAt: doneAt})
|
||||||
|
}
|
||||||
|
err = rows.Err()
|
||||||
|
if err != nil {
|
||||||
|
return common.InternalError(err, w, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
pageList := common.Paginate(logCount, perPage, 5)
|
||||||
|
pi := common.PanelLogsPage{common.GetTitlePhrase("panel_admin_logs"), user, headerVars, stats, "logs", logs, pageList, page, lastPage}
|
||||||
|
return panelRenderTemplate("panel_adminlogs", w, r, user, &pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func routePanelDebug(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func routePanelDebug(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
|
@ -2294,10 +2209,6 @@ func routePanelDebug(w http.ResponseWriter, r *http.Request, user common.User) c
|
||||||
openConnCount := dbStats.OpenConnections
|
openConnCount := dbStats.OpenConnections
|
||||||
// Disk I/O?
|
// Disk I/O?
|
||||||
|
|
||||||
pi := common.PanelDebugPage{common.GetTitlePhrase("panel-debug"), user, headerVars, stats, "debug", uptime, openConnCount, dbAdapter}
|
pi := common.PanelDebugPage{common.GetTitlePhrase("panel_debug"), user, headerVars, stats, "debug", uptime, openConnCount, dbAdapter}
|
||||||
err := common.Templates.ExecuteTemplate(w, "panel-debug.html", pi)
|
return panelRenderTemplate("panel_debug", w, r, user, &pi)
|
||||||
if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -507,6 +507,14 @@ $(document).ready(function(){
|
||||||
let action = optionNode.getAttribute("val");
|
let action = optionNode.getAttribute("val");
|
||||||
//console.log("action",action);
|
//console.log("action",action);
|
||||||
|
|
||||||
|
// Handle these specially
|
||||||
|
switch(action) {
|
||||||
|
case "move":
|
||||||
|
console.log("move action");
|
||||||
|
$("#mod_topic_mover").removeClass("auto_hide");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let url = "/topic/"+action+"/submit/";
|
let url = "/topic/"+action+"/submit/";
|
||||||
//console.log("JSON.stringify(selectedTopics) ", JSON.stringify(selectedTopics));
|
//console.log("JSON.stringify(selectedTopics) ", JSON.stringify(selectedTopics));
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
|
|
@ -230,6 +230,8 @@ func writeSelects(adapter qgen.Adapter) error {
|
||||||
|
|
||||||
build.Select("getModlogsOffset").Table("moderation_logs").Columns("action, elementID, elementType, ipaddress, actorID, doneAt").Orderby("doneAt DESC").Limit("?,?").Parse()
|
build.Select("getModlogsOffset").Table("moderation_logs").Columns("action, elementID, elementType, ipaddress, actorID, doneAt").Orderby("doneAt DESC").Limit("?,?").Parse()
|
||||||
|
|
||||||
|
build.Select("getAdminlogsOffset").Table("administration_logs").Columns("action, elementID, elementType, ipaddress, actorID, doneAt").Orderby("doneAt DESC").Limit("?,?").Parse()
|
||||||
|
|
||||||
build.Select("getReplyTID").Table("replies").Columns("tid").Where("rid = ?").Parse()
|
build.Select("getReplyTID").Table("replies").Columns("tid").Where("rid = ?").Parse()
|
||||||
|
|
||||||
build.Select("getTopicFID").Table("topics").Columns("parentID").Where("tid = ?").Parse()
|
build.Select("getTopicFID").Table("topics").Columns("parentID").Where("tid = ?").Parse()
|
||||||
|
|
|
@ -171,6 +171,9 @@ func main() {
|
||||||
"bing",
|
"bing",
|
||||||
"baidu",
|
"baidu",
|
||||||
"duckduckgo",
|
"duckduckgo",
|
||||||
|
"discord",
|
||||||
|
"lynx",
|
||||||
|
"blank",
|
||||||
}
|
}
|
||||||
|
|
||||||
tmplVars.AllAgentMap = make(map[string]int)
|
tmplVars.AllAgentMap = make(map[string]int)
|
||||||
|
@ -307,7 +310,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
// Track the user agents. Unfortunately, everyone pretends to be Mozilla, so this'll be a little less efficient than I would like.
|
// Track the user agents. Unfortunately, everyone pretends to be Mozilla, so this'll be a little less efficient than I would like.
|
||||||
// TODO: Add a setting to disable this?
|
// TODO: Add a setting to disable this?
|
||||||
// TODO: Use a more efficient detector instead of smashing every possible combination in
|
// TODO: Use a more efficient detector instead of smashing every possible combination in
|
||||||
ua := strings.TrimSuffix(strings.TrimPrefix(req.UserAgent(),"Mozilla/5.0 ")," Safari/537.36") // Noise, no one's going to be running this and it complicates implementing an efficient UA parser, particularly the more efficient right-to-left one I have in mind
|
ua := strings.TrimSpace(strings.TrimSuffix(strings.TrimPrefix(req.UserAgent(),"Mozilla/5.0 ")," Safari/537.36")) // Noise, no one's going to be running this and it complicates implementing an efficient UA parser, particularly the more efficient right-to-left one I have in mind
|
||||||
switch {
|
switch {
|
||||||
case strings.Contains(ua,"Google"):
|
case strings.Contains(ua,"Google"):
|
||||||
common.AgentViewCounter.Bump({{.AllAgentMap.googlebot}})
|
common.AgentViewCounter.Bump({{.AllAgentMap.googlebot}})
|
||||||
|
@ -331,6 +334,12 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
common.AgentViewCounter.Bump({{.AllAgentMap.baidu}})
|
common.AgentViewCounter.Bump({{.AllAgentMap.baidu}})
|
||||||
case strings.Contains(ua,"DuckDuckBot"):
|
case strings.Contains(ua,"DuckDuckBot"):
|
||||||
common.AgentViewCounter.Bump({{.AllAgentMap.duckduckgo}})
|
common.AgentViewCounter.Bump({{.AllAgentMap.duckduckgo}})
|
||||||
|
case strings.Contains(ua,"Discordbot"):
|
||||||
|
common.AgentViewCounter.Bump({{.AllAgentMap.discord}})
|
||||||
|
case strings.Contains(ua,"Lynx"):
|
||||||
|
common.AgentViewCounter.Bump({{.AllAgentMap.lynx}})
|
||||||
|
case ua == "":
|
||||||
|
common.AgentViewCounter.Bump({{.AllAgentMap.blank}})
|
||||||
default:
|
default:
|
||||||
common.AgentViewCounter.Bump({{.AllAgentMap.unknown}})
|
common.AgentViewCounter.Bump({{.AllAgentMap.unknown}})
|
||||||
if common.Dev.DebugMode {
|
if common.Dev.DebugMode {
|
||||||
|
|
113
template_list.go
113
template_list.go
|
@ -811,6 +811,7 @@ var topics_8 = []byte(`
|
||||||
<select class="mod_floater_options">
|
<select class="mod_floater_options">
|
||||||
<option val="delete">Delete them</option>
|
<option val="delete">Delete them</option>
|
||||||
<option val="lock">Lock them</option>
|
<option val="lock">Lock them</option>
|
||||||
|
<option val="move">Move them</option>
|
||||||
</select>
|
</select>
|
||||||
<button class="mod_floater_submit">Run</button>
|
<button class="mod_floater_submit">Run</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -819,21 +820,40 @@ var topics_8 = []byte(`
|
||||||
|
|
||||||
`)
|
`)
|
||||||
var topics_9 = []byte(`
|
var topics_9 = []byte(`
|
||||||
|
<div id="mod_topic_mover" class="modal_pane auto_hide">
|
||||||
|
<form action="/topic/move/submit/" method="post">
|
||||||
|
<div class="pane_header">
|
||||||
|
<h3>Move Topics (3)</h3>
|
||||||
|
</div>
|
||||||
|
<div class="pane_body">
|
||||||
|
<div class="pane_table">
|
||||||
|
<div class="pane_row"></div>
|
||||||
|
`)
|
||||||
|
var topics_10 = []byte(`<div class="pane_row">`)
|
||||||
|
var topics_11 = []byte(`</div>`)
|
||||||
|
var topics_12 = []byte(`
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="pane_buttons">
|
||||||
|
<button>Move Topics</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
<div class="rowblock topic_create_form quick_create_form" style="display: none;" aria-label="Quick Topic Form">
|
<div class="rowblock topic_create_form quick_create_form" style="display: none;" aria-label="Quick Topic Form">
|
||||||
<form name="topic_create_form_form" id="topic_create_form_form" enctype="multipart/form-data" action="/topic/create/submit/" method="post"></form>
|
<form name="topic_create_form_form" id="topic_create_form_form" enctype="multipart/form-data" action="/topic/create/submit/" method="post"></form>
|
||||||
<img class="little_row_avatar" src="`)
|
<img class="little_row_avatar" src="`)
|
||||||
var topics_10 = []byte(`" height="64" alt="Your Avatar" title="Your Avatar" />
|
var topics_13 = []byte(`" height="64" alt="Your Avatar" title="Your Avatar" />
|
||||||
<div class="main_form">
|
<div class="main_form">
|
||||||
<div class="topic_meta">
|
<div class="topic_meta">
|
||||||
<div class="formrow topic_board_row real_first_child">
|
<div class="formrow topic_board_row real_first_child">
|
||||||
<div class="formitem"><select form="topic_create_form_form" id="topic_board_input" name="topic-board">
|
<div class="formitem"><select form="topic_create_form_form" id="topic_board_input" name="topic-board">
|
||||||
`)
|
`)
|
||||||
var topics_11 = []byte(`<option `)
|
var topics_14 = []byte(`<option `)
|
||||||
var topics_12 = []byte(`selected`)
|
var topics_15 = []byte(`selected`)
|
||||||
var topics_13 = []byte(` value="`)
|
var topics_16 = []byte(` value="`)
|
||||||
var topics_14 = []byte(`">`)
|
var topics_17 = []byte(`">`)
|
||||||
var topics_15 = []byte(`</option>`)
|
var topics_18 = []byte(`</option>`)
|
||||||
var topics_16 = []byte(`
|
var topics_19 = []byte(`
|
||||||
</select></div>
|
</select></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="formrow topic_name_row">
|
<div class="formrow topic_name_row">
|
||||||
|
@ -851,77 +871,77 @@ var topics_16 = []byte(`
|
||||||
<div class="formitem">
|
<div class="formitem">
|
||||||
<button form="topic_create_form_form" class="formbutton">Create Topic</button>
|
<button form="topic_create_form_form" class="formbutton">Create Topic</button>
|
||||||
`)
|
`)
|
||||||
var topics_17 = []byte(`
|
var topics_20 = []byte(`
|
||||||
<input name="upload_files" form="topic_create_form_form" id="upload_files" multiple type="file" style="display: none;" />
|
<input name="upload_files" form="topic_create_form_form" id="upload_files" multiple type="file" style="display: none;" />
|
||||||
<label for="upload_files" class="formbutton add_file_button">Add File</label>
|
<label for="upload_files" class="formbutton add_file_button">Add File</label>
|
||||||
<div id="upload_file_dock"></div>`)
|
<div id="upload_file_dock"></div>`)
|
||||||
var topics_18 = []byte(`
|
var topics_21 = []byte(`
|
||||||
<button class="formbutton close_form">Cancel</button>
|
<button class="formbutton close_form">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`)
|
`)
|
||||||
var topics_19 = []byte(`
|
var topics_22 = []byte(`
|
||||||
<div id="topic_list" class="rowblock topic_list" aria-label="A list containing topics from every forum">
|
<div id="topic_list" class="rowblock topic_list" aria-label="A list containing topics from every forum">
|
||||||
`)
|
`)
|
||||||
var topics_20 = []byte(`<div class="topic_row" data-tid="`)
|
var topics_23 = []byte(`<div class="topic_row" data-tid="`)
|
||||||
var topics_21 = []byte(`">
|
|
||||||
<div class="rowitem topic_left passive datarow `)
|
|
||||||
var topics_22 = []byte(`topic_sticky`)
|
|
||||||
var topics_23 = []byte(`topic_closed`)
|
|
||||||
var topics_24 = []byte(`">
|
var topics_24 = []byte(`">
|
||||||
|
<div class="rowitem topic_left passive datarow `)
|
||||||
|
var topics_25 = []byte(`topic_sticky`)
|
||||||
|
var topics_26 = []byte(`topic_closed`)
|
||||||
|
var topics_27 = []byte(`">
|
||||||
<span class="selector"></span>
|
<span class="selector"></span>
|
||||||
<a href="`)
|
<a href="`)
|
||||||
var topics_25 = []byte(`"><img src="`)
|
var topics_28 = []byte(`"><img src="`)
|
||||||
var topics_26 = []byte(`" height="64" alt="`)
|
var topics_29 = []byte(`" height="64" alt="`)
|
||||||
var topics_27 = []byte(`'s Avatar" title="`)
|
var topics_30 = []byte(`'s Avatar" title="`)
|
||||||
var topics_28 = []byte(`'s Avatar" /></a>
|
var topics_31 = []byte(`'s Avatar" /></a>
|
||||||
<span class="topic_inner_left">
|
<span class="topic_inner_left">
|
||||||
<a class="rowtopic" href="`)
|
<a class="rowtopic" href="`)
|
||||||
var topics_29 = []byte(`" itemprop="itemListElement"><span>`)
|
var topics_32 = []byte(`" itemprop="itemListElement"><span>`)
|
||||||
var topics_30 = []byte(`</span></a> `)
|
var topics_33 = []byte(`</span></a> `)
|
||||||
var topics_31 = []byte(`<a class="rowsmall parent_forum" href="`)
|
var topics_34 = []byte(`<a class="rowsmall parent_forum" href="`)
|
||||||
var topics_32 = []byte(`">`)
|
|
||||||
var topics_33 = []byte(`</a>`)
|
|
||||||
var topics_34 = []byte(`
|
|
||||||
<br /><a class="rowsmall starter" href="`)
|
|
||||||
var topics_35 = []byte(`">`)
|
var topics_35 = []byte(`">`)
|
||||||
var topics_36 = []byte(`</a>
|
var topics_36 = []byte(`</a>`)
|
||||||
|
var topics_37 = []byte(`
|
||||||
|
<br /><a class="rowsmall starter" href="`)
|
||||||
|
var topics_38 = []byte(`">`)
|
||||||
|
var topics_39 = []byte(`</a>
|
||||||
`)
|
`)
|
||||||
var topics_37 = []byte(`<span class="rowsmall topic_status_e topic_status_closed" title="Status: Closed"> | 🔒︎</span>`)
|
var topics_40 = []byte(`<span class="rowsmall topic_status_e topic_status_closed" title="Status: Closed"> | 🔒︎</span>`)
|
||||||
var topics_38 = []byte(`<span class="rowsmall topic_status_e topic_status_sticky" title="Status: Pinned"> | 📍︎</span>`)
|
var topics_41 = []byte(`<span class="rowsmall topic_status_e topic_status_sticky" title="Status: Pinned"> | 📍︎</span>`)
|
||||||
var topics_39 = []byte(`
|
var topics_42 = []byte(`
|
||||||
</span>
|
</span>
|
||||||
<span class="topic_inner_right rowsmall" style="float: right;">
|
<span class="topic_inner_right rowsmall" style="float: right;">
|
||||||
<span class="replyCount">`)
|
<span class="replyCount">`)
|
||||||
var topics_40 = []byte(`</span><br />
|
var topics_43 = []byte(`</span><br />
|
||||||
<span class="likeCount">`)
|
<span class="likeCount">`)
|
||||||
var topics_41 = []byte(`</span>
|
var topics_44 = []byte(`</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="rowitem topic_right passive datarow `)
|
<div class="rowitem topic_right passive datarow `)
|
||||||
var topics_42 = []byte(`topic_sticky`)
|
var topics_45 = []byte(`topic_sticky`)
|
||||||
var topics_43 = []byte(`topic_closed`)
|
var topics_46 = []byte(`topic_closed`)
|
||||||
var topics_44 = []byte(`">
|
var topics_47 = []byte(`">
|
||||||
<a href="`)
|
<a href="`)
|
||||||
var topics_45 = []byte(`"><img src="`)
|
var topics_48 = []byte(`"><img src="`)
|
||||||
var topics_46 = []byte(`" height="64" alt="`)
|
var topics_49 = []byte(`" height="64" alt="`)
|
||||||
var topics_47 = []byte(`'s Avatar" title="`)
|
var topics_50 = []byte(`'s Avatar" title="`)
|
||||||
var topics_48 = []byte(`'s Avatar" /></a>
|
var topics_51 = []byte(`'s Avatar" /></a>
|
||||||
<span>
|
<span>
|
||||||
<a href="`)
|
<a href="`)
|
||||||
var topics_49 = []byte(`" class="lastName" style="font-size: 14px;">`)
|
var topics_52 = []byte(`" class="lastName" style="font-size: 14px;">`)
|
||||||
var topics_50 = []byte(`</a><br>
|
var topics_53 = []byte(`</a><br>
|
||||||
<span class="rowsmall lastReplyAt">`)
|
<span class="rowsmall lastReplyAt">`)
|
||||||
var topics_51 = []byte(`</span>
|
var topics_54 = []byte(`</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>`)
|
</div>`)
|
||||||
var topics_52 = []byte(`<div class="rowitem passive">There aren't any topics yet.`)
|
var topics_55 = []byte(`<div class="rowitem passive">There aren't any topics yet.`)
|
||||||
var topics_53 = []byte(` <a href="/topics/create/">Start one?</a>`)
|
var topics_56 = []byte(` <a href="/topics/create/">Start one?</a>`)
|
||||||
var topics_54 = []byte(`</div>`)
|
var topics_57 = []byte(`</div>`)
|
||||||
var topics_55 = []byte(`
|
var topics_58 = []byte(`
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
@ -973,6 +993,7 @@ var forum_18 = []byte(`
|
||||||
<select class="mod_floater_options">
|
<select class="mod_floater_options">
|
||||||
<option val="delete">Delete them</option>
|
<option val="delete">Delete them</option>
|
||||||
<option val="lock">Lock them</option>
|
<option val="lock">Lock them</option>
|
||||||
|
<option val="move">Move them</option>
|
||||||
</select>
|
</select>
|
||||||
<button>Run</button>
|
<button>Run</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
// Code generated by Gosora. More below:
|
// Code generated by Gosora. More below:
|
||||||
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
||||||
package main
|
package main
|
||||||
import "net/http"
|
|
||||||
import "./common"
|
import "./common"
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
import "net/http"
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -99,108 +99,116 @@ if tmpl_topics_vars.CurrentUser.ID != 0 {
|
||||||
w.Write(topics_8)
|
w.Write(topics_8)
|
||||||
if len(tmpl_topics_vars.ForumList) != 0 {
|
if len(tmpl_topics_vars.ForumList) != 0 {
|
||||||
w.Write(topics_9)
|
w.Write(topics_9)
|
||||||
w.Write([]byte(tmpl_topics_vars.CurrentUser.Avatar))
|
|
||||||
w.Write(topics_10)
|
|
||||||
if len(tmpl_topics_vars.ForumList) != 0 {
|
if len(tmpl_topics_vars.ForumList) != 0 {
|
||||||
for _, item := range tmpl_topics_vars.ForumList {
|
for _, item := range tmpl_topics_vars.ForumList {
|
||||||
w.Write(topics_11)
|
w.Write(topics_10)
|
||||||
if item.ID == tmpl_topics_vars.DefaultForum {
|
|
||||||
w.Write(topics_12)
|
|
||||||
}
|
|
||||||
w.Write(topics_13)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.ID)))
|
|
||||||
w.Write(topics_14)
|
|
||||||
w.Write([]byte(item.Name))
|
w.Write([]byte(item.Name))
|
||||||
|
w.Write(topics_11)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.Write(topics_12)
|
||||||
|
w.Write([]byte(tmpl_topics_vars.CurrentUser.Avatar))
|
||||||
|
w.Write(topics_13)
|
||||||
|
if len(tmpl_topics_vars.ForumList) != 0 {
|
||||||
|
for _, item := range tmpl_topics_vars.ForumList {
|
||||||
|
w.Write(topics_14)
|
||||||
|
if item.ID == tmpl_topics_vars.DefaultForum {
|
||||||
w.Write(topics_15)
|
w.Write(topics_15)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
w.Write(topics_16)
|
w.Write(topics_16)
|
||||||
if tmpl_topics_vars.CurrentUser.Perms.UploadFiles {
|
w.Write([]byte(strconv.Itoa(item.ID)))
|
||||||
w.Write(topics_17)
|
w.Write(topics_17)
|
||||||
}
|
w.Write([]byte(item.Name))
|
||||||
w.Write(topics_18)
|
w.Write(topics_18)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.Write(topics_19)
|
w.Write(topics_19)
|
||||||
|
if tmpl_topics_vars.CurrentUser.Perms.UploadFiles {
|
||||||
|
w.Write(topics_20)
|
||||||
|
}
|
||||||
|
w.Write(topics_21)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.Write(topics_22)
|
||||||
if len(tmpl_topics_vars.TopicList) != 0 {
|
if len(tmpl_topics_vars.TopicList) != 0 {
|
||||||
for _, item := range tmpl_topics_vars.TopicList {
|
for _, item := range tmpl_topics_vars.TopicList {
|
||||||
w.Write(topics_20)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.ID)))
|
|
||||||
w.Write(topics_21)
|
|
||||||
if item.Sticky {
|
|
||||||
w.Write(topics_22)
|
|
||||||
} else {
|
|
||||||
if item.IsClosed {
|
|
||||||
w.Write(topics_23)
|
w.Write(topics_23)
|
||||||
}
|
w.Write([]byte(strconv.Itoa(item.ID)))
|
||||||
}
|
|
||||||
w.Write(topics_24)
|
w.Write(topics_24)
|
||||||
w.Write([]byte(item.Creator.Link))
|
if item.Sticky {
|
||||||
w.Write(topics_25)
|
w.Write(topics_25)
|
||||||
w.Write([]byte(item.Creator.Avatar))
|
|
||||||
w.Write(topics_26)
|
|
||||||
w.Write([]byte(item.Creator.Name))
|
|
||||||
w.Write(topics_27)
|
|
||||||
w.Write([]byte(item.Creator.Name))
|
|
||||||
w.Write(topics_28)
|
|
||||||
w.Write([]byte(item.Link))
|
|
||||||
w.Write(topics_29)
|
|
||||||
w.Write([]byte(item.Title))
|
|
||||||
w.Write(topics_30)
|
|
||||||
if item.ForumName != "" {
|
|
||||||
w.Write(topics_31)
|
|
||||||
w.Write([]byte(item.ForumLink))
|
|
||||||
w.Write(topics_32)
|
|
||||||
w.Write([]byte(item.ForumName))
|
|
||||||
w.Write(topics_33)
|
|
||||||
}
|
|
||||||
w.Write(topics_34)
|
|
||||||
w.Write([]byte(item.Creator.Link))
|
|
||||||
w.Write(topics_35)
|
|
||||||
w.Write([]byte(item.Creator.Name))
|
|
||||||
w.Write(topics_36)
|
|
||||||
if item.IsClosed {
|
|
||||||
w.Write(topics_37)
|
|
||||||
}
|
|
||||||
if item.Sticky {
|
|
||||||
w.Write(topics_38)
|
|
||||||
}
|
|
||||||
w.Write(topics_39)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.PostCount)))
|
|
||||||
w.Write(topics_40)
|
|
||||||
w.Write([]byte(strconv.Itoa(item.LikeCount)))
|
|
||||||
w.Write(topics_41)
|
|
||||||
if item.Sticky {
|
|
||||||
w.Write(topics_42)
|
|
||||||
} else {
|
} else {
|
||||||
if item.IsClosed {
|
if item.IsClosed {
|
||||||
|
w.Write(topics_26)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.Write(topics_27)
|
||||||
|
w.Write([]byte(item.Creator.Link))
|
||||||
|
w.Write(topics_28)
|
||||||
|
w.Write([]byte(item.Creator.Avatar))
|
||||||
|
w.Write(topics_29)
|
||||||
|
w.Write([]byte(item.Creator.Name))
|
||||||
|
w.Write(topics_30)
|
||||||
|
w.Write([]byte(item.Creator.Name))
|
||||||
|
w.Write(topics_31)
|
||||||
|
w.Write([]byte(item.Link))
|
||||||
|
w.Write(topics_32)
|
||||||
|
w.Write([]byte(item.Title))
|
||||||
|
w.Write(topics_33)
|
||||||
|
if item.ForumName != "" {
|
||||||
|
w.Write(topics_34)
|
||||||
|
w.Write([]byte(item.ForumLink))
|
||||||
|
w.Write(topics_35)
|
||||||
|
w.Write([]byte(item.ForumName))
|
||||||
|
w.Write(topics_36)
|
||||||
|
}
|
||||||
|
w.Write(topics_37)
|
||||||
|
w.Write([]byte(item.Creator.Link))
|
||||||
|
w.Write(topics_38)
|
||||||
|
w.Write([]byte(item.Creator.Name))
|
||||||
|
w.Write(topics_39)
|
||||||
|
if item.IsClosed {
|
||||||
|
w.Write(topics_40)
|
||||||
|
}
|
||||||
|
if item.Sticky {
|
||||||
|
w.Write(topics_41)
|
||||||
|
}
|
||||||
|
w.Write(topics_42)
|
||||||
|
w.Write([]byte(strconv.Itoa(item.PostCount)))
|
||||||
w.Write(topics_43)
|
w.Write(topics_43)
|
||||||
}
|
w.Write([]byte(strconv.Itoa(item.LikeCount)))
|
||||||
}
|
|
||||||
w.Write(topics_44)
|
w.Write(topics_44)
|
||||||
w.Write([]byte(item.LastUser.Link))
|
if item.Sticky {
|
||||||
w.Write(topics_45)
|
w.Write(topics_45)
|
||||||
w.Write([]byte(item.LastUser.Avatar))
|
} else {
|
||||||
|
if item.IsClosed {
|
||||||
w.Write(topics_46)
|
w.Write(topics_46)
|
||||||
w.Write([]byte(item.LastUser.Name))
|
}
|
||||||
|
}
|
||||||
w.Write(topics_47)
|
w.Write(topics_47)
|
||||||
w.Write([]byte(item.LastUser.Name))
|
|
||||||
w.Write(topics_48)
|
|
||||||
w.Write([]byte(item.LastUser.Link))
|
w.Write([]byte(item.LastUser.Link))
|
||||||
|
w.Write(topics_48)
|
||||||
|
w.Write([]byte(item.LastUser.Avatar))
|
||||||
w.Write(topics_49)
|
w.Write(topics_49)
|
||||||
w.Write([]byte(item.LastUser.Name))
|
w.Write([]byte(item.LastUser.Name))
|
||||||
w.Write(topics_50)
|
w.Write(topics_50)
|
||||||
w.Write([]byte(item.RelativeLastReplyAt))
|
w.Write([]byte(item.LastUser.Name))
|
||||||
w.Write(topics_51)
|
w.Write(topics_51)
|
||||||
}
|
w.Write([]byte(item.LastUser.Link))
|
||||||
} else {
|
|
||||||
w.Write(topics_52)
|
w.Write(topics_52)
|
||||||
if tmpl_topics_vars.CurrentUser.Perms.CreateTopic {
|
w.Write([]byte(item.LastUser.Name))
|
||||||
w.Write(topics_53)
|
w.Write(topics_53)
|
||||||
}
|
w.Write([]byte(item.RelativeLastReplyAt))
|
||||||
w.Write(topics_54)
|
w.Write(topics_54)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
w.Write(topics_55)
|
w.Write(topics_55)
|
||||||
|
if tmpl_topics_vars.CurrentUser.Perms.CreateTopic {
|
||||||
|
w.Write(topics_56)
|
||||||
|
}
|
||||||
|
w.Write(topics_57)
|
||||||
|
}
|
||||||
|
w.Write(topics_58)
|
||||||
w.Write(footer_0)
|
w.Write(footer_0)
|
||||||
w.Write([]byte(common.BuildWidget("footer",tmpl_topics_vars.Header)))
|
w.Write([]byte(common.BuildWidget("footer",tmpl_topics_vars.Header)))
|
||||||
w.Write(footer_1)
|
w.Write(footer_1)
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
<select class="mod_floater_options">
|
<select class="mod_floater_options">
|
||||||
<option val="delete">Delete them</option>
|
<option val="delete">Delete them</option>
|
||||||
<option val="lock">Lock them</option>
|
<option val="lock">Lock them</option>
|
||||||
|
<option val="move">Move them</option>
|
||||||
</select>
|
</select>
|
||||||
<button>Run</button>
|
<button>Run</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
<div class="rowitem">
|
<div class="rowitem">
|
||||||
<a>Views</a>
|
<a>Views</a>
|
||||||
<select class="timeRangeSelector to_right" name="timeRange">
|
<select class="timeRangeSelector to_right" name="timeRange">
|
||||||
|
<option val="two-days"{{if eq .TimeRange "two-days"}} selected{{end}}>2 days</option>
|
||||||
<option val="one-day"{{if eq .TimeRange "one-day"}} selected{{end}}>1 day</option>
|
<option val="one-day"{{if eq .TimeRange "one-day"}} selected{{end}}>1 day</option>
|
||||||
<option val="twelve-hours"{{if eq .TimeRange "twelve-hours"}} selected{{end}}>12 hours</option>
|
<option val="twelve-hours"{{if eq .TimeRange "twelve-hours"}} selected{{end}}>12 hours</option>
|
||||||
<option val="six-hours"{{if eq .TimeRange "six-hours"}} selected{{end}}>6 hours</option>
|
<option val="six-hours"{{if eq .TimeRange "six-hours"}} selected{{end}}>6 hours</option>
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
<div class="rowitem">
|
<div class="rowitem">
|
||||||
<a>{{.Agent}} Views</a>
|
<a>{{.Agent}} Views</a>
|
||||||
<select class="timeRangeSelector to_right" name="timeRange">
|
<select class="timeRangeSelector to_right" name="timeRange">
|
||||||
|
<option val="two-days"{{if eq .TimeRange "two-days"}} selected{{end}}>2 days</option>
|
||||||
<option val="one-day"{{if eq .TimeRange "one-day"}} selected{{end}}>1 day</option>
|
<option val="one-day"{{if eq .TimeRange "one-day"}} selected{{end}}>1 day</option>
|
||||||
<option val="twelve-hours"{{if eq .TimeRange "twelve-hours"}} selected{{end}}>12 hours</option>
|
<option val="twelve-hours"{{if eq .TimeRange "twelve-hours"}} selected{{end}}>12 hours</option>
|
||||||
<option val="six-hours"{{if eq .TimeRange "six-hours"}} selected{{end}}>6 hours</option>
|
<option val="six-hours"{{if eq .TimeRange "six-hours"}} selected{{end}}>6 hours</option>
|
|
@ -7,6 +7,7 @@
|
||||||
<div class="rowitem">
|
<div class="rowitem">
|
||||||
<a>{{.Route}} Views</a>
|
<a>{{.Route}} Views</a>
|
||||||
<select class="timeRangeSelector to_right" name="timeRange">
|
<select class="timeRangeSelector to_right" name="timeRange">
|
||||||
|
<option val="two-days"{{if eq .TimeRange "two-days"}} selected{{end}}>2 days</option>
|
||||||
<option val="one-day"{{if eq .TimeRange "one-day"}} selected{{end}}>1 day</option>
|
<option val="one-day"{{if eq .TimeRange "one-day"}} selected{{end}}>1 day</option>
|
||||||
<option val="twelve-hours"{{if eq .TimeRange "twelve-hours"}} selected{{end}}>12 hours</option>
|
<option val="twelve-hours"{{if eq .TimeRange "twelve-hours"}} selected{{end}}>12 hours</option>
|
||||||
<option val="six-hours"{{if eq .TimeRange "six-hours"}} selected{{end}}>6 hours</option>
|
<option val="six-hours"{{if eq .TimeRange "six-hours"}} selected{{end}}>6 hours</option>
|
|
@ -17,6 +17,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{if ne .CurrentUser.ID 0}}
|
{{if ne .CurrentUser.ID 0}}
|
||||||
|
{{/** TODO: Hide these from unauthorised users? **/}}
|
||||||
<div class="mod_floater auto_hide">
|
<div class="mod_floater auto_hide">
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<div class="mod_floater_head">
|
<div class="mod_floater_head">
|
||||||
|
@ -26,6 +27,7 @@
|
||||||
<select class="mod_floater_options">
|
<select class="mod_floater_options">
|
||||||
<option val="delete">Delete them</option>
|
<option val="delete">Delete them</option>
|
||||||
<option val="lock">Lock them</option>
|
<option val="lock">Lock them</option>
|
||||||
|
<option val="move">Move them</option>
|
||||||
</select>
|
</select>
|
||||||
<button class="mod_floater_submit">Run</button>
|
<button class="mod_floater_submit">Run</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -33,6 +35,24 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{if .ForumList}}
|
{{if .ForumList}}
|
||||||
|
{{/** TODO: Have a seperate forum list for moving topics? Maybe an AJAX forum search compatible with plugin_guilds? **/}}
|
||||||
|
{{/** TODO: Add ARIA attributes for this **/}}
|
||||||
|
<div id="mod_topic_mover" class="modal_pane auto_hide">
|
||||||
|
<form action="/topic/move/submit/" method="post">
|
||||||
|
<div class="pane_header">
|
||||||
|
<h3>Move Topics (3)</h3>
|
||||||
|
</div>
|
||||||
|
<div class="pane_body">
|
||||||
|
<div class="pane_table">
|
||||||
|
<div class="pane_row"></div>
|
||||||
|
{{range .ForumList}}<div class="pane_row">{{.Name}}</div>{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="pane_buttons">
|
||||||
|
<button>Move Topics</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
<div class="rowblock topic_create_form quick_create_form" style="display: none;" aria-label="Quick Topic Form">
|
<div class="rowblock topic_create_form quick_create_form" style="display: none;" aria-label="Quick Topic Form">
|
||||||
<form name="topic_create_form_form" id="topic_create_form_form" enctype="multipart/form-data" action="/topic/create/submit/" method="post"></form>
|
<form name="topic_create_form_form" id="topic_create_form_form" enctype="multipart/form-data" action="/topic/create/submit/" method="post"></form>
|
||||||
<img class="little_row_avatar" src="{{.CurrentUser.Avatar}}" height="64" alt="Your Avatar" title="Your Avatar" />
|
<img class="little_row_avatar" src="{{.CurrentUser.Avatar}}" height="64" alt="Your Avatar" title="Your Avatar" />
|
||||||
|
|
|
@ -220,16 +220,18 @@ ul {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
color: var(--primary-text-color);
|
color: var(--primary-text-color);
|
||||||
-webkit-margin-before: 0;
|
|
||||||
-webkit-margin-after: 0;
|
|
||||||
margin-block-start: 0;
|
|
||||||
margin-block-end: 0;
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
.colstack_head a h1 {
|
.colstack_head a h1 {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: var(--primary-link-color);
|
color: var(--primary-link-color);
|
||||||
}
|
}
|
||||||
|
h1, h3 {
|
||||||
|
-webkit-margin-before: 0;
|
||||||
|
-webkit-margin-after: 0;
|
||||||
|
margin-block-start: 0;
|
||||||
|
margin-block-end: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.colstack {
|
.colstack {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -261,9 +263,9 @@ ul {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 15px;
|
bottom: 15px;
|
||||||
right: 15px;
|
right: 15px;
|
||||||
background-color: var(--inverse-primary-text-color);
|
|
||||||
width: 200px;
|
width: 200px;
|
||||||
height: 115px;
|
height: 115px;
|
||||||
|
background-color: var(--inverse-primary-text-color);
|
||||||
border: 1px solid var(--header-border-color);
|
border: 1px solid var(--header-border-color);
|
||||||
border-bottom: 2px solid var(--header-border-color);
|
border-bottom: 2px solid var(--header-border-color);
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
|
@ -308,6 +310,17 @@ ul {
|
||||||
margin-top: -2px;
|
margin-top: -2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal_pane {
|
||||||
|
position: fixed;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background-color: var(--inverse-primary-text-color);
|
||||||
|
border: 1px solid var(--header-border-color);
|
||||||
|
border-bottom: 2px solid var(--header-border-color);
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes fadein {
|
@keyframes fadein {
|
||||||
from { opacity: 0; }
|
from { opacity: 0; }
|
||||||
to { opacity: 1; }
|
to { opacity: 1; }
|
||||||
|
|
|
@ -174,7 +174,7 @@
|
||||||
stroke: hsl(359,98%,23%) !important;
|
stroke: hsl(359,98%,23%) !important;
|
||||||
}
|
}
|
||||||
.ct-point:hover {
|
.ct-point:hover {
|
||||||
stroke: hsl(359,98%,20%) !important;
|
stroke: hsl(359,98%,30%) !important;
|
||||||
}
|
}
|
||||||
.timeRangeSelector {
|
.timeRangeSelector {
|
||||||
margin-top: -5px;
|
margin-top: -5px;
|
||||||
|
|
Loading…
Reference in New Issue