Adjust convo permissions.

Speed up convo_view.html
Make ContentLines in ConvoViewRow an int as it should be.
Shorten common. in the generated templates.
Fix the page titles for the convo panes.
Stop non-present users from editing their convo posts but still allow them to delete them, if they somehow have a way to do that.
Reduce the amount of boilerplate in the currently broken guilds plugin.
This commit is contained in:
Azareal 2019-08-21 08:32:10 +10:00
parent f8991e089a
commit 0e9c459446
12 changed files with 144 additions and 117 deletions

View File

@ -180,7 +180,7 @@ func (list SFileList) JSTmplInit() error {
data = replace(data, "w.Write(", "out += ") data = replace(data, "w.Write(", "out += ")
data = replace(data, "strconv.Itoa(", "") data = replace(data, "strconv.Itoa(", "")
data = replace(data, "strconv.FormatInt(", "") data = replace(data, "strconv.FormatInt(", "")
data = replace(data, "common.", "") data = replace(data, "c.", "")
data = replace(data, "phrases.", "") data = replace(data, "phrases.", "")
data = replace(data, ", 10;", "") data = replace(data, ", 10;", "")
data = replace(data, shortName+"_tmpl_phrase_id = RegisterTmplPhraseNames([]string{", "[") data = replace(data, shortName+"_tmpl_phrase_id = RegisterTmplPhraseNames([]string{", "[")

View File

@ -273,14 +273,15 @@ type ConvoViewRow struct {
*ConversationPost *ConversationPost
User *User User *User
ClassName string ClassName string
ContentLines string ContentLines int
CanModify bool
} }
type ConvoViewPage struct { type ConvoViewPage struct {
*Header *Header
Convo *Conversation Convo *Conversation
Posts []ConvoViewRow Posts []ConvoViewRow
CanModify bool
Paginator Paginator
} }

View File

