Add new upload history page
This commit is contained in:
14
go.mod
14
go.mod
@@ -1,8 +1,8 @@
|
|||||||
module fornaxian.tech/pixeldrain_web
|
module fornaxian.tech/pixeldrain_web
|
||||||
|
|
||||||
go 1.21
|
go 1.22
|
||||||
|
|
||||||
toolchain go1.22.0
|
toolchain go1.22.4
|
||||||
|
|
||||||
replace (
|
replace (
|
||||||
fornaxian.tech/pixeldrain_api_client => ../pixeldrain_api_client
|
fornaxian.tech/pixeldrain_api_client => ../pixeldrain_api_client
|
||||||
@@ -12,21 +12,21 @@ replace (
|
|||||||
require (
|
require (
|
||||||
fornaxian.tech/config v0.0.0-20211108212237-6133aed90586
|
fornaxian.tech/config v0.0.0-20211108212237-6133aed90586
|
||||||
fornaxian.tech/log v0.0.0-20211102185326-552e9b1f8640
|
fornaxian.tech/log v0.0.0-20211102185326-552e9b1f8640
|
||||||
fornaxian.tech/pixeldrain_api_client v0.0.0-20221207191816-6872676df741
|
fornaxian.tech/pixeldrain_api_client v0.0.0-20240321144932-32993212d251
|
||||||
fornaxian.tech/util v0.0.0-20230520114728-bd827686fec7
|
fornaxian.tech/util v0.0.0-20240305140022-c865b3d36a3f
|
||||||
github.com/julienschmidt/httprouter v1.3.0
|
github.com/julienschmidt/httprouter v1.3.0
|
||||||
github.com/microcosm-cc/bluemonday v1.0.26
|
github.com/microcosm-cc/bluemonday v1.0.26
|
||||||
github.com/russross/blackfriday/v2 v2.1.0
|
github.com/russross/blackfriday/v2 v2.1.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/BurntSushi/toml v1.3.2 // indirect
|
github.com/BurntSushi/toml v1.4.0 // indirect
|
||||||
github.com/aymerick/douceur v0.2.0 // indirect
|
github.com/aymerick/douceur v0.2.0 // indirect
|
||||||
github.com/gocql/gocql v1.6.0 // indirect
|
github.com/gocql/gocql v1.6.0 // indirect
|
||||||
github.com/golang/snappy v0.0.4 // indirect
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
github.com/gorilla/css v1.0.1 // indirect
|
github.com/gorilla/css v1.0.1 // indirect
|
||||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
|
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
|
||||||
golang.org/x/crypto v0.21.0 // indirect
|
golang.org/x/crypto v0.24.0 // indirect
|
||||||
golang.org/x/net v0.22.0 // indirect
|
golang.org/x/net v0.26.0 // indirect
|
||||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
)
|
)
|
||||||
|
12
go.sum
12
go.sum
@@ -2,8 +2,8 @@ fornaxian.tech/config v0.0.0-20211108212237-6133aed90586 h1:/4a0Iq3cYeyTWcPHsN9p
|
|||||||
fornaxian.tech/config v0.0.0-20211108212237-6133aed90586/go.mod h1:ULIXF4J1DbBw4EsIPRNQDf6J3hl4P/jlihjy6UCm9FM=
|
fornaxian.tech/config v0.0.0-20211108212237-6133aed90586/go.mod h1:ULIXF4J1DbBw4EsIPRNQDf6J3hl4P/jlihjy6UCm9FM=
|
||||||
fornaxian.tech/log v0.0.0-20211102185326-552e9b1f8640 h1:UPDxJwLRCfh/cv80UMSanzmZ0jIcfS1mcd0Y06HYuLw=
|
fornaxian.tech/log v0.0.0-20211102185326-552e9b1f8640 h1:UPDxJwLRCfh/cv80UMSanzmZ0jIcfS1mcd0Y06HYuLw=
|
||||||
fornaxian.tech/log v0.0.0-20211102185326-552e9b1f8640/go.mod h1:sN82qMToeHhP2u3ehvrcE8y1IudRZJAZO9yG5OBYblo=
|
fornaxian.tech/log v0.0.0-20211102185326-552e9b1f8640/go.mod h1:sN82qMToeHhP2u3ehvrcE8y1IudRZJAZO9yG5OBYblo=
|
||||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||||
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
||||||
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
||||||
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY=
|
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY=
|
||||||
@@ -34,9 +34,9 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
|
|||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||||
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
|
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||||
|
@@ -1,158 +0,0 @@
|
|||||||
{{define "history_cookies"}}<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
{{template "meta_tags" "Upload History"}}
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.file_button {
|
|
||||||
position: relative;
|
|
||||||
width: 400px;
|
|
||||||
max-width: 90%;
|
|
||||||
height: 3.6em;
|
|
||||||
margin: 8px;
|
|
||||||
padding: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
border-radius: 6px;
|
|
||||||
background: var(--input_background);
|
|
||||||
color: var(--body_text_color);
|
|
||||||
word-break: break-all;
|
|
||||||
text-align: left;
|
|
||||||
line-height: 1.2em;
|
|
||||||
display: inline-block;
|
|
||||||
transition: box-shadow 0.3s, opacity 2s, background 0.2s;
|
|
||||||
white-space: normal;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
text-decoration: none;
|
|
||||||
vertical-align: top;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file_button:hover {
|
|
||||||
text-decoration: none;
|
|
||||||
background: var(--input_hover_background);
|
|
||||||
}
|
|
||||||
|
|
||||||
.file_button>img {
|
|
||||||
max-height: 100%;
|
|
||||||
max-width: 25%;
|
|
||||||
margin-right: 5px;
|
|
||||||
float: left;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file_button>.file_button_title {
|
|
||||||
color: var(--link_color);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
{{template "page_top" .}}
|
|
||||||
|
|
||||||
<header>
|
|
||||||
<h1>Upload History</h1>
|
|
||||||
</header>
|
|
||||||
<div id="page_content" class="page_content">
|
|
||||||
<section>
|
|
||||||
<p>
|
|
||||||
Here are all files you have previously uploaded to pixeldrain using this computer.
|
|
||||||
This data is saved locally in your web browser and gets updated every time you upload a file through your current browser.
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<div id="uploaded_files"></div>
|
|
||||||
</div>
|
|
||||||
{{template "page_bottom" .}}
|
|
||||||
|
|
||||||
<script>
|
|
||||||
let apiEndpoint = '{{.APIEndpoint}}';
|
|
||||||
function renderFileButton(apiURL, id, title, subtitle) {
|
|
||||||
let btn = document.createElement("a")
|
|
||||||
btn.classList = "file_button"
|
|
||||||
btn.href = "/u/" + id
|
|
||||||
btn.target = "_blank"
|
|
||||||
let thumbnail = document.createElement("img")
|
|
||||||
thumbnail.src = apiURL + "/file/" + id + "/thumbnail?width=80&height=80"
|
|
||||||
thumbnail.alt = title
|
|
||||||
let titleSpan = document.createElement("span")
|
|
||||||
titleSpan.classList = "file_button_title"
|
|
||||||
titleSpan.innerText = title
|
|
||||||
let br = document.createElement("br")
|
|
||||||
let subtitleSpan = document.createElement("span")
|
|
||||||
subtitleSpan.classList = "file_button_subtitle"
|
|
||||||
subtitleSpan.innerText = subtitle
|
|
||||||
|
|
||||||
btn.appendChild(thumbnail)
|
|
||||||
btn.appendChild(titleSpan)
|
|
||||||
btn.appendChild(br)
|
|
||||||
btn.appendChild(subtitleSpan)
|
|
||||||
return btn
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCookie(name) {
|
|
||||||
var result = new RegExp('(?:^|; )' + encodeURIComponent(name) + '=([^;]*)').exec(document.cookie)
|
|
||||||
return result ? result[1] : null
|
|
||||||
}
|
|
||||||
|
|
||||||
function printDate(date, hours, minutes, seconds) {
|
|
||||||
let dateStr = date.getFullYear()
|
|
||||||
+ "-" + ("00" + (date.getMonth() + 1)).slice(-2)
|
|
||||||
+ "-" + ("00" + date.getDate()).slice(-2)
|
|
||||||
|
|
||||||
if (hours) { dateStr += " " + ("00" + date.getHours()).slice(-2) }
|
|
||||||
if (minutes) { dateStr += ":" + ("00" + date.getMinutes()).slice(-2) }
|
|
||||||
if (seconds) { dateStr += ":" + ("00" + date.getMinutes()).slice(-2) }
|
|
||||||
return dateStr
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the uploads from localstorage
|
|
||||||
let uploadsStr = localStorage.getItem("uploaded_files")
|
|
||||||
if (uploadsStr === null) { uploadsStr = "" }
|
|
||||||
|
|
||||||
let uploads = Array()
|
|
||||||
if (uploadsStr != "") {
|
|
||||||
// Strip the trailing comma
|
|
||||||
uploads = uploadsStr.slice(0, -1).split(",")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the uploads from a cookie
|
|
||||||
uploadsStr = getCookie("pduploads")
|
|
||||||
if (uploadsStr === null) { uploadsStr = "" }
|
|
||||||
|
|
||||||
if (uploadsStr != "") {
|
|
||||||
uploadsStr = uploadsStr.slice(0, -1) // Strip the trailing dot
|
|
||||||
uploads.push(uploadsStr.split(".").reverse())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render all the items
|
|
||||||
function getHistoryItem() {
|
|
||||||
let item = uploads.shift()
|
|
||||||
if (item === undefined || item === "") { return }
|
|
||||||
|
|
||||||
fetch(
|
|
||||||
apiEndpoint + "/file/" + item + "/info"
|
|
||||||
).then(resp => {
|
|
||||||
if (!resp.ok) {
|
|
||||||
return Promise.reject()
|
|
||||||
}
|
|
||||||
return resp.json()
|
|
||||||
}).then(resp => {
|
|
||||||
document.getElementById("uploaded_files").appendChild(
|
|
||||||
renderFileButton(
|
|
||||||
apiEndpoint,
|
|
||||||
resp.id,
|
|
||||||
resp.name,
|
|
||||||
printDate(new Date(resp.date_upload), true, true, true),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
getHistoryItem()
|
|
||||||
}).catch(err => {
|
|
||||||
console.log("Fetch failed: " + err)
|
|
||||||
getHistoryItem()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
getHistoryItem()
|
|
||||||
</script>
|
|
||||||
{{template "analytics"}}
|
|
||||||
</body>
|
|
||||||
</html>{{end}}
|
|
19
res/template/upload_history.html
Normal file
19
res/template/upload_history.html
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{{define "upload_history"}}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
{{template "meta_tags" "Upload history"}}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.api_endpoint = '{{.APIEndpoint}}';
|
||||||
|
window.server_hostname = "{{.Hostname}}";
|
||||||
|
</script>
|
||||||
|
<script defer src='/res/svelte/upload_history.js?v{{cacheID}}'></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{{template "menu" .}}
|
||||||
|
<div id="page_body" class="page_body"></div>
|
||||||
|
{{template "analytics"}}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
{{end}}
|
6
svelte/package-lock.json
generated
6
svelte/package-lock.json
generated
@@ -2064,9 +2064,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001538",
|
"version": "1.0.30001599",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001538.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001599.tgz",
|
||||||
"integrity": "sha512-HWJnhnID+0YMtGlzcp3T9drmBJUVDchPJ08tpUGFLs9CYlwWPH2uLgpHn8fND5pCgXVtnGS3H4QR9XLMHVNkHw==",
|
"integrity": "sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@@ -17,6 +17,7 @@ export default [
|
|||||||
"home_page",
|
"home_page",
|
||||||
"text_upload",
|
"text_upload",
|
||||||
"speedtest",
|
"speedtest",
|
||||||
|
"upload_history",
|
||||||
].map((name, index) => ({
|
].map((name, index) => ({
|
||||||
input: `src/${name}.js`,
|
input: `src/${name}.js`,
|
||||||
output: {
|
output: {
|
||||||
|
8
svelte/src/upload_history.js
Normal file
8
svelte/src/upload_history.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import App from './upload_history/UploadHistory.svelte';
|
||||||
|
|
||||||
|
const app = new App({
|
||||||
|
target: document.getElementById("page_body"),
|
||||||
|
props: {}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default app;
|
159
svelte/src/upload_history/UploadHistory.svelte
Normal file
159
svelte/src/upload_history/UploadHistory.svelte
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
<script>
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
import { formatDate } from "../util/Formatting.svelte";
|
||||||
|
import Footer from "../layout/Footer.svelte"
|
||||||
|
import Button from "../layout/Button.svelte";
|
||||||
|
import LoadingIndicator from "../util/LoadingIndicator.svelte"
|
||||||
|
|
||||||
|
let files = []
|
||||||
|
let loading = true
|
||||||
|
|
||||||
|
const parse_file_list = () => {
|
||||||
|
// Get the file IDs from localstorage
|
||||||
|
let uploadsStr = localStorage.getItem("uploaded_files")
|
||||||
|
if (uploadsStr === null) {
|
||||||
|
uploadsStr = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return uploadsStr.split(",")
|
||||||
|
}
|
||||||
|
|
||||||
|
const save_file_list = () => {
|
||||||
|
if (loading) {
|
||||||
|
alert("Please wait for the file list to finish loading first")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const id_list = files.reduce((acc, val) => {
|
||||||
|
acc.push(val.id)
|
||||||
|
return acc
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
localStorage.setItem("uploaded_files", id_list.join(","))
|
||||||
|
}
|
||||||
|
|
||||||
|
// index is the index of the file ID in localstorage, id is the public file ID
|
||||||
|
// of the file
|
||||||
|
const remove_file = (id) => {
|
||||||
|
// Remove the file from the rendered files list
|
||||||
|
for (let i = 0; i < files.length; i++) {
|
||||||
|
if (id === files[i].id) {
|
||||||
|
console.debug("Removing file", id, "at index", i)
|
||||||
|
files.splice(i, 1)
|
||||||
|
files = files
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
save_file_list()
|
||||||
|
}
|
||||||
|
|
||||||
|
const get_files = async () => {
|
||||||
|
const file_ids = parse_file_list()
|
||||||
|
|
||||||
|
for (const id of file_ids) {
|
||||||
|
if (id === "") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const resp = await fetch(window.api_endpoint + "/file/" + id + "/info")
|
||||||
|
if (resp.status === 404) {
|
||||||
|
continue
|
||||||
|
} else if (resp.status >= 400) {
|
||||||
|
throw new Error(await resp.json())
|
||||||
|
}
|
||||||
|
files.push(await resp.json())
|
||||||
|
files = files
|
||||||
|
}
|
||||||
|
|
||||||
|
loading = false
|
||||||
|
save_file_list()
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => get_files())
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<LoadingIndicator loading={loading}/>
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<h1>File upload history</h1>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div id="page_content" class="page_content">
|
||||||
|
<section>
|
||||||
|
<p>
|
||||||
|
Here are all files you have previously uploaded to pixeldrain using this
|
||||||
|
computer. This data is saved locally in your web browser and gets updated
|
||||||
|
every time you upload a file through your current browser.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{#each files as file (file.id)}
|
||||||
|
<a class="file_button" href="/u/{file.id}" target="_blank">
|
||||||
|
<img src="/api/file/{file.id}/thumbnail?width=80&height=80" alt="{file.name}">
|
||||||
|
<div>
|
||||||
|
<span class="file_button_title">
|
||||||
|
{file.name}
|
||||||
|
</span>
|
||||||
|
<br/>
|
||||||
|
<span class="file_button_subtitle">
|
||||||
|
{formatDate(file.date_upload, true, true, true)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
click={e => {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
remove_file(file.id)
|
||||||
|
}}
|
||||||
|
icon="cancel"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Footer/>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.file_button {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
width: 400px;
|
||||||
|
max-width: 90%;
|
||||||
|
height: 3.6em;
|
||||||
|
margin: 8px;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: var(--input_background);
|
||||||
|
color: var(--body_text_color);
|
||||||
|
word-break: break-all;
|
||||||
|
text-align: left;
|
||||||
|
line-height: 1.2em;
|
||||||
|
transition: box-shadow 0.3s, opacity 2s, background 0.2s;
|
||||||
|
white-space: normal;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
text-decoration: none;
|
||||||
|
vertical-align: top;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file_button:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
background: var(--input_hover_background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.file_button>img {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
max-height: 100%;
|
||||||
|
max-width: 25%;
|
||||||
|
margin-right: 5px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file_button_title {
|
||||||
|
color: var(--link_color);
|
||||||
|
}
|
||||||
|
</style>
|
@@ -135,7 +135,7 @@ func New(r *httprouter.Router, prefix string, conf Config) (wc *WebController) {
|
|||||||
// General navigation
|
// General navigation
|
||||||
{GET, "" /* */, wc.serveTemplate("home", handlerOpts{})},
|
{GET, "" /* */, wc.serveTemplate("home", handlerOpts{})},
|
||||||
{GET, "api" /* */, wc.serveMarkdown("api.md", handlerOpts{})},
|
{GET, "api" /* */, wc.serveMarkdown("api.md", handlerOpts{})},
|
||||||
{GET, "history" /* */, wc.serveTemplate("history_cookies", handlerOpts{})},
|
{GET, "history" /* */, wc.serveTemplate("upload_history", handlerOpts{})},
|
||||||
{GET, "u/:id" /* */, wc.serveFileViewer},
|
{GET, "u/:id" /* */, wc.serveFileViewer},
|
||||||
{GET, "u/:id/preview" /* */, wc.serveFilePreview},
|
{GET, "u/:id/preview" /* */, wc.serveFilePreview},
|
||||||
{GET, "l/:id" /* */, wc.serveListViewer},
|
{GET, "l/:id" /* */, wc.serveListViewer},
|
||||||
@@ -400,6 +400,10 @@ func (wc *WebController) serveNotFound(w http.ResponseWriter, r *http.Request) {
|
|||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
wc.templates.Get().ExecuteTemplate(w, "404", wc.newTemplateData(w, r))
|
wc.templates.Get().ExecuteTemplate(w, "404", wc.newTemplateData(w, r))
|
||||||
}
|
}
|
||||||
|
func (wc *WebController) serveUnavailableForLegalReasons(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.WriteHeader(http.StatusUnavailableForLegalReasons)
|
||||||
|
wc.templates.Get().ExecuteTemplate(w, "451", wc.newTemplateData(w, r))
|
||||||
|
}
|
||||||
|
|
||||||
func (wc *WebController) getAPIKey(r *http.Request) (key string, err error) {
|
func (wc *WebController) getAPIKey(r *http.Request) (key string, err error) {
|
||||||
if cookie, err := r.Cookie("pd_auth_key"); err == nil {
|
if cookie, err := r.Cookie("pd_auth_key"); err == nil {
|
||||||
|
Reference in New Issue
Block a user