parent
							
								
									9d9f02fbc9
								
							
						
					
					
						commit
						7fade4e2c5
					
				|  | @ -53,6 +53,10 @@ button:hover { | |||
|     background-color: #1E88E5; | ||||
| } | ||||
| 
 | ||||
| .mobile-only { | ||||
|     display: none !important; | ||||
| } | ||||
| 
 | ||||
| .container { | ||||
|     width: 95%; | ||||
|     max-width: 960px; | ||||
|  | @ -366,6 +370,7 @@ header>div { | |||
|     display: flex; | ||||
|     width: 100%; | ||||
|     padding: 0.5em 0.5em 0.5em 1em; | ||||
|     align-items: center; | ||||
| } | ||||
| 
 | ||||
| header p { | ||||
|  | @ -387,12 +392,12 @@ header>div div { | |||
|     vertical-align: middle; | ||||
|     position: relative; | ||||
|     text-overflow: ellipsis; | ||||
|     overflow: hidden; | ||||
|     /* overflow: hidden; */ | ||||
|     white-space: nowrap; | ||||
| } | ||||
| 
 | ||||
| header .actions { | ||||
|     margin-left: auto; | ||||
|     /* margin-left: auto; */ | ||||
| } | ||||
| 
 | ||||
| #logout { | ||||
|  | @ -401,6 +406,20 @@ header .actions { | |||
|     padding: .15em; | ||||
| } | ||||
| 
 | ||||
| #click-overlay { | ||||
|     display: none; | ||||
|     position: fixed; | ||||
|     cursor: pointer; | ||||
|     top: 0; | ||||
|     left: 0; | ||||
|     height: 100%; | ||||
|     width: 100%; | ||||
| } | ||||
| 
 | ||||
| #click-overlay.active { | ||||
|     display: block; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* * * * * * * * * * * * * * * * | ||||
|  *            TOP BAR          * | ||||
|  | @ -559,7 +578,7 @@ header .actions { | |||
|     height: 3.8em; | ||||
| } | ||||
| 
 | ||||
| #bottom-bar div:first-child>* { | ||||
| #bottom-bar>div:first-child>* { | ||||
|     display: inline-block; | ||||
|     vertical-align: middle; | ||||
| } | ||||
|  | @ -568,6 +587,14 @@ header .actions { | |||
|     margin-right: .3em; | ||||
| } | ||||
| 
 | ||||
| #bottom-bar>*:first-child { | ||||
|     margin-right: auto; | ||||
| } | ||||
| 
 | ||||
| #more { | ||||
|     display: none; | ||||
| } | ||||
| 
 | ||||
| #file-only { | ||||
|     display: inline-block; | ||||
|     border-right: 1px solid rgba(0, 0, 0, 0.075); | ||||
|  | @ -584,55 +611,79 @@ header .actions { | |||
| 
 | ||||
| 
 | ||||
| /* * * * * * * * * * * * * * * * | ||||
|  *          BREADCRUMBS        * | ||||
|  *            DROPDOWN         * | ||||
|  * * * * * * * * * * * * * * * */ | ||||
| 
 | ||||
| #breadcrumbs-button { | ||||
|     padding: .4em 0.3em; | ||||
|     border-radius: .1em; | ||||
|     cursor: pointer; | ||||
|     transition: .1s ease all; | ||||
| } | ||||
| 
 | ||||
| #breadcrumbs-button.active, | ||||
| #breadcrumbs-button:hover { | ||||
|     box-shadow: 0 0 5px rgba(0, 0, 0, 0.1); | ||||
|     background: #fff; | ||||
| } | ||||
| 
 | ||||
| #current-file { | ||||
|     line-height: 2.7em; | ||||
| } | ||||
| 
 | ||||
| #breadcrumbs { | ||||
|     transition: .1s ease all; | ||||
|     padding: 0; | ||||
|     margin: 0; | ||||
|     list-style: none; | ||||
|     display: inline-flex; | ||||
| .dropdown { | ||||
|     position: fixed; | ||||
|     top: -100%; | ||||
|     right: -100%; | ||||
|     visibility: hidden; | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     border-radius: 2px; | ||||
|     border-radius: .1em; | ||||
|     border-top-left-radius: 0; | ||||
|     box-shadow: 0 0 5px rgba(0, 0, 0, 0.1); | ||||
|     background: #fff; | ||||
|     z-index: 9999999; | ||||
| } | ||||
| 
 | ||||