@ -176,7 +176,7 @@ func CompileTemplates() error {
c.SetConfig(config) c.SetConfig(config)
c.SetBaseImportMap(map[string]string{ c.SetBaseImportMap(map[string]string{
"io": "io", "io": "io",
"github.com/Azareal/Gosora/common": "github.com/Azareal/Gosora/common", "github.com/Azareal/Gosora/common": "c github.com/Azareal/Gosora/common",
}) })
c.SetBuildTags("!no_templategen") c.SetBuildTags("!no_templategen")
c.SetOverrideTrack(overriden) c.SetOverrideTrack(overriden)
@ -225,12 +225,12 @@ func compileCommons(c *tmpl.CTemplateSet, header *Header, header2 *Header, forum
var topicsList []*TopicsRow var topicsList []*TopicsRow
topicsList = append(topicsList, &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "127.0.0.1", 1, 0, 1, 1, 0, "classname", 0, "", &user2, "", 0, &user3, "General", "/forum/general.2", nil}) topicsList = append(topicsList, &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "127.0.0.1", 1, 0, 1, 1, 0, "classname", 0, "", &user2, "", 0, &user3, "General", "/forum/general.2", nil})
topicListPage := TopicListPage{htitle("Topic List"), topicsList, forumList, Config.DefaultForum, TopicListSort{"lastupdated", false}, Paginator{[]int{1}, 1, 1}} topicListPage := TopicListPage{htitle("Topic List"), topicsList, forumList, Config.DefaultForum, TopicListSort{"lastupdated", false}, Paginator{[]int{1}, 1, 1}}
out.Add("topics", "common.TopicListPage", topicListPage) out.Add("topics", "c.TopicListPage", topicListPage)
forumItem := BlankForum(1, "general-forum.1", "General Forum", "Where the general stuff happens", true, "all", 0, "", 0) forumItem := BlankForum(1, "general-forum.1", "General Forum", "Where the general stuff happens", true, "all", 0, "", 0)
forumPage := ForumPage{htitle("General Forum"), topicsList, forumItem, Paginator{[]int{1}, 1, 1}} forumPage := ForumPage{htitle("General Forum"), topicsList, forumItem, Paginator{[]int{1}, 1, 1}}
out.Add("forum", "common.ForumPage", forumPage) out.Add("forum", "c.ForumPage", forumPage)
out.Add("forums", "common.ForumsPage", ForumsPage{htitle("Forum List"), forumList}) out.Add("forums", "c.ForumsPage", ForumsPage{htitle("Forum List"), forumList})
poll := Poll{ID: 1, Type: 0, Options: map[int]string{0: "Nothing", 1: "Something"}, Results: map[int]int{0: 5, 1: 2}, QuickOptions: []PollOption{ poll := Poll{ID: 1, Type: 0, Options: map[int]string{0: "Nothing", 1: "Something"}, Results: map[int]int{0: 5, 1: 2}, QuickOptions: []PollOption{
PollOption{0, "Nothing"}, PollOption{0, "Nothing"},
@ -247,8 +247,8 @@ func compileCommons(c *tmpl.CTemplateSet, header *Header, header2 *Header, forum
replyList = append(replyList, ru) replyList = append(replyList, ru)
tpage := TopicPage{htitle("Topic Name"), replyList, topic, &Forum{ID: 1, Name: "Hahaha"}, poll, Paginator{[]int{1}, 1, 1}} tpage := TopicPage{htitle("Topic Name"), replyList, topic, &Forum{ID: 1, Name: "Hahaha"}, poll, Paginator{[]int{1}, 1, 1}}
tpage.Forum.Link = BuildForumURL(NameToSlug(tpage.Forum.Name), tpage.Forum.ID) tpage.Forum.Link = BuildForumURL(NameToSlug(tpage.Forum.Name), tpage.Forum.ID)
out.Add("topic", "common.TopicPage", tpage) out.Add("topic", "c.TopicPage", tpage)
out.Add("topic_alt", "common.TopicPage", tpage) out.Add("topic_alt", "c.TopicPage", tpage)
return nil return nil
} }
@ -296,7 +296,7 @@ func compileTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName string
} }
ppage := ProfilePage{htitle("User 526"), replyList, user, 0, 0} // TODO: Use the score from user to generate the currentScore and nextScore ppage := ProfilePage{htitle("User 526"), replyList, user, 0, 0} // TODO: Use the score from user to generate the currentScore and nextScore
tmpls.Add("profile", "common.ProfilePage", ppage) tmpls.Add("profile", "c.ProfilePage", ppage)
var topicsList []*TopicsRow var topicsList []*TopicsRow
topicsList = append(topicsList, &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "127.0.0.1", 1, 0, 1, 1, 0, "classname", 0, "", &user2, "", 0, &user3, "General", "/forum/general.2", nil}) topicsList = append(topicsList, &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "127.0.0.1", 1, 0, 1, 1, 0, "classname", 0, "", &user2, "", 0, &user3, "General", "/forum/general.2", nil})
@ -318,13 +318,13 @@ func compileTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName string
var pi interface{} var pi interface{}
switch sp[1] { switch sp[1] {
case "common.TopicListPage": case "c.TopicListPage":
pi = topicListPage pi = topicListPage
case "common.ForumPage": case "c.ForumPage":
pi = forumPage pi = forumPage
case "common.ProfilePage": case "c.ProfilePage":
pi = ppage pi = ppage
case "common.Page": case "c.Page":
pi = Page{htitle("Something"), tList, nil} pi = Page{htitle("Something"), tList, nil}
default: default:
continue continue
@ -337,22 +337,27 @@ func compileTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName string
} }
} }
tmpls.AddStd("login", "common.Page", Page{htitle("Login Page"), tList, nil}) tmpls.AddStd("login", "c.Page", Page{htitle("Login Page"), tList, nil})
tmpls.AddStd("register", "common.Page", Page{htitle("Registration Page"), tList, "nananana"}) tmpls.AddStd("register", "c.Page", Page{htitle("Registration Page"), tList, "nananana"})
tmpls.AddStd("error", "common.ErrorPage", ErrorPage{htitle("Error"), "A problem has occurred in the system."}) tmpls.AddStd("error", "c.ErrorPage", ErrorPage{htitle("Error"), "A problem has occurred in the system."})
ipSearchPage := IPSearchPage{htitle("IP Search"), map[int]*User{1: &user2}, "::1"} ipSearchPage := IPSearchPage{htitle("IP Search"), map[int]*User{1: &user2}, "::1"}
tmpls.AddStd("ip_search", "common.IPSearchPage", ipSearchPage) tmpls.AddStd("ip_search", "c.IPSearchPage", ipSearchPage)
var inter nobreak var inter nobreak
accountPage := Account{header, "dashboard", "account_own_edit", inter} accountPage := Account{header, "dashboard", "account_own_edit", inter}
tmpls.AddStd("account", "common.Account", accountPage) tmpls.AddStd("account", "c.Account", accountPage)
convo := &Conversation{1,user.ID,time.Now(),0,time.Now()}
convoItems := []ConvoViewRow{ConvoViewRow{&ConversationPost{1,1,"hey","",user.ID}, &user, "", 4, true}}
convoPage := ConvoViewPage{header, convo, convoItems, Paginator{[]int{1}, 1, 1}}
tmpls.AddStd("convo", "c.ConvoViewPage", convoPage)
basePage := &BasePanelPage{header, PanelStats{}, "dashboard", ReportForumID} basePage := &BasePanelPage{header, PanelStats{}, "dashboard", ReportForumID}
tmpls.AddStd("panel", "common.Panel", Panel{basePage, "panel_dashboard_right", "", "panel_dashboard", inter}) tmpls.AddStd("panel", "c.Panel", Panel{basePage, "panel_dashboard_right", "", "panel_dashboard", inter})
ges := []GridElement{GridElement{"","", "", 1, "grid_istat", "", "", ""}} ges := []GridElement{GridElement{"","", "", 1, "grid_istat", "", "", ""}}
tmpls.AddStd("panel_dashboard", "common.DashGrids", DashGrids{ges,ges}) tmpls.AddStd("panel_dashboard", "c.DashGrids", DashGrids{ges,ges})
//tmpls.AddStd("panel_analytics", "common.PanelAnalytics", Panel{basePage, "panel_dashboard_right","panel_dashboard", inter}) //tmpls.AddStd("panel_analytics", "c.PanelAnalytics", Panel{basePage, "panel_dashboard_right","panel_dashboard", inter})
var writeTemplate = func(name string, content interface{}) { var writeTemplate = func(name string, content interface{}) {
log.Print("Writing template '" + name + "'") log.Print("Writing template '" + name + "'")
@ -469,7 +474,7 @@ func CompileJSTemplates() error {
return err return err
} }
} }
var dirPrefix = "./tmpl_client/" dirPrefix := "./tmpl_client/"
writeTemplateList(c, &wg, dirPrefix) writeTemplateList(c, &wg, dirPrefix)
return nil return nil
} }
@ -478,7 +483,7 @@ func compileJSTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName stri
user, user2, user3 := tmplInitUsers() user, user2, user3 := tmplInitUsers()
header, _, _ := tmplInitHeaders(user, user2, user3) header, _, _ := tmplInitHeaders(user, user2, user3)
now := time.Now() now := time.Now()
var varList = make(map[string]tmpl.VarItem) varList := make(map[string]tmpl.VarItem)
c.SetBaseImportMap(map[string]string{ c.SetBaseImportMap(map[string]string{
"io": "io", "io": "io",
@ -494,15 +499,15 @@ func compileJSTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName stri
c.SetBaseImportMap(map[string]string{ c.SetBaseImportMap(map[string]string{
"io": "io", "io": "io",
"github.com/Azareal/Gosora/common": "github.com/Azareal/Gosora/common", "github.com/Azareal/Gosora/common": "c github.com/Azareal/Gosora/common",
}) })
// TODO: Fix the import loop so we don't have to use this hack anymore // TODO: Fix the import loop so we don't have to use this hack anymore
c.SetBuildTags("!no_templategen,tmplgentopic") c.SetBuildTags("!no_templategen,tmplgentopic")
tmpls := TItemHold(make(map[string]TItem)) tmpls := TItemHold(make(map[string]TItem))
var topicsRow = &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "127.0.0.1", 1, 0, 1, 0, 1, "classname", 0, "", &user2, "", 0, &user3, "General", "/forum/general.2", nil} topicsRow := &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "127.0.0.1", 1, 0, 1, 0, 1, "classname", 0, "", &user2, "", 0, &user3, "General", "/forum/general.2", nil}
tmpls.AddStd("topics_topic", "common.TopicsRow", topicsRow) tmpls.AddStd("topics_topic", "c.TopicsRow", topicsRow)
poll := Poll{ID: 1, Type: 0, Options: map[int]string{0: "Nothing", 1: "Something"}, Results: map[int]int{0: 5, 1: 2}, QuickOptions: []PollOption{ poll := Poll{ID: 1, Type: 0, Options: map[int]string{0: "Nothing", 1: "Something"}, Results: map[int]int{0: 5, 1: 2}, QuickOptions: []PollOption{
PollOption{0, "Nothing"}, PollOption{0, "Nothing"},
@ -523,17 +528,17 @@ func compileJSTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName stri
header.Title = "Topic Name" header.Title = "Topic Name"
tpage := TopicPage{header, replyList, topic, &Forum{ID: 1, Name: "Hahaha"}, poll, Paginator{[]int{1}, 1, 1}} tpage := TopicPage{header, replyList, topic, &Forum{ID: 1, Name: "Hahaha"}, poll, Paginator{[]int{1}, 1, 1}}
tpage.Forum.Link = BuildForumURL(NameToSlug(tpage.Forum.Name), tpage.Forum.ID) tpage.Forum.Link = BuildForumURL(NameToSlug(tpage.Forum.Name), tpage.Forum.ID)
tmpls.AddStd("topic_posts", "common.TopicPage", tpage) tmpls.AddStd("topic_posts", "c.TopicPage", tpage)
tmpls.AddStd("topic_alt_posts", "common.TopicPage", tpage) tmpls.AddStd("topic_alt_posts", "c.TopicPage", tpage)
itemsPerPage := 25 itemsPerPage := 25
_, page, lastPage := PageOffset(20, 1, itemsPerPage) _, page, lastPage := PageOffset(20, 1, itemsPerPage)
pageList := Paginate(page, lastPage, 5) pageList := Paginate(page, lastPage, 5)
tmpls.AddStd("paginator", "common.Paginator", Paginator{pageList, page, lastPage}) tmpls.AddStd("paginator", "c.Paginator", Paginator{pageList, page, lastPage})
tmpls.AddStd("topic_c_edit_post", "common.TopicCEditPost", TopicCEditPost{ID: 0, Source: "", Ref: ""}) tmpls.AddStd("topic_c_edit_post", "c.TopicCEditPost", TopicCEditPost{ID: 0, Source: "", Ref: ""})
tmpls.AddStd("topic_c_attach_item", "common.TopicCAttachItem", TopicCAttachItem{ID: 1, ImgSrc: "", Path: "", FullPath: ""}) tmpls.AddStd("topic_c_attach_item", "c.TopicCAttachItem", TopicCAttachItem{ID: 1, ImgSrc: "", Path: "", FullPath: ""})
tmpls.AddStd("topic_c_poll_input", "common.TopicCPollInput", TopicCPollInput{Index:0}) tmpls.AddStd("topic_c_poll_input", "c.TopicCPollInput", TopicCPollInput{Index:0})
tmpls.AddStd("notice", "string", "nonono") tmpls.AddStd("notice", "string", "nonono")

View File

@ -193,8 +193,13 @@ func (c *CTemplateSet) CompileByLoggedin(name string, fileDir string, expects st
} }
var importList string var importList string
for _, item := range c.importMap { for _, item := range c.importMap {
ispl := strings.Split(item," ")
if len(ispl) > 1 {
importList += "import "+ispl[0]+" \"" + ispl[1] + "\"\n"
} else {
importList += "import \"" + item + "\"\n" importList += "import \"" + item + "\"\n"
} }
}
fname := strings.TrimSuffix(name, filepath.Ext(name)) fname := strings.TrimSuffix(name, filepath.Ext(name))
if c.themeName != "" { if c.themeName != "" {
@ -204,7 +209,7 @@ func (c *CTemplateSet) CompileByLoggedin(name string, fileDir string, expects st
} }
fname += "_" + c.themeName fname += "_" + c.themeName
} }
c.importMap["github.com/Azareal/Gosora/common"] = "github.com/Azareal/Gosora/common" c.importMap["github.com/Azareal/Gosora/common"] = "c github.com/Azareal/Gosora/common"
stub = `package ` + c.config.PackageName + ` stub = `package ` + c.config.PackageName + `
` + importList + ` ` + importList + `
@ -215,14 +220,14 @@ import "errors"
stub += "// nolint\nfunc init() {\n" stub += "// nolint\nfunc init() {\n"
if !c.config.SkipHandles && c.themeName == "" { if !c.config.SkipHandles && c.themeName == "" {
stub += "\tcommon.Template_" + fname + "_handle = Template_" + fname + "\n" stub += "\tc.Template_" + fname + "_handle = Template_" + fname + "\n"
stub += "\tcommon.Ctemplates = append(common.Ctemplates,\"" + fname + "\")\n" stub += "\tc.Ctemplates = append(c.Ctemplates,\"" + fname + "\")\n"
} }
if !c.config.SkipTmplPtrMap { if !c.config.SkipTmplPtrMap {
stub += "tmpl := Template_" + fname + "\n" stub += "tmpl := Template_" + fname + "\n"
stub += "\tcommon.TmplPtrMap[\"" + fname + "\"] = &tmpl\n" stub += "\tc.TmplPtrMap[\"" + fname + "\"] = &tmpl\n"
stub += "\tcommon.TmplPtrMap[\"o_" + fname + "\"] = tmpl\n" stub += "\tc.TmplPtrMap[\"o_" + fname + "\"] = tmpl\n"
} }
stub += "}\n\n" stub += "}\n\n"
@ -361,7 +366,7 @@ func (c *CTemplateSet) compile(name string, content string, expects string, expe
c.detailf("c.overridenRoots: %+v\n", c.overridenRoots) c.detailf("c.overridenRoots: %+v\n", c.overridenRoots)
var outBuf []OutBufferFrame var outBuf []OutBufferFrame
var rootHold = "tmpl_" + fname + "_vars" rootHold := "tmpl_" + fname + "_vars"
con := CContext{ con := CContext{
RootHolder: rootHold, RootHolder: rootHold,
VarHolder: rootHold, VarHolder: rootHold,
@ -408,8 +413,13 @@ func (c *CTemplateSet) compile(name string, content string, expects string, expe
} }
var importList string var importList string
for _, item := range c.importMap { for _, item := range c.importMap {
ispl := strings.Split(item," ")
if len(ispl) > 1 {
importList += "import "+ispl[0]+" \"" + ispl[1] + "\"\n"
} else {
importList += "import \"" + item + "\"\n" importList += "import \"" + item + "\"\n"
} }
}
var varString string var varString string
for _, varItem := range c.varList { for _, varItem := range c.varList {
varString += "var " + varItem.Name + " " + varItem.Type + " = " + varItem.Destination + "\n" varString += "var " + varItem.Name + " " + varItem.Type + " = " + varItem.Destination + "\n"
@ -429,14 +439,14 @@ func (c *CTemplateSet) compile(name string, content string, expects string, expe
fout += "// nolint\nfunc init() {\n" fout += "// nolint\nfunc init() {\n"
if !c.config.SkipHandles && c.themeName == "" { if !c.config.SkipHandles && c.themeName == "" {
fout += "\tcommon.Template_" + fname + "_handle = Template_" + fname + "\n" fout += "\tc.Template_" + fname + "_handle = Template_" + fname + "\n"
fout += "\tcommon.Ctemplates = append(common.Ctemplates,\"" + fname + "\")\n" fout += "\tc.Ctemplates = append(c.Ctemplates,\"" + fname + "\")\n"
} }
if !c.config.SkipTmplPtrMap { if !c.config.SkipTmplPtrMap {
fout += "tmpl := Template_" + fname + "\n" fout += "tmpl := Template_" + fname + "\n"
fout += "\tcommon.TmplPtrMap[\"" + fname + "\"] = &tmpl\n" fout += "\tc.TmplPtrMap[\"" + fname + "\"] = &tmpl\n"
fout += "\tcommon.TmplPtrMap[\"o_" + fname + "\"] = tmpl\n" fout += "\tc.TmplPtrMap[\"o_" + fname + "\"] = tmpl\n"
} }
if len(c.langIndexToName) > 0 { if len(c.langIndexToName) > 0 {
fout += "\t" + fname + "_tmpl_phrase_id = phrases.RegisterTmplPhraseNames([]string{\n" fout += "\t" + fname + "_tmpl_phrase_id = phrases.RegisterTmplPhraseNames([]string{\n"
@ -456,7 +466,7 @@ func (c *CTemplateSet) compile(name string, content string, expects string, expe
} }
` `
fout += `var iw http.ResponseWriter fout += `var iw http.ResponseWriter
gzw, ok := w.(common.GzipResponseWriter) gzw, ok := w.(c.GzipResponseWriter)
if ok { if ok {
iw = gzw.ResponseWriter iw = gzw.ResponseWriter
} }
@ -1069,7 +1079,7 @@ ArgLoop:
val = val3 val = val3
// TODO: Refactor this // TODO: Refactor this
litString("common.BuildWidget("+leftParam+","+rightParam+")", false) litString("c.BuildWidget("+leftParam+","+rightParam+")", false)
break ArgLoop break ArgLoop
case "hasWidgets": case "hasWidgets":
// TODO: Implement string literals properly // TODO: Implement string literals properly
@ -1092,7 +1102,7 @@ ArgLoop:
val = val3 val = val3
// TODO: Refactor this // TODO: Refactor this
out = "common.HasWidgets(" + leftParam + "," + rightParam + ")" out = "c.HasWidgets(" + leftParam + "," + rightParam + ")"
literal = true literal = true
break ArgLoop break ArgLoop
case "lang": case "lang":
@ -1178,7 +1188,7 @@ ArgLoop:
panic("The leftoperand for function buint cannot be left blank") panic("The leftoperand for function buint cannot be left blank")
} }
leftParam, _ := c.compileIfVarSub(con, leftOperand) leftParam, _ := c.compileIfVarSub(con, leftOperand)
out = "{\nbyteFloat, unit := common.ConvertByteUnit(float64(" + leftParam + "))\n" out = "{\nbyteFloat, unit := c.ConvertByteUnit(float64(" + leftParam + "))\n"
out += "w.Write(fmt.Sprintf(\"%.1f\", byteFloat) + unit)\n" out += "w.Write(fmt.Sprintf(\"%.1f\", byteFloat) + unit)\n"
literal = true literal = true
break ArgLoop break ArgLoop
@ -1200,7 +1210,7 @@ ArgLoop:
} }
leftParam, _ := c.compileIfVarSub(con, leftOperand) leftParam, _ := c.compileIfVarSub(con, leftOperand)
// TODO: Refactor this // TODO: Refactor this
litString("common.RelativeTime("+leftParam+")", false) litString("c.RelativeTime("+leftParam+")", false)
break ArgLoop break ArgLoop
case "scope": case "scope":
literal = true literal = true

View File

@ -6,7 +6,7 @@ import "github.com/Azareal/Gosora/query_gen"
var Gstore GuildStore var Gstore GuildStore
type GuildStore interface { type GuildStore interface {
Get(guildID int) (guild *Guild, err error) Get(id int) (guild *Guild, err error)
Create(name string, desc string, active bool, privacy int, uid int, fid int) (int, error) Create(name string, desc string, active bool, privacy int, uid int, fid int) (int, error)
} }
@ -23,19 +23,19 @@ func NewSQLGuildStore() (*SQLGuildStore, error) {
}, acc.FirstError() }, acc.FirstError()
} }
func (store *SQLGuildStore) Close() { func (s *SQLGuildStore) Close() {
_ = store.get.Close() _ = s.get.Close()
_ = store.create.Close() _ = s.create.Close()
} }
func (store *SQLGuildStore) Get(guildID int) (guild *Guild, err error) { func (s *SQLGuildStore) Get(id int) (guild *Guild, err error) {
guild = &Guild{ID: guildID} g = &Guild{ID: id}
err = store.get.QueryRow(guildID).Scan(&guild.Name, &guild.Desc, &guild.Active, &guild.Privacy, &guild.Joinable, &guild.Owner, &guild.MemberCount, &guild.MainForumID, &guild.Backdrop, &guild.CreatedAt, &guild.LastUpdateTime) err = s.get.QueryRow(guildID).Scan(&g.Name, &g.Desc, &g.Active, &g.Privacy, &g.Joinable, &g.Owner, &g.MemberCount, &g.MainForumID, &g.Backdrop, &g.CreatedAt, &g.LastUpdateTime)
return guild, err return g, err
} }
func (store *SQLGuildStore) Create(name string, desc string, active bool, privacy int, uid int, fid int) (int, error) { func (s *SQLGuildStore) Create(name string, desc string, active bool, privacy int, uid int, fid int) (int, error) {
res, err := store.create.Exec(name, desc, active, privacy, uid, fid) res, err := s.create.Exec(name, desc, active, privacy, uid, fid)
if err != nil { if err != nil {
return 0, err return 0, err
} }

View File

@ -1,7 +1,7 @@
package main package main
import ( import (
"github.com/Azareal/Gosora/common" c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/extend/guilds/lib" "github.com/Azareal/Gosora/extend/guilds/lib"
) )
@ -9,21 +9,21 @@ import (
// TODO: Add a plugin interface instead of having a bunch of argument to AddPlugin? // TODO: Add a plugin interface instead of having a bunch of argument to AddPlugin?
func init() { func init() {
common.Plugins.Add(&common.Plugin{UName: "guilds", Name: "Guilds", Author: "Azareal", URL: "https://github.com/Azareal", Init: initGuilds, Deactivate: deactivateGuilds, Install: installGuilds}) c.Plugins.Add(&c.Plugin{UName: "guilds", Name: "Guilds", Author: "Azareal", URL: "https://github.com/Azareal", Init: initGuilds, Deactivate: deactivateGuilds, Install: installGuilds})
// TODO: Is it possible to avoid doing this when the plugin isn't activated? // TODO: Is it possible to avoid doing this when the plugin isn't activated?
common.PrebuildTmplList = append(common.PrebuildTmplList, guilds.PrebuildTmplList) c.PrebuildTmplList = append(c.PrebuildTmplList, guilds.PrebuildTmplList)
} }
func initGuilds(plugin *common.Plugin) (err error) { func initGuilds(pl *c.Plugin) (err error) {
plugin.AddHook("intercept_build_widgets", guilds.Widgets) pl.AddHook("intercept_build_widgets", guilds.Widgets)
plugin.AddHook("trow_assign", guilds.TrowAssign) pl.AddHook("trow_assign", guilds.TrowAssign)
plugin.AddHook("topic_create_pre_loop", guilds.TopicCreatePreLoop) pl.AddHook("topic_create_pre_loop", guilds.TopicCreatePreLoop)
plugin.AddHook("pre_render_forum", guilds.PreRenderViewForum) pl.AddHook("pre_render_forum", guilds.PreRenderViewForum)
plugin.AddHook("simple_forum_check_pre_perms", guilds.ForumCheck) pl.AddHook("simple_forum_check_pre_perms", guilds.ForumCheck)
plugin.AddHook("forum_check_pre_perms", guilds.ForumCheck) pl.AddHook("forum_check_pre_perms", guilds.ForumCheck)
// TODO: Auto-grant this perm to admins upon installation? // TODO: Auto-grant this perm to admins upon installation?
common.RegisterPluginPerm("CreateGuild") c.RegisterPluginPerm("CreateGuild")
router.HandleFunc("/guilds/", guilds.RouteGuildList) router.HandleFunc("/guilds/", guilds.RouteGuildList)
router.HandleFunc("/guild/", guilds.MiddleViewGuild) router.HandleFunc("/guild/", guilds.MiddleViewGuild)
router.HandleFunc("/guild/create/", guilds.RouteCreateGuild) router.HandleFunc("/guild/create/", guilds.RouteCreateGuild)
@ -54,14 +54,14 @@ func initGuilds(plugin *common.Plugin) (err error) {
return acc.FirstError() return acc.FirstError()
} }
func deactivateGuilds(plugin *common.Plugin) { func deactivateGuilds(pl *common.Plugin) {
plugin.RemoveHook("intercept_build_widgets", guilds.Widgets) pl.RemoveHook("intercept_build_widgets", guilds.Widgets)
plugin.RemoveHook("trow_assign", guilds.TrowAssign) pl.RemoveHook("trow_assign", guilds.TrowAssign)
plugin.RemoveHook("topic_create_pre_loop", guilds.TopicCreatePreLoop) pl.RemoveHook("topic_create_pre_loop", guilds.TopicCreatePreLoop)
plugin.RemoveHook("pre_render_forum", guilds.PreRenderViewForum) pl.RemoveHook("pre_render_forum", guilds.PreRenderViewForum)
plugin.RemoveHook("simple_forum_check_pre_perms", guilds.ForumCheck) pl.RemoveHook("simple_forum_check_pre_perms", guilds.ForumCheck)
plugin.RemoveHook("forum_check_pre_perms", guilds.ForumCheck) pl.RemoveHook("forum_check_pre_perms", guilds.ForumCheck)
common.DeregisterPluginPerm("CreateGuild") c.DeregisterPluginPerm("CreateGuild")
_ = router.RemoveFunc("/guilds/") _ = router.RemoveFunc("/guilds/")
_ = router.RemoveFunc("/guild/") _ = router.RemoveFunc("/guild/")
_ = router.RemoveFunc("/guild/create/") _ = router.RemoveFunc("/guild/create/")
@ -76,22 +76,23 @@ func deactivateGuilds(plugin *common.Plugin) {
} }
// TODO: Stop accessing the query builder directly and add a feature in Gosora which is more easily reversed, if an error comes up during the installation process // TODO: Stop accessing the query builder directly and add a feature in Gosora which is more easily reversed, if an error comes up during the installation process
type tC = qgen.DBTableColumn
func installGuilds(plugin *common.Plugin) error { func installGuilds(plugin *common.Plugin) error {
guildTableStmt, err := qgen.Builder.CreateTable("guilds", "utf8mb4", "utf8mb4_general_ci", guildTableStmt, err := qgen.Builder.CreateTable("guilds", "utf8mb4", "utf8mb4_general_ci",
[]qgen.DBTableColumn{ []tC{
qgen.DBTableColumn{"guildID", "int", 0, false, true, ""}, tC{"guildID", "int", 0, false, true, ""},
qgen.DBTableColumn{"name", "varchar", 100, false, false, ""}, tC{"name", "varchar", 100, false, false, ""},
qgen.DBTableColumn{"desc", "varchar", 200, false, false, ""}, tC{"desc", "varchar", 200, false, false, ""},
qgen.DBTableColumn{"active", "boolean", 1, false, false, ""}, tC{"active", "boolean", 1, false, false, ""},
qgen.DBTableColumn{"privacy", "smallint", 0, false, false, ""}, tC{"privacy", "smallint", 0, false, false, ""},
qgen.DBTableColumn{"joinable", "smallint", 0, false, false, "0"}, tC{"joinable", "smallint", 0, false, false, "0"},
qgen.DBTableColumn{"owner", "int", 0, false, false, ""}, tC{"owner", "int", 0, false, false, ""},
qgen.DBTableColumn{"memberCount", "int", 0, false, false, ""}, tC{"memberCount", "int", 0, false, false, ""},
qgen.DBTableColumn{"mainForum", "int", 0, false, false, "0"}, // The board the user lands on when they click on a group, we'll make it possible for group admins to change what users land on tC{"mainForum", "int", 0, false, false, "0"}, // The board the user lands on when they click on a group, we'll make it possible for group admins to change what users land on
//qgen.DBTableColumn{"boards","varchar",255,false,false,""}, // Cap the max number of boards at 8 to avoid overflowing the confines of a 64-bit integer? //tC{"boards","varchar",255,false,false,""}, // Cap the max number of boards at 8 to avoid overflowing the confines of a 64-bit integer?
qgen.DBTableColumn{"backdrop", "varchar", 200, false, false, ""}, // File extension for the uploaded file, or an external link tC{"backdrop", "varchar", 200, false, false, ""}, // File extension for the uploaded file, or an external link
qgen.DBTableColumn{"createdAt", "createdAt", 0, false, false, ""}, tC{"createdAt", "createdAt", 0, false, false, ""},
qgen.DBTableColumn{"lastUpdateTime", "datetime", 0, false, false, ""}, tC{"lastUpdateTime", "datetime", 0, false, false, ""},
}, },
[]qgen.DBTableKey{ []qgen.DBTableKey{
qgen.DBTableKey{"guildID", "primary"}, qgen.DBTableKey{"guildID", "primary"},
@ -107,12 +108,12 @@ func installGuilds(plugin *common.Plugin) error {
} }
guildMembersTableStmt, err := qgen.Builder.CreateTable("guilds_members", "", "", guildMembersTableStmt, err := qgen.Builder.CreateTable("guilds_members", "", "",
[]qgen.DBTableColumn{ []tC{
qgen.DBTableColumn{"guildID", "int", 0, false, false, ""}, tC{"guildID", "int", 0, false, false, ""},
qgen.DBTableColumn{"uid", "int", 0, false, false, ""}, tC{"uid", "int", 0, false, false, ""},
qgen.DBTableColumn{"rank", "int", 0, false, false, "0"}, /* 0: Member. 1: Mod. 2: Admin. */ tC{"rank", "int", 0, false, false, "0"}, /* 0: Member. 1: Mod. 2: Admin. */
qgen.DBTableColumn{"posts", "int", 0, false, false, "0"}, /* Per-Group post count. Should we do some sort of score system? */ tC{"posts", "int", 0, false, false, "0"}, /* Per-Group post count. Should we do some sort of score system? */
qgen.DBTableColumn{"joinedAt", "datetime", 0, false, false, ""}, tC{"joinedAt", "datetime", 0, false, false, ""},
}, nil, }, nil,
) )
if err != nil { if err != nil {
@ -124,6 +125,6 @@ func installGuilds(plugin *common.Plugin) error {
} }
// TO-DO; Implement an uninstallation system into Gosora. And a better installation system. // TO-DO; Implement an uninstallation system into Gosora. And a better installation system.
func uninstallGuilds(plugin *common.Plugin) error { func uninstallGuilds(plugin *c.Plugin) error {
return nil return nil
} }

View File

@ -143,8 +143,8 @@
"account_logins":"Logins", "account_logins":"Logins",
"account_penalties":"Penalties", "account_penalties":"Penalties",
"account_level_list":"Level Progress", "account_level_list":"Level Progress",
"convos_head":"Conversations", "convos":"Conversations",
"convo_head":"Conversation", "convo":"Conversation",
"panel_dashboard":"Control Panel Dashboard", "panel_dashboard":"Control Panel Dashboard",
"panel_forums":"Forum Manager", "panel_forums":"Forum Manager",

View File

@ -63,15 +63,15 @@ func Convo(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header
pitems := make([]c.ConvoViewRow, len(posts)) pitems := make([]c.ConvoViewRow, len(posts))
for i, post := range posts { for i, post := range posts {
user, err := c.Users.Get(post.CreatedBy) uuser, err := c.Users.Get(post.CreatedBy)
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
pitems[i] = c.ConvoViewRow{post, user, "", "4"} canModify := user.ID == post.CreatedBy || user.IsSuperMod
pitems[i] = c.ConvoViewRow{post, uuser, "", 4, canModify}
} }
canModify := user.ID == convo.CreatedBy || user.IsSuperMod
pi := c.Account{header, "dashboard", "convo", c.ConvoViewPage{header, convo, pitems, canModify, c.Paginator{pageList, page, lastPage}}} pi := c.Account{header, "dashboard", "convo", c.ConvoViewPage{header, convo, pitems, c.Paginator{pageList, page, lastPage}}}
return renderTemplate("account", w, r, header, pi) return renderTemplate("account", w, r, header, pi)
} }
@ -89,7 +89,7 @@ func ConvosCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.R
return ferr return ferr
} }
if user.IsBanned { if user.IsBanned {
return c.NoPermissions(w,r,user) return c.NoPermissions(w, r, user)
} }
recps := c.SanitiseSingleLine(r.PostFormValue("recp")) recps := c.SanitiseSingleLine(r.PostFormValue("recp"))
@ -145,7 +145,7 @@ func ConvosCreateReplySubmit(w http.ResponseWriter, r *http.Request, user c.User
return ferr return ferr
} }
if user.IsBanned { if user.IsBanned {
return c.NoPermissions(w,r,user) return c.NoPermissions(w, r, user)
} }
cid, err := strconv.Atoi(scid) cid, err := strconv.Atoi(scid)
if err != nil { if err != nil {
@ -163,7 +163,7 @@ func ConvosCreateReplySubmit(w http.ResponseWriter, r *http.Request, user c.User
return c.NotFound(w, r, nil) return c.NotFound(w, r, nil)
} }
if !convo.Has(user.ID) { if !convo.Has(user.ID) {
return c.LocalError("You are not in this conversation.",w,r,user) return c.LocalError("You are not in this conversation.", w, r, user)
} }
body := c.PreparseMessage(r.PostFormValue("content")) body := c.PreparseMessage(r.PostFormValue("content"))
@ -173,7 +173,7 @@ func ConvosCreateReplySubmit(w http.ResponseWriter, r *http.Request, user c.User
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
http.Redirect(w, r, "/user/convo/" + strconv.Itoa(convo.ID), http.StatusSeeOther) http.Redirect(w, r, "/user/convo/"+strconv.Itoa(convo.ID), http.StatusSeeOther)
return nil return nil
} }
@ -205,8 +205,8 @@ func ConvosDeleteReplySubmit(w http.ResponseWriter, r *http.Request, user c.User
if pcount == 0 { if pcount == 0 {
return c.NotFound(w, r, nil) return c.NotFound(w, r, nil)
} }
if user.ID != convo.CreatedBy && !user.IsSuperMod { if user.ID != post.CreatedBy && !user.IsSuperMod {
return c.NoPermissions(w,r,user) return c.NoPermissions(w, r, user)
} }
posts, err := convo.Posts(0, c.Config.ItemsPerPage) posts, err := convo.Posts(0, c.Config.ItemsPerPage)
@ -259,8 +259,11 @@ func ConvosEditReplySubmit(w http.ResponseWriter, r *http.Request, user c.User,
if pcount == 0 { if pcount == 0 {
return c.NotFound(w, r, nil) return c.NotFound(w, r, nil)
} }
if user.ID != convo.CreatedBy && !user.IsSuperMod { if user.ID != post.CreatedBy && !user.IsSuperMod {
return c.NoPermissions(w,r,user) return c.NoPermissions(w, r, user)
}
if !convo.Has(user.ID) {
return c.LocalError("You are not in this conversation.", w, r, user)
} }
post.Body = c.PreparseMessage(r.PostFormValue("edit_item")) post.Body = c.PreparseMessage(r.PostFormValue("edit_item"))

View File

@ -3,7 +3,10 @@
<h1>{{lang "convo_head"}}</h1> <h1>{{lang "convo_head"}}</h1>
</div> </div>
</div> </div>
<div class="colstack_item hash_hide">{{template "convo_row.html" . }}</div> <div class="colstack_item parti">
<div class="rowitem">Participants: Blah, Blah 2, Blah 3</div>
</div>
<div class="colstack_item">{{template "convo_row.html" .}}</div>
{{if not .CurrentUser.IsBanned}} {{if not .CurrentUser.IsBanned}}
<form action="/user/convo/create/submit/{{.Convo.ID}}?s={{.CurrentUser.Session}}" method="post"> <form action="/user/convo/create/submit/{{.Convo.ID}}?s={{.CurrentUser.Session}}" method="post">
<div class="colstack_item topic_reply_form" style="border-top:none;"> <div class="colstack_item topic_reply_form" style="border-top:none;">

View File

@ -6,7 +6,7 @@
<span class="controls"> <span class="controls">
<a href="{{.User.Link}}" class="real_username username">{{.User.Name}}</a>&nbsp;&nbsp; <a href="{{.User.Link}}" class="real_username username">{{.User.Name}}</a>&nbsp;&nbsp;
{{if $.CanModify}}<a href="/user/convo/edit/submit/{{.ID}}?s={{$.CurrentUser.Session}}" class="mod_button" title="{{lang "profile_comments_edit_tooltip"}}" aria-label="{{lang "profile_comments_edit_aria"}}"><button class="username edit_item edit_label"></button></a> {{if .CanModify}}<a href="/user/convo/edit/submit/{{.ID}}?s={{$.CurrentUser.Session}}" class="mod_button" title="{{lang "profile_comments_edit_tooltip"}}" aria-label="{{lang "profile_comments_edit_aria"}}"><button class="username edit_item edit_label"></button></a>
<a href="/user/convo/delete/submit/{{.ID}}?s={{$.CurrentUser.Session}}" class="mod_button" title="{{lang "profile_comments_delete_tooltip"}}" aria-label="{{lang "profile_comments_delete_aria"}}"><button class="username delete_item delete_label"></button></a>{{end}} <a href="/user/convo/delete/submit/{{.ID}}?s={{$.CurrentUser.Session}}" class="mod_button" title="{{lang "profile_comments_delete_tooltip"}}" aria-label="{{lang "profile_comments_delete_aria"}}"><button class="username delete_item delete_label"></button></a>{{end}}

View File

@ -9,7 +9,7 @@
</span> </span>
</div> </div>
<span class="controls"> <span class="controls">
{{if $.CanModify}} {{if .CanModify}}
<a href="/user/convo/edit/submit/{{.ID}}?s={{$.CurrentUser.Session}}" class="mod_button" title="{{lang "profile_comments_edit_tooltip"}}" aria-label="{{lang "profile_comments_edit_aria"}}"><button class="username edit_item edit_label"></button></a> <a href="/user/convo/edit/submit/{{.ID}}?s={{$.CurrentUser.Session}}" class="mod_button" title="{{lang "profile_comments_edit_tooltip"}}" aria-label="{{lang "profile_comments_edit_aria"}}"><button class="username edit_item edit_label"></button></a>
<a href="/user/convo/delete/submit/{{.ID}}?s={{$.CurrentUser.Session}}" class="mod_button" title="{{lang "profile_comments_delete_tooltip"}}" aria-label="{{lang "profile_comments_delete_aria"}}"><button class="username delete_item delete_label"></button></a> <a href="/user/convo/delete/submit/{{.ID}}?s={{$.CurrentUser.Session}}" class="mod_button" title="{{lang "profile_comments_delete_tooltip"}}" aria-label="{{lang "profile_comments_delete_aria"}}"><button class="username delete_item delete_label"></button></a>

View File

@ -1,3 +1,7 @@
.parti {
margin-bottom: 8px;
}
.rowitem .topRow { .rowitem .topRow {
display: flex; display: flex;
width: 100%; width: 100%;