Tighten validation on group promotion delete.

Shorten some variable names.
Reduce the amount of duplication in the panel group routes.
Rename isJs to js here and there.
Localise group promotions.

Phrases:

Rename create_topic_create_topic_button to create_topic_create_button
Rename quick_topic.create_topic_button to quick_topic.create_button
Rename quick_topic.create_topic_button_short to quick_topic.create_button_short
Rename panel_groups_create_create_group_button to panel_groups_create_button
Rename panel_word_filters_create_create_word_filter_button to panel_word_filters_create_button
Rename panel_pages_create_submit_button to panel_pages_create_button
Add panel_group_promotions_create_head
Add panel_group_promotions_from
Add panel_group_promotions_to
Add panel_group_promotions_two_way
Add panel_group_promotions_level
Add panel_group_promotions_create_button
This commit is contained in:
Azareal 2019-09-30 20:15:50 +10:00
parent 69e1e8d364
commit 764b9904f1
15 changed files with 237 additions and 241 deletions

View File

@ -552,7 +552,7 @@
"create_topic_name":"Topic Name",
"create_topic_content":"Content",
"create_topic_placeholder":"Insert content here",
"create_topic_create_topic_button":"Create Topic",
"create_topic_create_button":"Create Topic",
"create_topic_add_file_button":"Add File",
"quick_topic.aria":"Quick Topic Form",
@ -561,8 +561,8 @@
"quick_topic.whatsup":"What's up?",
"quick_topic.content_placeholder":"Insert post here",
"quick_topic.add_poll_option_first":"Poll option #0",
"quick_topic.create_topic_button":"Create Topic",
"quick_topic.create_topic_button_short":"New Topic",
"quick_topic.create_button":"Create Topic",
"quick_topic.create_button_short":"New Topic",
"quick_topic.add_poll_button":"Add Poll",
"quick_topic.add_file_button":"Add File",
"quick_topic.cancel_button":"Cancel",
@ -870,7 +870,7 @@
"panel_groups_create_name_placeholder":"Administrator",
"panel_groups_create_type":"Type",
"panel_groups_create_tag":"Tag",
"panel_groups_create_create_group_button":"Add Group",
"panel_groups_create_button":"Add Group",
"panel_group_menu_head":"Group Editor",
"panel_group_menu_general":"General",
@ -885,6 +885,13 @@
"panel_group_update_button":"Update Group",
"panel_group_extended_permissions":"Extended Permissions",
"panel_group_promotions_create_head":"Add Promotion",
"panel_group_promotions_from":"From",
"panel_group_promotions_to":"To",
"panel_group_promotions_two_way":"Two Way",
"panel_group_promotions_level":"Level",
"panel_group_promotions_create_button":"Add Promotion",
"panel_word_filters_head":"Word Filters",
"panel_word_filters_to":"to",
"panel_word_filters_edit_button_aria":"Edit Word Filter",
@ -896,7 +903,7 @@
"panel_word_filters_create_find_placeholder":"fuck",
"panel_word_filters_create_replacement":"Replacement",
"panel_word_filters_create_replacement_placeholder":"fudge",
"panel_word_filters_create_create_word_filter_button":"Add Filter",
"panel_word_filters_create_button":"Add Filter",
"panel_pages_head":"Page Manager",
"panel_pages_edit_button_aria":"Edit Page",
@ -908,7 +915,7 @@
"panel_pages_create_title":"Title",
"panel_pages_create_title_placeholder":"Frequently Asked Questions",
"panel_pages_create_body_placeholder":"We understand you have a lot of questions.",
"panel_pages_create_submit_button":"Create Page",
"panel_pages_create_button":"Create Page",
"panel_pages_edit_head":"Page Editor",
"panel_pages_name":"Name",

View File

