Skip to content

Commit a881e07

Browse files
committed
web: resolve #18
* Fix: possibility that config would stop working after submitting the form once
1 parent 831cd11 commit a881e07

File tree

7 files changed

+47
-31
lines changed

7 files changed

+47
-31
lines changed

cmd/airliftd/bindata_files/static.go

Lines changed: 3 additions & 3 deletions
Large diffs are not rendered by default.

cmd/airliftd/bindata_files/templates.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ import (
77
)
88

99
func init() {
10-
bindata.RegisterFile("templates/config.tmpl", time.Unix(1449686731, 0), []byte("{{ define \"config\" }}\n {{ template \"%overview\" . }}\n {{ template \"%config\" . }}\n{{ end }}\n\n{{ define \"%config\" }}\n{{ with .Data }}\n <section id=\"section-config\" class=\"floating-section\">\n <h1>Configuration</h1>\n <form id=\"config\">\n <div class=\"box\" id=\"host-box\" data-tooltip=\"Returned file links will begin with this domain and path.\" data-tt-pos=\"top\">\n <label for=\"host\">Base URL</label>\n <input type=\"text\" id=\"host\" name=\"host\" value=\"{{ .Conf.Host }}\" placeholder=\"i.example.com\">\n </div>\n <div class=\"box\" id=\"id-box\">\n /<span id=\"sample-id\"></span><span id=\"sample-ext\">.ext</span>\n </div>\n <div class=\"box\">\n <label for=\"id-size\">Length of File ID</label>\n <input type=\"range\" id=\"id-size\" name=\"id-size\" min=\"2\" max=\"12\" value=\"{{ .Conf.HashLen }}\">\n </div>\n <div class=\"box checkbox\" data-tooltip=\"Enable to append the original file extension to returned links.\" data-tt-pos=\"left\">\n <input type=\"checkbox\" id=\"append-ext\" name=\"append-ext\"{{ if .Conf.AppendExt }} checked{{ end }}>\n <label for=\"append-ext\">Append File Extensions</label>\n </div>\n <div class=\"box check-enable\">\n <input type=\"checkbox\" class=\"hider\" id=\"enable-age-prune\" name=\"enable-age-prune\"{{ if .Conf.MaxAgeEnable }} checked{{ end }}>\n <label for=\"enable-age-prune\">Limit Upload Age</label>\n <div class=\"hidee\">\n <label for=\"max-age\">Maximum Age (Days)</label>\n <input type=\"number\" id=\"max-age\" name=\"max-age\" value=\"{{ .Conf.Age }}\" min=\"0\"{{ if not .Conf.MaxAgeEnable }} disabled{{ end }}>\n </div>\n </div>\n <div class=\"box check-enable\">\n <input type=\"checkbox\" class=\"hider\" id=\"enable-size-prune\" name=\"enable-size-prune\"{{ if .Conf.MaxSizeEnable }} checked{{ end }}>\n <label for=\"enable-size-prune\">Limit Total Uploads Size</label>\n <div class=\"hidee\">\n <label for=\"max-size\">Maximum Size (MB)</label>\n <input type=\"number\" id=\"max-size\" name=\"max-size\" value=\"{{ .Conf.Size }}\" min=\"0\"{{ if not .Conf.MaxSizeEnable }} disabled{{ end }}>\n </div>\n </div>\n <div class=\"box check-enable\" data-tooltip=\"Enable to allow uploads to show Twitter Cards with file previews if applicable.\" data-tt-pos=\"left\">\n <input type=\"checkbox\" class=\"hider\" name=\"twitter-card\"{{ if .Conf.TwitterCardEnable }} checked{{ end }}>\n <label for=\"twitter-card\">Enable Twitter Cards</label>\n <div class=\"hidee\">\n <label for=\"twitter-handle\">Twitter Handle</label>\n <input type=\"text\" id=\"twitter-handle\" name=\"twitter-handle\" value=\"{{ .Conf.TwitterHandle }}\" required placeholder=\"@handle\"{{ if not .Conf.TwitterCardEnable }} disabled{{ end }}>\n </div>\n </div>\n <div class=\"box\" id=\"directory-box\">\n <label for=\"directory\">Upload Directory</label>\n <input type=\"text\" id=\"directory\" name=\"directory\" value=\"{{ .Conf.Directory }}\" placeholder=\"/home/user/uploads\">\n </div>\n <div class=\"box\" id=\"newpass-box\" data-tooltip=\"Enter a new password here to change your password.\" data-tt-pos=\"right\">\n <label for=\"newpass\">New Password</label>\n <input type=\"password\" id=\"newpass\" name=\"newpass\" placeholder=\"\xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2\">\n </div>\n <hr>\n <div class=\"box\" id=\"password-box\" data-tooltip=\"Current password is required to update configuration\" data-tt-pos=\"left\">\n <label for=\"password\">Current Password</label>\n <input type=\"password\" id=\"password\" name=\"password\" required placeholder=\"Required\">\n </div>\n <button id=\"submit\" type=\"button\">Update configuration</button>\n </form>\n </section>\n <script src=\"/-/static/common.js\"></script>\n <script src=\"/-/static/config.js\"></script>\n{{ end }}\n{{ end }}\n\n{{ define \"%overview\" }}\n{{ with .Data }}\n <section id=\"section-overview\" class=\"floating-section\">\n <h1>Overview</h1>\n <p><strong><a href=\"/-/history/0\">{{ .NumUploads }} upload{{ if ne .NumUploads 1 }}s{{ end }}</a></strong> totalling <strong>{{ .UploadsSize }}</strong>. (<a href=\"javascript:purgeAll()\">purge</a>)</p>\n <p>Thumbnail cache is <strong>{{ .ThumbsSize }}</strong>. (<a href=\"javascript:purgeThumbs()\">purge</a>)</p>\n </section>\n{{ end }}\n{{ end }}\n"))
10+
bindata.RegisterFile("templates/config.tmpl", time.Unix(1449692250, 0), []byte("{{ define \"config\" }}\n {{ template \"%overview\" . }}\n {{ template \"%config\" . }}\n{{ end }}\n\n{{ define \"%config\" }}\n{{ with .Data }}\n <section id=\"section-config\" class=\"floating-section\">\n <h1>Configuration</h1>\n <form id=\"config\" autocomplete=\"off\">\n <div class=\"box\" id=\"host-box\" data-tooltip=\"Returned file links will begin with this domain and path.\" data-tt-pos=\"top\">\n <label for=\"host\">Base URL</label>\n <input type=\"text\" id=\"host\" name=\"host\" value=\"{{ .Conf.Host }}\" placeholder=\"i.example.com\">\n </div>\n <div class=\"box\" id=\"id-box\">\n /<span id=\"sample-id\"></span><span id=\"sample-ext\">.ext</span>\n </div>\n <div class=\"box\">\n <label for=\"id-size\">Length of File ID</label>\n <input type=\"range\" id=\"id-size\" name=\"id-size\" min=\"2\" max=\"12\" value=\"{{ .Conf.HashLen }}\">\n </div>\n <div class=\"box checkbox\" data-tooltip=\"Enable to append the original file extension to returned links.\" data-tt-pos=\"left\">\n <input type=\"checkbox\" id=\"append-ext\" name=\"append-ext\"{{ if .Conf.AppendExt }} checked{{ end }}>\n <label for=\"append-ext\">Append File Extensions</label>\n </div>\n <div class=\"box check-enable\">\n <input type=\"checkbox\" class=\"hider\" id=\"enable-age-prune\" name=\"enable-age-prune\"{{ if .Conf.MaxAgeEnable }} checked{{ end }}>\n <label for=\"enable-age-prune\">Limit Upload Age</label>\n <div class=\"hidee\">\n <label for=\"max-age\">Maximum Age (Days)</label>\n <input type=\"number\" id=\"max-age\" name=\"max-age\" value=\"{{ .Conf.Age }}\" min=\"0\"{{ if not .Conf.MaxAgeEnable }} disabled{{ end }}>\n </div>\n </div>\n <div class=\"box check-enable\">\n <input type=\"checkbox\" class=\"hider\" id=\"enable-size-prune\" name=\"enable-size-prune\"{{ if .Conf.MaxSizeEnable }} checked{{ end }}>\n <label for=\"enable-size-prune\">Limit Total Uploads Size</label>\n <div class=\"hidee\">\n <label for=\"max-size\">Maximum Size (MB)</label>\n <input type=\"number\" id=\"max-size\" name=\"max-size\" value=\"{{ .Conf.Size }}\" min=\"0\"{{ if not .Conf.MaxSizeEnable }} disabled{{ end }}>\n </div>\n </div>\n <div class=\"box check-enable\" data-tooltip=\"Enable to allow uploads to show Twitter Cards with file previews if applicable.\" data-tt-pos=\"left\">\n <input type=\"checkbox\" class=\"hider\" name=\"twitter-card\"{{ if .Conf.TwitterCardEnable }} checked{{ end }}>\n <label for=\"twitter-card\">Enable Twitter Cards</label>\n <div class=\"hidee\">\n <label for=\"twitter-handle\">Twitter Handle</label>\n <input type=\"text\" id=\"twitter-handle\" name=\"twitter-handle\" value=\"{{ .Conf.TwitterHandle }}\" required placeholder=\"@handle\"{{ if not .Conf.TwitterCardEnable }} disabled{{ end }}>\n </div>\n </div>\n <div class=\"box\" id=\"directory-box\">\n <label for=\"directory\">Upload Directory</label>\n <input type=\"text\" id=\"directory\" name=\"directory\" value=\"{{ .Conf.Directory }}\" placeholder=\"/home/user/uploads\">\n </div>\n <div class=\"box\" id=\"newpass-box\" data-tooltip=\"Enter a new password here to change your password.\" data-tt-pos=\"right\">\n <label for=\"newpass\">New Password</label>\n <input type=\"password\" id=\"newpass\" name=\"newpass\" placeholder=\"\xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2\">\n </div>\n <hr>\n <div class=\"box\" id=\"password-box\" data-tooltip=\"Current password is required to update configuration\" data-tt-pos=\"left\">\n <label for=\"password\">Current Password</label>\n <input type=\"password\" id=\"password\" name=\"password\" required placeholder=\"Required\">\n </div>\n <button id=\"submit\" type=\"button\">Update configuration</button>\n </form>\n </section>\n <script src=\"/-/static/common.js\"></script>\n <script src=\"/-/static/config.js\"></script>\n{{ end }}\n{{ end }}\n\n{{ define \"%overview\" }}\n{{ with .Data }}\n <section id=\"section-overview\" class=\"floating-section\">\n <h1>Overview</h1>\n <p><strong><a href=\"/-/history/0\">{{ .NumUploads }} upload{{ if ne .NumUploads 1 }}s{{ end }}</a></strong> totalling <strong>{{ .UploadsSize }}</strong>. (<a id=\"purge-all-link\" href=\"javascript:void(0)\">purge</a>)</p>\n <p>Thumbnail cache is <strong>{{ .ThumbsSize }}</strong>. (<a id=\"purge-thumbs-link\" href=\"javascript:void(0)\">purge</a>)</p>\n </section>\n{{ end }}\n{{ end }}\n"))
1111
bindata.RegisterFile("templates/errors/errors.tmpl", time.Unix(1443849891, 0), []byte("{{ define \"400\" }}<!doctype html>\n<html>\n <head>\n <title>400</title>\n <link rel=\"stylesheet\" href=\"/-/static/style.css\">\n </head>\n <body>\n <div class=\"error\">\n <h1>You're doing it wrong.</h1>\n {{ if .Err }}<p>{{ .Err }}</p>{{ end }}\n </div>\n </body>\n</html>\n{{ end }}\n{{ define \"404\" }}<!doctype html>\n<html>\n <head>\n <title>404</title>\n <link rel=\"stylesheet\" href=\"/-/static/style.css\">\n </head>\n <body>\n <div class=\"error\">\n <h1>This isn't the page you're looking for.</h1>\n </div>\n </body>\n</html>\n{{ end }}\n{{ define \"500\" }}<!doctype html>\n<html>\n <head>\n <title>500</title>\n <link rel=\"stylesheet\" href=\"/-/static/style.css\">\n </head>\n <body>\n <div class=\"error\">\n <h1>Something went wrong.</h1>\n {{ if .Err }}<p>{{ .Err }}</p>{{ end }}\n </div>\n </body>\n</html>\n{{ end }}\n"))
12-
bindata.RegisterFile("templates/history.tmpl", time.Unix(1449631078, 0), []byte("{{ define \"history\" }}\n{{ with .Data }}\n<section id=\"history\">\n {{ if len .List | lt 25 }}{{ template \"pagination\" . }}{{ end }}\n <ul>\n {{ range .List }}\n <li class=\"history-item\" data-id=\"{{ .ID }}\">\n <a href=\"/{{ .ID }}{{ if $.Data.AppendExt }}{{ .Ext }}{{ end }}\" class=\"upload-link\">{{ if .HasThumb }}<img src=\"/-/thumb/{{ .ID }}.jpg\">{{ else }}<img src=\"/-/static/file.svg\"><div class=\"file-ext-overlay\">{{ .Ext }}</div>{{ end }}</a>\n <div class=\"history-item-name\" title=\"{{ .Name }}\">{{ .Name }}</div>\n <div class=\"history-item-data\">{{ .Size }} / <span title=\"{{ .Uploaded.Format \"2006-01-02 15:04:05 MST\" }}\">{{ .Ago }}</span> ago</div>\n <div class=\"history-item-data\"><a href=\"javascript:\" class=\"delete-upload\">Delete</a></div>\n </li>\n {{ end }}\n </ul>\n {{ template \"pagination\" . }}\n</section>\n<script src=\"/-/static/common.js\"></script>\n<script src=\"/-/static/history.js\"></script>\n{{ end }}\n{{ end }}\n\n{{ define \"pagination\" }}\n<nav class=\"pagination\">\n <span class=\"prevnext{{ if gt .CurrentPage 1 }} active{{ end }}\"><a href=\"/-/history/{{ .PrevPage }}\">Back</a> \xe2\x80\x94</span>\n Page {{ .CurrentPage }} of {{ .TotalPages }}\n <span class=\"prevnext{{ if ne .NextPage 0 }} active{{ end }}\">\xe2\x80\x94 <a href=\"/-/history/{{ .NextPage }}\">Next</a></span>\n</nav>\n{{ end }}\n"))
12+
bindata.RegisterFile("templates/history.tmpl", time.Unix(1449690290, 0), []byte("{{ define \"history\" }}\n{{ template \"%history\" . }}\n<script src=\"/-/static/common.js\"></script>\n<script src=\"/-/static/history.js\"></script>\n{{ end }}\n\n{{ define \"%history\" }}\n{{ with .Data }}\n<section id=\"history\">\n {{ if len .List | lt 25 }}{{ template \"pagination\" . }}{{ end }}\n <ul>\n {{ range .List }}\n <li class=\"history-item\" data-id=\"{{ .ID }}\">\n <a href=\"/{{ .ID }}{{ if $.Data.AppendExt }}{{ .Ext }}{{ end }}\" class=\"upload-link\">{{ if .HasThumb }}<img src=\"/-/thumb/{{ .ID }}.jpg\">{{ else }}<img src=\"/-/static/file.svg\"><div class=\"file-ext-overlay\">{{ .Ext }}</div>{{ end }}</a>\n <div class=\"history-item-name\" title=\"{{ .Name }}\">{{ .Name }}</div>\n <div class=\"history-item-data\">{{ .Size }} / <span title=\"{{ .Uploaded.Format \"2006-01-02 15:04:05 MST\" }}\">{{ .Ago }}</span> ago</div>\n <div class=\"history-item-data\"><a href=\"javascript:\" class=\"delete-upload\">Delete</a></div>\n </li>\n {{ end }}\n </ul>\n {{ template \"pagination\" . }}\n</section>\n{{ end }}\n{{ end }}\n\n{{ define \"pagination\" }}\n<nav class=\"pagination\">\n <span class=\"prevnext{{ if gt .CurrentPage 1 }} active{{ end }}\"><a href=\"/-/history/{{ .PrevPage }}\">Back</a> \xe2\x80\x94</span>\n Page {{ .CurrentPage }} of {{ .TotalPages }}\n <span class=\"prevnext{{ if ne .NextPage 0 }} active{{ end }}\">\xe2\x80\x94 <a href=\"/-/history/{{ .NextPage }}\">Next</a></span>\n</nav>\n{{ end }}\n"))
1313
bindata.RegisterFile("templates/index.tmpl", time.Unix(1449631983, 0), []byte("{{ define \"index\" }}\n <section id=\"upload\" class=\"floating-section\">\n <input type=\"file\" id=\"picker\" name=\"picker[]\" multiple>\n <div id=\"drop-zone\">\n <div class=\"progress-bar\"></div>\n <div id=\"drop-zone-text\">Click/tap/drop/paste</div>\n </div>\n <div id=\"uploaded-urls\">\n <ul></ul>\n </div>\n </section>\n <script src=\"/-/static/common.js\"></script>\n <script src=\"/-/static/uploader.js\"></script>\n{{ end }}\n\n{{ define \"default-index\" }}\n<!doctype html>\n<html>\n <head>\n <title>Airlift</title>\n {{ template \"head\" }}\n </head>\n <body>\n <section id=\"front\">\n <div id=\"big-logo\">\n <div id=\"big-logo-text\">{{ $.Config.Host }} is powered by <a href=\"https://github.com/moshee/airlift\">Airlift</a>.</div>\n </div>\n <div class=\"login-link\"><a href=\"/-/login\">Log in</a></div>\n </section>\n </body>\n</html>\n{{ end }}\n"))
1414
bindata.RegisterFile("templates/layout.tmpl", time.Unix(1449631940, 0), []byte("{{ define \"head\" }}\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<link rel=\"shortcut icon\" href=\"/-/static/favicon.png\">\n<link rel=\"apple-touch-icon\" sizes=\"76x76\" href=\"/-/static/airlift_76x76.png\">\n<link rel=\"apple-touch-icon\" sizes=\"120x120\" href=\"/-/static/airlift_120x120.png\">\n<link rel=\"apple-touch-icon\" sizes=\"152x152\" href=\"/-/static/airlift_152x152.png\">\n<link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"/-/static/airlift_180x180.png\">\n<link rel=\"stylesheet\" href=\"/-/static/style.css\">\n{{ end }}\n{{ define \"common\" }}<!doctype html>\n<html>\n <head>\n <title>Airlift</title>\n {{ template \"head\" }}\n </head>\n <body>\n <div id=\"message-box\"></div>\n <nav id=\"nav\">\n <a href=\"/\">Upload</a> /\n <a href=\"/-/history/0\">History</a> /\n <a href=\"/-/config\">Configure</a> /\n <a href=\"/-/logout\">Log out</a>\n </nav>\n {{ content }}\n <div id=\"version\">airliftd {{ .Version }}</div>\n </body>\n</html>\n{{ end }}\n"))
1515
bindata.RegisterFile("templates/login.tmpl", time.Unix(1442347253, 0), []byte("{{ define \"login\" }}<!doctype html>\n<html>\n <head>\n <title>Log in</title>\n {{ template \"head\" }}\n </head>\n <body>\n <section id=\"section-login\" class=\"floating-section\">\n <form method=\"post\" action=\"/-/login\" id=\"login\">\n {{ if . }}<p id=\"message-box\" class=\"bad\">Incorrect password.</p>{{ end }}\n <label for=\"password\">Password: </label><input name=\"pass\" id=\"password\" type=\"password\" placeholder=\"password\" autofocus required>\n <hr>\n <button type=\"submit\" id=\"submit\">Log in</button>\n </form>\n </section>\n </body>\n</html>\n{{ end }}\n"))

cmd/airliftd/static/common.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,19 @@ function json(method, url, data, async, cb, mutate) {
114114
return h(x);
115115
}
116116
}
117+
118+
function reloadSection(endpoint, target, cb) {
119+
var x = new XMLHttpRequest();
120+
x.addEventListener('load', function(e) {
121+
var section = $(target);
122+
var newSection = $(target, e.target.response);
123+
section.parentNode.replaceChild(newSection, section);
124+
if (cb != null) {
125+
cb();
126+
}
127+
}, false);
128+
x.open('GET', endpoint, true);
129+
x.responseType = 'document';
130+
x.setRequestHeader('X-Ajax-Partial', 1);
131+
x.send();
132+
}

