You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							363 lines
						
					
					
						
							11 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							363 lines
						
					
					
						
							11 KiB
						
					
					
				| <!DOCTYPE html> | |
| <html> | |
| <head> | |
|     <title>SeaweedFS Filer {{ .Version }}</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 <small>{{ .Version }}</small> | |
|         </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 }} | |
|             </a></li> | |
|             {{ 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>
 |