|
|
<!DOCTYPE html> <html> <head> <title>SeaweedFS Filer</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="/seaweedfsstatic/bootstrap/3.3.1/css/bootstrap.min.css"> <style> body { padding-bottom: 128px; }
#drop-area { border: 1px transparent; margin-top: 5px; }
#drop-area.highlight { border-color: purple; border: 2px dashed #ccc; }
.button { display: inline-block; padding: 2px; background: #ccc; cursor: pointer; border-radius: 2px; border: 1px solid #ccc; float: right; margin-left: 2px; margin-bottom: 0; }
label { font-weight: normal; }
.button:hover { background: #ddd; }
#fileElem { display: none; }
td, th { vertical-align: bottom; }
.table-hover > tbody > tr:hover > * > div.operations { display: block; }
.table > tbody > tr { height: 39px; }
div.operations { display: none; }
.footer { position: absolute; bottom: 0px; right: 5%; min-width: 25%; border-left: 1px solid #ccc; border-right: 1px solid #ccc; }
.add-files { font-size: 46px; text-align: center; border: 1px dashed #999; padding-bottom: 9px; margin: 0 2px; } </style> </head> <body> <div class="container"> <div class="page-header"> <h1> <a href="https://github.com/seaweedfs/seaweedfs"><img src="/seaweedfsstatic/seaweed50x50.png"></img></a> SeaweedFS Filer </h1> </div> <div class="row"> <div> <div class="btn-group btn-group-sm pull-right" role="group" style="margin-top:3px;"> <label class="btn btn-default" onclick="handleCreateDir()"> <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> New Folder </label> <label class="btn btn-default" for="fileElem"> <span class="glyphicon glyphicon-cloud-upload" aria-hidden="true"></span> Upload </label> </div> <ol class="breadcrumb"> {{ range $entry := .Breadcrumbs }} <li><a href="{{ printpath $entry.Link }}"> {{ $entry.Name }} </li></a> {{ end }} </ol> </div> </div>
<div class="row" id="drop-area"> <form class="upload-form"> <input type="file" id="fileElem" multiple onchange="handleFiles(this.files)">
{{ if .EmptyFolder }} <div class="row add-files"> + </div> {{ else }} <table width="100%" class="table table-hover"> {{ $path := .Path }} {{ $showDirDel := .ShowDirectoryDelete }} {{ range $entry_index, $entry := .Entries }} <tr> <td> {{ if $entry.IsDirectory }} <span class="glyphicon glyphicon-folder-open" aria-hidden="true"></span> <a href="{{ printpath $path "/" $entry.Name "/"}}" > {{ $entry.Name }} </a> {{ else }} <a href="{{ printpath $path "/" $entry.Name }}" > {{ $entry.Name }} </a> {{ end }} </td> <td align="right" nowrap> {{ if not $entry.IsDirectory }} {{ $entry.Mime }} {{ end }} </td> <td align="right" nowrap> {{ if not $entry.IsDirectory }} {{ $entry.Size | humanizeBytes }} {{ end }} </td> <td align="right" nowrap> {{ $entry.Timestamp.Format "2006-01-02 15:04" }} </td> <td style="width:75px"> <div class="btn-group btn-group-xs pull-right operations" role="group"> <label class="btn" onclick="handleRename('{{ $entry.Name }}', '{{ printpath $path "/" }}')"> <span class="glyphicon glyphicon-edit" aria-hidden="true"></span> </label> {{ if and $entry.IsDirectory $showDirDel }} <label class="btn" onclick="handleDelete('{{ printpath $path "/" $entry.Name "/" }}')"> <span class="glyphicon glyphicon-trash" aria-hidden="true"></span> </label> {{ end }} {{ if not $entry.IsDirectory }} <label class="btn" onclick="handleDelete('{{ printpath $path "/" $entry.Name }}')"> <span class="glyphicon glyphicon-trash" aria-hidden="true"></span> </label> {{ end }} </div> </td> </tr> {{ end }} </table> {{ end }} </form> </div>
{{ if .ShouldDisplayLoadMore }} <div class="row"> <a href={{ print .Path "?limit=" .Limit "&lastFileName=" .LastFileName }} > Load more </a> </div> {{ end }}
<br/> <br/> <div id="progress-area" class="footer" style="display: none;"> </div> </div> </body> <script type="text/javascript"> // ************************ Drag and drop ***************** // let dropArea = document.getElementById("drop-area"); let progressArea = document.getElementById("progress-area");
// Prevent default drag behaviors ;['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { dropArea.addEventListener(eventName, preventDefaults, false); document.body.addEventListener(eventName, preventDefaults, false); });
// Highlight drop area when item is dragged over it ;['dragenter', 'dragover'].forEach(eventName => { dropArea.addEventListener(eventName, highlight, false); });
;['dragleave', 'drop'].forEach(eventName => { dropArea.addEventListener(eventName, unhighlight, false); });
// Handle dropped files dropArea.addEventListener('drop', handleDrop, false);
function preventDefaults(e) { e.preventDefault(); e.stopPropagation(); }
function highlight(e) { dropArea.classList.add('highlight'); }
function unhighlight(e) { dropArea.classList.remove('highlight'); }
function handleDrop(e) { var dt = e.dataTransfer; var files = dt.files;
handleFiles(files); }
function reloadPage() { window.location.reload(true); }
var uploadList = {};
function handleFiles(files) { files = [...files]; files.forEach(startUpload); renderProgress(); files.forEach(uploadFile); }
function startUpload(file, i) { uploadList[file.name] = {'name': file.name, 'percent': 0, 'finish': false}; }
function renderProgress() { var values = Object.values(uploadList); var html = '<table class="table">\n<tr><th>Uploading</th><\/tr>\n'; for (let i of values) { var progressBarClass = 'progress-bar-striped active'; if (i.percent >= 100) { progressBarClass = 'progress-bar-success'; } html += '<tr>\n<td>\n'; html += '<div class="progress" style="margin-bottom: 2px;">\n'; html += '<div class="progress-bar ' + progressBarClass + '" role="progressbar" aria-valuenow="' + '100" aria-valuemin="0" aria-valuemax="100" style="width:' + i.percent + '%;">'; html += '<span style="margin-right: 10px;">' + i.name + '</span>' + i.percent + '%<\/div>'; html += '<\/div>\n<\/td>\n<\/tr>\n'; } html += '<\/table>\n'; progressArea.innerHTML = html; if (values.length > 0) { progressArea.attributes.style.value = ''; } }
function reportProgress(file, percent) { var item = uploadList[file] item.percent = percent; renderProgress(); }
function finishUpload(file) { uploadList[file]['finish'] = true; renderProgress(); var allFinish = true; for (let i of Object.values(uploadList)) { if (!i.finish) { allFinish = false; break; } } if (allFinish) { console.log('All Finish'); reloadPage(); } }
function uploadFile(file, i) { var url = window.location.href; var xhr = new XMLHttpRequest(); var fileName = file.name; xhr.onreadystatechange = function() { if (xhr.readyState == XMLHttpRequest.DONE) { finishUpload(fileName) } } xhr.upload.addEventListener('progress', function(e) { if (e.lengthComputable) { var percent = Math.ceil((e.loaded / e.total) * 100); reportProgress(fileName, percent) } }); xhr.upload.addEventListener('loadend', function(e) { finishUpload(fileName); }); var formData = new FormData(); xhr.open('POST', url, true); formData.append('file', file); xhr.send(formData); }
function handleCreateDir() { var dirName = prompt('Folder Name:', ''); dirName = dirName.trim(); if (dirName == null || dirName == '') { return; } var baseUrl = window.location.href; if (!baseUrl.endsWith('/')) { baseUrl += '/'; } var url = baseUrl + encodeURIComponent(dirName); if (!url.endsWith('/')) { url += '/'; } var xhr = new XMLHttpRequest(); xhr.open('POST', url, false); xhr.setRequestHeader('Content-Type', ''); xhr.send(); reloadPage(); }
function handleRename(originName, basePath) { var newName = prompt('New Name:', originName); if (newName == null || newName == '') { return; } var url = basePath + encodeURIComponent(newName); var originPath = basePath + originName; url += '?mv.from=' + encodeURIComponent(originPath); var xhr = new XMLHttpRequest(); xhr.open('POST', url, false); xhr.setRequestHeader('Content-Type', ''); xhr.send(); reloadPage(); }
function handleDelete(path) { if (!confirm('Are you sure to delete ' + path + '?')) { return; } var url = path; if (url.endsWith('/')) { url += '?recursive=true'; }
var xhr = new XMLHttpRequest(); xhr.open('DELETE', url, false); xhr.send(); reloadPage(); } </script> </html>
|