more file manager progress

This commit is contained in:
2020-01-30 22:55:32 +01:00
parent 5d59b52f1e
commit 047169e080
2 changed files with 190 additions and 49 deletions

View File

@@ -1,16 +1,39 @@
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.directoryArea = this.window.querySelector("#directory_area");
this.directoryFooter = this.window.querySelector("#directory_footer");
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.directorySorters = this.window.querySelector("#directory_sorters");
this.directoryArea = this.window.querySelector("#directory_area");
this.directoryFooter = this.window.querySelector("#directory_footer");
// Sorters
this.currentSortField = "";
this.currentSortAscending = true;
this.btnSortName = document.createElement("div");
this.btnSortName.innerText = "Name";
this.btnSortName.addEventListener("click", () => { this.sortBy("name"); });
this.directorySorters.appendChild(this.btnSortName);
this.btnSortType = document.createElement("div");
this.btnSortType.innerText = "Type";
this.btnSortType.addEventListener("click", () => { this.sortBy("type"); });
this.directorySorters.appendChild(this.btnSortType);
this.btnSortSize = document.createElement("div");
this.btnSortSize.innerText = "Size";
this.btnSortSize.addEventListener("click", () => { this.sortBy("size"); });
this.directorySorters.appendChild(this.btnSortSize);
// Buttons
this.btnReload.addEventListener("click", () => { this.getUserFiles(); })
this.dirContainer = document.createElement("div");
this.directoryArea.appendChild(this.dirContainer);
@@ -22,12 +45,27 @@ function FileManager(windowElement) {
this.renderVisibleFiles(this.visibleFiles, false);
})
// type: {icon, name, href, type, size}
this.allFiles = [];
this.visibleFiles = [];
this.lastScrollTop = 0;
}
FileManager.prototype.setSpinner = function() {
this.window.appendChild(document.getElementById("tpl_spinner").content.cloneNode(true));
}
FileManager.prototype.delSpinner = function() {
for (let i in this.window.children) {
if (
typeof(this.window.children[i].classList) === "object" &&
this.window.children[i].classList.contains("spinner")
) {
this.window.children[i].remove();
}
}
}
FileManager.prototype.search = function(term) {
if (term === "") {
this.visibleFiles = this.allFiles;
@@ -51,28 +89,36 @@ FileManager.prototype.getDirectory = function(path) {
}
FileManager.prototype.getUserFiles = function() {
this.setSpinner();
let getAll = (page) => {
fetch(apiEndpoint+"/user/files?page="+page+"&limit=10000").then(resp => {
if (!resp.ok) {Promise.reject("yo");}
return resp.json();
}).then(resp => {
if (page === 0) {
this.allFiles = resp.files;
} else {
this.allFiles = this.allFiles.concat(resp.files);
for (let i in resp.files) {
this.allFiles.push({
icon: apiEndpoint+"/file/"+resp.files[i].id+"/thumbnail?width=32&height=32",
name: resp.files[i].name,
href: "/u/"+resp.files[i].id,
type: resp.files[i].mime_type,
size: resp.files[i].size
})
}
this.allFiles.sort((a, b) => {
return a.name.localeCompare(b.name);
});
this.visibleFiles = this.allFiles;
this.renderVisibleFiles(this.visibleFiles, true);
this.currentSortField = "";
this.sortBy("name");
if (resp.files.length === 10000) {
getAll(page+1);
} else {
// Less than 10000 results means we're done loading, we can
// remove the loading spinner
this.delSpinner();
}
}).catch((err) => {
this.delSpinner();
console.log("Req failed:" + err);
})
}
@@ -80,9 +126,77 @@ FileManager.prototype.getUserFiles = function() {
getAll(0);
}
FileManager.prototype.getUserLists = function() {
this.setSpinner();
let getAll = (page) => {
fetch(apiEndpoint+"/user/lists?page="+page+"&limit=10000").then(resp => {
if (!resp.ok) {Promise.reject("yo");}
return resp.json();
}).then(resp => {
for (let i in resp.lists) {
this.allFiles.push({
icon: apiEndpoint+"/list/"+resp.lists[i].id+"/thumbnail?width=32&height=32",
name: resp.lists[i].title,
href: "/l/"+resp.lists[i].id,
type: "list",
size: 0
})
}
this.visibleFiles = this.allFiles;
this.currentSortField = "";
this.sortBy("name");
if (resp.lists.length === 10000) {
getAll(page+1);
} else {
// Less than 10000 results means we're done loading, we can
// remove the loading spinner
this.delSpinner();
}
}).catch((err) => {
this.delSpinner();
console.log("Req failed:" + err);
})
}
getAll(0);
}
FileManager.prototype.sortBy = function(field) {
if (this.currentSortField !== field) {
this.currentSortAscending = true;
this.currentSortField = field;
} else if (this.currentSortField === field) {
this.currentSortAscending = !this.currentSortAscending;
}
this.visibleFiles.sort((a, b) => {
if (this.currentSortAscending) {
return a[field].localeCompare(b[field]);
} else {
return b[field].localeCompare(a[field]);
}
});
this.renderVisibleFiles(this.visibleFiles, true);
}
FileManager.prototype.renderVisibleFiles = function(files, freshStart) {
let scrollDown = this.lastScrollTop <= this.directoryArea.scrollTop;
this.lastScrollTop = this.directoryArea.scrollTop;
let fileMargin = 4;
let fileHeight = 32 + fileMargin;
let totalHeight = (files.length * fileHeight);
let viewportHeight = this.directoryArea.clientHeight;
if (freshStart) {
this.dirContainer.innerHTML = "";
this.dirContainer.style.height = totalHeight+"px";
this.dirContainer.scrollTop = 0;
this.lastScrollTop = 0;
scrollDown = true;
let totalSize = 0;
for (let i in files) {
@@ -95,25 +209,15 @@ FileManager.prototype.renderVisibleFiles = function(files, freshStart) {
+formatDataVolume(totalSize, 4);
}
let scrollDown = this.lastScrollTop <= this.directoryArea.scrollTop;
this.lastScrollTop = this.directoryArea.scrollTop;
let paddingTop = this.lastScrollTop - this.lastScrollTop%fileHeight;
let start = Math.floor(paddingTop/fileHeight) - 5;
if (start < 0) { start = 0; }
let fileHeight = 32;
let totalHeight = (files.length * fileHeight)+38;
let viewportHeight = this.directoryArea.clientHeight;
let paddingTop = this.lastScrollTop - this.lastScrollTop%fileHeight;
if (paddingTop < 0) { paddingTop = 0;}
let paddingBottom = totalHeight - paddingTop - viewportHeight - this.lastScrollTop%fileHeight;
if (paddingBottom < 0) {paddingBottom = 0;}
// Pad the items out which we're not going to show
this.dirContainer.style.marginTop = paddingTop+"px";
this.dirContainer.style.marginBottom = paddingBottom+"px";
let start = Math.floor(paddingTop/fileHeight);
let end = Math.ceil((paddingTop+viewportHeight)/fileHeight);
let end = Math.ceil((paddingTop+viewportHeight)/fileHeight) + 5;
if (end > files.length) { end = files.length-1; }
this.dirContainer.style.paddingTop = (start*fileHeight)+"px";
// First remove the elements which are out of bounds
let firstEl;
let firstIdx = -1;
@@ -142,13 +246,13 @@ FileManager.prototype.renderVisibleFiles = function(files, freshStart) {
let makeButton = (i, file) => {
let el = document.createElement("a");
el.classList = "node";
el.href = "/u/"+file.id;
el.href = file.href;
el.target = "_blank";
el.title = file.name;
el.setAttribute("fileindex", i);
let thumb = document.createElement("img");
thumb.src = apiEndpoint+"/file/"+file.id+"/thumbnail?width=32&height=32";
thumb.src = file.icon;
let label = document.createElement("span");
label.innerText = file.name;