| .dropdown.active { | ||||
|     right: .5em; | ||||
|     top: 4.5em; | ||||
|     visibility: visible; | ||||
| } | ||||
| 
 | ||||
| .dropdown .action { | ||||
|     padding: .7em; | ||||
| } | ||||
| 
 | ||||
| .dropdown i { | ||||
|     padding: 0; | ||||
|     vertical-align: middle; | ||||
| } | ||||
| 
 | ||||
| .dropdown span { | ||||
|     display: inline-block; | ||||
|     margin-left: .5em; | ||||
|     font-size: .9em; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* * * * * * * * * * * * * * * * | ||||
|  *          BREADCRUMBS        * | ||||
|  * * * * * * * * * * * * * * * */ | ||||
| 
 | ||||
| #previous { | ||||
|     margin-left: -.5em; | ||||
| } | ||||
| 
 | ||||
| #breadcrumbs { | ||||
|     list-style: none; | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     position: absolute; | ||||
|     left: 0; | ||||
|     top: 2.3em; | ||||
|     margin: 0; | ||||
|     padding: 0; | ||||
|     min-width: 7em; | ||||
|     z-index: 999; | ||||
|     opacity: 0; | ||||
|     visibility: hidden; | ||||
|     color: #656565; | ||||
| } | ||||
| 
 | ||||
| #breadcrumbs.active { | ||||
|     opacity: 1; | ||||
|     visibility: visible; | ||||
|     top: 0; | ||||
|     left: 0; | ||||
|     right: auto; | ||||
| } | ||||
| 
 | ||||
| #breadcrumbs li { | ||||
|     line-height: 1.5em; | ||||
|     padding: .3em; | ||||
|     line-height: 1; | ||||
|     padding: .7em; | ||||
|     transition: .1s ease all; | ||||
| } | ||||
| 
 | ||||
| #breadcrumbs li:hover { | ||||
|     background-color: rgba(0, 0, 0, 0.04); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -859,6 +910,39 @@ header .actions { | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* * * * * * * * * * * * * * * * | ||||
|  *  MULTIPLE SELECTION DIALOG  * | ||||
|  * * * * * * * * * * * * * * * */ | ||||
| 
 | ||||
| #multiple-selection { | ||||
|     position: fixed; | ||||
|     bottom: -4em; | ||||
|     left: 0; | ||||
|     z-index: 99999999; | ||||
|     width: 100%; | ||||
|     background-color: #2196f3; | ||||
|     height: 4em; | ||||
|     display: flex !important; | ||||
|     padding: 0.5em 0.5em 0.5em 1em; | ||||
|     justify-content: space-between; | ||||
|     align-items: center; | ||||
|     transition: .2s ease all; | ||||
| } | ||||
| 
 | ||||
| #multiple-selection.active { | ||||
|     bottom: 0; | ||||
| } | ||||
| 
 | ||||
| #multiple-selection * { | ||||
|     margin: 0; | ||||
| } | ||||
| 
 | ||||
| #multiple-selection p, | ||||
| #multiple-selection i { | ||||
|     color: #fff; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* * * * * * * * * * * * * * * * | ||||
|  *            PROMPT           * | ||||
|  * * * * * * * * * * * * * * * */ | ||||
|  | @ -992,6 +1076,12 @@ footer a:hover { | |||
|  * * * * * * * * * * * * * * * */ | ||||
| 
 | ||||
| @media screen and (max-width: 650px) { | ||||
|     body { | ||||
|         transition: .2s ease padding; | ||||
|     } | ||||
|     .mobile-only { | ||||
|         display: inherit !important; | ||||
|     } | ||||
|     #top-bar>div:nth-child(1) { | ||||
|         display: none; | ||||
|     } | ||||
|  | @ -1008,6 +1098,44 @@ footer a:hover { | |||
|         width: calc(100% - 10em); | ||||
|         padding: .5em; | ||||
|     } | ||||
|     #main-actions { | ||||
|         position: fixed; | ||||
|         top: -100%; | ||||
|         right: -100%; | ||||
|         visibility: hidden; | ||||
|         display: flex; | ||||
|         flex-direction: column; | ||||
|         border-radius: .1em; | ||||
|         border-top-left-radius: 0; | ||||
|         box-shadow: 0 0 5px rgba(0, 0, 0, 0.1); | ||||
|         background: #fff; | ||||
|         z-index: 9999999; | ||||
|     } | ||||
|     #main-actions.active { | ||||
|         right: .5em; | ||||
|         top: 4.5em; | ||||
|         visibility: visible; | ||||
|     } | ||||
|     #main-actions .action { | ||||
|         padding: .7em; | ||||
|         border-radius: 0; | ||||
|     } | ||||
|     #main-actions .action:hover { | ||||
|         background-color: rgba(0, 0, 0, 0.04); | ||||
|     } | ||||
|     #main-actions i { | ||||
|         padding: 0; | ||||
|         vertical-align: middle; | ||||
|     } | ||||
|     #main-actions .action:hover i { | ||||
|         padding: 0; | ||||
|         background-color: transparent; | ||||
|     } | ||||
|     #main-actions span { | ||||
|         display: inline-block; | ||||
|         margin-left: .5em; | ||||
|         font-size: .9em; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,7 +3,8 @@ | |||
| var tempID = "_fm_internal_temporary_id", | ||||
|     buttons = {}, | ||||
|     templates = {}, | ||||
|     selectedItems = []; | ||||
|     selectedItems = [], | ||||
|     overlay, clickOverlay; | ||||
| 
 | ||||
