~aw/fishbb

87a2b9fd14a53204bb145d47bd8804a826838c58 — alex wennerberg a month ago c9aec73
WIP locking and pinning threads
5 files changed, 60 insertions(+), 4 deletions(-)

M TODO
M thread.go
M views/forum.html
M views/style.css
M web.go
M TODO => TODO +0 -1
@@ 7,7 7,6 @@ links on home and thread list should go to the post
Login/Reigster:
finish up oauth integration
admin/mod ability to delete / edit posts
Edit save should return to post
proper page titles
ts hover to show full TS + Timestamp into a template snippet
Notifications (Including integration with PWA / browser API)

M thread.go => thread.go +2 -2
@@ 51,12 51,12 @@ func getThreads(forumID, page int) ([]Thread, error) {
	return threads, nil
}

func threadPin(threadid int, pinned bool) error {
func setThreadPin(threadid int, pinned bool) error {
	_, err := stmtThreadPin.Exec(pinned, threadid)
	return err
}

func threadLock(threadid int, locked bool) error {
func setThreadLock(threadid int, locked bool) error {
	_, err := stmtThreadLock.Exec(locked, threadid)
	return err
}

M views/forum.html => views/forum.html +17 -1
@@ 13,8 13,20 @@
    <td>
		{{ if .Locked }} {{ template "lock.svg" }} {{ end }}
		{{ if .Pinned }} {{ template "pin.svg" }} {{ end }}
      <a class="title-link" href="/f/general/{{.ID}}">{{.Title}}</a><br>
		<div class="flex-between">
		<div>
		<a class="title-link" href="/f/{{$.ForumSlug}}/{{.ID}}">{{.Title}}</a><br>
	  by <a href="/user/{{.Author.ID}}">{{.Author.Username}}</a> <span class="text-alt">{{ timeago .Created }}</span>
		</div>
	  {{ if $.User.Role.ModLevel }}
	  <div>
		  <form method="POST" action="/f/{{$.ForumSlug}}/{{.ID}}/lock"><button class="link-button" id="submit">Lock</button></form>
		  {{ if not .Pinned }}
		  <form method="POST" action="/f/{{$.ForumSlug}}/{{.ID}}/pin"><button class="link-button" id="submit">Pin</button></form>
		  {{ end }}
	  </div>
		</div>
	  {{ end }}
    </td>
	<td style="text-align:center;">{{.Replies}}</td>
    <td>


@@ 28,7 40,11 @@
</tr>
{{ end }}
</table>
{{ $pages := pageArr .ItemCount }}
{{ $length := len $pages }}
{{ if ne $length 1 }}
<div class="body-footer">
{{ template "pagelist.html" . }}
</div>
{{ end }}
{{ template "footer.html" . }}

M views/style.css => views/style.css +5 -0
@@ 112,6 112,11 @@ body {
  border-bottom: 1px solid var(--border);
}

.flex-between {
  justify-content: space-between;
  display: flex;
  flex-direction: row;
}
.body-header {
  display: flex;
  justify-content: space-between;

M web.go => web.go +36 -0
@@ 93,6 93,7 @@ func forumPage(w http.ResponseWriter, r *http.Request) {
		return
	}
	tmpl["ForumID"] = fid
	tmpl["ForumSlug"] = r.PathValue("forum")
	tmpl["Threads"] = threads
	// pagination
	tmpl["Page"] = page


@@ 530,6 531,36 @@ func doCreateForum(w http.ResponseWriter, r *http.Request) {
	http.Redirect(w, r, "/control", http.StatusSeeOther)
}

func doLockThread(w http.ResponseWriter, r *http.Request) {
	threadID, err := strconv.Atoi(r.PathValue("tid"))
	if err != nil {
		serverError(w, r, err)
		return
	}
	err = setThreadLock(threadID, true)
	if err != nil {
		serverError(w, r, err)
		return
	}
	// TODO paginate redirect
	http.Redirect(w, r, "/f/"+r.PathValue("forum"), http.StatusSeeOther)
}

func doPinThread(w http.ResponseWriter, r *http.Request) {
	threadID, err := strconv.Atoi(r.PathValue("tid"))
	if err != nil {
		serverError(w, r, err)
		return
	}
	err = setThreadPin(threadID, true)
	if err != nil {
		serverError(w, r, err)
		return
	}
	// TODO paginate redirect
	http.Redirect(w, r, "/f/"+r.PathValue("forum"), http.StatusSeeOther)
}

// placeholder
func dummy(w http.ResponseWriter, r *http.Request) {
}


@@ 604,6 635,11 @@ func serve() {
		r.HandleFunc("POST /user/{userid}/change-password", dummy)
	})

	r.Group(func(r chi.Router) {
		r.Use(Mod)
		r.HandleFunc("POST /f/{forum}/{tid}/pin", doPinThread)
		r.HandleFunc("POST /f/{forum}/{tid}/lock", doLockThread)
	})
	// admin functions
	// TODO admin auth
	r.Group(func(r chi.Router) {