cmd/airliftd/static/config.js

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,12 @@
33

44
var oldMaxSize, oldMaxAge, sampleID, sampleExt, idSize, addExt;
55

6-
function reloadSection(endpoint, target) {
7-
var x = new XMLHttpRequest();
8-
x.addEventListener('load', function(e) {
9-
var section = $(target);
10-
var newSection = $(target, e.target.response);
11-
section.parentNode.replaceChild(newSection, section);
12-
}, false);
13-
x.open('GET',endpoint, true);
14-
x.responseType = 'document';
15-
x.setRequestHeader('X-Ajax-Partial', 1);
16-
x.send();
17-
}
18-
196
function reloadConfigValues() {
20-
reloadSection('/-/config', '#section-config');
7+
reloadSection('/-/config', '#section-config', setupConfig);
218
}
229

2310
function reloadOverview() {
24-
reloadSection('/-/config/overview', '#section-overview');
11+
reloadSection('/-/config/overview', '#section-overview', setupOverview);
2512
}
2613

2714
function updateSample() {
@@ -60,7 +47,12 @@
6047
json('POST', '/purge/thumbs', null, true, purgeDone);
6148
}
6249

63-
window.addEventListener('DOMContentLoaded', function() {
50+
function setupOverview() {
51+
$('#purge-all-link').addEventListener('click', purgeAll, false);
52+
$('#purge-thumbs-link').addEventListener('click', purgeThumbs, false);
53+
}
54+
55+
function setupConfig() {
6456
var buttons = $$('button'), host = $('#host');
6557
oldMaxSize = parseInt($('#max-size').value);
6658
oldMaxAge = parseInt($('#max-age').value);
@@ -158,5 +150,8 @@
158150
});
159151
}).catch(errorMessage).pass();
160152
}, false);
161-
}, false);
153+
}
154+
155+
window.addEventListener('DOMContentLoaded', setupOverview, false);
156+
window.addEventListener('DOMContentLoaded', setupConfig, false);
162157
})();

cmd/airliftd/static/history.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111
if (code == 204) {
1212
item.style.opacity = '0.0';
1313
item.addEventListener('transitionend', function(e) {
14-
e.target.parentNode.removeChild(e.target);
15-
window.location.reload(true);
14+
reloadSection(window.location.pathname, '#history', setupHistory);
1615
}, false);
1716
} else {
1817
item.style.opacity = '';
@@ -22,8 +21,10 @@
2221
}, false);
2322
}
2423

25-
window.addEventListener('DOMContentLoaded', function() {
24+
function setupHistory() {
2625
var items = $$('.history-item');
2726
Array.prototype.forEach.call(items, bindHistoryItem);
28-
}, true);
27+
}
28+
29+
window.addEventListener('DOMContentLoaded', setupHistory, true);
2930
})();

0 commit comments

Comments
 (0)