@ -436,7 +436,7 @@ function mainInit(){
url: target,
type: "POST",
dataType: "json",
data: { isJs: 1 },
data: { js: 1 },
error: ajaxError,
success: function (data, status, xhr) {
if("success" in data && data["success"] == "1") return;
@ -729,7 +729,7 @@ function mainInit(){
type: "POST",
dataType: "json",
error: ajaxError,
data: { isJs: "1", edit_item: newContent }
data: { js: "1", edit_item: newContent }
});
});
});
@ -771,7 +771,7 @@ function mainInit(){
$(".submit_edit").click(function(event) {
event.preventDefault();
var outData = {isJs: "1"}
var outData = {js: "1"}
var blockParent = $(this).closest('.editable_parent');
blockParent.find('.editable_block').each(function() {
var fieldName = this.getAttribute("data-field");
@ -856,7 +856,7 @@ function mainInit(){
url: this.form.getAttribute("action") + "?s=" + me.User.S,
type: "POST",
dataType: "json",
data: { "newTheme": this.options[this.selectedIndex].getAttribute("val"), isJs: "1" },
data: { "newTheme": this.options[this.selectedIndex].getAttribute("val"), js: "1" },
error: ajaxError,
success: function (data, status, xhr) {
console.log("Theme successfully switched");

View File

@ -83,19 +83,19 @@ func CustomPage(w http.ResponseWriter, r *http.Request, user c.User, header *c.H
// TODO: Set the cookie domain
func ChangeTheme(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
//headerLite, _ := SimpleUserCheck(w, r, &user)
// TODO: Rename isJs to something else, just in case we rewrite the JS side in WebAssembly?
isJs := (r.PostFormValue("isJs") == "1")
// TODO: Rename js to something else, just in case we rewrite the JS side in WebAssembly?
js := (r.PostFormValue("js") == "1")
newTheme := c.SanitiseSingleLine(r.PostFormValue("newTheme"))
theme, ok := c.Themes[newTheme]
if !ok || theme.HideFromThemes {
return c.LocalErrorJSQ("That theme doesn't exist", w, r, user, isJs)
return c.LocalErrorJSQ("That theme doesn't exist", w, r, user, js)
}
cookie := http.Cookie{Name: "current_theme", Value: newTheme, Path: "/", MaxAge: int(c.Year)}
http.SetCookie(w, &cookie)
if !isJs {
if !js {
http.Redirect(w, r, "/", http.StatusSeeOther)
} else {
_, _ = w.Write(successJSONBytes)

View File

@ -1052,7 +1052,7 @@ func AnalyticsLanguages(w http.ResponseWriter, r *http.Request, user c.User) c.R
ovList := analyticsVMapToOVList(vMap)
ex := strings.Split(r.FormValue("ex"), ",")
var inEx = func(name string) bool {
inEx := func(name string) bool {
for _, e := range ex {
if e == name {
return true
@ -1134,7 +1134,7 @@ func AnalyticsReferrers(w http.ResponseWriter, r *http.Request, user c.User) c.R
}
showSpam := r.FormValue("spam") == "1"
var isSpammy = func(domain string) bool {
isSpammy := func(domain string) bool {
for _, substr := range c.SpammyDomainBits {
if strings.Contains(domain, substr) {
return true

View File

@ -10,14 +10,14 @@ import (
p "github.com/Azareal/Gosora/common/phrases"
)
func Groups(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "groups", "groups")
func Groups(w http.ResponseWriter, r *http.Request, u c.User) c.RouteError {
bPage, ferr := buildBasePage(w, r, &u, "groups", "groups")
if ferr != nil {
return ferr
}
page, _ := strconv.Atoi(r.FormValue("page"))
perPage := 15
offset, page, lastPage := c.PageOffset(basePage.Stats.Groups, page, perPage)
offset, page, lastPage := c.PageOffset(bPage.Stats.Groups, page, perPage)
// Skip the 'Unknown' group
offset++
@ -25,7 +25,7 @@ func Groups(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
var count int
var groupList []c.GroupAdmin
groups, _ := c.Groups.GetRange(offset, 0)
for _, group := range groups {
for _, g := range groups {
if count == perPage {
break
}
@ -33,33 +33,33 @@ func Groups(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
var rankClass string
var canDelete = false
// TODO: Use a switch for this
// TODO: Localise this
if group.IsAdmin {
switch {
case g.IsAdmin:
rank = "Admin"
rankClass = "admin"
} else if group.IsMod {
case g.IsMod:
rank = "Mod"
rankClass = "mod"
} else if group.IsBanned {
case g.IsBanned:
rank = "Banned"
rankClass = "banned"
} else if group.ID == 6 {
case g.ID == 6:
rank = "Guest"
rankClass = "guest"
} else {
default:
rank = "Member"
rankClass = "member"
}
canEdit := user.Perms.EditGroup && (!group.IsAdmin || user.Perms.EditGroupAdmin) && (!group.IsMod || user.Perms.EditGroupSuperMod)
groupList = append(groupList, c.GroupAdmin{group.ID, group.Name, rank, rankClass, canEdit, canDelete})
canEdit := u.Perms.EditGroup && (!g.IsAdmin || u.Perms.EditGroupAdmin) && (!g.IsMod || u.Perms.EditGroupSuperMod)
groupList = append(groupList, c.GroupAdmin{g.ID, g.Name, rank, rankClass, canEdit, canDelete})
count++
}
pageList := c.Paginate(page, lastPage, 5)
pi := c.PanelGroupPage{basePage, groupList, c.Paginator{pageList, page, lastPage}}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_groups",&pi})
pi := c.PanelGroupPage{bPage, groupList, c.Paginator{pageList, page, lastPage}}
return renderTemplate("panel", w, r, bPage.Header, c.Panel{bPage, "", "", "panel_groups", &pi})
}
func GroupsEdit(w http.ResponseWriter, r *http.Request, user c.User, sgid string) c.RouteError {
@ -75,38 +75,32 @@ func GroupsEdit(w http.ResponseWriter, r *http.Request, user c.User, sgid string
if err != nil {
return c.LocalError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, user)
}
group, err := c.Groups.Get(gid)
g, err := c.Groups.Get(gid)
if err == sql.ErrNoRows {
//log.Print("aaaaa monsters")
return c.NotFound(w, r, basePage.Header)
} else if err != nil {
return c.InternalError(err, w, r)
}
if group.IsAdmin && !user.Perms.EditGroupAdmin {
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user)
}
if group.IsMod && !user.Perms.EditGroupSuperMod {
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user)
ferr = groupCheck(w,r,user,g,err)
if ferr != nil {
return ferr
}
var rank string
switch {
case group.IsAdmin:
case g.IsAdmin:
rank = "Admin"
case group.IsMod:
case g.IsMod:
rank = "Mod"
case group.IsBanned:
case g.IsBanned:
rank = "Banned"
case group.ID == 6:
case g.ID == 6:
rank = "Guest"
default:
rank = "Member"
}
disableRank := !user.Perms.EditGroupGlobalPerms || (group.ID == 6)
disableRank := !user.Perms.EditGroupGlobalPerms || (g.ID == 6)
pi := c.PanelEditGroupPage{basePage, group.ID, group.Name, group.Tag, rank, disableRank}
pi := c.PanelEditGroupPage{basePage, g.ID, g.Name, g.Tag, rank, disableRank}
return renderTemplate("panel_group_edit", w, r, basePage.Header, pi)
}
@ -123,19 +117,14 @@ func GroupsEditPromotions(w http.ResponseWriter, r *http.Request, user c.User, s
if err != nil {
return c.LocalError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, user)
}
g, err := c.Groups.Get(gid)
if err == sql.ErrNoRows {
//log.Print("aaaaa monsters")
return c.NotFound(w, r, basePage.Header)
} else if err != nil {
return c.InternalError(err, w, r)
}
if g.IsAdmin && !user.Perms.EditGroupAdmin {
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user)
}
if g.IsMod && !user.Perms.EditGroupSuperMod {
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user)
ferr = groupCheck(w,r,user,g,err)
if ferr != nil {
return ferr
}
promotions, err := c.GroupPromotions.GetByGroup(g.ID)
@ -146,13 +135,13 @@ func GroupsEditPromotions(w http.ResponseWriter, r *http.Request, user c.User, s
for i, promote := range promotions {
fg, err := c.Groups.Get(promote.From)
if err == sql.ErrNoRows {
fg = &c.Group{Name:"Deleted Group"}
fg = &c.Group{Name: "Deleted Group"}
} else if err != nil {
return c.InternalError(err, w, r)
}
tg, err := c.Groups.Get(promote.To)
if err == sql.ErrNoRows {
tg = &c.Group{Name:"Deleted Group"}
tg = &c.Group{Name: "Deleted Group"}
} else if err != nil {
return c.InternalError(err, w, r)
}
@ -180,6 +169,21 @@ func GroupsEditPromotions(w http.ResponseWriter, r *http.Request, user c.User, s
return renderTemplate("panel_group_edit_promotions", w, r, basePage.Header, pi)
}
func groupCheck(w http.ResponseWriter, r *http.Request, user c.User, g *c.Group, err error) c.RouteError {
if err == sql.ErrNoRows {
return c.LocalError("No such group.", w, r, user)
} else if err != nil {
return c.InternalError(err, w, r)
}
if g.IsAdmin && !user.Perms.EditGroupAdmin {
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user)
}
if g.IsMod && !user.Perms.EditGroupSuperMod {
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user)
}
return nil
}
func GroupsPromotionsCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User, sgid string) c.RouteError {
if !user.Perms.EditGroup {
return c.NoPermissions(w, r, user)
@ -206,34 +210,18 @@ func GroupsPromotionsCreateSubmit(w http.ResponseWriter, r *http.Request, user c
}
g, err := c.Groups.Get(from)
if err == sql.ErrNoRows {
return c.LocalError("No such group.",w, r, user)
} else if err != nil {
return c.InternalError(err, w, r)
ferr := groupCheck(w, r, user, g, err)
if err != nil {
return ferr
}
if g.IsAdmin && !user.Perms.EditGroupAdmin {
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user)
}
if g.IsMod && !user.Perms.EditGroupSuperMod {
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user)
}
g, err = c.Groups.Get(to)
if err == sql.ErrNoRows {
return c.LocalError("No such group.",w, r, user)
} else if err != nil {
return c.InternalError(err, w, r)
ferr = groupCheck(w, r, user, g, err)
if err != nil {
return ferr
}
if g.IsAdmin && !user.Perms.EditGroupAdmin {
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user)
}
if g.IsMod && !user.Perms.EditGroupSuperMod {
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user)
}
_, err = c.GroupPromotions.Create(from, to, twoWay, level)
if err != nil {
return c.InternalError(err,w,r)
return c.InternalError(err, w, r)
}
http.Redirect(w, r, "/panel/groups/edit/promotions/"+strconv.Itoa(gid), http.StatusSeeOther)
@ -246,7 +234,7 @@ func GroupsPromotionsDeleteSubmit(w http.ResponseWriter, r *http.Request, user c
}
spl := strings.Split(sspl, "-")
if len(spl) < 2 {
return c.LocalError("need two params",w,r,user)
return c.LocalError("need two params", w, r, user)
}
gid, err := strconv.Atoi(spl[0])
if err != nil {
@ -257,9 +245,26 @@ func GroupsPromotionsDeleteSubmit(w http.ResponseWriter, r *http.Request, user c
return c.LocalError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, user)
}
pro, err := c.GroupPromotions.Get(pid)
if err == sql.ErrNoRows {
return c.LocalError("That group promotion doesn't exist", w, r, user)
} else if err != nil {
return c.InternalError(err, w, r)
}
g, err := c.Groups.Get(pro.From)
ferr := groupCheck(w, r, user, g, err)
if err != nil {
return ferr
}
g, err = c.Groups.Get(pro.To)
ferr = groupCheck(w, r, user, g, err)
if err != nil {
return ferr
}
err = c.GroupPromotions.Delete(pid)
if err != nil {
return c.InternalError(err,w,r)
return c.InternalError(err, w, r)
}
http.Redirect(w, r, "/panel/groups/edit/promotions/"+strconv.Itoa(gid), http.StatusSeeOther)
@ -360,14 +365,10 @@ func GroupsEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, sgid
if err == sql.ErrNoRows {
//log.Print("aaaaa monsters")
return c.NotFound(w, r, nil)
} else if err != nil {
return c.InternalError(err, w, r)
}
if group.IsAdmin && !user.Perms.EditGroupAdmin {
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user)
}
if group.IsMod && !user.Perms.EditGroupSuperMod {
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user)
ferr = groupCheck(w, r, user, group, err)
if ferr != nil {
return ferr
}
gname := r.FormValue("group-name")
@ -447,31 +448,24 @@ func GroupsEditPermsSubmit(w http.ResponseWriter, r *http.Request, user c.User,
if err == sql.ErrNoRows {
//log.Print("aaaaa monsters o.o")
return c.NotFound(w, r, nil)
} else if err != nil {
return c.InternalError(err, w, r)
}
if group.IsAdmin && !user.Perms.EditGroupAdmin {
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user)
}
if group.IsMod && !user.Perms.EditGroupSuperMod {
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user)
ferr = groupCheck(w, r, user, group, err)
if ferr != nil {
return ferr
}
// TODO: Don't unset perms we don't have permission to set?
pmap := make(map[string]bool)
if user.Perms.EditGroupLocalPerms {
for _, perm := range c.LocalPermList {
pvalue := r.PostFormValue("group-perm-" + perm)
pmap[perm] = (pvalue == "1")
}
}
if user.Perms.EditGroupGlobalPerms {
for _, perm := range c.GlobalPermList {
pvalue := r.PostFormValue("group-perm-" + perm)
pmap[perm] = (pvalue == "1")
pCheck := func(hasPerm bool, perms []string) {
if hasPerm {
for _, perm := range perms {
pvalue := r.PostFormValue("group-perm-" + perm)
pmap[perm] = (pvalue == "1")
}
}
}
pCheck(user.Perms.EditGroupLocalPerms, c.LocalPermList)
pCheck(user.Perms.EditGroupGlobalPerms, c.GlobalPermList)
err = group.UpdatePerms(pmap)
if err != nil {
@ -499,19 +493,19 @@ func GroupsCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.R
var isAdmin, isMod, isBanned bool
if user.Perms.EditGroupGlobalPerms {
groupType := r.PostFormValue("group-type")
if groupType == "Admin" {
switch r.PostFormValue("group-type") {
case "Admin":
if !user.Perms.EditGroupAdmin {
return c.LocalError(p.GetErrorPhrase("panel_groups_create_cannot_designate_admin"), w, r, user)
}
isAdmin = true
isMod = true
} else if groupType == "Mod" {
case "Mod":
if !user.Perms.EditGroupSuperMod {
return c.LocalError(p.GetErrorPhrase("panel_groups_create_cannot_designate_supermod"), w, r, user)
}
isMod = true
} else if groupType == "Banned" {
case "Banned":
isBanned = true
}
}

View File

@ -25,7 +25,7 @@ func WordFilters(w http.ResponseWriter, r *http.Request, user c.User) c.RouteErr
}
pi := c.PanelPage{basePage, tList, filterList}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_word_filters",&pi})
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_word_filters", &pi})
}
func WordFiltersCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
@ -36,23 +36,23 @@ func WordFiltersCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User
if !user.Perms.EditSettings {
return c.NoPermissions(w, r, user)
}
isJs := (r.PostFormValue("js") == "1")
js := (r.PostFormValue("js") == "1")
// ? - We're not doing a full sanitise here, as it would be useful if admins were able to put down rules for replacing things with HTML, etc.
find := strings.TrimSpace(r.PostFormValue("find"))
if find == "" {
return c.LocalErrorJSQ("You need to specify what word you want to match", w, r, user, isJs)
return c.LocalErrorJSQ("You need to specify what word you want to match", w, r, user, js)
}
// Unlike with find, it's okay if we leave this blank, as this means that the admin wants to remove the word entirely with no replacement
replacement := strings.TrimSpace(r.PostFormValue("replacement"))
replace := strings.TrimSpace(r.PostFormValue("replacement"))
err := c.WordFilters.Create(find, replacement)
err := c.WordFilters.Create(find, replace)
if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
return successRedirect("/panel/settings/word-filters/", w, r, isJs)
return successRedirect("/panel/settings/word-filters/", w, r, js)
}
// TODO: Implement this as a non-JS fallback
@ -67,7 +67,7 @@ func WordFiltersEdit(w http.ResponseWriter, r *http.Request, user c.User, wfid s
_ = wfid
pi := c.PanelPage{basePage, tList, nil}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_word_filters_edit",&pi})
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_word_filters_edit", &pi})
}
func WordFiltersEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, wfid string) c.RouteError {
@ -75,28 +75,26 @@ func WordFiltersEditSubmit(w http.ResponseWriter, r *http.Request, user c.User,
if ferr != nil {
return ferr
}
// TODO: Either call it isJs or js rather than flip-flopping back and forth across the routes x.x
isJs := (r.PostFormValue("isJs") == "1")
js := (r.PostFormValue("js") == "1")
if !user.Perms.EditSettings {
return c.NoPermissionsJSQ(w, r, user, isJs)
return c.NoPermissionsJSQ(w, r, user, js)
}
id, err := strconv.Atoi(wfid)
if err != nil {
return c.LocalErrorJSQ("The word filter ID must be an integer.", w, r, user, isJs)
return c.LocalErrorJSQ("The word filter ID must be an integer.", w, r, user, js)
}
find := strings.TrimSpace(r.PostFormValue("find"))
if find == "" {
return c.LocalErrorJSQ("You need to specify what word you want to match", w, r, user, isJs)
return c.LocalErrorJSQ("You need to specify what word you want to match", w, r, user, js)
}
// Unlike with find, it's okay if we leave this blank, as this means that the admin wants to remove the word entirely with no replacement
replacement := strings.TrimSpace(r.PostFormValue("replacement"))
replace := strings.TrimSpace(r.PostFormValue("replacement"))
err = c.WordFilters.Update(id, find, replacement)
err = c.WordFilters.Update(id, find, replace)
if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
http.Redirect(w, r, "/panel/settings/word-filters/", http.StatusSeeOther)
@ -109,19 +107,19 @@ func WordFiltersDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User
return ferr
}
isJs := (r.PostFormValue("isJs") == "1")
js := (r.PostFormValue("js") == "1")
if !user.Perms.EditSettings {
return c.NoPermissionsJSQ(w, r, user, isJs)
return c.NoPermissionsJSQ(w, r, user, js)
}
id, err := strconv.Atoi(wfid)
if err != nil {
return c.LocalErrorJSQ("The word filter ID must be an integer.", w, r, user, isJs)
return c.LocalErrorJSQ("The word filter ID must be an integer.", w, r, user, js)
}
err = c.WordFilters.Delete(id)
if err == sql.ErrNoRows {
return c.LocalErrorJSQ("This word filter doesn't exist", w, r, user, isJs)
return c.LocalErrorJSQ("This word filter doesn't exist", w, r, user, js)
}
http.Redirect(w, r, "/panel/settings/word-filters/", http.StatusSeeOther)

View File

@ -118,7 +118,7 @@ func CreateReplySubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
}
// Make sure the indices are sequential to avoid out of bounds issues
var seqPollInputItems = make(map[int]string)
seqPollInputItems := make(map[int]string)
for i := 0; i < len(pollInputItems); i++ {
seqPollInputItems[i] = pollInputItems[i]
}
@ -282,24 +282,24 @@ func ReplyEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid s
// TODO: Refactor this
// TODO: Disable stat updates in posts handled by plugin_guilds
func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
isJs := (r.PostFormValue("isJs") == "1")
js := (r.PostFormValue("js") == "1")
rid, err := strconv.Atoi(srid)
if err != nil {
return c.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, isJs)
return c.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, js)
}
reply, err := c.Rstore.Get(rid)
if err == sql.ErrNoRows {
return c.PreErrorJSQ("The reply you tried to delete doesn't exist.", w, r, isJs)
return c.PreErrorJSQ("The reply you tried to delete doesn't exist.", w, r, js)
} else if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
topic, err := c.Topics.Get(reply.ParentID)
if err == sql.ErrNoRows {
return c.PreErrorJSQ("The parent topic doesn't exist.", w, r, isJs)
return c.PreErrorJSQ("The parent topic doesn't exist.", w, r, js)
} else if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
// TODO: Add hooks to make use of headerLite
@ -308,12 +308,12 @@ func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid
return ferr
}
if !user.Perms.ViewTopic || !user.Perms.DeleteReply {
return c.NoPermissionsJSQ(w, r, user, isJs)
return c.NoPermissionsJSQ(w, r, user, js)
}
err = reply.Delete()
if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
skip, rerr := lite.Hooks.VhookSkippable("action_end_delete_reply", reply.ID, &user)
@ -322,7 +322,7 @@ func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid
}
//log.Printf("Reply #%d was deleted by c.User #%d", rid, user.ID)
if !isJs {
if !js {
http.Redirect(w, r, "/topic/"+strconv.Itoa(reply.ParentID), http.StatusSeeOther)
} else {
w.Write(successJSONBytes)
@ -334,15 +334,15 @@ func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid
wcount := c.WordCount(reply.Content)
err = replyCreator.DecreasePostStats(wcount, false)
if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
} else if err != sql.ErrNoRows {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
err = c.ModLogs.Create("delete", reply.ParentID, "reply", user.LastIP, user.ID)
if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
return nil
}
@ -501,34 +501,34 @@ func ProfileReplyCreateSubmit(w http.ResponseWriter, r *http.Request, user c.Use
}
func ProfileReplyEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
isJs := (r.PostFormValue("js") == "1")
js := (r.PostFormValue("js") == "1")
rid, err := strconv.Atoi(srid)
if err != nil {
return c.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, isJs)
return c.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, js)
}
reply, err := c.Prstore.Get(rid)
if err == sql.ErrNoRows {
return c.PreErrorJSQ("The target reply doesn't exist.", w, r, isJs)
return c.PreErrorJSQ("The target reply doesn't exist.", w, r, js)
} else if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
creator, err := c.Users.Get(reply.CreatedBy)
if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
// ? Does the admin understand that this group perm affects this?
if user.ID != creator.ID && !user.Perms.EditReply {
return c.NoPermissionsJSQ(w, r, user, isJs)
return c.NoPermissionsJSQ(w, r, user, js)
}
err = reply.SetBody(r.PostFormValue("edit_item"))
if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
if !isJs {
if !js {
http.Redirect(w, r, "/user/"+strconv.Itoa(creator.ID)+"#reply-"+strconv.Itoa(rid), http.StatusSeeOther)
} else {
w.Write(successJSONBytes)
@ -537,35 +537,34 @@ func ProfileReplyEditSubmit(w http.ResponseWriter, r *http.Request, user c.User,
}
func ProfileReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
isJs := (r.PostFormValue("isJs") == "1")
js := (r.PostFormValue("js") == "1")
rid, err := strconv.Atoi(srid)
if err != nil {
return c.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, isJs)
return c.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, js)
}
reply, err := c.Prstore.Get(rid)
if err == sql.ErrNoRows {
return c.PreErrorJSQ("The target reply doesn't exist.", w, r, isJs)
return c.PreErrorJSQ("The target reply doesn't exist.", w, r, js)
} else if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
creator, err := c.Users.Get(reply.CreatedBy)
if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
if user.ID != creator.ID && !user.Perms.DeleteReply {
return c.NoPermissionsJSQ(w, r, user, isJs)
return c.NoPermissionsJSQ(w, r, user, js)
}
err = reply.Delete()
if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
//log.Printf("The profile post '%d' was deleted by c.User #%d", reply.ID, user.ID)
if !isJs {
if !js {
//http.Redirect(w,r, "/user/" + strconv.Itoa(creator.ID), http.StatusSeeOther)
} else {
w.Write(successJSONBytes)
@ -574,25 +573,25 @@ func ProfileReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.Use
}
func ReplyLikeSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
isJs := (r.PostFormValue("isJs") == "1")
js := (r.PostFormValue("js") == "1")
rid, err := strconv.Atoi(srid)
if err != nil {
return c.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, isJs)
return c.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, js)
}
reply, err := c.Rstore.Get(rid)
if err == sql.ErrNoRows {
return c.PreErrorJSQ("You can't like something which doesn't exist!", w, r, isJs)
return c.PreErrorJSQ("You can't like something which doesn't exist!", w, r, js)
} else if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
topic, err := c.Topics.Get(reply.ParentID)
if err == sql.ErrNoRows {
return c.PreErrorJSQ("The parent topic doesn't exist.", w, r, isJs)
return c.PreErrorJSQ("The parent topic doesn't exist.", w, r, js)
} else if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
// TODO: Add hooks to make use of headerLite
@ -601,31 +600,31 @@ func ReplyLikeSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid s
return ferr
}
if !user.Perms.ViewTopic || !user.Perms.LikeItem {
return c.NoPermissionsJSQ(w, r, user, isJs)
return c.NoPermissionsJSQ(w, r, user, js)
}
if reply.CreatedBy == user.ID {
return c.LocalErrorJSQ("You can't like your own replies", w, r, user, isJs)
return c.LocalErrorJSQ("You can't like your own replies", w, r, user, js)
}
_, err = c.Users.Get(reply.CreatedBy)
if err != nil && err != sql.ErrNoRows {
return c.LocalErrorJSQ("The target user doesn't exist", w, r, user, isJs)
return c.LocalErrorJSQ("The target user doesn't exist", w, r, user, js)
} else if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
err = reply.Like(user.ID)
if err == c.ErrAlreadyLiked {
return c.LocalErrorJSQ("You've already liked this!", w, r, user, isJs)
return c.LocalErrorJSQ("You've already liked this!", w, r, user, js)
} else if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
// ! Be careful about leaking per-route permission state with &user
alert := c.Alert{ActorID: user.ID, TargetUserID: reply.CreatedBy, Event: "like", ElementType: "post", ElementID: rid, Actor: &user}
err = c.AddActivityAndNotifyTarget(alert)
if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
skip, rerr := lite.Hooks.VhookSkippable("action_end_like_reply", reply.ID, &user)
@ -633,7 +632,7 @@ func ReplyLikeSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid s
return rerr
}
if !isJs {
if !js {
http.Redirect(w, r, "/topic/"+strconv.Itoa(reply.ParentID), http.StatusSeeOther)
} else {
_, _ = w.Write(successJSONBytes)

View File

@ -14,7 +14,7 @@ func ReportSubmit(w http.ResponseWriter, r *http.Request, user c.User, sitemID s
if ferr != nil {
return ferr
}
isJs := (r.PostFormValue("isJs") == "1")
js := (r.PostFormValue("js") == "1")
itemID, err := strconv.Atoi(sitemID)
if err != nil {
@ -104,7 +104,7 @@ func ReportSubmit(w http.ResponseWriter, r *http.Request, user c.User, sitemID s
}
counters.PostCounter.Bump()
if !isJs {
if !js {
// TODO: Redirect back to where we came from
http.Redirect(w, r, "/", http.StatusSeeOther)
} else {

View File

@ -508,17 +508,17 @@ func uploadFilesWithHash(w http.ResponseWriter, r *http.Request, user c.User, di
// TODO: Update the stats after edits so that we don't under or over decrement stats during deletes
// TODO: Disable stat updates in posts handled by plugin_guilds
func EditTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid string) c.RouteError {
isJs := (r.PostFormValue("js") == "1")
js := (r.PostFormValue("js") == "1")
tid, err := strconv.Atoi(stid)
if err != nil {
return c.PreErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, isJs)
return c.PreErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, js)
}
topic, err := c.Topics.Get(tid)
if err == sql.ErrNoRows {
return c.PreErrorJSQ("The topic you tried to edit doesn't exist.", w, r, isJs)
return c.PreErrorJSQ("The topic you tried to edit doesn't exist.", w, r, js)
} else if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
// TODO: Add hooks to make use of headerLite
@ -527,10 +527,10 @@ func EditTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
return ferr
}
if !user.Perms.ViewTopic || !user.Perms.EditTopic {
return c.NoPermissionsJSQ(w, r, user, isJs)
return c.NoPermissionsJSQ(w, r, user, js)
}
if topic.IsClosed && !user.Perms.CloseTopic {
return c.NoPermissionsJSQ(w, r, user, isJs)
return c.NoPermissionsJSQ(w, r, user, js)
}
err = topic.Update(r.PostFormValue("topic_name"), r.PostFormValue("topic_content"))
@ -538,26 +538,26 @@ func EditTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
if err != nil {
switch err {
case c.ErrNoTitle:
return c.LocalErrorJSQ("This topic doesn't have a title", w, r, user, isJs)
return c.LocalErrorJSQ("This topic doesn't have a title", w, r, user, js)
case c.ErrLongTitle:
return c.LocalErrorJSQ("The length of the title is too long, max: "+strconv.Itoa(c.Config.MaxTopicTitleLength), w, r, user, isJs)
return c.LocalErrorJSQ("The length of the title is too long, max: "+strconv.Itoa(c.Config.MaxTopicTitleLength), w, r, user, js)
case c.ErrNoBody:
return c.LocalErrorJSQ("This topic doesn't have a body", w, r, user, isJs)
return c.LocalErrorJSQ("This topic doesn't have a body", w, r, user, js)
}
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
err = c.Forums.UpdateLastTopic(topic.ID, user.ID, topic.ParentID)
if err != nil && err != sql.ErrNoRows {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
// TODO: Avoid the load to get this faster?
topic, err = c.Topics.Get(topic.ID)
if err == sql.ErrNoRows {
return c.PreErrorJSQ("The updated topic doesn't exist.", w, r, isJs)
return c.PreErrorJSQ("The updated topic doesn't exist.", w, r, js)
} else if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
skip, rerr := lite.Hooks.VhookSkippable("action_end_edit_topic", topic.ID, &user)
@ -565,12 +565,12 @@ func EditTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
return rerr
}
if !isJs {
if !js {
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
} else {
outBytes, err := json.Marshal(JsonReply{c.ParseMessage(topic.Content, topic.ParentID, "forums")})
if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
w.Write(outBytes)
}
@ -582,7 +582,7 @@ func EditTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
func DeleteTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
// TODO: Move this to some sort of middleware
var tids []int
var isJs = false
js := false
if c.ReqIsJson(r) {
if r.Body == nil {
return c.PreErrorJS("No request body", w, r)
@ -591,7 +591,7 @@ func DeleteTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
if err != nil {
return c.PreErrorJS("We weren't able to parse your data", w, r)
}
isJs = true
js = true
} else {
tid, err := strconv.Atoi(r.URL.Path[len("/topic/delete/submit/"):])
if err != nil {
@ -600,15 +600,15 @@ func DeleteTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
tids = append(tids, tid)
}
if len(tids) == 0 {
return c.LocalErrorJSQ("You haven't provided any IDs", w, r, user, isJs)
return c.LocalErrorJSQ("You haven't provided any IDs", w, r, user, js)
}
for _, tid := range tids {
topic, err := c.Topics.Get(tid)
if err == sql.ErrNoRows {
return c.PreErrorJSQ("The topic you tried to delete doesn't exist.", w, r, isJs)
return c.PreErrorJSQ("The topic you tried to delete doesn't exist.", w, r, js)
} else if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
// TODO: Add hooks to make use of headerLite
@ -617,24 +617,24 @@ func DeleteTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
return ferr
}
if !user.Perms.ViewTopic || !user.Perms.DeleteTopic {
return c.NoPermissionsJSQ(w, r, user, isJs)
return c.NoPermissionsJSQ(w, r, user, js)
}
// We might be able to handle this err better
err = topic.Delete()
if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
err = c.ModLogs.Create("delete", tid, "topic", user.LastIP, user.ID)
if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
// ? - We might need to add soft-delete before we can do an action reply for this
/*_, err = stmts.createActionReply.Exec(tid,"delete",ipaddress,user.ID)
if err != nil {
return c.InternalErrorJSQ(err,w,r,isJs)
return c.InternalErrorJSQ(err,w,r,js)
}*/
// TODO: Do a bulk delete action hook?
@ -712,7 +712,7 @@ func UnstickTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, sti
func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
// TODO: Move this to some sort of middleware
var tids []int
var isJs = false
js := false
if c.ReqIsJson(r) {
if r.Body == nil {
return c.PreErrorJS("No request body", w, r)
@ -721,7 +721,7 @@ func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
if err != nil {
return c.PreErrorJS("We weren't able to parse your data", w, r)
}
isJs = true
js = true
} else {
tid, err := strconv.Atoi(r.URL.Path[len("/topic/lock/submit/"):])
if err != nil {
@ -730,15 +730,15 @@ func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
tids = append(tids, tid)
}
if len(tids) == 0 {
return c.LocalErrorJSQ("You haven't provided any IDs", w, r, user, isJs)
return c.LocalErrorJSQ("You haven't provided any IDs", w, r, user, js)
}
for _, tid := range tids {
topic, err := c.Topics.Get(tid)
if err == sql.ErrNoRows {
return c.PreErrorJSQ("The topic you tried to lock doesn't exist.", w, r, isJs)
return c.PreErrorJSQ("The topic you tried to lock doesn't exist.", w, r, js)
} else if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
// TODO: Add hooks to make use of headerLite
@ -747,17 +747,17 @@ func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
return ferr
}
if !user.Perms.ViewTopic || !user.Perms.CloseTopic {
return c.NoPermissionsJSQ(w, r, user, isJs)
return c.NoPermissionsJSQ(w, r, user, js)
}
err = topic.Lock()
if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
err = addTopicAction("lock", topic, user)
if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
// TODO: Do a bulk lock action hook?
@ -863,17 +863,17 @@ func addTopicAction(action string, topic *c.Topic, user c.User) error {
// TODO: Refactor this
func LikeTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid string) c.RouteError {
isJs := (r.PostFormValue("isJs") == "1")
js := (r.PostFormValue("js") == "1")
tid, err := strconv.Atoi(stid)
if err != nil {
return c.PreErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, isJs)
return c.PreErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, js)
}
topic, err := c.Topics.Get(tid)
if err == sql.ErrNoRows {
return c.PreErrorJSQ("The requested topic doesn't exist.", w, r, isJs)
return c.PreErrorJSQ("The requested topic doesn't exist.", w, r, js)
} else if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
// TODO: Add hooks to make use of headerLite
@ -882,32 +882,32 @@ func LikeTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
return ferr
}
if !user.Perms.ViewTopic || !user.Perms.LikeItem {
return c.NoPermissionsJSQ(w, r, user, isJs)
return c.NoPermissionsJSQ(w, r, user, js)
}
if topic.CreatedBy == user.ID {
return c.LocalErrorJSQ("You can't like your own topics", w, r, user, isJs)
return c.LocalErrorJSQ("You can't like your own topics", w, r, user, js)
}
_, err = c.Users.Get(topic.CreatedBy)
if err != nil && err == sql.ErrNoRows {
return c.LocalErrorJSQ("The target user doesn't exist", w, r, user, isJs)
return c.LocalErrorJSQ("The target user doesn't exist", w, r, user, js)
} else if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
score := 1
err = topic.Like(score, user.ID)
if err == c.ErrAlreadyLiked {
return c.LocalErrorJSQ("You already liked this", w, r, user, isJs)
return c.LocalErrorJSQ("You already liked this", w, r, user, js)
} else if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
// ! Be careful about leaking per-route permission state with &user
alert := c.Alert{ActorID: user.ID, TargetUserID: topic.CreatedBy, Event: "like", ElementType: "topic", ElementID: tid, Actor: &user}
err = c.AddActivityAndNotifyTarget(alert)
if err != nil {
return c.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, js)
}
skip, rerr := lite.Hooks.VhookSkippable("action_end_like_topic", topic.ID, &user)
@ -915,7 +915,7 @@ func LikeTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
return rerr
}
if !isJs {
if !js {
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
} else {
_, _ = w.Write(successJSONBytes)

View File

@ -20,7 +20,7 @@
<div class="formitem"><textarea form="quick_post_form" class="large" id="topic_content" name="topic-content" placeholder="{{lang "create_topic_placeholder"}}" required></textarea></div>
</div>
<div class="formrow">
<button form="quick_post_form" name="topic-button" class="formbutton">{{lang "create_topic_create_topic_button"}}</button>
<button form="quick_post_form" name="topic-button" class="formbutton">{{lang "create_topic_create_button"}}</button>
{{if .CurrentUser.Perms.UploadFiles}}
<input name="quick_topic_upload_files" form="quick_post_form" id="quick_topic_upload_files" multiple type="file" style="display: none;" />
<label for="quick_topic_upload_files" class="formbutton add_file_button">{{lang "create_topic_add_file_button"}}</label>{{end}}

View File

@ -1,22 +1,20 @@
</div>
<aside class="midRight sidebar">{{dock "rightSidebar" .Header }}</aside>
<aside class="midRight sidebar">{{dock "rightSidebar" .Header}}</aside>
</div>
<div class="footBlock">
<div class="footLeft"></div>
<div class="footer">
{{dock "footer" .Header }}
{{dock "footer" .Header}}
<div id="poweredByHolder" class="footerBit">
<div id="poweredBy">
<a id="poweredByName" href="https://github.com/Azareal/Gosora">{{lang "footer_powered_by"}}</a><span id="poweredByDash"> - </span><span id="poweredByMaker">{{lang "footer_made_with_love"}}</span>
</div>
{{if .CurrentUser.IsAdmin}}<div title="start to before tmpl" class="elapsed">{{.Header.Elapsed1}}</div><div title="start to footer" class="elapsed">{{elapsed .Header.StartedAt}}</div>{{end}}
{{/**{{if .CurrentUser.IsAdmin}}**/}}<div title="start to before tmpl" class="elapsed">{{.Header.Elapsed1}}</div><div title="start to footer" class="elapsed">{{elapsed .Header.StartedAt}}</div>{{/**{{end}}**/}}
<form action="/theme/" method="post">
<div id="themeSelector">
<select id="themeSelectorSelect" name="themeSelector" aria-label="{{lang "footer_theme_selector_aria"}}">
{{range .Header.Themes}}
<select id="themeSelectorSelect" name="themeSelector" aria-label="{{lang "footer_theme_selector_aria"}}">{{range .Header.Themes}}
{{if not .HideFromThemes}}<option val="{{.Name}}"{{if eq $.Header.Theme.Name .Name}} selected{{end}}>{{.FriendlyName}}</option>{{end}}
{{end}}
</select>
{{end}}</select>
<noscript><input type="submit" /></noscript>
</div>
</form>

View File

@ -24,12 +24,12 @@
{{if .CurrentUser.Perms.EditGroup}}
<div class="colstack_item colstack_head">
<div class="rowitem"><h1>Add Promotion</h1></div>
<div class="rowitem"><h1>{{lang "panel_group_promotions_create_head"}}</h1></div>
</div>
<div class="colstack_item the_form">
<form action="/panel/groups/promotions/create/submit/{{.ID}}?s={{.CurrentUser.Session}}" method="post">
<div class="formrow">
<div class="formitem formlabel"><a>From</a></div>
<div class="formitem formlabel"><a>{{lang "panel_group_promotions_from"}}</a></div>
<div class="formitem">
<select name="from">
{{range .Groups}}<option value="{{.ID}}">{{.Name}}</option>{{end}}
@ -37,7 +37,7 @@
</div>
</div>
<div class="formrow">
<div class="formitem formlabel"><a>To</a></div>
<div class="formitem formlabel"><a>{{lang "panel_group_promotions_to"}}</a></div>
<div class="formitem">
<select name="to">
{{range .Groups}}<option value="{{.ID}}">{{.Name}}</option>{{end}}
@ -45,7 +45,7 @@
</div>
</div>
<div class="formrow">
<div class="formitem formlabel"><a>Two Way</a></div>
<div class="formitem formlabel"><a>{{lang "panel_group_promotions_two_way"}}</a></div>
<div class="formitem">
<select name="two-way" disabled>
<option value=1>{{lang "option_yes"}}</option>
@ -54,11 +54,11 @@
</div>
</div>
<div class="formrow">
<div class="formitem formlabel"><a>Level</a></div>
<div class="formitem formlabel"><a>{{lang "panel_group_promotions_level"}}</a></div>
<div class="formitem"><input name="level" type="number" value=0 /></div>
</div>
<div class="formrow form_button_row">
<div class="formitem"><button name="panel-button" class="formbutton">{{lang "panel_groups_create_create_group_button"}}</button></div>
<div class="formitem"><button name="panel-button" class="formbutton">{{lang "panel_group_promotions_create_button"}}</button></div>
</div>
</form>
</div>

View File

@ -34,7 +34,7 @@
<div class="formitem"><input name="replacement" type="text" placeholder="{{lang "panel_word_filters_create_replacement_placeholder"}}" /></div>
</div>
<div class="formrow">
<div class="formitem"><button name="panel-button" class="formbutton form_middle_button">{{lang "panel_word_filters_create_create_word_filter_button"}}</button></div>
<div class="formitem"><button name="panel-button" class="formbutton form_middle_button">{{lang "panel_word_filters_create_button"}}</button></div>
</div>
</form>
</div>

View File

@ -15,7 +15,7 @@
</div>
<div class="formrow quick_button_row">
<div class="formitem">
<button form="quick_post_form" class="formbutton">{{lang "quick_topic.create_topic_button"}}</button>
<button form="quick_post_form" class="formbutton">{{lang "quick_topic.create_button"}}</button>
<button form="quick_post_form" class="formbutton" id="add_poll_button">{{lang "quick_topic.add_poll_button"}}</button>
{{if .CurrentUser.Perms.UploadFiles}}
<input name="upload_files" form="quick_post_form" id="upload_files" multiple type="file" class="auto_hide" />

View File

@ -486,7 +486,7 @@ h2 {
white-space: nowrap;
}
.topic_list_title_block .create_topic_opt a:before {
content: "{{lang "quick_topic.create_topic_button" . }}";
content: "{{lang "quick_topic.create_button" . }}";
}
.topic_list_title_block .mod_opt a:before {
content: "{{lang "topic_list.moderate" . }}";
@ -1312,7 +1312,7 @@ input[type=checkbox]:checked + label .sel {
display: none;
}
.topic_list_title_block .create_topic_opt a:before {
content: "{{lang "quick_topic.create_topic_button_short" . }}";
content: "{{lang "quick_topic.create_button_short" . }}";
}
.topic_list_title_block .mod_opt a:before {
content: "{{lang "topic_list.moderate_short" . }}";