This commit is contained in:
Henrique Dias 2016-12-29 22:50:36 +00:00
parent 72e65e85fb
commit ebbe370ebb
8 changed files with 202 additions and 394 deletions

View File

@ -395,7 +395,7 @@ textarea {
body { body {
font-family: 'Roboto', sans-serif; font-family: 'Roboto', sans-serif;
padding-top: 5em; padding-top: 9em;
background-color: #f8f8f8; background-color: #f8f8f8;
text-rendering: optimizespeed; text-rendering: optimizespeed;
} }
@ -602,11 +602,15 @@ pre {
/* HEADER */ /* HEADER */
header { header {
z-index: 999; z-index: 1000;
padding: 1.7em 0;
background-color: #fff; background-color: #fff;
border-bottom: 1px solid rgba(0, 0, 0, 0.075); border-bottom: 1px solid rgba(0, 0, 0, 0.075);
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1); box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
position: fixed;
top: 0;
left: 0;
width: 100%;
padding: 0;
} }
header h1 { header h1 {
@ -621,10 +625,7 @@ header a:hover,
color: inherit; color: inherit;
} }
header p { header p {}
font-size: 1.5em;
max-width: calc(100% - 3em);
}
header p i { header p i {
font-size: 1em !important; font-size: 1em !important;
@ -632,14 +633,10 @@ header p i {
} }
header #logout { header #logout {
background-color: rgba(0, 0, 0, 0.05); /* background-color: rgba(0, 0, 0, 0.05); */
border-radius: 0; border-radius: 0;
margin: -0.5em -0.5em -0.5em 0; margin: 0 0 0 auto;
padding: .5em; padding: .2em;
}
header p i {
vertical-align: middle;
} }
#search { #search {
@ -771,29 +768,46 @@ header p i {
color: rgba(255, 255, 255, .5); color: rgba(255, 255, 255, .5);
} }
#toolbar, header>div {
header {
position: fixed;
top: 0;
left: 0;
display: -webkit-box;
display: -ms-flexbox;
display: flex; display: flex;
width: 100%; width: 100%;
padding: 0.5em; padding: 0.5em 0.5em 0.5em 1em;
max-height: 4em;
} }
#toolbar div, header>div:first-child>div:nth-child(1) {
header div { margin-right: 2em;
font-weight: 500;
font-size: 1.5em;
line-height: 2;
}
header>div:last-child {
background-color: #fafafa;
border-top: 1px solid rgba(0, 0, 0, 0.075);
border-bottom: 1px solid rgba(0, 0, 0, 0.075);
}
header>div div {
vertical-align: middle; vertical-align: middle;
-webkit-box-flex: 1;
-ms-flex-positive: 1;
flex-grow: 1;
position: relative; position: relative;
} }
#toolbar p, header .actions {
margin-left: auto;
}
header #file-only {
display: inline-block;
border-right: 1px solid rgba(0, 0, 0, 0.075);
padding-right: .3em;
margin-right: .3em;
transition: .2s ease all;
}
#file-only.disabled {
opacity: 0;
}
header p { header p {
display: inline-block; display: inline-block;
margin: 0; margin: 0;
@ -804,49 +818,12 @@ header #open-nav {
display: none; display: none;
} }
#toolbar p a,
#toolbar p a:hover,
header p a, header p a,
header p a:hover { header p a:hover {
color: inherit; color: inherit;
} }
#toolbar { header>div div:nth-child(2) {}
z-index: 1000;
top: -4em;
-webkit-transition: 0.2s ease-in-out all;
transition: 0.2s ease-in-out all;
opacity: 0;
color: #fff;
background-color: #2196f3;
}
#toolbar.enabled {
top: 0;
opacity: 1;
}
#toolbar div:nth-child(2),
header div:nth-child(2) {
text-align: right;
}
header #overlay {
visibility: hidden;
opacity: 0;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 999;
transition: .2s ease all;
background-color: rgba(0, 0, 0, 0.35);
}
header .only-side {
display: none;
}
.action:hover ul { .action:hover ul {
display: flex; display: flex;
@ -908,11 +885,12 @@ header .only-side {
.action { .action {
display: inline-block; display: inline-block;
margin: 0 0.2em;
cursor: pointer; cursor: pointer;
-webkit-transition: 0.2s ease all; -webkit-transition: 0.2s ease all;
transition: 0.2s ease all; transition: 0.2s ease all;
border: 0; border: 0;
margin: 0;
color: #546E7A;
border-radius: 50%; border-radius: 50%;
} }
@ -922,7 +900,7 @@ header .only-side {
} }
.action i { .action i {
padding: 0.5em; padding: 0.4em;
-webkit-transition: 0.2s ease-in-out all; -webkit-transition: 0.2s ease-in-out all;
transition: 0.2s ease-in-out all; transition: 0.2s ease-in-out all;
border-radius: 50%; border-radius: 50%;
@ -932,7 +910,6 @@ header .only-side {
background-color: rgba(0, 0, 0, .1); background-color: rgba(0, 0, 0, .1);
} }
#toolbar .action span,
header .action span { header .action span {
display: none; display: none;
} }
@ -983,8 +960,6 @@ header .action span {
justify-content: flex-start; justify-content: flex-start;
max-width: calc(100% - 2.2em); max-width: calc(100% - 2.2em);
width: 100%; width: 100%;
opacity: 0;
transition: .1s ease all;
} }
#listing.list { #listing.list {
@ -1000,7 +975,7 @@ header .action span {
border: 0; border: 0;
box-shadow: none; box-shadow: none;
border-radius: 0; border-radius: 0;
border-bottom: 1px solid rgba(0,0,0,0.1); border-bottom: 1px solid rgba(0, 0, 0, 0.1);
padding: 1em; padding: 1em;
} }
@ -1053,7 +1028,6 @@ header .action span {
vertical-align: bottom; vertical-align: bottom;
} }
#listing.list .item div:first-of-type { #listing.list .item div:first-of-type {
width: 3em; width: 3em;
} }
@ -1066,6 +1040,7 @@ header .action span {
width: calc(100% - 3em); width: calc(100% - 3em);
} }
/* ANIMATIONS */ /* ANIMATIONS */
i.spin { i.spin {
@ -1237,130 +1212,4 @@ i.spin {
display: inline-block; display: inline-block;
text-align: right; text-align: right;
float: right; float: right;
}
@media screen and (max-width: 1024px) {
header .only-side {
display: block;
padding: .5em;
background-color: #2196f3;
color: #fff;
max-height: 4em;
}
header>div:first-child #prev {
display: none;
}
header #open-nav {
display: inline-block;
}
/* SIDEBAR */
header>div:nth-child(2) {
position: fixed;
top: 0;
z-index: 999999;
background-color: #fff;
height: 100%;
width: 95%;
max-width: 20em;
text-align: left;
color: #212121;
left: -100%;
transition: .2s ease-in-out all;
}
header>div:nth-child(2).active {
left: 0;
}
header>div:nth-child(2).active+#overlay {
opacity: 1;
visibility: visible;
}
header #search {
height: auto;
background-color: transparent;
color: #212121;
border-bottom: 1px solid #eee;
border-radius: 0;
display: block;
width: 100%;
padding: .5em 0;
text-align: left;
}
header #search input {
color: #212121;
display: inline-block;
width: auto;
min-width: 16em;
}
header #search i {
color: #6f6f6f;
display: inline-block;
padding: .5em;
margin: 0;
}
header>div:nth-child(2)>div {
display: block;
}
header>div:nth-child(2) .action {
border-radius: 0 !important;
padding: .5em 0 !important;
margin: 0 !important;
text-align: left;
background-color: transparent !important;
}
header>div:nth-child(2) #prev {
border-radius: 50% !important;
padding: 0 !important;
}
header>div:nth-child(2) #prev i {
color: #fff;
}
header>div:nth-child(2) .action:hover {
background-color: rgba(0, 0, 0, .1) !important;
}
header>div:nth-child(2) .action:hover i {
background-color: transparent;
}
header>div:nth-child(2) .action i {
border-radius: 0;
color: #6f6f6f;
}
header>div:nth-child(2) .action span {}
header>div:nth-child(2) .action i,
header>div:nth-child(2) .action span {
vertical-align: middle;
display: inline-block;
}
}
@media screen and (max-width: 800px) {
#listing .item {
width: calc(50% - 1em);
}
}
@media screen and (max-width: 700px) {
header>div:first-child p a,
header>div:first-child p i {
display: none !important;
}
header>div:first-child p {
font-size: 1em;
}
#editor .frontmatter {
column-count: 1;
column-gap: 0;
}
}
@media screen and (max-width: 650px) {
#listing .item {
width: 100%;
margin: 0 0 1em;
}
}
@media screen and (max-width: 450px) {
#toolbar p {
display: none;
}
} }

