You can now post in any forum you want via the Board selector.

Added a lock indicator for forums you don't have permission to post in.
Added a New Topic option in forums you have permission to post in.
General is now the default forum for topics.
/topics/ no longer shows topics for forums you aren't able to access.
This commit is contained in:
Azareal 2017-02-05 14:41:53 +00:00
parent c233f1fbbe
commit df5f70ee6b
10 changed files with 130 additions and 44 deletions

View File

@ -74,7 +74,7 @@ CREATE TABLE `topics`(
`createdBy` int not null, `createdBy` int not null,
`is_closed` tinyint DEFAULT 0 not null, `is_closed` tinyint DEFAULT 0 not null,
`sticky` tinyint DEFAULT 0 not null, `sticky` tinyint DEFAULT 0 not null,
`parentID` int DEFAULT 1 not null, `parentID` int DEFAULT 2 not null,
`ipaddress` varchar(200) DEFAULT '0.0.0.0.0' not null, `ipaddress` varchar(200) DEFAULT '0.0.0.0.0' not null,
`postCount` int DEFAULT 1 not null, `postCount` int DEFAULT 1 not null,
`data` varchar(200) DEFAULT '' not null, `data` varchar(200) DEFAULT '' not null,

View File

@ -42,6 +42,7 @@ var template_topics_handle func(TopicsPage,io.Writer) = nil
var template_forum_handle func(ForumPage,io.Writer) = nil var template_forum_handle func(ForumPage,io.Writer) = nil
var template_forums_handle func(ForumsPage,io.Writer) = nil var template_forums_handle func(ForumsPage,io.Writer) = nil
var template_profile_handle func(ProfilePage,io.Writer) = nil var template_profile_handle func(ProfilePage,io.Writer) = nil
var template_create_topic_handle func(CreateTopicPage,io.Writer) = nil
func compile_templates() { func compile_templates() {
var c CTemplateSet var c CTemplateSet

View File

@ -130,7 +130,7 @@ func init_database(err error) {
} }
log.Print("Preparing create_topic statement.") log.Print("Preparing create_topic statement.")
create_topic_stmt, err = db.Prepare("insert into topics(title,content,parsed_content,createdAt,ipaddress,createdBy) VALUES(?,?,?,NOW(),?,?)") create_topic_stmt, err = db.Prepare("insert into topics(parentID,title,content,parsed_content,createdAt,ipaddress,createdBy) VALUES(?,?,?,?,NOW(),?,?)")
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }

View File

@ -63,6 +63,16 @@ type ProfilePage struct
ExtData interface{} ExtData interface{}
} }
type CreateTopicPage struct
{
Title string
CurrentUser User
NoticeList []string
ItemList []Forum
FID int
ExtData interface{}
}
type PageSimple struct type PageSimple struct
{ {
Title string Title string

View File

@ -74,7 +74,6 @@ func route_custom_page(w http.ResponseWriter, r *http.Request){
if !ok { if !ok {
return return
} }
name := r.URL.Path[len("/pages/"):] name := r.URL.Path[len("/pages/"):]
if templates.Lookup("page_" + name) == nil { if templates.Lookup("page_" + name) == nil {
NotFound(w,r,user) NotFound(w,r,user)
@ -93,8 +92,17 @@ func route_topics(w http.ResponseWriter, r *http.Request){
return return
} }
var fidList []string
group := groups[user.Group]
for _, fid := range group.CanSee {
if forums[fid].Name != "" {
fidList = append(fidList,strconv.Itoa(fid))
}
}
var topicList []TopicUser var topicList []TopicUser
rows, err := get_topic_list_stmt.Query() rows, err := db.Query("select topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.parentID, users.name, users.avatar from topics left join users ON topics.createdBy = users.uid where parentID in("+strings.Join(fidList,",")+") order by topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC")
//rows, err := get_topic_list_stmt.Query()
if err != nil { if err != nil {
InternalError(err,w,r,user) InternalError(err,w,r,user)
return return
@ -530,9 +538,9 @@ func route_profile(w http.ResponseWriter, r *http.Request){
if template_profile_handle != nil { if template_profile_handle != nil {
template_profile_handle(ppage,w) template_profile_handle(ppage,w)
} else { } else {
err = templates.ExecuteTemplate(w,"profile.html", ppage) err = templates.ExecuteTemplate(w,"profile.html",ppage)
if err != nil { if err != nil {
InternalError(err, w, r, user) InternalError(err,w,r,user)
} }
} }
} }
@ -546,8 +554,35 @@ func route_topic_create(w http.ResponseWriter, r *http.Request){
NoPermissions(w,r,user) NoPermissions(w,r,user)
return return
} }
pi := Page{"Create Topic",user,noticeList,tList,0}
templates.ExecuteTemplate(w,"create-topic.html", pi) var fid int
var err error
sfid := r.URL.Path[len("/topics/create/"):]
if sfid != "" {
fid, err = strconv.Atoi(sfid)
if err != nil {
LocalError("The provided ForumID is not a valid number.",w,r,user)
return
}
}
var forumList []Forum
group := groups[user.Group]
for _, fid := range group.CanSee {
if forums[fid].Active && forums[fid].Name != "" {
forumList = append(forumList, forums[fid])
}
}
ctpage := CreateTopicPage{"Create Topic",user,noticeList,forumList,fid,nil}
if template_create_topic_handle != nil {
template_create_topic_handle(ctpage,w)
} else {
err = templates.ExecuteTemplate(w,"create-topic.html",ctpage)
if err != nil {
InternalError(err,w,r,user)
}
}
} }
// POST functions. Authorised users only. // POST functions. Authorised users only.
@ -563,11 +598,15 @@ func route_create_topic(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm() err := r.ParseForm()
if err != nil { if err != nil {
LocalError("Bad Form", w, r, user) LocalError("Bad Form",w,r,user)
return return
} }
fid := 2 fid, err := strconv.Atoi(r.PostFormValue("topic-board"))
if err != nil {
LocalError("The provided ForumID is not a valid number.",w,r,user)
return
}
topic_name := html.EscapeString(r.PostFormValue("topic-name")) topic_name := html.EscapeString(r.PostFormValue("topic-name"))
content := html.EscapeString(preparse_message(r.PostFormValue("topic-content"))) content := html.EscapeString(preparse_message(r.PostFormValue("topic-content")))
ipaddress, _, err := net.SplitHostPort(r.RemoteAddr) ipaddress, _, err := net.SplitHostPort(r.RemoteAddr)
@ -581,7 +620,7 @@ func route_create_topic(w http.ResponseWriter, r *http.Request) {
return return
} }
res, err := create_topic_stmt.Exec(topic_name,content,parse_message(content),ipaddress,user.ID) res, err := create_topic_stmt.Exec(fid,topic_name,content,parse_message(content),ipaddress,user.ID)
if err != nil { if err != nil {
InternalError(err,w,r,user) InternalError(err,w,r,user)
return return
@ -593,22 +632,27 @@ func route_create_topic(w http.ResponseWriter, r *http.Request) {
return return
} }
_, err = add_topics_to_forum_stmt.Exec(1, fid) _, err = add_topics_to_forum_stmt.Exec(1,fid)
if err != nil { if err != nil {
InternalError(err,w,r,user) InternalError(err,w,r,user)
return return
} }
forums[fid].TopicCount -= 1 forums[fid].TopicCount -= 1
_, err = update_forum_cache_stmt.Exec(topic_name, lastId, user.Name, user.ID, fid) _, err = update_forum_cache_stmt.Exec(topic_name,lastId,user.Name,user.ID,fid)
if err != nil { if err != nil {
InternalError(err,w,r,user) InternalError(err,w,r,user)
return return
} }
forums[fid].LastTopic = topic_name
forums[fid].LastTopicID = int(lastId)
forums[fid].LastReplyer = user.Name
forums[fid].LastReplyerID = user.ID
forums[fid].LastTopicTime = ""
http.Redirect(w, r, "/topic/" + strconv.FormatInt(lastId,10), http.StatusSeeOther) http.Redirect(w, r, "/topic/" + strconv.FormatInt(lastId,10), http.StatusSeeOther)
wcount := word_count(content) wcount := word_count(content)
err = increase_post_user_stats(wcount, user.ID, true, user) err = increase_post_user_stats(wcount,user.ID,true,user)
if err != nil { if err != nil {
InternalError(err,w,r,user) InternalError(err,w,r,user)
return return

View File

@ -1,7 +1,7 @@
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */ /* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
package main package main
import "io"
import "strconv" import "strconv"
import "io"
func init() { func init() {
template_forum_handle = template_forum template_forum_handle = template_forum
@ -61,34 +61,50 @@ w.Write(forum_7)
w.Write(forum_8) w.Write(forum_8)
w.Write([]byte(tmpl_forum_vars.Title)) w.Write([]byte(tmpl_forum_vars.Title))
w.Write(forum_9) w.Write(forum_9)
if len(tmpl_forum_vars.ItemList) != 0 { if tmpl_forum_vars.CurrentUser.ID != 0 {
for _, item := range tmpl_forum_vars.ItemList { if !tmpl_forum_vars.CurrentUser.Perms.CreateTopic {
w.Write(forum_10) w.Write(forum_10)
if item.Avatar != "" { } else {
w.Write(forum_11) w.Write(forum_11)
w.Write([]byte(item.Avatar)) w.Write([]byte(strconv.Itoa(tmpl_forum_vars.Forum.ID)))
w.Write(forum_12) w.Write(forum_12)
} }
if item.Sticky { }
w.Write(forum_13) w.Write(forum_13)
} else { if len(tmpl_forum_vars.ItemList) != 0 {
if item.Is_Closed { for _, item := range tmpl_forum_vars.ItemList {
w.Write(forum_14) w.Write(forum_14)
} if item.Avatar != "" {
}
w.Write(forum_15) w.Write(forum_15)
w.Write([]byte(strconv.Itoa(item.ID))) w.Write([]byte(item.Avatar))
w.Write(forum_16) w.Write(forum_16)
w.Write([]byte(item.Title)) }
if item.Sticky {
w.Write(forum_17) w.Write(forum_17)
} else {
if item.Is_Closed { if item.Is_Closed {
w.Write(forum_18) w.Write(forum_18)
} }
}
w.Write(forum_19) w.Write(forum_19)
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(forum_20)
w.Write([]byte(item.Title))
w.Write(forum_21)
if item.Is_Closed {
w.Write(forum_22)
}
w.Write(forum_23)
} }
} else { } else {
w.Write(forum_20) w.Write(forum_24)
if tmpl_forum_vars.CurrentUser.Perms.CreateTopic {
w.Write(forum_25)
w.Write([]byte(strconv.Itoa(tmpl_forum_vars.Forum.ID)))
w.Write(forum_26)
} }
w.Write(forum_21) w.Write(forum_27)
}
w.Write(forum_28)
w.Write(footer_0) w.Write(footer_0)
} }

View File

@ -425,24 +425,32 @@ var forum_7 []byte = []byte(`">&gt;</a></div>`)
var forum_8 []byte = []byte(` var forum_8 []byte = []byte(`
<div class="rowblock"> <div class="rowblock">
<div class="rowitem rowhead"><a>`) <div class="rowitem rowhead"><a>`)
var forum_9 []byte = []byte(`</a></div> var forum_9 []byte = []byte(`</a>
`)
var forum_10 []byte = []byte(`<span class='username' title='No Permissions' style="font-weight:normal;float: right;position:relative;top:-5px;">&#x1F512;&#xFE0E</span>`)
var forum_11 []byte = []byte(`<a href="/topics/create/`)
var forum_12 []byte = []byte(`" class='username' style="float: right;position:relative;top:-5px;">New Topic</a>`)
var forum_13 []byte = []byte(`</div>
</div> </div>
<div class="rowblock"> <div class="rowblock">
`) `)
var forum_10 []byte = []byte(`<div class="rowitem passive" style="`) var forum_14 []byte = []byte(`<div class="rowitem passive" style="`)
var forum_11 []byte = []byte(`background-image: url(`) var forum_15 []byte = []byte(`background-image: url(`)
var forum_12 []byte = []byte(`);background-position: left;background-repeat: no-repeat;background-size: 64px;padding-left: 72px;`) var forum_16 []byte = []byte(`);background-position: left;background-repeat: no-repeat;background-size: 64px;padding-left: 72px;`)
var forum_13 []byte = []byte(`background-color: #FFFFCC;`) var forum_17 []byte = []byte(`background-color: #FFFFCC;`)
var forum_14 []byte = []byte(`background-color: #eaeaea;`) var forum_18 []byte = []byte(`background-color: #eaeaea;`)
var forum_15 []byte = []byte(`"> var forum_19 []byte = []byte(`">
<a href="/topic/`) <a href="/topic/`)
var forum_16 []byte = []byte(`">`) var forum_20 []byte = []byte(`">`)
var forum_17 []byte = []byte(`</a> `) var forum_21 []byte = []byte(`</a> `)
var forum_18 []byte = []byte(`<span class="username topic_status_e topic_status_closed" title="Status: Closed" style="float: right;position:relative;top:-5px;">&#x1F512;&#xFE0E</span>`) var forum_22 []byte = []byte(`<span class="username topic_status_e topic_status_closed" title="Status: Closed" style="float: right;position:relative;top:-5px;">&#x1F512;&#xFE0E</span>`)
var forum_19 []byte = []byte(` var forum_23 []byte = []byte(`
</div> </div>
`) `)
var forum_20 []byte = []byte(`<div class="rowitem passive">There aren't any topics in this forum yet.</div>`) var forum_24 []byte = []byte(`<div class="rowitem passive">There aren't any topics in this forum yet.`)
var forum_21 []byte = []byte(` var forum_25 []byte = []byte(` <a href="/topics/create/`)
var forum_26 []byte = []byte(`">Start one?</a>`)
var forum_27 []byte = []byte(`</div>`)
var forum_28 []byte = []byte(`
</div> </div>
`) `)

View File

@ -1,7 +1,7 @@
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */ /* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
package main package main
import "io"
import "strconv" import "strconv"
import "io"
func init() { func init() {
template_profile_handle = template_profile template_profile_handle = template_profile

View File

@ -4,6 +4,12 @@
</div> </div>
<div class="rowblock"> <div class="rowblock">
<form action="/topic/create/submit/" method="post"> <form action="/topic/create/submit/" method="post">
<div class="formrow">
<div class="formitem"><a>Board</a></div>
<div class="formitem"><select name="topic-board">
{{range .ItemList}}<option {{if eq .ID $.FID}}selected{{end}} value="{{.ID}}">{{.Name}}</option>{{end}}
</select></div>
</div>
<div class="formrow"> <div class="formrow">
<div class="formitem"><a>Topic Name</a></div> <div class="formitem"><a>Topic Name</a></div>
<div class="formitem"><input name="topic-name" type="text" placeholder="Topic Name" /></div> <div class="formitem"><input name="topic-name" type="text" placeholder="Topic Name" /></div>

View File

@ -3,12 +3,13 @@
{{if ne .LastPage .Page}}<link rel="prerender" href="/forum/{{.Forum.ID}}?page={{add .Page 1}}" /> {{if ne .LastPage .Page}}<link rel="prerender" href="/forum/{{.Forum.ID}}?page={{add .Page 1}}" />
<div id="nextFloat" class="next_button"><a class="next_link" href="/forum/{{.Forum.ID}}?page={{add .Page 1}}">&gt;</a></div>{{end}} <div id="nextFloat" class="next_button"><a class="next_link" href="/forum/{{.Forum.ID}}?page={{add .Page 1}}">&gt;</a></div>{{end}}
<div class="rowblock"> <div class="rowblock">
<div class="rowitem rowhead"><a>{{.Title}}</a></div> <div class="rowitem rowhead"><a>{{.Title}}</a>
{{if ne .CurrentUser.ID 0}}{{if not .CurrentUser.Perms.CreateTopic}}<span class='username' title='No Permissions' style="font-weight:normal;float: right;position:relative;top:-5px;">&#x1F512;&#xFE0E</span>{{else}}<a href="/topics/create/{{.Forum.ID}}" class='username' style="float: right;position:relative;top:-5px;">New Topic</a>{{end}}{{end}}</div>
</div> </div>
<div class="rowblock"> <div class="rowblock">
{{range .ItemList}}<div class="rowitem passive" style="{{if .Avatar}}background-image: url({{.Avatar}});background-position: left;background-repeat: no-repeat;background-size: 64px;padding-left: 72px;{{end}}{{if .Sticky}}background-color: #FFFFCC;{{else if .Is_Closed}}background-color: #eaeaea;{{end}}"> {{range .ItemList}}<div class="rowitem passive" style="{{if .Avatar}}background-image: url({{.Avatar}});background-position: left;background-repeat: no-repeat;background-size: 64px;padding-left: 72px;{{end}}{{if .Sticky}}background-color: #FFFFCC;{{else if .Is_Closed}}background-color: #eaeaea;{{end}}">
<a href="/topic/{{.ID}}">{{.Title}}</a> {{if .Is_Closed}}<span class="username topic_status_e topic_status_closed" title="Status: Closed" style="float: right;position:relative;top:-5px;">&#x1F512;&#xFE0E</span>{{end}} <a href="/topic/{{.ID}}">{{.Title}}</a> {{if .Is_Closed}}<span class="username topic_status_e topic_status_closed" title="Status: Closed" style="float: right;position:relative;top:-5px;">&#x1F512;&#xFE0E</span>{{end}}
</div> </div>
{{else}}<div class="rowitem passive">There aren't any topics in this forum yet.</div>{{end}} {{else}}<div class="rowitem passive">There aren't any topics in this forum yet.{{if .CurrentUser.Perms.CreateTopic}} <a href="/topics/create/{{.Forum.ID}}">Start one?</a>{{end}}</div>{{end}}
</div> </div>
{{template "footer.html" . }} {{template "footer.html" . }}