Refactored the routing logic.

Continued refactoring the prequeries.
Continued work on the profiles.
Moved more logic out of the routes.
This commit is contained in:
Azareal 2017-11-12 07:18:25 +00:00
parent 2047fed0b9
commit f1c418bd13
14 changed files with 272 additions and 154 deletions

View File

@ -92,7 +92,6 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
routeStatic(w, req)
return
}
if common.Dev.SuperDebug {
log.Print("before PreRoute")
}
@ -102,7 +101,6 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if !ok {
return
}
if common.Dev.SuperDebug {
log.Print("after PreRoute")
}
@ -130,36 +128,48 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
router.handleError(err,w,req,user)
}
case "/theme":
err = common.ParseForm(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = routeChangeTheme(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
}
case "/attachs":
err = common.ParseForm(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = routeShowAttachment(w,req,user,extra_data)
if err != nil {
router.handleError(err,w,req,user)
}
case "/report":
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.NoBanned(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
switch(req.URL.Path) {
case "/report/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = routeReportSubmit(w,req,user,extra_data)
}
if err != nil {
@ -248,7 +258,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
case "/panel/settings/word-filters/":
err = routePanelWordFilters(w,req,user)
case "/panel/settings/word-filters/create/":
err = common.ParseForm(w,req,user)
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
@ -258,7 +268,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
case "/panel/settings/word-filters/edit/":
err = routePanelWordFiltersEdit(w,req,user,extra_data)
case "/panel/settings/word-filters/edit/submit/":
err = common.ParseForm(w,req,user)
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
@ -266,7 +276,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
err = routePanelWordFiltersEditSubmit(w,req,user,extra_data)
case "/panel/settings/word-filters/delete/submit/":
err = common.ParseForm(w,req,user)
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
@ -418,6 +428,12 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
err = routeAccountEditUsername(w,req,user)
case "/user/edit/username/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
@ -434,6 +450,12 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
err = routeAccountEditEmail(w,req,user)
case "/user/edit/token/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
@ -449,12 +471,6 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
router.handleError(err,w,req,user)
}
case "/users":
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
switch(req.URL.Path) {
case "/users/ban/submit/":
err = common.NoSessionMismatch(w,req,user)
@ -463,6 +479,12 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = routeBanSubmit(w,req,user)
case "/users/unban/":
err = common.NoSessionMismatch(w,req,user)
@ -471,6 +493,12 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = routeUnban(w,req,user)
case "/users/activate/":
err = common.NoSessionMismatch(w,req,user)
@ -479,8 +507,20 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = routeActivate(w,req,user)
case "/users/ips/":
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = routeIps(w,req,user)
}
if err != nil {

View File

@ -985,11 +985,6 @@ func routeLogout(w http.ResponseWriter, r *http.Request, user common.User) commo
}
func routeShowAttachment(w http.ResponseWriter, r *http.Request, user common.User, filename string) common.RouteError {
err := r.ParseForm()
if err != nil {
return common.PreError("Bad Form", w, r)
}
filename = common.Stripslashes(filename)
var ext = filepath.Ext("./attachs/" + filename)
//log.Print("ext ", ext)

View File

@ -1071,6 +1071,11 @@ func (adapter *MssqlAdapter) Select(nlist ...string) *selectPrebuilder {
return &selectPrebuilder{name, "", "", "", "", "", adapter}
}
func (adapter *MssqlAdapter) Insert(nlist ...string) *insertPrebuilder {
name := optString(nlist, "_builder")
return &insertPrebuilder{name, "", "", "", adapter}
}
func (adapter *MssqlAdapter) Write() error {
var stmts, body string
for _, name := range adapter.BufferOrder {

View File

@ -557,6 +557,11 @@ func (adapter *MysqlAdapter) Select(nlist ...string) *selectPrebuilder {
return &selectPrebuilder{name, "", "", "", "", "", adapter}
}
func (adapter *MysqlAdapter) Insert(nlist ...string) *insertPrebuilder {
name := optString(nlist, "_builder")
return &insertPrebuilder{name, "", "", "", adapter}
}
func (adapter *MysqlAdapter) Write() error {
var stmts, body string
for _, name := range adapter.BufferOrder {

View File

@ -323,6 +323,11 @@ func (adapter *PgsqlAdapter) Select(nlist ...string) *selectPrebuilder {
return &selectPrebuilder{name, "", "", "", "", "", adapter}
}
func (adapter *PgsqlAdapter) Insert(nlist ...string) *insertPrebuilder {
name := optString(nlist, "_builder")
return &insertPrebuilder{name, "", "", "", adapter}
}
func (adapter *PgsqlAdapter) Write() error {
var stmts, body string
for _, name := range adapter.BufferOrder {

View File

@ -117,9 +117,8 @@ type Adapter interface {
SimpleCount(string, string, string, string) (string, error)
Select(name ...string) *selectPrebuilder
Insert(name ...string) *insertPrebuilder
Write() error
// TODO: Add a simple query builder
}
func GetAdapter(name string) (adap Adapter, err error) {

View File

@ -232,37 +232,37 @@ func writeSelects(adapter qgen.Adapter) error {
adapter.Select("isPluginActive").Table("plugins").Columns("active").Where("uname = ?").Parse()
//adapter.SimpleSelect("isPluginInstalled","plugins","installed","uname = ?","","")
//adapter.Select("isPluginInstalled").Table("plugins").Columns("installed").Where("uname = ?").Parse()
adapter.Select("getUsersOffset").Table("users").Columns("uid, name, group, active, is_super_admin, avatar").Orderby("uid ASC").Limit("?,?").Parse()
adapter.SimpleSelect("isThemeDefault", "themes", "default", "uname = ?", "", "")
adapter.Select("isThemeDefault").Table("themes").Columns("default").Where("uname = ?").Parse()
adapter.SimpleSelect("getModlogs", "moderation_logs", "action, elementID, elementType, ipaddress, actorID, doneAt", "", "", "")
adapter.Select("getModlogs").Table("moderation_logs").Columns("action, elementID, elementType, ipaddress, actorID, doneAt").Parse()
adapter.SimpleSelect("getModlogsOffset", "moderation_logs", "action, elementID, elementType, ipaddress, actorID, doneAt", "", "doneAt DESC", "?,?")
adapter.Select("getModlogsOffset").Table("moderation_logs").Columns("action, elementID, elementType, ipaddress, actorID, doneAt").Orderby("doneAt DESC").Limit("?,?").Parse()
adapter.SimpleSelect("getReplyTID", "replies", "tid", "rid = ?", "", "")
adapter.Select("getReplyTID").Table("replies").Columns("tid").Where("rid = ?").Parse()
adapter.SimpleSelect("getTopicFID", "topics", "parentID", "tid = ?", "", "")
adapter.Select("getTopicFID").Table("topics").Columns("parentID").Where("tid = ?").Parse()
adapter.SimpleSelect("getUserReplyUID", "users_replies", "uid", "rid = ?", "", "")
adapter.Select("getUserReplyUID").Table("users_replies").Columns("uid").Where("rid = ?").Parse()
adapter.SimpleSelect("getUserName", "users", "name", "uid = ?", "", "")
adapter.Select("getUserName").Table("users").Columns("name").Where("uid = ?").Parse()
adapter.SimpleSelect("getEmailsByUser", "emails", "email, validated, token", "uid = ?", "", "")
adapter.Select("getEmailsByUser").Table("emails").Columns("email, validated, token").Where("uid = ?").Parse()
adapter.SimpleSelect("getTopicBasic", "topics", "title, content", "tid = ?", "", "")
adapter.Select("getTopicBasic").Table("topics").Columns("title, content").Where("tid = ?").Parse()
adapter.SimpleSelect("getActivityEntry", "activity_stream", "actor, targetUser, event, elementType, elementID", "asid = ?", "", "")
adapter.Select("getActivityEntry").Table("activity_stream").Columns("actor, targetUser, event, elementType, elementID").Where("asid = ?").Parse()
adapter.SimpleSelect("forumEntryExists", "forums", "fid", "name = ''", "fid ASC", "0,1")
adapter.Select("forumEntryExists").Table("forums").Columns("fid").Where("name = ''").Orderby("fid ASC").Limit("0,1").Parse()
adapter.SimpleSelect("groupEntryExists", "users_groups", "gid", "name = ''", "gid ASC", "0,1")
adapter.Select("groupEntryExists").Table("users_groups").Columns("gid").Where("name = ''").Orderby("gid ASC").Limit("0,1").Parse()
adapter.SimpleSelect("getForumTopicsOffset", "topics", "tid, title, content, createdBy, is_closed, sticky, createdAt, lastReplyAt, lastReplyBy, parentID, postCount, likeCount", "parentID = ?", "sticky DESC, lastReplyAt DESC, createdBy DESC", "?,?")
adapter.Select("getForumTopicsOffset").Table("topics").Columns("tid, title, content, createdBy, is_closed, sticky, createdAt, lastReplyAt, lastReplyBy, parentID, postCount, likeCount").Where("parentID = ?").Orderby("sticky DESC, lastReplyAt DESC, createdBy DESC").Limit("?,?").Parse()
adapter.SimpleSelect("getAttachment", "attachments", "sectionID, sectionTable, originID, originTable, uploadedBy, path", "path = ? AND sectionID = ? AND sectionTable = ?", "", "")
adapter.Select("getAttachment").Table("attachments").Columns("sectionID, sectionTable, originID, originTable, uploadedBy, path").Where("path = ? AND sectionID = ? AND sectionTable = ?").Parse()
return nil
}
@ -291,11 +291,11 @@ func writeInnerJoins(adapter qgen.Adapter) (err error) {
}
func writeInserts(adapter qgen.Adapter) error {
adapter.SimpleInsert("createReport", "topics", "title, content, parsed_content, createdAt, lastReplyAt, createdBy, lastReplyBy, data, parentID, css_class", "?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,1,'report'")
adapter.Insert("createReport").Table("topics").Columns("title, content, parsed_content, createdAt, lastReplyAt, createdBy, lastReplyBy, data, parentID, css_class").Fields("?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,1,'report'").Parse()
adapter.SimpleInsert("addActivity", "activity_stream", "actor, targetUser, event, elementType, elementID", "?,?,?,?,?")
adapter.Insert("addActivity").Table("activity_stream").Columns("actor, targetUser, event, elementType, elementID").Fields("?,?,?,?,?").Parse()
adapter.SimpleInsert("notifyOne", "activity_stream_matches", "watcher, asid", "?,?")
adapter.Insert("notifyOne").Table("activity_stream_matches").Columns("watcher, asid").Fields("?,?").Parse()
adapter.SimpleInsert("addEmail", "emails", "email, uid, validated, token", "?,?,?,?")

View File

@ -52,12 +52,7 @@ func main() {
}
for _, group := range routeGroups {
var end int
if group.Path[len(group.Path)-1] == '/' {
end = len(group.Path) - 1
} else {
end = len(group.Path) - 1
}
var end = len(group.Path) - 1
out += `
case "` + group.Path[0:end] + `":`
for _, runnable := range group.RunBefore {
@ -84,7 +79,24 @@ func main() {
out += "\n\t\t\t\tcase \"" + route.Path + "\":"
if len(route.RunBefore) > 0 {
skipRunnable:
for _, runnable := range route.RunBefore {
for _, gRunnable := range group.RunBefore {
if gRunnable.Contents == runnable.Contents {
continue
}
// TODO: Stop hard-coding these
if gRunnable.Contents == "AdminOnly" && runnable.Contents == "MemberOnly" {
continue skipRunnable
}
if gRunnable.Contents == "AdminOnly" && runnable.Contents == "SuperModOnly" {
continue skipRunnable
}
if gRunnable.Contents == "SuperModOnly" && runnable.Contents == "MemberOnly" {
continue skipRunnable
}
}
if runnable.Literal {
out += "\n\t\t\t\t\t" + runnable.Contents
} else {
@ -227,7 +239,6 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
routeStatic(w, req)
return
}
if common.Dev.SuperDebug {
log.Print("before PreRoute")
}
@ -237,7 +248,6 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if !ok {
return
}
if common.Dev.SuperDebug {
log.Print("after PreRoute")
}

View File

@ -7,7 +7,12 @@ type RouteGroup struct {
}
func newRouteGroup(path string, routes ...*RouteImpl) *RouteGroup {
return &RouteGroup{path, routes, []Runnable{}}
group := &RouteGroup{Path: path}
for _, route := range routes {
route.Parent = group
group.RouteList = append(group.RouteList, route)
}
return group
}
func (group *RouteGroup) Not(path ...string) *RouteSubset {
@ -45,6 +50,9 @@ func (group *RouteGroup) LitBefore(lines ...string) *RouteGroup {
}
func (group *RouteGroup) Routes(routes ...*RouteImpl) *RouteGroup {
group.RouteList = append(group.RouteList, routes...)
for _, route := range routes {
route.Parent = group
group.RouteList = append(group.RouteList, route)
}
return group
}

View File

@ -1,10 +1,13 @@
package main
type RouteImpl struct {
Name string
Path string
Vars []string
RunBefore []Runnable
Name string
Path string
Vars []string
MemberAction bool
RunBefore []Runnable
Parent *RouteGroup
}
type Runnable struct {
@ -30,14 +33,64 @@ func (route *RouteImpl) LitBefore(items ...string) *RouteImpl {
return route
}
func (route *RouteImpl) hasBefore(items ...string) bool {
for _, item := range items {
for _, before := range route.RunBefore {
if before.Contents == item {
return true
}
}
}
return false
}
func addRouteGroup(routeGroup *RouteGroup) {
routeGroups = append(routeGroups, routeGroup)
}
func blankRoute() *RouteImpl {
return &RouteImpl{"", "", []string{}, []Runnable{}}
return &RouteImpl{"", "", []string{}, false, []Runnable{}, nil}
}
func Route(fname string, path string, args ...string) *RouteImpl {
return &RouteImpl{fname, path, args, []Runnable{}}
func View(fname string, path string, args ...string) *RouteImpl {
return &RouteImpl{fname, path, args, false, []Runnable{}, nil}
}
func MemberView(fname string, path string, args ...string) *RouteImpl {
route := &RouteImpl{fname, path, args, false, []Runnable{}, nil}
if !route.hasBefore("SuperModOnly", "AdminOnly") {
route.Before("MemberOnly")
}
return route
}
func ModView(fname string, path string, args ...string) *RouteImpl {
route := &RouteImpl{fname, path, args, false, []Runnable{}, nil}
if !route.hasBefore("AdminOnly") {
route.Before("SuperModOnly")
}
return route
}
func Action(fname string, path string, args ...string) *RouteImpl {
route := &RouteImpl{fname, path, args, true, []Runnable{}, nil}
route.Before("NoSessionMismatch")
if !route.hasBefore("SuperModOnly", "AdminOnly") {
route.Before("MemberOnly")
}
return route
}
func AnonAction(fname string, path string, args ...string) *RouteImpl {
route := &RouteImpl{fname, path, args, false, []Runnable{}, nil}
route.Before("ParseForm")
return route
}
func UploadAction(fname string, path string, args ...string) *RouteImpl {
route := &RouteImpl{fname, path, args, true, []Runnable{}, nil}
if !route.hasBefore("SuperModOnly", "AdminOnly") {
route.Before("MemberOnly")
}
return route
}

View File

@ -2,27 +2,25 @@ package main
// TODO: How should we handle headerLite and headerVar?
func routes() {
//addRoute("default_route","","")
addRoute(Route("routeAPI", "/api/"))
///addRoute("routeStatic","/static/","req.URL.Path += extra_data")
addRoute(Route("routeOverview", "/overview/"))
addRoute(View("routeAPI", "/api/"))
addRoute(View("routeOverview", "/overview/"))
//addRoute("routeCustomPage","/pages/",""/*,"&extra_data"*/)
addRoute(Route("routeForums", "/forums/" /*,"&forums"*/))
addRoute(Route("routeForum", "/forum/", "extra_data"))
//addRoute("routeTopicCreate","/topics/create/","","extra_data")
//addRoute("routeTopics","/topics/",""/*,"&groups","&forums"*/)
addRoute(Route("routeChangeTheme", "/theme/"))
addRoute(Route("routeShowAttachment", "/attachs/", "extra_data"))
addRoute(View("routeForums", "/forums/" /*,"&forums"*/))
addRoute(View("routeForum", "/forum/", "extra_data"))
addRoute(AnonAction("routeChangeTheme", "/theme/"))
addRoute(
View("routeShowAttachment", "/attachs/", "extra_data").Before("ParseForm"),
)
// TODO: Reduce the number of Befores. With a new method, perhaps?
reportGroup := newRouteGroup("/report/",
Route("routeReportSubmit", "/report/submit/", "extra_data"),
).Before("MemberOnly", "NoBanned", "NoSessionMismatch")
Action("routeReportSubmit", "/report/submit/", "extra_data"),
).Before("NoBanned")
addRouteGroup(reportGroup)
topicGroup := newRouteGroup("/topics/",
Route("routeTopics", "/topics/"),
Route("routeTopicCreate", "/topics/create/", "extra_data").Before("MemberOnly"),
View("routeTopics", "/topics/"),
MemberView("routeTopicCreate", "/topics/create/", "extra_data"),
)
addRouteGroup(topicGroup)
@ -34,73 +32,73 @@ func routes() {
func buildUserRoutes() {
userGroup := newRouteGroup("/user/")
userGroup.Routes(
Route("routeProfile", "/user/").LitBefore("req.URL.Path += extra_data"),
Route("routeAccountEditCritical", "/user/edit/critical/"),
Route("routeAccountEditCriticalSubmit", "/user/edit/critical/submit/").Before("NoSessionMismatch"), // TODO: Full test this
Route("routeAccountEditAvatar", "/user/edit/avatar/"),
Route("routeAccountEditAvatarSubmit", "/user/edit/avatar/submit/"),
Route("routeAccountEditUsername", "/user/edit/username/"),
Route("routeAccountEditUsernameSubmit", "/user/edit/username/submit/"), // TODO: Full test this
Route("routeAccountEditEmail", "/user/edit/email/"),
Route("routeAccountEditEmailTokenSubmit", "/user/edit/token/", "extra_data"),
).Not("/user/").Before("MemberOnly")
View("routeProfile", "/user/").LitBefore("req.URL.Path += extra_data"),
MemberView("routeAccountEditCritical", "/user/edit/critical/"),
Action("routeAccountEditCriticalSubmit", "/user/edit/critical/submit/"), // TODO: Full test this
MemberView("routeAccountEditAvatar", "/user/edit/avatar/"),
UploadAction("routeAccountEditAvatarSubmit", "/user/edit/avatar/submit/"),
MemberView("routeAccountEditUsername", "/user/edit/username/"),
Action("routeAccountEditUsernameSubmit", "/user/edit/username/submit/"), // TODO: Full test this
MemberView("routeAccountEditEmail", "/user/edit/email/"),
Action("routeAccountEditEmailTokenSubmit", "/user/edit/token/", "extra_data"),
)
addRouteGroup(userGroup)
// TODO: Auto test and manual test these routes
userGroup = newRouteGroup("/users/").Before("MemberOnly")
userGroup = newRouteGroup("/users/")
userGroup.Routes(
Route("routeBanSubmit", "/users/ban/submit/"),
Route("routeUnban", "/users/unban/"),
Route("routeActivate", "/users/activate/"),
Route("routeIps", "/users/ips/"),
).Not("/users/ips/").Before("NoSessionMismatch")
Action("routeBanSubmit", "/users/ban/submit/"),
Action("routeUnban", "/users/unban/"),
Action("routeActivate", "/users/activate/"),
MemberView("routeIps", "/users/ips/"),
)
addRouteGroup(userGroup)
}
func buildPanelRoutes() {
panelGroup := newRouteGroup("/panel/").Before("SuperModOnly")
panelGroup.Routes(
Route("routePanel", "/panel/"),
Route("routePanelForums", "/panel/forums/"),
Route("routePanelForumsCreateSubmit", "/panel/forums/create/").Before("NoSessionMismatch"),
Route("routePanelForumsDelete", "/panel/forums/delete/", "extra_data").Before("NoSessionMismatch"),
Route("routePanelForumsDeleteSubmit", "/panel/forums/delete/submit/", "extra_data").Before("NoSessionMismatch"),
Route("routePanelForumsEdit", "/panel/forums/edit/", "extra_data"),
Route("routePanelForumsEditSubmit", "/panel/forums/edit/submit/", "extra_data").Before("NoSessionMismatch"),
Route("routePanelForumsEditPermsSubmit", "/panel/forums/edit/perms/submit/", "extra_data").Before("NoSessionMismatch"),
View("routePanel", "/panel/"),
View("routePanelForums", "/panel/forums/"),
Action("routePanelForumsCreateSubmit", "/panel/forums/create/"),
Action("routePanelForumsDelete", "/panel/forums/delete/", "extra_data"),
Action("routePanelForumsDeleteSubmit", "/panel/forums/delete/submit/", "extra_data"),
View("routePanelForumsEdit", "/panel/forums/edit/", "extra_data"),
Action("routePanelForumsEditSubmit", "/panel/forums/edit/submit/", "extra_data"),
Action("routePanelForumsEditPermsSubmit", "/panel/forums/edit/perms/submit/", "extra_data"),
Route("routePanelSettings", "/panel/settings/"),
Route("routePanelSetting", "/panel/settings/edit/", "extra_data"),
Route("routePanelSettingEdit", "/panel/settings/edit/submit/", "extra_data").Before("NoSessionMismatch"),
View("routePanelSettings", "/panel/settings/"),
View("routePanelSetting", "/panel/settings/edit/", "extra_data"),
Action("routePanelSettingEdit", "/panel/settings/edit/submit/", "extra_data"),
Route("routePanelWordFilters", "/panel/settings/word-filters/"),
Route("routePanelWordFiltersCreate", "/panel/settings/word-filters/create/").Before("ParseForm"),
Route("routePanelWordFiltersEdit", "/panel/settings/word-filters/edit/", "extra_data"),
Route("routePanelWordFiltersEditSubmit", "/panel/settings/word-filters/edit/submit/", "extra_data").Before("ParseForm"),
Route("routePanelWordFiltersDeleteSubmit", "/panel/settings/word-filters/delete/submit/", "extra_data").Before("ParseForm"),
View("routePanelWordFilters", "/panel/settings/word-filters/"),
Action("routePanelWordFiltersCreate", "/panel/settings/word-filters/create/"),
View("routePanelWordFiltersEdit", "/panel/settings/word-filters/edit/", "extra_data"),
Action("routePanelWordFiltersEditSubmit", "/panel/settings/word-filters/edit/submit/", "extra_data"),
Action("routePanelWordFiltersDeleteSubmit", "/panel/settings/word-filters/delete/submit/", "extra_data"),
Route("routePanelThemes", "/panel/themes/"),
Route("routePanelThemesSetDefault", "/panel/themes/default/", "extra_data").Before("NoSessionMismatch"),
View("routePanelThemes", "/panel/themes/"),
Action("routePanelThemesSetDefault", "/panel/themes/default/", "extra_data"),
Route("routePanelPlugins", "/panel/plugins/"),
Route("routePanelPluginsActivate", "/panel/plugins/activate/", "extra_data").Before("NoSessionMismatch"),
Route("routePanelPluginsDeactivate", "/panel/plugins/deactivate/", "extra_data").Before("NoSessionMismatch"),
Route("routePanelPluginsInstall", "/panel/plugins/install/", "extra_data").Before("NoSessionMismatch"),
View("routePanelPlugins", "/panel/plugins/"),
Action("routePanelPluginsActivate", "/panel/plugins/activate/", "extra_data"),
Action("routePanelPluginsDeactivate", "/panel/plugins/deactivate/", "extra_data"),
Action("routePanelPluginsInstall", "/panel/plugins/install/", "extra_data"),
Route("routePanelUsers", "/panel/users/"),
Route("routePanelUsersEdit", "/panel/users/edit/", "extra_data"),
Route("routePanelUsersEditSubmit", "/panel/users/edit/submit/", "extra_data").Before("NoSessionMismatch"),
View("routePanelUsers", "/panel/users/"),
View("routePanelUsersEdit", "/panel/users/edit/", "extra_data"),
Action("routePanelUsersEditSubmit", "/panel/users/edit/submit/", "extra_data"),
Route("routePanelGroups", "/panel/groups/"),
Route("routePanelGroupsEdit", "/panel/groups/edit/", "extra_data"),
Route("routePanelGroupsEditPerms", "/panel/groups/edit/perms/", "extra_data"),
Route("routePanelGroupsEditSubmit", "/panel/groups/edit/submit/", "extra_data").Before("NoSessionMismatch"),
Route("routePanelGroupsEditPermsSubmit", "/panel/groups/edit/perms/submit/", "extra_data").Before("NoSessionMismatch"),
Route("routePanelGroupsCreateSubmit", "/panel/groups/create/").Before("NoSessionMismatch"),
View("routePanelGroups", "/panel/groups/"),
View("routePanelGroupsEdit", "/panel/groups/edit/", "extra_data"),
View("routePanelGroupsEditPerms", "/panel/groups/edit/perms/", "extra_data"),
Action("routePanelGroupsEditSubmit", "/panel/groups/edit/submit/", "extra_data"),
Action("routePanelGroupsEditPermsSubmit", "/panel/groups/edit/perms/submit/", "extra_data"),
Action("routePanelGroupsCreateSubmit", "/panel/groups/create/"),
Route("routePanelBackups", "/panel/backups/", "extra_data"),
Route("routePanelLogsMod", "/panel/logs/mod/"),
Route("routePanelDebug", "/panel/debug/").Before("AdminOnly"),
View("routePanelBackups", "/panel/backups/", "extra_data"),
View("routePanelLogsMod", "/panel/logs/mod/"),
View("routePanelDebug", "/panel/debug/").Before("AdminOnly"),
)
addRouteGroup(panelGroup)
}

View File

@ -918,31 +918,15 @@ func routeRegisterSubmit(w http.ResponseWriter, r *http.Request, user common.Use
// TODO: Set the cookie domain
func routeChangeTheme(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
//headerLite, _ := SimpleUserCheck(w, r, &user)
err := r.ParseForm()
if err != nil {
return common.PreError("Bad Form", w, r)
}
// TODO: Rename isJs to something else, just in case we rewrite the JS side in WebAssembly?
isJs := (r.PostFormValue("isJs") == "1")
newTheme := html.EscapeString(r.PostFormValue("newTheme"))
theme, ok := common.Themes[newTheme]
if !ok || theme.HideFromThemes {
// TODO: Should we be logging this?
log.Print("Bad Theme: ", newTheme)
return common.LocalErrorJSQ("That theme doesn't exist", w, r, user, isJs)
}
// TODO: Store the current theme in the user's account?
/*if user.Loggedin {
_, err = stmts.changeTheme.Exec(newTheme, user.ID)
if err != nil {
return common.InternalError(err, w, r)
}
}*/
cookie := http.Cookie{Name: "current_theme", Value: newTheme, Path: "/", MaxAge: common.Year}
http.SetCookie(w, &cookie)

View File

@ -7,11 +7,13 @@
<div class="rowitem"><h1>Profile</h1></div>
</header>-->
<div id="profile_left_pane" class="rowmenu">
<div class="rowitem avatarRow">
<img src="{{.ProfileOwner.Avatar}}" class="avatar" />
</div>
<div class="rowitem nameRow">
<span class="profileName">{{.ProfileOwner.Name}}</span>{{if .ProfileOwner.Tag}}<span class="username">{{.ProfileOwner.Tag}}</span>{{end}}
<div class="topBlock">
<div class="rowitem avatarRow">
<img src="{{.ProfileOwner.Avatar}}" class="avatar" />
</div>
<div class="rowitem nameRow">
<span class="profileName">{{.ProfileOwner.Name}}</span>{{if .ProfileOwner.Tag}}<span class="username">{{.ProfileOwner.Tag}}</span>{{end}}
</div>
</div>
<div class="passiveBlock">
<div class="rowitem passive">

View File

@ -699,18 +699,18 @@ select, input, textarea {
margin-right: 10px;
}
#profile_container, #profile_left_pane {
#profile_container, #profile_left_pane .topBlock {
display: flex;
}
#profile_left_lane {
margin-left: 8px;
margin-right: 16px;
border: 1px solid var(--element-border-color);
border-bottom: 2px solid var(--element-border-color);
}
#profile_left_pane {
#profile_left_pane .topBlock {
flex-direction: column;
padding-bottom: 18px;
border: 1px solid var(--element-border-color);
border-bottom: 2px solid var(--element-border-color);
}
#profile_left_pane .avatarRow {
padding: 24px;
@ -731,6 +731,15 @@ select, input, textarea {
#profile_left_pane .profileName {
font-size: 19px;
}
#profile_left_pane .passiveBlock .passive {
border: 1px solid var(--element-border-color);
border-bottom: 2px solid var(--element-border-color);
margin-top: 6px;
padding: 12px;
padding-top: 10px;
padding-bottom: 10px;
}
#profile_right_lane {
width: 100%;
margin-right: 12px;
@ -740,6 +749,11 @@ select, input, textarea {
border-bottom: 2px solid var(--element-border-color);
}
.footer {
border: 1px solid var(--element-border-color);
border-bottom: 2px solid var(--element-border-color);
}
@media(max-width: 670px) {
.topic_inner_right {
display: none;