diff --git a/res/include/script/file_manager/DirectoryElement.js b/res/include/script/file_manager/DirectoryElement.js index 9efbe53..3d9080d 100644 --- a/res/include/script/file_manager/DirectoryElement.js +++ b/res/include/script/file_manager/DirectoryElement.js @@ -28,10 +28,10 @@ function DirectoryElement(directoryArea, footer) { this.fieldDateWidth = "160px" this.fieldSizeWidth = "90px" this.fieldTypeWidth = "200px" - makeSortButton("name", "Name", "") + makeSortButton("name", "Name", "") makeSortButton("dateCreated", "Creation Date", this.fieldDateWidth) - makeSortButton("size", "Size", this.fieldSizeWidth) - makeSortButton("type", "Type", this.fieldTypeWidth) + makeSortButton("size", "Size", this.fieldSizeWidth) + makeSortButton("type", "Type", this.fieldTypeWidth) // Scroll event for rendering new file nodes when they become visible @@ -55,21 +55,21 @@ function DirectoryElement(directoryArea, footer) { // rendering the file list correctly // type: {icon, name, href, type, size, sizeLabel, dateCreated, selected} - this.allFiles = [] + this.allFiles = [] // This array contains indexes referring to places in the allFiles array this.visibleFiles = [] this.lastSearchTerm = "" - this.lastScrollTop = 0 + this.lastScrollTop = 0 } -DirectoryElement.prototype.reset = function() { +DirectoryElement.prototype.reset = function () { this.allFiles = [] this.visibleFiles = [] } -DirectoryElement.prototype.addFile = function(icon, name, href, type, size, sizeLabel, dateCreated) { +DirectoryElement.prototype.addFile = function (icon, name, href, type, size, sizeLabel, dateCreated) { this.allFiles.push({ icon: icon, name: name, @@ -82,14 +82,14 @@ DirectoryElement.prototype.addFile = function(icon, name, href, type, size, size }) } -DirectoryElement.prototype.renderFiles = function() { +DirectoryElement.prototype.renderFiles = function () { this.search(this.lastSearchTerm) } // search filters the allFiles array on a search term. All files which match the // search term will be put into visibleFiles. The visibleFiles array will then // be rendered by renderVisibleFiles -DirectoryElement.prototype.search = function(term) { +DirectoryElement.prototype.search = function (term) { term = term.toLowerCase() this.lastSearchTerm = term this.visibleFiles = [] @@ -124,7 +124,7 @@ DirectoryElement.prototype.search = function(term) { } // searchSubmit opens the first file in the search results -DirectoryElement.prototype.searchSubmit = function() { +DirectoryElement.prototype.searchSubmit = function () { if (this.visibleFiles.length === 0) { return // There are no files visible } @@ -132,7 +132,7 @@ DirectoryElement.prototype.searchSubmit = function() { window.location = this.getVisibleFile(0).href } -DirectoryElement.prototype.sortBy = function(field) { +DirectoryElement.prototype.sortBy = function (field) { if (field === "") { // If no sort field is provided we use the last used sort field field = this.currentSortField @@ -158,9 +158,9 @@ DirectoryElement.prototype.sortBy = function(field) { // Then prepend the arrow to the current sort label if (this.currentSortAscending) { - this.sortButtons[field].innerText = "▼ "+this.sortButtons[field].innerText + this.sortButtons[field].innerText = "▼ " + this.sortButtons[field].innerText } else { - this.sortButtons[field].innerText = "▲ "+this.sortButtons[field].innerText + this.sortButtons[field].innerText = "▲ " + this.sortButtons[field].innerText } let fieldA, fieldB @@ -168,7 +168,7 @@ DirectoryElement.prototype.sortBy = function(field) { fieldA = this.allFiles[a][this.currentSortField] fieldB = this.allFiles[b][this.currentSortField] - if (typeof(fieldA) === "number") { + if (typeof (fieldA) === "number") { if (this.currentSortAscending) { return fieldA - fieldB } else { @@ -185,7 +185,7 @@ DirectoryElement.prototype.sortBy = function(field) { this.renderVisibleFiles(true) } -DirectoryElement.prototype.createFileButton = function(file, index) { +DirectoryElement.prototype.createFileButton = function (file, index) { let el = document.createElement("a") el.classList = "node" el.href = file.href @@ -235,38 +235,38 @@ DirectoryElement.prototype.createFileButton = function(file, index) { // This function dereferences an index in the visibleFiles array to a real file // in the allFiles array. The notation is a bit confusing so the separate // function is just for clarity -DirectoryElement.prototype.getVisibleFile = function(index) { +DirectoryElement.prototype.getVisibleFile = function (index) { return this.allFiles[this.visibleFiles[index]] } -DirectoryElement.prototype.renderVisibleFiles = function(freshStart) { +DirectoryElement.prototype.renderVisibleFiles = function (freshStart) { let scrollDown = this.lastScrollTop <= this.directoryArea.scrollTop this.lastScrollTop = this.directoryArea.scrollTop - let fileHeight = 40 - let totalHeight = (this.visibleFiles.length * fileHeight) + let fileHeight = 40 + let totalHeight = (this.visibleFiles.length * fileHeight) let viewportHeight = this.directoryArea.clientHeight if (freshStart) { this.dirContainer.innerHTML = "" - this.dirContainer.style.height = totalHeight+"px" + this.dirContainer.style.height = totalHeight + "px" scrollDown = true let totalSize = 0 for (let i in this.visibleFiles) { totalSize += this.getVisibleFile(i).size } - this.footer.innerText = this.visibleFiles.length+" items. Total size: "+formatDataVolume(totalSize, 4) + this.footer.innerText = this.visibleFiles.length + " items. Total size: " + formatDataVolume(totalSize, 4) } - let paddingTop = this.lastScrollTop - this.lastScrollTop%fileHeight - let start = Math.floor(paddingTop/fileHeight) - 5 + let paddingTop = this.lastScrollTop - this.lastScrollTop % fileHeight + let start = Math.floor(paddingTop / fileHeight) - 5 if (start < 0) { start = 0 } - let end = Math.ceil((paddingTop+viewportHeight)/fileHeight) + 5 - if (end > this.visibleFiles.length) { end = this.visibleFiles.length-1 } + let end = Math.ceil((paddingTop + viewportHeight) / fileHeight) + 5 + if (end > this.visibleFiles.length) { end = this.visibleFiles.length - 1 } - this.dirContainer.style.paddingTop = (start*fileHeight)+"px" + this.dirContainer.style.paddingTop = (start * fileHeight) + "px" // Remove the elements which are out of bounds let firstEl @@ -274,31 +274,31 @@ DirectoryElement.prototype.renderVisibleFiles = function(freshStart) { let lastEl let lastIdx = -1 while (!freshStart) { - firstEl = this.dirContainer.firstElementChild + firstEl = this.dirContainer.firstElementChild if (firstEl === null) { break } firstIdx = Number.parseInt(firstEl.getAttribute("fileindex")) - lastEl = this.dirContainer.lastElementChild - lastIdx = Number.parseInt(lastEl.getAttribute("fileindex")) + lastEl = this.dirContainer.lastElementChild + lastIdx = Number.parseInt(lastEl.getAttribute("fileindex")) if (firstIdx < start) { this.dirContainer.removeChild(firstEl) - console.debug("Remove start "+firstIdx) + console.debug("Remove start " + firstIdx) } else if (lastIdx > end) { this.dirContainer.removeChild(lastEl) - console.debug("Remove end "+lastIdx) + console.debug("Remove end " + lastIdx) } else { break } } console.debug( - "start "+start+ - " end "+end+ - " firstIdx "+firstIdx+ - " lastIdx "+lastIdx+ - " freshStart "+freshStart+ - " scrollDown "+scrollDown+ - " children "+this.dirContainer.childElementCount + "start " + start + + " end " + end + + " firstIdx " + firstIdx + + " lastIdx " + lastIdx + + " freshStart " + freshStart + + " scrollDown " + scrollDown + + " children " + this.dirContainer.childElementCount ) // Then add the elements which have become visible. When the user scrolls @@ -311,7 +311,7 @@ DirectoryElement.prototype.renderVisibleFiles = function(freshStart) { continue } this.dirContainer.append(this.createFileButton(this.getVisibleFile(i), i)) - console.debug("Append "+i); + console.debug("Append " + i); } } else { for (let i = end; i >= start; i--) { @@ -319,7 +319,7 @@ DirectoryElement.prototype.renderVisibleFiles = function(freshStart) { continue } this.dirContainer.prepend(this.createFileButton(this.getVisibleFile(i), i)) - console.debug("Prepend "+i); + console.debug("Prepend " + i); } } } diff --git a/res/include/script/file_manager/DirectoryNode.js b/res/include/script/file_manager/DirectoryNode.js deleted file mode 100644 index 0933a91..0000000 --- a/res/include/script/file_manager/DirectoryNode.js +++ /dev/null @@ -1,99 +0,0 @@ - -function DirectoryNode(file, index) { - this.el = document.createElement("div") - this.el.classList = "node" - if (file.selected) { - this.el.classList += " node_selected" - } - this.el.href = file.href - this.el.target = "_blank" - this.el.title = file.name - this.el.setAttribute("fileindex", index) - - this.el.addEventListener("click", e => { - if (e.detail > 1) { - return // Prevent dblclick from triggering click - } - if (e.which == 2) { - // Middle mouse button opens the file in a new window - this.open(true) - return - } - this.select() - }) - this.el.addEventListener("tap") - this.el.addEventListener("dblclick", e => { - this.open(false) - }) - - { - let cell = document.createElement("div") - let thumb = document.createElement("img") - thumb.src = file.icon - cell.appendChild(thumb) - let label = document.createElement("span") - label.innerText = file.name - cell.appendChild(label) - cell.appendChild(label) - this.el.appendChild(cell) - } - { - let cell = document.createElement("div") - cell.style.width = this.fieldDateWidth - let label = document.createElement("span") - label.innerText = printDate(new Date(file.dateCreated), true, true, false) - cell.appendChild(label) - this.el.appendChild(cell) - } - { - let cell = document.createElement("div") - cell.style.width = this.fieldSizeWidth - let label = document.createElement("span") - label.innerText = file.sizeLabel - cell.appendChild(label) - this.el.appendChild(cell) - } - { - let cell = document.createElement("div") - cell.style.width = this.fieldTypeWidth - let label = document.createElement("span") - label.innerText = file.type - cell.appendChild(label) - this.el.appendChild(cell) - } - - return this.el -} - -DirectoryNode.prototype.select = function() { - if (this.el.classList.contains("node_selected")) { - this.el.classList = "node" - file.selected = false - } else { - this.el.classList = "node node_selected" - file.selected = true - } -} -DirectoryNode.prototype.open = function(newTab) { - if (newTab) { - window.open(file.href, "_blank") - } else { - window.open(file.href) - } -} -DirectoryNode.prototype.click = function(e) { - if (e.detail > 1) { - return // Prevent dblclick from triggering click - } - if (e.which == 2) { - // Middle mouse button opens the file in a new window - e.preventDefault() - window.open(file.href, "_blank") - return - } - - -} -DirectoryNode.prototype.doubleClick = function() { - window.open(file.href) -} diff --git a/res/include/script/file_manager/FileManager.js b/res/include/script/file_manager/FileManager.js index ecc13a1..24695c5 100644 --- a/res/include/script/file_manager/FileManager.js +++ b/res/include/script/file_manager/FileManager.js @@ -1,14 +1,14 @@ function FileManager(windowElement) { - this.window = windowElement - this.navBar = this.window.querySelector("#nav_bar") - this.btnMenu = this.navBar.querySelector("#btn_menu") - this.btnBack = this.navBar.querySelector("#btn_back") - this.btnUp = this.navBar.querySelector("#btn_up") - this.btnForward = this.navBar.querySelector("#btn_forward") - this.btnHome = this.navBar.querySelector("#btn_home") - this.breadcrumbs = this.navBar.querySelector("#breadcrumbs") - this.btnReload = this.navBar.querySelector("#btn_reload") - this.inputSearch = this.navBar.querySelector("#input_search") + this.window = windowElement + this.navBar = this.window.querySelector("#nav_bar") + this.btnMenu = this.navBar.querySelector("#btn_menu") + this.btnBack = this.navBar.querySelector("#btn_back") + this.btnUp = this.navBar.querySelector("#btn_up") + this.btnForward = this.navBar.querySelector("#btn_forward") + this.btnHome = this.navBar.querySelector("#btn_home") + this.breadcrumbs = this.navBar.querySelector("#breadcrumbs") + this.btnReload = this.navBar.querySelector("#btn_reload") + this.inputSearch = this.navBar.querySelector("#input_search") // Register keyboard shortcuts document.addEventListener("keydown", e => { this.keyboardEvent(e) }) @@ -34,13 +34,13 @@ function FileManager(windowElement) { ) } -FileManager.prototype.setSpinner = function() { +FileManager.prototype.setSpinner = function () { this.window.appendChild(document.getElementById("tpl_spinner").content.cloneNode(true)) } -FileManager.prototype.delSpinner = function() { +FileManager.prototype.delSpinner = function () { for (let i in this.window.children) { if ( - typeof(this.window.children[i].classList) === "object" && + typeof (this.window.children[i].classList) === "object" && this.window.children[i].classList.contains("spinner") ) { this.window.children[i].remove() @@ -48,24 +48,20 @@ FileManager.prototype.delSpinner = function() { } } -FileManager.prototype.getDirectory = function(path) { - console.log("ayy!") -} - -FileManager.prototype.getUserFiles = function() { +FileManager.prototype.getUserFiles = function () { this.setSpinner() let getAll = (page) => { let numFiles = 1000 - fetch(apiEndpoint+"/user/files?page="+page+"&limit="+numFiles).then(resp => { + fetch(apiEndpoint + "/user/files?page=" + page + "&limit=" + numFiles).then(resp => { if (!resp.ok) { Promise.reject("yo") } return resp.json() }).then(resp => { for (let i in resp.files) { this.directoryElement.addFile( - apiEndpoint+"/file/"+resp.files[i].id+"/thumbnail?width=32&height=32", + apiEndpoint + "/file/" + resp.files[i].id + "/thumbnail?width=32&height=32", resp.files[i].name, - "/u/"+resp.files[i].id, + "/u/" + resp.files[i].id, resp.files[i].mime_type, resp.files[i].size, formatDataVolume(resp.files[i].size, 4), @@ -76,7 +72,7 @@ FileManager.prototype.getUserFiles = function() { this.directoryElement.renderFiles() if (resp.files.length === numFiles) { - getAll(page+1) + getAll(page + 1) } else { // Less than the maximum number of results means we're done // loading, we can remove the loading spinner @@ -84,7 +80,7 @@ FileManager.prototype.getUserFiles = function() { } }).catch((err) => { this.delSpinner() - throw(err) + throw (err) }) } @@ -92,22 +88,22 @@ FileManager.prototype.getUserFiles = function() { getAll(0) } -FileManager.prototype.getUserLists = function() { +FileManager.prototype.getUserLists = function () { this.setSpinner() this.directoryElement.reset() - fetch(apiEndpoint+"/user/lists").then(resp => { + fetch(apiEndpoint + "/user/lists").then(resp => { if (!resp.ok) { Promise.reject("yo") } return resp.json() }).then(resp => { for (let i in resp.lists) { this.directoryElement.addFile( - apiEndpoint+"/list/"+resp.lists[i].id+"/thumbnail?width=32&height=32", + apiEndpoint + "/list/" + resp.lists[i].id + "/thumbnail?width=32&height=32", resp.lists[i].title, - "/l/"+resp.lists[i].id, + "/l/" + resp.lists[i].id, "list", resp.lists[i].file_count, - resp.lists[i].file_count+" files", + resp.lists[i].file_count + " files", resp.lists[i].date_created, ) } @@ -116,12 +112,12 @@ FileManager.prototype.getUserLists = function() { this.delSpinner() }).catch((err) => { this.delSpinner() - throw(err) + throw (err) }) } -FileManager.prototype.keyboardEvent = function(e) { - console.log("Pressed: "+e.keyCode) +FileManager.prototype.keyboardEvent = function (e) { + console.log("Pressed: " + e.keyCode) // CTRL + F or "/" opens the search bar if (e.ctrlKey && e.keyCode === 70 || !e.ctrlKey && e.keyCode === 191) { diff --git a/res/template/account/file_manager_svelte.html b/res/template/account/file_manager_svelte.html new file mode 100644 index 0000000..65af86d --- /dev/null +++ b/res/template/account/file_manager_svelte.html @@ -0,0 +1,21 @@ +{{define "file_manager_svelte"}} + + + {{template "meta_tags" "File Manager"}} + {{template "user_style" .}} + + + + + + + + + {{template "page_menu" .}} +
+ {{template "analytics"}} + + +{{end}} diff --git a/res/template/file_viewer_svelte.html b/res/template/file_viewer_svelte.html new file mode 100644 index 0000000..fd59834 --- /dev/null +++ b/res/template/file_viewer_svelte.html @@ -0,0 +1,35 @@ +{{define "file_viewer_svelte"}} + + + + {{.Title}} + + + {{ template "opengraph" .OGData }} + + {{ template "user_style" . }} + + + + + + + + + + + + + + + + + + + + + +{{end}} diff --git a/svelte/rollup.config.js b/svelte/rollup.config.js index 1e110a4..d8087e2 100644 --- a/svelte/rollup.config.js +++ b/svelte/rollup.config.js @@ -29,9 +29,11 @@ function serve() { const builddir = "../res/static/svelte" export default [ + "file_viewer", "filesystem", "modal", "user_buckets", + "user_file_manager", "admin_abuse_reporters", "admin_abuse_reports", ].map((name, index) => ({ diff --git a/svelte/src/user_file_manager.js b/svelte/src/user_file_manager.js new file mode 100644 index 0000000..e02f8a9 --- /dev/null +++ b/svelte/src/user_file_manager.js @@ -0,0 +1,8 @@ +import App from './user_file_manager/FileManager.svelte'; + +const app = new App({ + target: document.getElementById("page_body"), + props: {} +}); + +export default app; diff --git a/svelte/src/user_file_manager/DirectoryElement.svelte b/svelte/src/user_file_manager/DirectoryElement.svelte new file mode 100644 index 0000000..d736cd6 --- /dev/null +++ b/svelte/src/user_file_manager/DirectoryElement.svelte @@ -0,0 +1,360 @@ + + +
+
+
+ {#each tableColumns as col} +
{col.name}
+ {/each} +
+
+ {#each allFiles as file} + {#if file.visible && !file.filtered} + +
+ file thumbnail + {file.name} +
+
+ {formatDate(new Date(file.dateCreated), true, true, false)} +
+
+ {file.sizeLabel} +
+
+ {file.type} +
+
+ {/if} + {/each} +
+
+ +
+ + diff --git a/svelte/src/user_file_manager/FileManager.svelte b/svelte/src/user_file_manager/FileManager.svelte new file mode 100644 index 0000000..5ed6a10 --- /dev/null +++ b/svelte/src/user_file_manager/FileManager.svelte @@ -0,0 +1,196 @@ + + + + +
+ + + + {#if loading} +
+ +
+ {/if} + +
+ +