Add pagination on files and lists page
This commit is contained in:
10
Makefile
10
Makefile
@@ -1,9 +1,9 @@
|
||||
run:
|
||||
${MAKE} -j2 backgroundrun backgroundts
|
||||
build:
|
||||
tsc res/static/res/typescript/lib/*.ts --outFile res/static/res/script/pixellib.js \
|
||||
res/static/res/typescript/home/*.ts \
|
||||
res/static/res/typescript/lib/*.ts --outFile res/static/res/script/home.js
|
||||
tsc res/static/typescript/lib/*.ts --outFile res/static/script/pixellib.js \
|
||||
res/static/typescript/home/*.ts \
|
||||
res/static/typescript/lib/*.ts --outFile res/static/script/home.js
|
||||
go build main.go -o pixeldrain-web
|
||||
|
||||
deps:
|
||||
@@ -12,8 +12,8 @@ deps:
|
||||
backgroundrun:
|
||||
go run main.go
|
||||
backgroundts:
|
||||
tsc --watch --project res/static/res/typescript/home
|
||||
--project res/static/res/typescript/textupload
|
||||
tsc --watch --project res/static/typescript/home
|
||||
--project res/static/typescript/textupload
|
||||
|
||||
docker:
|
||||
go build -o docker/pixeldrain-web docker/main.go
|
||||
|
@@ -86,7 +86,7 @@ body{
|
||||
.navigation .icon {
|
||||
display: none;
|
||||
}
|
||||
@media screen and (max-width: 500px) {
|
||||
@media screen and (max-width: 35em) {
|
||||
.navigation a:not(:first-child) {display: none;}
|
||||
.navigation a.icon {
|
||||
float: right;
|
||||
@@ -163,7 +163,7 @@ a:hover {color: var(--highlight_color); text-decoration: underline;}
|
||||
table:not(.form) {border-collapse: collapse; width: 100%;}
|
||||
tr:not(.form) {border-bottom: 1px var(--accent_color_medium_border) solid;}
|
||||
tr > td {padding: 0.5em;}
|
||||
@media(max-width: 28em) {
|
||||
@media(max-width: 30em) {
|
||||
tr > td {
|
||||
box-sizing: border-box;
|
||||
float: left;
|
||||
|
@@ -14,12 +14,12 @@
|
||||
<form onSubmit="return submitForm();" class="highlight_dark border_top border_bottom">
|
||||
<table class="form">
|
||||
<tr class="form">
|
||||
<td>Username</td>
|
||||
<td><input id="username" name="username" type="text" autocomplete="username" value=""/></td>
|
||||
<td>Username / e-mail</td>
|
||||
<td><input id="username" name="username" type="text" autocomplete="username" value="" class="form_input"/></td>
|
||||
</tr>
|
||||
<tr class="form">
|
||||
<td>Password</td>
|
||||
<td><input id="password" name="password" type="password" autocomplete="current-password"/></td>
|
||||
<td><input id="password" name="password" type="password" autocomplete="current-password" class="form_input"/></td>
|
||||
</tr>
|
||||
<tr class="form">
|
||||
<td colspan=2 style="text-align: right;"><input type="submit" value="Login" class="button_highlight"/></td>
|
||||
|
@@ -7,14 +7,30 @@
|
||||
|
||||
<body>
|
||||
{{template "menu" .}}
|
||||
<div class="highlight_dark border_bottom">
|
||||
<div class="highlight_middle border_bottom">
|
||||
These files were uploaded while logged in to your pixeldrain account,
|
||||
<a href="/history">click here</a> to view files uploaded anonymously
|
||||
in this browser.
|
||||
</div>
|
||||
|
||||
{{$limit := 100}}
|
||||
{{$page := .URLQuery.Get "page" | pageNr}}
|
||||
{{$files := .PixelAPI.UserFiles $page $limit}}
|
||||
<div class="highlight_dark">
|
||||
{{if ne $page 0}}
|
||||
<a href="?page={{sub $page 4}}" class="button">🡄 4 Pages</a>
|
||||
<a href="?page={{sub $page 2}}" class="button">⬅ 2 Pages</a>
|
||||
<a href="?page={{sub $page 1}}" class="button button_highlight" style="margin-right: 2em;">← Last Page</a>
|
||||
{{end}}
|
||||
Page {{$page}}
|
||||
{{if len $files.Files | eq $limit}}
|
||||
<a href="?page={{add $page 1}}" class="button button_highlight" style="margin-left: 2em;">Next Page →</a>
|
||||
<a href="?page={{add $page 2}}" class="button">2 Pages ⮕</a>
|
||||
<a href="?page={{add $page 4}}" class="button">4 Pages 🡆</a>
|
||||
{{end}}
|
||||
</div>
|
||||
<br/>
|
||||
{{$files := .PixelAPI.UserFiles 0 1000}}
|
||||
|
||||
{{range $files.Files}}
|
||||
<a class="file_button" href="/u/{{.ID}}" target="_blank">
|
||||
<img src="{{$.APIEndpoint}}/file/{{.ID}}/thumbnail" alt="{{.Name}}" />
|
||||
@@ -24,6 +40,21 @@
|
||||
</a>
|
||||
{{end}}
|
||||
|
||||
<br/>
|
||||
<div class="highlight_dark">
|
||||
{{if ne $page 0}}
|
||||
<a href="?page={{sub $page 4}}" class="button">🡄 4 Pages</a>
|
||||
<a href="?page={{sub $page 2}}" class="button">⬅ 2 Pages</a>
|
||||
<a href="?page={{sub $page 1}}" class="button button_highlight" style="margin-right: 2em;">← Last Page</a>
|
||||
{{end}}
|
||||
Page {{$page}}
|
||||
{{if len $files.Files | eq $limit}}
|
||||
<a href="?page={{add $page 1}}" class="button button_highlight" style="margin-left: 2em;">Next Page →</a>
|
||||
<a href="?page={{add $page 2}}" class="button">2 Pages ⮕</a>
|
||||
<a href="?page={{add $page 4}}" class="button">4 Pages 🡆</a>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
{{template "analytics"}}
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -22,7 +22,7 @@
|
||||
</a>
|
||||
{{end}}
|
||||
<br/>
|
||||
<a href="/user/files">...All my files</a>
|
||||
<a href="/user/files" class="button">...All my files</a>
|
||||
</div>
|
||||
<br/>
|
||||
<h2>Your most recently created lists:</h2>
|
||||
@@ -38,6 +38,7 @@
|
||||
</a>
|
||||
{{end}}
|
||||
<br/>
|
||||
<a href="/user/lists" class="button">...All my lists</a>
|
||||
</div>
|
||||
<hr/>
|
||||
|
||||
|
56
res/template/account/user_lists.html
Normal file
56
res/template/account/user_lists.html
Normal file
@@ -0,0 +1,56 @@
|
||||
{{define "user_lists"}}<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
{{template "meta_tags" "Lists"}}
|
||||
<script type="text/javascript">var apiEndpoint = '{{.APIEndpoint}}';</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{{template "menu" .}}
|
||||
{{$limit := 100}}
|
||||
{{$page := .URLQuery.Get "page" | pageNr}}
|
||||
{{$lists := .PixelAPI.UserLists $page $limit}}
|
||||
<div class="highlight_dark">
|
||||
{{if ne $page 0}}
|
||||
<a href="?page={{sub $page 4}}" class="button">🡄 4 Pages</a>
|
||||
<a href="?page={{sub $page 2}}" class="button">⬅ 2 Pages</a>
|
||||
<a href="?page={{sub $page 1}}" class="button button_highlight" style="margin-right: 2em;">← Last Page</a>
|
||||
{{end}}
|
||||
Page {{$page}}
|
||||
{{if len $lists.Lists | eq $limit}}
|
||||
<a href="?page={{add $page 1}}" class="button button_highlight" style="margin-left: 2em;">Next Page →</a>
|
||||
<a href="?page={{add $page 2}}" class="button">2 Pages ⮕</a>
|
||||
<a href="?page={{add $page 4}}" class="button">4 Pages 🡆</a>
|
||||
{{end}}
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
{{range $lists.Lists}}
|
||||
<a class="file_button" href="/l/{{.ID}}" target="_blank">
|
||||
<img src="{{$.APIEndpoint}}/list/{{.ID}}/thumbnail" alt="{{.Title}}" />
|
||||
<span style="color: var(--highlight_color);">{{.Title}}</span>
|
||||
({{.FileCount}} Files)
|
||||
<br/>
|
||||
{{.DateCreated.Format "2006-01-02 15:04:05"}}
|
||||
</a>
|
||||
{{end}}
|
||||
|
||||
<br/>
|
||||
<div class="highlight_dark">
|
||||
{{if ne $page 0}}
|
||||
<a href="?page={{sub $page 4}}" class="button">🡄 4 Pages</a>
|
||||
<a href="?page={{sub $page 2}}" class="button">⬅ 2 Pages</a>
|
||||
<a href="?page={{sub $page 1}}" class="button button_highlight" style="margin-right: 2em;">← Last Page</a>
|
||||
{{end}}
|
||||
Page {{$page}}
|
||||
{{if len $lists.Lists | eq $limit}}
|
||||
<a href="?page={{add $page 1}}" class="button button_highlight" style="margin-left: 2em;">Next Page →</a>
|
||||
<a href="?page={{add $page 2}}" class="button">2 Pages ⮕</a>
|
||||
<a href="?page={{add $page 4}}" class="button">4 Pages 🡆</a>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
{{template "analytics"}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
@@ -2,6 +2,7 @@
|
||||
<div id="navigation" class="highlight_light border_top border_bottom navigation">
|
||||
<a href="/">Home</a>
|
||||
<a href="{{if .Authenticated}}/user/files{{else}}/history{{end}}">My Files</a>
|
||||
{{if .Authenticated}}<a href="/user/lists">My Lists</a>{{end}}
|
||||
<a href="/api">API</a>
|
||||
{{if .Authenticated}}<a href="/user">{{.Username}}</a>
|
||||
<a href="/logout" style="vertical-align: 0.6em; font-size: 0.9em; padding: 1px;">(Log out)</a>{{else}}
|
||||
|
@@ -3,6 +3,7 @@ package webcontroller
|
||||
import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"fornaxian.com/pixeldrain-web/pixelapi"
|
||||
@@ -17,8 +18,9 @@ type TemplateData struct {
|
||||
APIEndpoint template.URL
|
||||
PixelAPI *pixelapi.PixelAPI
|
||||
|
||||
Other interface{}
|
||||
Title string
|
||||
Other interface{}
|
||||
URLQuery url.Values
|
||||
Title string
|
||||
}
|
||||
|
||||
func (wc *WebController) newTemplateData(w http.ResponseWriter, r *http.Request) *TemplateData {
|
||||
@@ -26,6 +28,7 @@ func (wc *WebController) newTemplateData(w http.ResponseWriter, r *http.Request)
|
||||
Authenticated: false,
|
||||
Username: "",
|
||||
APIEndpoint: template.URL(wc.conf.APIURLExternal),
|
||||
URLQuery: r.URL.Query(),
|
||||
}
|
||||
|
||||
if key, err := wc.getAPIKey(r); err == nil {
|
||||
|
@@ -4,11 +4,14 @@ import (
|
||||
"html/template"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/Fornaxian/log"
|
||||
)
|
||||
|
||||
// TemplateManager parses templates and provides utility functions to the
|
||||
// templates' scripting language
|
||||
type TemplateManager struct {
|
||||
templates *template.Template
|
||||
|
||||
@@ -18,6 +21,7 @@ type TemplateManager struct {
|
||||
debugModeEnabled bool
|
||||
}
|
||||
|
||||
// NewTemplateManager creates a new template manager
|
||||
func NewTemplateManager(templateDir, externalAPIEndpoint string, debugMode bool) *TemplateManager {
|
||||
return &TemplateManager{
|
||||
templateDir: templateDir,
|
||||
@@ -72,17 +76,31 @@ func (tm *TemplateManager) funcMap() template.FuncMap {
|
||||
"bgPatternCount": tm.bgPatternCount,
|
||||
"debugMode": tm.debugMode,
|
||||
"apiUrl": tm.apiURL,
|
||||
"pageNr": tm.pageNr,
|
||||
"add": tm.add,
|
||||
"sub": tm.sub,
|
||||
}
|
||||
}
|
||||
|
||||
func (tm *TemplateManager) bgPatternCount() uint8 {
|
||||
return uint8(time.Now().UnixNano() % 17)
|
||||
}
|
||||
|
||||
func (tm *TemplateManager) debugMode() bool {
|
||||
return tm.debugModeEnabled
|
||||
}
|
||||
|
||||
func (tm *TemplateManager) apiURL() string {
|
||||
return tm.externalAPIEndpoint
|
||||
}
|
||||
func (tm *TemplateManager) pageNr(s string) (nr int) {
|
||||
// Atoi returns 0 on error, which is fine for page numbers
|
||||
if nr, _ = strconv.Atoi(s); nr < 0 {
|
||||
return 0
|
||||
}
|
||||
return nr
|
||||
}
|
||||
func (tm *TemplateManager) add(a, b int) int {
|
||||
return a + b
|
||||
}
|
||||
func (tm *TemplateManager) sub(a, b int) int {
|
||||
return a - b
|
||||
}
|
||||
|
@@ -59,6 +59,7 @@ func New(r *httprouter.Router, prefix string, conf *conf.PixelWebConfig) *WebCon
|
||||
r.POST(p+"/logout" /* */, wc.serveLogout)
|
||||
r.GET(p+"/user" /* */, wc.serveTemplate("user_home", true))
|
||||
r.GET(p+"/user/files" /* */, wc.serveTemplate("user_files", true))
|
||||
r.GET(p+"/user/lists" /* */, wc.serveTemplate("user_lists", true))
|
||||
r.GET(p+"/user/filemanager" /**/, wc.serveTemplate("file_manager", true))
|
||||
|
||||
r.NotFound = http.HandlerFunc(wc.serveNotFound)
|
||||
|
Reference in New Issue
Block a user