View File

@ -85,6 +85,21 @@ Element.prototype.changeToDone = function(error, html) {
return false; return false;
} }
function getCSSRule(ruleName) {
ruleName = ruleName.toLowerCase();
var result = null;
var find = Array.prototype.find;
find.call(document.styleSheets, styleSheet => {
result = find.call(styleSheet.cssRules, cssRule => {
return cssRule instanceof CSSStyleRule &&
cssRule.selectorText.toLowerCase() == ruleName;
});
return result != null;
});
return result;
}
var toWebDavURL = function(url) { var toWebDavURL = function(url) {
url = url.replace(baseURL + "/", webdavURL + "/"); url = url.replace(baseURL + "/", webdavURL + "/");
return window.location.origin + url return window.location.origin + url
@ -171,8 +186,7 @@ var reloadListing = function(callback) {
if (request.status == 200) { if (request.status == 200) {
document.querySelector('body main').innerHTML = request.responseText; document.querySelector('body main').innerHTML = request.responseText;
addNewDirEvents(); addNewDirEvents();
document.getElementById("listing").style.opacity = 1;
if (typeof callback == 'function') { if (typeof callback == 'function') {
callback(); callback();
} }
@ -193,23 +207,24 @@ var renameEvent = function(event) {
location.refresh(); location.refresh();
} }
let link = selectedItems[0]; let item = document.getElementById(selectedItems[0]),
let item = document.getElementById(link); link = item.dataset.url,
let span = item.getElementsByTagName('span')[0]; span = item.getElementsByTagName('span')[0],
let name = span.innerHTML; name = span.innerHTML;
span.setAttribute('contenteditable', 'true'); span.setAttribute('contenteditable', 'true');
span.focus(); span.focus();
let keyDownEvent = (event) => { let keyDownEvent = (event) => {
if (event.keyCode == 13) { if (event.keyCode == 13) {
let newName = span.innerHTML; let newName = span.innerHTML,
let newLink = toWebDavURL(link).replace(name, newName) newLink = RemoveLastDirectoryPartOf(toWebDavURL(link)) + newName,
let html = document.getElementById('rename').changeToLoading(); html = document.getElementById('rename').changeToLoading(),
let request = new XMLHttpRequest(); request = new XMLHttpRequest();
request.open('MOVE', toWebDavURL(link)); request.open('MOVE', toWebDavURL(link));
request.setRequestHeader('Destination', newLink); request.setRequestHeader('Destination', newLink);
request.setRequestHeader('Content-type', 'text/plain; charset=utf-8');
request.send(); request.send();
request.onreadystatechange = function() { request.onreadystatechange = function() {
// TODO: redirect if it's moved to another folder // TODO: redirect if it's moved to another folder
@ -221,11 +236,10 @@ var renameEvent = function(event) {
let newLink = encodeURI(link.replace(name, newName)); let newLink = encodeURI(link.replace(name, newName));
console.log(request.body) console.log(request.body)
reloadListing(() => { reloadListing(() => {
let newLink = encodeURI(link.replace(name, newName)); newName = btoa(newName);
selectedItems = [newLink]; selectedItems = [newName];
document.getElementById(newLink).classList.add("selected") document.getElementById(newName).setAttribute("aria-selected", true);
var event = new CustomEvent('changed-selected'); document.sendCostumEvent('changed-selected');
document.dispatchEvent(event);
}); });
} }
@ -376,12 +390,13 @@ var newDirEvent = function(event) {
// Handles the event when there is change on selected elements // Handles the event when there is change on selected elements
document.addEventListener("changed-selected", function(event) { document.addEventListener("changed-selected", function(event) {
var toolbar = document.getElementById("toolbar"); redefineDownloadURLs();
var selectedNumber = selectedItems.length;
document.getElementById("selected-number").innerHTML = selectedNumber; let selectedNumber = selectedItems.length,
fileAction = document.getElementById("file-only");
if (selectedNumber) { if (selectedNumber) {
toolbar.classList.add("enabled"); fileAction.classList.remove("disabled");
if (selectedNumber > 1) { if (selectedNumber > 1) {
document.getElementById("open").classList.add("disabled"); document.getElementById("open").classList.add("disabled");
@ -393,12 +408,10 @@ document.addEventListener("changed-selected", function(event) {
document.getElementById("rename").classList.remove("disabled"); document.getElementById("rename").classList.remove("disabled");
} }
redefineDownloadURLs();
return false; return false;
} }
toolbar.classList.remove("enabled"); fileAction.classList.add("disabled");
return false; return false;
}); });
@ -406,7 +419,8 @@ var redefineDownloadURLs = function() {
let files = ""; let files = "";
for (let i = 0; i < selectedItems.length; i++) { for (let i = 0; i < selectedItems.length; i++) {
files += selectedItems[i].replace(window.location.pathname, "") + ","; let url = document.getElementById(selectedItems[i]).dataset.url;
files += url.replace(window.location.pathname, "") + ",";
} }
files = files.substring(0, files.length - 1); files = files.substring(0, files.length - 1);
@ -484,13 +498,26 @@ var searchEvent = function(event) {
} }
} }
document.addEventListener('listing', event => { document.addEventListener('listing', event => {
// Handles the current view mode and adds the event to the button // Handles the current view mode and adds the event to the button
handleViewType(document.getCookie("view-list")); handleViewType(document.getCookie("view-list"));
document.getElementById("view").addEventListener("click", viewEvent); document.getElementById("view").addEventListener("click", viewEvent);
let updateColumns = () => {
let columns = Math.floor(document.getElementById('listing').offsetWidth / 300),
itens = getCSSRule('#listing .item');
itens.style.width = `calc(${100/columns}% - 1em)`;
}
updateColumns();
window.addEventListener("resize", () => {
updateColumns();
});
// Add event to back button and executes back event on ESC // Add event to back button and executes back event on ESC
document.getElementById("back").addEventListener("click", backEvent)
document.addEventListener('keydown', (event) => { document.addEventListener('keydown', (event) => {
if (event.keyCode == 27) { if (event.keyCode == 27) {
backEvent(event); backEvent(event);
@ -628,6 +655,7 @@ function itemDrop(e) {
let el = e.target, let el = e.target,
id = e.dataTransfer.getData("id"), id = e.dataTransfer.getData("id"),
name = e.dataTransfer.getData("name"); name = e.dataTransfer.getData("name");
if (id == "" || name == "") return; if (id == "" || name == "") return;
for (let i = 0; i < 5; i++) { for (let i = 0; i < 5; i++) {
@ -638,10 +666,10 @@ function itemDrop(e) {
if (el.id === id) return; if (el.id === id) return;
let oldLink = toWebDavURL(id); let oldLink = toWebDavURL(document.getElementById(id).dataset.url),
let newLink = toWebDavURL(el.id + name); newLink = toWebDavURL(el.dataset.url + name),
request = new XMLHttpRequest();
let request = new XMLHttpRequest();
request.open('MOVE', oldLink); request.open('MOVE', oldLink);
request.setRequestHeader('Destination', newLink); request.setRequestHeader('Destination', newLink);
request.send(); request.send();
@ -660,20 +688,18 @@ function openItem(event) {
} }
function selectItem(event) { function selectItem(event) {
let el = event.currentTarget, let el = event.currentTarget;
url = el.dataset.url;
if (selectedItems.length != 0) event.preventDefault(); if (selectedItems.length != 0) event.preventDefault();
if (selectedItems.indexOf(url) == -1) { if (selectedItems.indexOf(el.id) == -1) {
el.setAttribute("aria-selected", true); el.setAttribute("aria-selected", true);
selectedItems.push(url); selectedItems.push(el.id);
} else { } else {
el.setAttribute("aria-selected", false); el.setAttribute("aria-selected", false);
selectedItems.removeElement(url); selectedItems.removeElement(el.id);
} }
var event = new CustomEvent('changed-selected'); document.sendCostumEvent("changed-selected");
document.dispatchEvent(event);
return false; return false;
} }
@ -969,13 +995,6 @@ document.addEventListener("DOMContentLoaded", function(event) {
document.getElementById("delete").addEventListener("click", deleteEvent); document.getElementById("delete").addEventListener("click", deleteEvent);
} }
document.getElementById("open-nav").addEventListener("click", event => {
document.querySelector("header > div:nth-child(2)").classList.toggle("active");
});
document.getElementById("overlay").addEventListener("click", event => {
document.querySelector("header > div:nth-child(2)").classList.toggle("active");
});
if (document.getElementById('listing')) { if (document.getElementById('listing')) {
document.sendCostumEvent('listing'); document.sendCostumEvent('listing');
} }
@ -985,36 +1004,4 @@ document.addEventListener("DOMContentLoaded", function(event) {
} }
return false; return false;
}); });
(function() {
let columns = Math.floor(document.getElementById('listing').offsetWidth / 300);
var header = getCSSRule('#listing .item');
header.style.width = `calc(${100/columns}% - 1em)`;
document.getElementById("listing").style.opacity = 1;
}());
window.addEventListener("resize", () => {
let columns = Math.floor(document.getElementById('listing').offsetWidth / 300);
var itens = getCSSRule('#listing .item');
itens.style.width = `calc(${100/columns}% - 1em)`;
});
function getCSSRule(ruleName) {
ruleName = ruleName.toLowerCase();
var result = null;
var find = Array.prototype.find;
find.call(document.styleSheets, styleSheet => {
result = find.call(styleSheet.cssRules, cssRule => {
return cssRule instanceof CSSStyleRule &&
cssRule.selectorText.toLowerCase() == ruleName;
});
return result != null;
});
return result;
}

View File

@ -1,33 +0,0 @@
{{ define "actions" }}
<div class="action" id="open">
<i class="material-icons" title="See raw">open_in_new</i> <span>See raw</span>
</div>
{{ if and .IsDir .User.AllowEdit }}
<div class="action" id="rename">
<i class="material-icons" title="Edit">mode_edit</i>
</div>
{{ end }}
<!-- {{ if .IsDir }}
<div class="action" id="info">
<i class="material-icons">info</i>
</div>
{{ end }}-->
<div class="action" id="download">
<a href="?download=true">
<i class="material-icons" title="Download">file_download</i> <span>Download</span>
</a>
{{ if .IsDir }}
<ul class="prev-links">
<a data-format="tarbz2" href="?download=tarbz2"><li>tar.bz2</li></a>
<a data-format="targz" href="?download=targz"><li>tar.gz</li></a>
<a data-format="tar" href="?download=tar"><li>tar</li></a>
<a data-format="zip" href="?download=zip"><li>zip</li></a>
</ul>
{{ end }}
</div>
{{ if .User.AllowEdit }}
<div class="action" id="delete">
<i class="material-icons" title="Delete">delete</i> <span>Delete</span>
</div>
{{ end }}
{{ end }}

View File

@ -4,6 +4,7 @@
<head> <head>
<title>{{.Name}}</title> <title>{{.Name}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="utf-8">
<meta name="token" content="{{ .Token }}"> <meta name="token" content="{{ .Token }}">
<link rel="stylesheet" href="{{ .Config.AbsoluteURL }}/_filemanagerinternal/css/styles.css"> <link rel="stylesheet" href="{{ .Config.AbsoluteURL }}/_filemanagerinternal/css/styles.css">
{{ if ne .User.StyleSheet "" }} {{ if ne .User.StyleSheet "" }}
@ -19,103 +20,96 @@
</head> </head>
<body> <body>
<header> <header>
<!-- TOP BAR -->
<div> <div>
{{ $lnk := .PreviousLink }} <div><p>File Manager</p></div>
<div class="action{{ if eq $lnk ""}} disabled{{ end }}" id="prev"> {{ if .User.AllowCommands }}
{{ if ne $lnk ""}}<a href="{{ $lnk }}">{{ end }} <div id="search">
<i class="material-icons" title="Previous">subdirectory_arrow_left</i> <i class="material-icons" title="Storage">storage</i>
{{ if ne $lnk ""}}</a>{{ end }} <input type="text" placeholder="Search or execute a command...">
<div>
{{ if ne $lnk ""}} <div>Write your git, mercurial or svn command and press enter.</div>
<ul class="prev-links"> <p><i class="material-icons spin">autorenew</i></p>
{{ range $link, $name := .BreadcrumbMap }}<a href="{{ $absURL }}{{ $link }}"><li>{{ $name }}</li></a>{{ end }} </div>
</ul>
{{ end }}
</div> </div>
<div class="action" id="open-nav">
<i class="material-icons" title="Menu">menu</i>
</div>
{{ if ne .Name "/"}}<p>{{ .Name }}</p>{{ end }}
</div>
<div>
<div class="only-side">
{{ $lnk := .PreviousLink }}
{{ if ne $lnk ""}}<a href="{{ $lnk }}">{{ end }}
<div class="action{{ if eq $lnk ""}} disabled{{ end }}" id="prev">
<i class="material-icons" title="Previous">subdirectory_arrow_left</i>
</div>
{{ if ne $lnk ""}}</a>{{ end }}
<p><a href="{{ if eq .Config.AbsoluteURL "" }}/{{ else }}{{ .Config.AbsoluteURL }}{{ end }}">File Manager</a></p>
</div>
{{ if .IsDir}}
{{ if .User.AllowCommands }}
<div id="search">
<i class="material-icons" title="Storage">storage</i>
<input type="text" placeholder="Search or execute a command...">
<div>
<div>Write your git, mercurial or svn command and press enter.</div>
<p><i class="material-icons spin">autorenew</i></p>
</div>
</div>
{{ end }}
<div class="action" id="view">
<i class="material-icons" title="Switch view">view_headline</i> <span>Switch view</span>
</div>
{{ if .User.AllowNew }}
<div class="action" id="upload">
<i class="material-icons" title="Upload">file_upload</i> <span>Upload</span>
</div>
{{ end }}
<div class="action">
<a href="?download=true">
<i class="material-icons" title="Download">file_download</i> <span>Download</span>
</a>
<ul class="prev-links">
<a href="?download=tarbz2"><li>tar.bz2</li></a>
<a href="?download=targz"><li>tar.gz</li></a>
<a href="?download=tar"><li>tar</li></a>
<a href="?download=zip"><li>zip</li></a>
</ul>
</div>
{{ else }}
{{ template "actions" . }}
{{ end }} {{ end }}
<div class="action" id="logout"> <div class="action" id="logout">
<i class="material-icons" title="Logout">exit_to_app</i> <span>Logout</span> <i class="material-icons" title="Logout">exit_to_app</i> <span>Logout</span>
</div> </div>
</div> </div>
<div id="overlay"></div>
</header> <!-- BOTTOM BAR -->
{{ if .IsDir }}
<div id="toolbar">
<div> <div>
<div class="action" id="back"> <div>
<i class="material-icons" title="Back">arrow_back</i> {{ $lnk := .PreviousLink }}
<div class="action{{ if eq $lnk ""}} disabled{{ end }}" id="prev">
{{ if ne $lnk ""}}<a href="{{ $lnk }}">{{ end }}
<i class="material-icons" title="Previous">subdirectory_arrow_left</i>
{{ if ne $lnk ""}}</a>{{ end }}
{{ if ne $lnk ""}}
<ul class="prev-links">
{{ range $link, $name := .BreadcrumbMap }}<a href="{{ $absURL }}{{ $link }}"><li>{{ $name }}</li></a>{{ end }}
</ul>
{{ end }}
</div>
{{ if ne .Name "/"}}<p>{{ .Name }}</p>{{ end }}
</div>
<!-- ACTIONS -->
<div class="actions">
<div id="file-only" {{ if .IsDir }}class="disabled"{{ end }}>
<div class="action" id="open">
<i class="material-icons" title="See raw">open_in_new</i> <span>See raw</span>
</div>
{{ if and .IsDir .User.AllowEdit }}
<div class="action" id="rename">
<i class="material-icons" title="Edit">mode_edit</i>
</div>
{{ end }}
{{ if .User.AllowEdit }}
<div class="action" id="delete">
<i class="material-icons" title="Delete">delete</i> <span>Delete</span>
</div>
{{ end }}
</div>
{{ if and (.User.AllowNew) (.IsDir) }}
<div class="action" id="upload">
<i class="material-icons" title="Upload">file_upload</i> <span>Upload</span>
</div>
{{ end }}
<div class="action" id="download">
<a href="?download=true">
<i class="material-icons" title="Download">file_download</i> <span>Download</span>
</a>
{{ if .IsDir }}
<ul class="prev-links">
<a data-format="tarbz2" href="?download=tarbz2"><li>tar.bz2</li></a>
<a data-format="targz" href="?download=targz"><li>tar.gz</li></a>
<a data-format="tar" href="?download=tar"><li>tar</li></a>
<a data-format="zip" href="?download=zip"><li>zip</li></a>
</ul>
{{ end }}
</div>
{{ if .IsDir }}
<div class="action" id="view">
<i class="material-icons" title="Switch view">view_headline</i> <span>Switch view</span>
</div>
{{ end }}
</div> </div>
<p><span id="selected-number">0</span> selected.</p>
</div> </div>
<div> </header>
{{ template "actions" . }}
</div>
</div>
{{ end }}
<main> <main>
{{ template "content" . }} {{ template "content" . }}
</main> </main>
<footer>Served with <a rel="noopener noreferrer" href="https://caddyserver.com">Caddy</a> and <a rel="noopener noreferrer" href="https://github.com/hacdias/caddy-filemanager">File Manager</a>.</footer> <footer>Served with <a rel="noopener noreferrer" href="https://caddyserver.com">Caddy</a> and <a rel="noopener noreferrer" href="https://github.com/hacdias/caddy-filemanager">File Manager</a>.</footer>
</body> </body>
</html> </html>

View File

@ -12,7 +12,7 @@
ondblclick="openItem(event)" ondblclick="openItem(event)"
data-dir="{{ .IsDir }}" data-dir="{{ .IsDir }}"
data-url="{{ .URL }}" data-url="{{ .URL }}"
id="{{.URL}}"> id="{{ EncodeBase64 .Name }}">
<div> <div>
{{- if .IsDir}} {{- if .IsDir}}
<i class="material-icons">folder</i> <i class="material-icons">folder</i>

View File

@ -4,7 +4,7 @@
{{ if eq .Type "image" }} {{ if eq .Type "image" }}
<img src="{{ .URL }}?raw=true"> <img src="{{ .URL }}?raw=true">
{{ else if eq .Type "audio" }} {{ else if eq .Type "audio" }}
<audio src="{{ .URL }}?raw=true"></audio> <audio src="{{ .URL }}?raw=true" controls></audio>
{{ else if eq .Type "video" }} {{ else if eq .Type "video" }}
<video src="{{ .URL }}?raw=true" controls> <video src="{{ .URL }}?raw=true" controls>
Sorry, your browser doesn't support embedded videos, Sorry, your browser doesn't support embedded videos,

View File

@ -4,6 +4,7 @@ import (
"io" "io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/url"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
@ -29,6 +30,12 @@ func Download(w http.ResponseWriter, r *http.Request, c *config.Config, i *file.
if len(names) != 0 { if len(names) != 0 {
for _, name := range names { for _, name := range names {
name, err := url.QueryUnescape(name)
if err != nil {
return http.StatusInternalServerError, err
}
files = append(files, filepath.Join(i.Path, name)) files = append(files, filepath.Join(i.Path, name))
} }
@ -78,7 +85,7 @@ func Download(w http.ResponseWriter, r *http.Request, c *config.Config, i *file.
} }
name := i.Name() name := i.Name()
if name == "" { if name == "." || name == "" {
name = "download" name = "download"
} }

View File

@ -3,6 +3,7 @@ package page
import ( import (
"bytes" "bytes"
"encoding/base64"
"encoding/json" "encoding/json"
"html/template" "html/template"
"log" "log"
@ -90,12 +91,15 @@ func (p Page) PrintAsHTML(w http.ResponseWriter, templates ...string) (int, erro
a, _ := json.Marshal(v) a, _ := json.Marshal(v)
return template.JS(a) return template.JS(a)
}, },
"EncodeBase64": func(s string) string {
return base64.StdEncoding.EncodeToString([]byte(s))
},
} }
if p.Minimal { if p.Minimal {
templates = append(templates, "actions", "minimal") templates = append(templates, "minimal")
} else { } else {
templates = append(templates, "actions", "base") templates = append(templates, "base")
} }
var tpl *template.Template var tpl *template.Template