~aw/fishbb

9eefc6e95533ea7e229743808fb9b8bf5e61f39d — alex wennerberg 2 months ago 829ed25
smaller fixes, organize TODO
8 files changed, 38 insertions(+), 13 deletions(-)

M TODO
M db.go
M forum.go
M views/forum.html
M views/index.html
M views/login.html
M views/thread.html
M web.go
M TODO => TODO +12 -3
@@ 1,15 1,24 @@
Setup fishbb.org (cloud provider)

FEATURES:
minor/bugs:
rate limit registration
better error handling on login
better ux for account creation
move lock to right place
links on home and thread list should go to the post

NOTIFICATIONS:
- @mentions
- auto-hyperlink @mention maybe?

"shortpsot" list -> use summary code

Login/Reigster:
add a reply button that uses @mentions
finish up oauth integration
admin/mod ability to delete / edit posts
Notifications (Including integration with PWA / browser API)
links on home and thread list should go to the post
Search
thread count on index.html

----- alpha waterline ----- (may push lower to get something more complete out)


M db.go => db.go +4 -1
@@ 93,7 93,8 @@ func prepareStatements(db *sql.DB) {
	stmtGetForums = prepare(db, `
		select forums.id, name, description, permissions,
		coalesce(threadid, 0), coalesce(latest.title, ''), coalesce(latest.id, 0), coalesce(latest.authorid, 0),
		coalesce(latest.username, ''), coalesce(latest.created, '')
		coalesce(latest.username, ''), coalesce(latest.created, ''),
		count(1)
		from forums
		left join (
			select threadid, threads.title, posts.id, threads.authorid,


@@ 103,6 104,8 @@ func prepareStatements(db *sql.DB) {
			join threads on posts.threadid = threads.id
			group by forumid 
		) latest on latest.forumid = forums.id
		left join threads on threads.forumid = forums.id
		group by 1

`)
	stmtGetForum = prepare(db, "select id, name, description, slug, permissions from forums where id = ?")

M forum.go => forum.go +2 -1
@@ 12,6 12,7 @@ type Forum struct {
	// lowest level that can view this for
	Permissions Role
	LastPost    PostSummary
	ThreadCount int
}

func createForum(name, description string) error {


@@ 58,7 59,7 @@ func getForums() ([]Forum, error) {
		err := rows.Scan(&f.ID, &f.Name, &f.Description, &f.Permissions,
			&f.LastPost.ThreadID, &f.LastPost.ThreadTitle,
			&f.LastPost.ID,
			&f.LastPost.Author.ID, &f.LastPost.Author.Username, &created)
			&f.LastPost.Author.ID, &f.LastPost.Author.Username, &created, &f.ThreadCount)
		if err != nil {
			return nil, err
		}

M views/forum.html => views/forum.html +2 -2
@@ 20,8 20,8 @@
		</div>
	  {{ if and $.User $.User.Role.ModLevel }}
	  <span>
		  <form style="display:inline;" method="POST" action="/f/{{$.ForumSlug}}/{{.ID}}/lock?s={{not .Locked}}"><button class="link-button" id="submit">{{ if .Locked}}Unl{{else}}L{{end}}ock</button></form>
		  <form style="display:inline;" method="POST" action="/f/{{$.ForumSlug}}/{{.ID}}/pin?s={{ not .Pinned}}"><button class="link-button" id="submit">{{ if .Pinned}}Unp{{else}}P{{end}}in</button></form>
		  <form style="display:inline;" method="POST" action="/f/{{$.Forum.Slug}}/{{.ID}}/lock?s={{not .Locked}}"><button class="link-button" id="submit">{{ if .Locked}}Unl{{else}}L{{end}}ock</button></form>
		  <form style="display:inline;" method="POST" action="/f/{{$.Forum.Slug}}/{{.ID}}/pin?s={{ not .Pinned}}"><button class="link-button" id="submit">{{ if .Pinned}}Unp{{else}}P{{end}}in</button></form>
	  </span>
		</div>
	  {{ end }}

M views/index.html => views/index.html +3 -2
@@ 1,15 1,16 @@
{{ template "header.html" . }}
<table class="nav-table" id="forums">
  <tr><th style="width:66%">Forum</th><th style="width:33%">Last Post</th></tr>
	<tr><th style="width:60%">Forum</th><th>Threads</th><th style="width:30%">Last Post</th></tr>
  {{ range .Forums }}
  <tr>
    <td>
      <a class="title-link" href="/f/{{.Slug}}">{{.Name}}</a><br>
      {{.Description}}
    </td>
	<td style="text-align:center;">{{.ThreadCount}}</td>
    <td>
		<a href="/f/{{.Slug}}/{{.LastPost.ThreadID}}?p={{.LastPost.ID}}">{{ timeago .LastPost.Created }}</a> 
		by <a href="/user/{{.LastPost.Author.ID}}">{{.LastPost.Author.Username}}</a>
		by <a href="/user/{{.LastPost.Author.ID}}">{{.LastPost.Author.Username}}</a><br>
		in <a href="/f/{{.Slug}}/{{.LastPost.ThreadID}}">{{.LastPost.ThreadTitle}}</a><br>
    </td>
  </tr>

M views/login.html => views/login.html +1 -0
@@ 9,6 9,7 @@
<button tabindex=1 name="login" value="login">Login</button>
</form>
{{ if .Config.GoogleOAuthClientID }}
No account yet? <a href="/register">Register!</a>
<br>
<a href="/auth/google/login">
<button class="gsi-material-button">

M views/thread.html => views/thread.html +6 -1
@@ 1,9 1,14 @@
{{ template "header.html" . }}
<div class="body-header">
	{{ if or (not .Thread.Locked) (.User.Role.ModLevel) }}
<a href="/post/new?threadid={{.Thread.ID}}"><button class="top-button">Reply</button></a>
	{{ end }}
{{ template "pagelist.html" . }}
</div>
<div class="div-header"><a href="/f/{{.Forum.Slug}}">{{.Forum.Name}}</a> > {{.Thread.Title}}
<div class="div-header">

	{{ if .Thread.Locked }} {{ template "lock.svg" }} {{end}}
	<a href="/f/{{.Forum.Slug}}">{{.Forum.Name}}</a> > {{.Thread.Title}}
</div>
{{ range .Posts }}
<div class="post" id={{.ID}}>

M web.go => web.go +8 -3
@@ 171,6 171,11 @@ func createNewPost(w http.ResponseWriter, r *http.Request) {
		return // TODO 4xx
	}
	tid, _ := strconv.Atoi(r.URL.Query().Get("threadid"))
	thread, _ := getThread(tid)
	if thread.Locked && !u.Role.ModLevel() {
		// can't post in locked thread
		return // TODO 4xx
	}
	pid, err := createPost(u.UserID, int(tid), content)
	if err != nil {
		serverError(w, r, err)


@@ 196,7 201,7 @@ func doDeletePost(w http.ResponseWriter, r *http.Request) {
		return
	}
	aid := post.Author.ID
	if u.UserID != aid {
	if u.UserID != aid && !u.Role.ModLevel() {
		unauthorized(w, r)
		return
	}


@@ 217,7 222,7 @@ func editPostPage(w http.ResponseWriter, r *http.Request) {
		return
	}
	u := GetUserInfo(r)
	if post.Author.ID != u.UserID {
	if post.Author.ID != u.UserID && !u.Role.ModLevel() {
		unauthorized(w, r)
		return
	}


@@ 308,7 313,7 @@ func registerPage(w http.ResponseWriter, r *http.Request) {
			return
		}

		err := createUser(username, email, password, RoleUser, config.RequiresApproval)
		err := createUser(username, email, password, RoleUser, !config.RequiresApproval)
		if err != nil {
			serverError(w, r, err)
		}