| // Removes an element, if exists, from an array
 | ||||
| Array.prototype.removeElement = function(element) { | ||||
|  | @ -36,7 +37,8 @@ Element.prototype.changeToLoading = function() { | |||
|     element.style.opacity = 0; | ||||
| 
 | ||||
|     setTimeout(function() { | ||||
|         element.innerHTML = '<i class="material-icons spin">autorenew</i>'; | ||||
|         element.classList.add('spin'); | ||||
|         element.innerHTML = 'autorenew'; | ||||
|         element.style.opacity = 1; | ||||
|     }, 200); | ||||
| 
 | ||||
|  | @ -60,13 +62,9 @@ Element.prototype.changeToDone = function(error, html) { | |||
|     } | ||||
| 
 | ||||
|     let firstStep = () => { | ||||
|         this.innerHTML = '<i class="material-icons">done</i>'; | ||||
|         if (error) { | ||||
|             this.innerHTML = '<i class="material-icons">close</i>'; | ||||
|         } | ||||
| 
 | ||||
|         this.classList.remove('spin'); | ||||
|         this.innerHTML = error ? 'close' : 'done'; | ||||
|         this.style.opacity = 1; | ||||
| 
 | ||||
|         setTimeout(secondStep, 1000); | ||||
|     } | ||||
| 
 | ||||
|  | @ -109,7 +107,7 @@ var removeLastDirectoryPartOf = function(url) { | |||
|  * * * * * * * * * * * * * * * */ | ||||
| function closePrompt(event) { | ||||
|     let prompt = document.querySelector('.prompt'); | ||||
|      | ||||
| 
 | ||||
|     if (!prompt) return; | ||||
| 
 | ||||
|     event.preventDefault(); | ||||
|  | @ -123,6 +121,7 @@ function closePrompt(event) { | |||
| 
 | ||||
| function notImplemented(event) { | ||||
|     event.preventDefault(); | ||||
|     clickOverlay.click(); | ||||
| 
 | ||||
|     let clone = document.importNode(templates.info.content, true); | ||||
|     clone.querySelector('h3').innerHTML = 'Not implemented'; | ||||
|  | @ -172,7 +171,7 @@ function deleteSelected(single) { | |||
| 
 | ||||
|         Array.from(selectedItems).forEach(id => { | ||||
|             let request = new XMLHttpRequest(), | ||||
|                 html = buttons.delete.changeToLoading(), | ||||
|                 html = buttons.delete.querySelector('i').changeToLoading(), | ||||
|                 el, url; | ||||
| 
 | ||||
|             if (single) { | ||||
|  | @ -194,7 +193,7 @@ function deleteSelected(single) { | |||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     buttons.delete.changeToDone(request.status != 204, html); | ||||
|                     buttons.delete.querySelector('i').changeToDone(request.status != 204, html); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|  | @ -216,13 +215,13 @@ function deleteEvent(event) { | |||
| 
 | ||||
|     let clone = document.importNode(templates.question.content, true); | ||||
|     clone.querySelector('h3').innerHTML = 'Delete files'; | ||||
|      | ||||
| 
 | ||||
|     if (single) { | ||||
|         clone.querySelector('p').innerHTML = `Are you sure you want to delete this file/folder?`;    | ||||
|         clone.querySelector('p').innerHTML = `Are you sure you want to delete this file/folder?`; | ||||
|     } else { | ||||
|         clone.querySelector('p').innerHTML = `Are you sure you want to delete ${selectedItems.length} file(s)?`;         | ||||
|         clone.querySelector('p').innerHTML = `Are you sure you want to delete ${selectedItems.length} file(s)?`; | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     clone.querySelector('input').remove(); | ||||
|     clone.querySelector('.ok').innerHTML = 'Delete'; | ||||
|     clone.querySelector('form').addEventListener('submit', deleteSelected(single)); | ||||
|  | @ -360,29 +359,29 @@ function setupSearch() { | |||
| 
 | ||||
| function closeHelp(event) { | ||||
|     event.preventDefault(); | ||||
|      | ||||
| 
 | ||||
|     document.querySelector('.help').classList.remove('active'); | ||||
|     document.querySelector('.overlay').classList.remove('active'); | ||||
| } | ||||
| 
 | ||||
| function openHelp(event) { | ||||
|     closePrompt(event); | ||||
|      | ||||
| 
 | ||||
|     document.querySelector('.help').classList.add('active'); | ||||
|     document.querySelector('.overlay').classList.add('active'); | ||||
| } | ||||
| 
 | ||||
| window.addEventListener('keydown', (event) => { | ||||
|     if (event.keyCode == 27) {  | ||||
|     if (event.keyCode == 27) { | ||||
|         if (document.querySelector('.help.active')) { | ||||
|             closeHelp(event); | ||||
|         } | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     if (event.keyCode == 46) { | ||||
|         deleteEvent(event); | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     if (event.keyCode == 112) { | ||||
|         event.preventDefault(); | ||||
|         openHelp(event); | ||||
|  | @ -396,10 +395,13 @@ window.addEventListener('keydown', (event) => { | |||
|  * * * * * * * * * * * * * * * */ | ||||
| 
 | ||||
| document.addEventListener("DOMContentLoaded", function(event) { | ||||
|     overlay = document.querySelector('.overlay'); | ||||
|     clickOverlay = document.querySelector('#click-overlay'); | ||||
|      | ||||
|     buttons.logout = document.getElementById("logout"); | ||||
|     buttons.open = document.getElementById("open"); | ||||
|     buttons.delete = document.getElementById("delete"); | ||||
|     buttons.breadcrumbs = document.getElementById("breadcrumbs-button"); | ||||
|     buttons.previous = document.getElementById("previous"); | ||||
| 
 | ||||
|     // Attach event listeners
 | ||||
|     buttons.logout.addEventListener("click", logoutEvent); | ||||
|  | @ -412,21 +414,42 @@ document.addEventListener("DOMContentLoaded", function(event) { | |||
|         buttons.delete.addEventListener("click", deleteEvent); | ||||
|     } | ||||
| 
 | ||||
|     if (buttons.breadcrumbs) { | ||||
|         buttons.breadcrumbs.addEventListener("click", event => { | ||||
|             event.currentTarget.classList.toggle("active"); | ||||
|     if (buttons.previous) { | ||||
|         buttons.previous.addEventListener("click", event => { | ||||
|             document.getElementById("breadcrumbs").classList.toggle("active"); | ||||
|              | ||||
|             clickOverlay.classList.add('active'); | ||||
|              | ||||
|             clickOverlay.addEventListener('click', event => {         | ||||
|                 document.getElementById("breadcrumbs").classList.remove("active"); | ||||
|                 clickOverlay.classList.remove('active'); | ||||
|             }) | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     document.querySelector('.overlay').addEventListener('click', event => { | ||||
|     overlay.addEventListener('click', event => { | ||||
|         if (document.querySelector('.help.active')) { | ||||
|             closeHelp(event); | ||||
|             return; | ||||
|         } | ||||
|          | ||||
| 
 | ||||
|         closePrompt(event); | ||||
|     }) | ||||
|      | ||||
|     let mainActions = document.getElementById('main-actions'); | ||||
|      | ||||
|     document.getElementById('more').addEventListener('click', event => { | ||||
|         event.preventDefault(); | ||||
|         event.stopPropagation(); | ||||
|          | ||||
|         clickOverlay.classList.add('active'); | ||||
|         mainActions.classList.add('active'); | ||||
|          | ||||
|         clickOverlay.addEventListener('click', event => {         | ||||
|             mainActions.classList.remove('active'); | ||||
|             clickOverlay.classList.remove('active'); | ||||
|         }) | ||||
|     })     | ||||
| 
 | ||||
|     setupSearch(); | ||||
|     return false; | ||||
|  |  | |||
|  | @ -209,7 +209,7 @@ document.addEventListener("DOMContentLoaded", (event) => { | |||
|             data.content = data.content.toString(); | ||||
|         } | ||||
| 
 | ||||
|         let html = button.changeToLoading(), | ||||
|         let html = button.querySelector('i').changeToLoading(), | ||||
|             request = new XMLHttpRequest(); | ||||
| 
 | ||||
|         request.open("PUT", toWebDavURL(window.location.pathname)); | ||||
|  | @ -217,7 +217,7 @@ document.addEventListener("DOMContentLoaded", (event) => { | |||
|         request.send(JSON.stringify(data)); | ||||
|         request.onreadystatechange = function() { | ||||
|             if (request.readyState == 4) { | ||||
|                 button.changeToDone((request.status != 201), html); | ||||
|                 button.querySelector('i').changeToDone((request.status != 201), html); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -1,6 +1,8 @@ | |||
| 'use strict'; | ||||
| 
 | ||||
| var listing = {}; | ||||
| var listing = { | ||||
|     selectMultiple: false | ||||
| }; | ||||
| 
 | ||||
| listing.reload = function(callback) { | ||||
|     let request = new XMLHttpRequest(); | ||||
|  | @ -126,7 +128,7 @@ listing.rename = function(event) { | |||
| 
 | ||||
|         let newName = event.currentTarget.querySelector('input').value, | ||||
|             newLink = removeLastDirectoryPartOf(toWebDavURL(link)) + "/" + newName, | ||||
|             html = buttons.rename.changeToLoading(), | ||||
|             html = buttons.rename.querySelector('i').changeToLoading(), | ||||
|             request = new XMLHttpRequest(); | ||||
| 
 | ||||
|         request.open('MOVE', toWebDavURL(link)); | ||||
|  | @ -147,7 +149,7 @@ listing.rename = function(event) { | |||
|                     }); | ||||
|                 } | ||||
| 
 | ||||
|                 buttons.rename.changeToDone((request.status != 201 && request.status != 204), html); | ||||
|                 buttons.rename.querySelector('i').changeToDone((request.status != 201 && request.status != 204), html); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -169,7 +171,7 @@ listing.rename = function(event) { | |||
| 
 | ||||
| listing.handleFiles = function(files, base) { | ||||
|     let button = document.getElementById("upload"), | ||||
|         html = button.changeToLoading(); | ||||
|         html = button.querySelector('i').changeToLoading(); | ||||
| 
 | ||||
|     for (let i = 0; i < files.length; i++) { | ||||
|         let request = new XMLHttpRequest(); | ||||
|  | @ -182,7 +184,7 @@ listing.handleFiles = function(files, base) { | |||
|                     listing.reload(); | ||||
|                 } | ||||
| 
 | ||||
|                 button.changeToDone((request.status != 201), html); | ||||
|                 button.querySelector('i').changeToDone((request.status != 201), html); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -222,7 +224,7 @@ listing.handleSelectionChange = function(event) { | |||
|             } else { | ||||
|                 buttons.open.classList.remove("disabled"); | ||||
|             } | ||||
|              | ||||
| 
 | ||||
|             buttons.rename.classList.remove("disabled"); | ||||
|         } | ||||
| 
 | ||||
|  | @ -259,7 +261,7 @@ listing.selectItem = function(event) { | |||
| 
 | ||||
|     if (selectedItems.length != 0) event.preventDefault(); | ||||
|     if (selectedItems.indexOf(el.id) == -1) { | ||||
|         if (!event.ctrlKey) listing.unselectAll(); | ||||
|         if (!event.ctrlKey && !listing.selectMultiple) listing.unselectAll(); | ||||
| 
 | ||||
|         el.setAttribute("aria-selected", true); | ||||
|         selectedItems.push(el.id); | ||||
|  | @ -290,7 +292,7 @@ listing.newFilePrompt = function(event) { | |||
|     event.preventDefault(); | ||||
| 
 | ||||
|     let button = document.getElementById('new'), | ||||
|         html = button.changeToLoading(), | ||||
|         html = button.querySelector('i').changeToLoading(), | ||||
|         request = new XMLHttpRequest(), | ||||
|         name = event.currentTarget.querySelector('input').value; | ||||
| 
 | ||||
|  | @ -298,7 +300,7 @@ listing.newFilePrompt = function(event) { | |||
|     request.send(); | ||||
|     request.onreadystatechange = function() { | ||||
|         if (request.readyState == 4) { | ||||
|             button.changeToDone((request.status != 201), html); | ||||
|             button.querySelector('i').changeToDone((request.status != 201), html); | ||||
|             listing.reload(); | ||||
|         } | ||||
|     } | ||||
|  | @ -322,13 +324,12 @@ window.addEventListener('keydown', (event) => { | |||
|         if (document.querySelectorAll('.prompt').length) { | ||||
|             closePrompt(event); | ||||
|         } | ||||
|          | ||||
|     } | ||||
| 
 | ||||
|     if (event.keyCode == 113) { | ||||
|         listing.rename(); | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     if (event.ctrlKey || event.metaKey) { | ||||
|         console.log("hey") | ||||
|         switch (String.fromCharCode(event.which).toLowerCase()) { | ||||
|  | @ -351,9 +352,26 @@ document.addEventListener('DOMContentLoaded', event => { | |||
|     buttons.new = document.getElementById('new'); | ||||
|     buttons.download = document.getElementById('download'); | ||||
| 
 | ||||
|     document.getElementById('multiple-selection-activate').addEventListener('click', event => { | ||||
|         listing.selectMultiple = true; | ||||
|         clickOverlay.click(); | ||||
|          | ||||
|         document.getElementById('multiple-selection').classList.add('active'); | ||||
|         document.querySelector('body').style.paddingBottom = "4em"; | ||||
|     }) | ||||
| 
 | ||||
|     document.getElementById('multiple-selection-cancel').addEventListener('click', event => { | ||||
|         listing.selectMultiple = false; | ||||
| 
 | ||||
|         document.querySelector('body').style.paddingBottom = "0"; | ||||
|         document.getElementById('multiple-selection').classList.remove('active'); | ||||
|     }) | ||||
| 
 | ||||
|     if (user.AllowEdit) { | ||||
|         buttons.rename.addEventListener("click", listing.rename); | ||||
|     } | ||||
|      | ||||
|     let items = document.getElementsByClassName('item'); | ||||
| 
 | ||||
|     if (user.AllowNew) { | ||||
|         buttons.upload.addEventListener("click", (event) => { | ||||
|  | @ -363,7 +381,6 @@ document.addEventListener('DOMContentLoaded', event => { | |||
|         buttons.new.addEventListener('click', listing.newFileButton); | ||||
| 
 | ||||
|         // Drag and Drop
 | ||||
|         let items = document.getElementsByClassName('item'); | ||||
|         document.addEventListener("dragover", function(event) { | ||||
|             event.preventDefault(); | ||||
|         }, false); | ||||
|  | @ -382,4 +399,26 @@ document.addEventListener('DOMContentLoaded', event => { | |||
| 
 | ||||
|         document.addEventListener("drop", listing.documentDrop, false); | ||||
|     } | ||||
|      | ||||
|     let touches = { | ||||
|         id: '', | ||||
|         count: 0 | ||||
|     }; | ||||
|      | ||||
|     Array.from(items).forEach(file => { | ||||
|         file.addEventListener('touchstart', event => { | ||||
|             if (touches.id != file.id) { | ||||
|                 touches.id = file.id; | ||||
|                 touches.count = 1; | ||||
|                  | ||||
|                 return; | ||||
|             } | ||||
|              | ||||
|             touches.count++; | ||||
|              | ||||
|             if (touches.count > 1) { | ||||
|                 window.location = file.dataset.url; | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
|  | @ -3,7 +3,7 @@ | |||
| {{ $absURL := .Config.AbsoluteURL }} | ||||
| <head> | ||||
|     <title>{{.Name}}</title> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"> | ||||
|     <meta charset="utf-8"> | ||||
|     <meta name="token" content="{{ .Token  }}"> | ||||
|     <link rel="stylesheet" href="{{ .Config.AbsoluteURL }}/_filemanagerinternal/css/normalize.css"> | ||||
|  | @ -47,69 +47,81 @@ | |||
|          | ||||
|         <div id="bottom-bar"> | ||||
|             <div> | ||||
|                 {{- if ne .Name "/"}} | ||||
|                 <p id="breadcrumbs-button">Previous</p> | ||||
|                 <ul id="breadcrumbs"> | ||||
|                 {{- if ne .Name "/"}}                 | ||||
|                 <div class="action" id="previous"> | ||||
|                     <i class="material-icons">subdirectory_arrow_left</i> | ||||
|                 </div> | ||||
| 
 | ||||
|                 <ul class="dropdown" id="breadcrumbs"> | ||||
|                 {{- range $item := .BreadcrumbMap }} | ||||
|                 <a href="{{ $absURL }}{{ $item.URL }}"><li>{{ $item.Name }}</li></a> | ||||
|                 {{- end }} | ||||
|                 </ul><i class="material-icons">keyboard_arrow_right</i> | ||||
|                 </ul> | ||||
|                 {{- end }} | ||||
|                 <p id="current-file">{{ if ne .Name "/"}}{{ .Name }}{{ else }}Root{{ end }}</p> | ||||
|                  | ||||
|                 <p>{{ if ne .Name "/"}}{{ .Name }}{{ else }}Root{{ end }}</p> | ||||
|             </div> | ||||
|              | ||||
|             <div class="actions"> | ||||
|                 <div id="file-only" {{ if .IsDir }}class="disabled"{{ end }}> | ||||
|                     {{- if and (not .IsDir) (.User.AllowEdit) }} | ||||
|                     {{- if .Editor}} | ||||
|                     {{- if eq .Data.Mode "markdown" }} | ||||
|                     <div class="action" id="preview" onclick="notImplemented(event);"> | ||||
|                         <i class="material-icons">remove_red_eye</i> | ||||
|                     </div> | ||||
|                     {{- end }} | ||||
|                     {{- end }} | ||||
|                      | ||||
|                     <div class="action" id="save"> | ||||
|                         <i class="material-icons" title="Save">save</i> | ||||
|                     </div> | ||||
|                     {{- end }} | ||||
|                      | ||||
|                     <div class="action" id="open"> | ||||
|                         <i class="material-icons" title="See raw">open_in_new</i> | ||||
|                     </div> | ||||
|                      | ||||
|                     {{- if and .IsDir .User.AllowEdit }} | ||||
|                     <div class="action" id="rename"> | ||||
|                         <i class="material-icons" title="Edit">mode_edit</i> | ||||
|                     </div> | ||||
|                     {{- end }} | ||||
|             <div class="action mobile-only" id="more"> | ||||
|                 <i class="material-icons">more_vert</i> | ||||
|             </div> | ||||
|              | ||||
|             <div class="actions{{ if .IsDir }} disabled{{ end }}" id="file-only"> | ||||
|                 {{- if and (not .IsDir) (.User.AllowEdit) }} | ||||
|                 {{- if .Editor}} | ||||
|                 {{- if eq .Data.Mode "markdown" }} | ||||
|                 <div class="action" id="preview" onclick="notImplemented(event);"> | ||||
|                     <i class="material-icons">remove_red_eye</i> | ||||
|                 </div> | ||||
|                 {{- end }} | ||||
|                 {{- end }} | ||||
|                  | ||||
|                     {{- if .User.AllowEdit }} | ||||
|                     <div class="action" id="delete"> | ||||
|                         <i class="material-icons" title="Delete">delete</i> <span>Delete</span> | ||||
|                     </div> | ||||
|                     {{- end }} | ||||
|                 <div class="action" id="save"> | ||||
|                     <i class="material-icons" title="Save">save</i> | ||||
|                 </div> | ||||
|                 {{- end }} | ||||
|                  | ||||
|                 <div class="action" id="open"> | ||||
|                     <i class="material-icons" title="See raw">open_in_new</i> | ||||
|                 </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> | ||||
|              | ||||
|             <div class="actions" id="main-actions">                 | ||||
|                 {{- if .IsDir }} | ||||
|                 <div class="action" id="view"> | ||||
|                     {{- if eq .Display "mosaic" }} | ||||
|                         <a href="?display=list"><i class="material-icons" title="Switch View">view_list</i></a> | ||||
|                         <a href="?display=list"><i class="material-icons" title="Switch View">view_list</i><span>Switch view</span></a> | ||||
|                     {{- else }}  | ||||
|                         <a href="?display=mosaic"><i class="material-icons" title="Switch View">view_module</i></a> | ||||
|                         <a href="?display=mosaic"><i class="material-icons" title="Switch View">view_module</i><span>Switch view</span></a> | ||||
|                     {{- end }} | ||||
|                 </div> | ||||
|                  | ||||
|                 <div class="action mobile-only" id="multiple-selection-activate"> | ||||
|                     <i class="material-icons">check_circle</i><span>Select</span> | ||||
|                 </div> | ||||
|                 {{- end }} | ||||
|                  | ||||
|                 {{- if and (.User.AllowNew) (.IsDir) }} | ||||
|                 <div class="action" id="upload"> | ||||
|                     <i class="material-icons" title="Upload">file_upload</i> <span>Upload</span> | ||||
|                     <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> | ||||
|                         <i class="material-icons" title="Download">file_download</i><span>Download</span> | ||||
|                     </a> | ||||
|                     {{- if .IsDir }} | ||||
|                     <ul class="prev-links"> | ||||
|  | @ -122,12 +134,21 @@ | |||
|                 </div> | ||||
|                  | ||||
|                 <div class="action" id="info" onclick="notImplemented(event);"> | ||||
|                     <i class="material-icons" title="Info">info</i> | ||||
|                     <i class="material-icons" title="Info">info</i><span>Info</span> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|          | ||||
|         <div id="click-overlay"></div> | ||||
|     </header>     | ||||
| 
 | ||||
|      | ||||
|     <div id="multiple-selection" class="mobile-only"> | ||||
|         <p>Multiple selection enabled</p> | ||||
|         <div class="action" id="multiple-selection-cancel"> | ||||
|             <i class="material-icons" title="Clear">clear</i> | ||||
|         </div> | ||||
|     </div> | ||||
|      | ||||
|     <main> | ||||
|         {{- template "content" . }} | ||||
|     </main> | ||||
|  |  | |||
|  | @ -36,7 +36,7 @@ | |||
|     <h2>Folders</h2> | ||||
|     <div> | ||||
|     {{- range .Items }} | ||||
|         {{- if and (.UserAllowed) (.IsDir) }} | ||||
|         {{- if (.IsDir) }} | ||||
|         {{ template "item" .}} | ||||
|         {{- end }} | ||||
|     {{- end }} | ||||
|  | @ -47,7 +47,7 @@ | |||
|     <h2>Files</h2> | ||||
|     <div> | ||||
|     {{- range .Items }} | ||||
|         {{- if and (.UserAllowed) (not .IsDir) }} | ||||
|         {{- if (not .IsDir) }} | ||||
|         {{ template "item" .}} | ||||
|         {{- end }} | ||||
|     {{- end }} | ||||
|  | @ -55,7 +55,7 @@ | |||
|     {{- end }} | ||||
| </div> | ||||
| 
 | ||||
| <input style="display:none" type="file" id="upload-input" onchange="handleFiles(this.files, '')" value="Upload" multiple> | ||||
| <input style="display:none" type="file" id="upload-input" onchange="listing.handleFiles(this.files, '')" value="Upload" multiple> | ||||
| {{- end -}} | ||||
| {{- end -}} | ||||
| 
 | ||||
|  |  | |||
|  | @ -57,6 +57,11 @@ func GetListing(u *config.User, filePath string, baseURL string) (*Listing, erro | |||
| 
 | ||||
| 	for _, f := range files { | ||||
| 		name := f.Name() | ||||
| 		allowed := u.Allowed("/" + name) | ||||
| 
 | ||||
| 		if !allowed { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		if f.IsDir() { | ||||
| 			name += "/" | ||||
|  | @ -71,7 +76,7 @@ func GetListing(u *config.User, filePath string, baseURL string) (*Listing, erro | |||
| 		i := Info{ | ||||
| 			FileInfo:    f, | ||||
| 			URL:         url.String(), | ||||
| 			UserAllowed: u.Allowed("/" + name), | ||||
| 			UserAllowed: allowed, | ||||
| 		} | ||||
| 		i.RetrieveFileType() | ||||
| 
 | ||||
|  |  | |||
|  | @ -10,6 +10,8 @@ const errTemplate = `<!DOCTYPE html> | |||
| <html> | ||||
| <head> | ||||
|     <title>TITLE</title> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||
|     <meta charset="utf-8"> | ||||
|     <style> | ||||
|     html { | ||||
|         background-color: #2196f3; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Henrique Dias
						Henrique Dias