From 07f7f797d1ee07dae9134cb246c9afa5ad146f1f Mon Sep 17 00:00:00 2001 From: helamanl0424 Date: Mon, 25 Mar 2024 10:42:14 -0600 Subject: [PATCH] Update index.js Added functions: Display items in folders Back button Create/Delete folder Add Photo --- samples/index.js | 369 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 368 insertions(+), 1 deletion(-) diff --git a/samples/index.js b/samples/index.js index 19463e0..2a1e26d 100644 --- a/samples/index.js +++ b/samples/index.js @@ -1,6 +1,22 @@ let pod = true; +const podURL = 'http://localhost:3000/test/'; +const addFolderURL = 'http://localhost:3001/sky/event/cltqlszq00012ycu4dtvt55l9/1556/test/create_folder?containerURL=' + podURL; +const deleteFolderURL = 'http://localhost:3001/sky/event/cltqlszq00012ycu4dtvt55l9/1556/test/remove_folder?containerURL=' + podURL; +const listURL = 'http://localhost:3001/sky/event/cltqlszq00012ycu4dtvt55l9/1556/test/ls?directoryURL='; +const fetchFileURL = 'http://localhost:3001/sky/event/cltqlszq00012ycu4dtvt55l9/1556/test/fetch_file?fileURL=' + podURL; +const addFileURL = 'http://localhost:3001/sky/event/cltqlszq00012ycu4dtvt55l9/1556/test/overwrite_file' + +let currentPath = ''; +let lastURL = []; document.addEventListener("DOMContentLoaded", function() { + + // Show all items in the root storage URL + fetchAndDisplayItems(); + + // Show primary control panel + toggleControlPanel(true); + // Set default photo setCurrentFolder(''); @@ -41,8 +57,14 @@ document.addEventListener("DOMContentLoaded", function() { console.error('Error:', error); }); }); -}); + const fileInput = document.createElement('input'); + fileInput.type = 'file'; + fileInput.id = 'fileInput'; + fileInput.style.display = 'none'; + document.body.appendChild(fileInput); + fileInput.addEventListener('change', handleFileSelect); +}); async function attach(event) { event.preventDefault(); @@ -111,3 +133,348 @@ function setCurrentFolder(url) { function getCurrentFolder() { return localStorage.getItem('currentFolder'); } + +async function fetchAndDisplayItems(folderPath = '', goBack = false) { + const event = listURL + folderPath; + try { + const response = await fetch(event); + if (!response.ok) { + throw new Error(`List items failed: ${response.status}`); + } + if (!goBack) lastURL.push(currentPath); + currentPath = folderPath; + const json = await response.json(); + let items = json.directives[0].name; + + if (items != null) { + // Sort items by type: folders, photos, others + items.sort((a, b) => { + const typeA = getItemType(a), typeB = getItemType(b); + if (typeA === typeB) return 0; // Keep original order if the same type + if (typeA === 'folder') return -1; // Folder comes first + if (typeB === 'folder') return 1; // Folder comes first + if (typeA === 'photo') return -1; // Photo comes second + if (typeB === 'photo') return 1; // Photo comes second + // 'other' implicitly comes last + return 0; + }); + + const urlMap = await prefetchFileURLs(items); + const folderDiv = document.querySelector('.folder'); + folderDiv.innerHTML = ''; // Clear current contents + + items.forEach(itemName => { + const url = urlMap[itemName] || ''; // Default to empty string if no URL for non-photos + const itemHTML = createItemHTML(itemName, url); + folderDiv.innerHTML += itemHTML; + }); + } + + // Display current path + displayCurrentPath(currentPath); + + } catch (error) { + console.error("Failed to fetch items:", error); + } +} + +// Function to create HTML for an item +function createItemHTML(itemName, url) { + const itemType = getItemType(itemName); + let src = ''; + let altText = ''; + let onClickAttribute = ''; + + switch (itemType) { + case 'folder': + src = 'folder.png'; + altText = 'Folder'; + onClickAttribute = `onclick="fetchAndDisplayItems('${currentPath}${itemName}')"`; + break; + case 'photo': + src = url; + altText = 'Photo'; + onClickAttribute = `onclick="displayFullSizePhoto('${url}', '${itemName}')"`; + break; + case 'other': + src = 'file.png'; + altText = 'File'; + break; + } + + return `
+ ${altText} +

${itemName.replace('/', '')}

+
`; +} + +function displayFullSizePhoto(url, itemName) { + const folderDiv = document.querySelector('.folder'); + folderDiv.innerHTML = ``; + lastURL.push(currentPath); + currentPath += itemName; + displayCurrentPath(currentPath); + toggleControlPanel(false); +} + +function addButton(id, text, action) { + const button = document.createElement('button'); + button.id = id; + button.textContent = text; + button.addEventListener('click', action); + button.style.marginRight = "5px"; + button.style.marginBottom = "5px"; + document.querySelector('.control-panel').appendChild(button); +} + +function toggleControlPanel(showDefaultButtons) { + const controlPanel = document.querySelector('.control-panel'); + controlPanel.innerHTML = ''; // Clear existing buttons + if (showDefaultButtons) { + addButton('back', 'Back', backAction); + addButton('addPhoto', 'Add photo', addPhotoAction); + addButton('addFolder', 'Add folder', addFolderAction); + addButton('deleteFolder', 'Delete folder', deletFolderAction); + addButton('sample', 'sample', sampleAction); + } else { + addButton('back', 'Back', backAction); + addButton('deletePhoto', 'Delete photo', deleteFileAction); + addButton('copy', 'Copy', copyAction); + addButton('grantAccessToggle', 'Private', grantAccessAction); + addButton('grantAccessTo', 'Grant Access to', grantAccessToAction); + addButton('removeAccessFrom', 'Remove Access from', removeAccessFromAction); + } +} + +function getItemType(itemName) { + if (itemName.endsWith('/')) return 'folder'; + if (['.jpg', '.png', '.jpeg'].some(ext => itemName.endsWith(ext))) return 'photo'; + return 'other'; +} + +function backAction() { + if (lastURL.length == 0) { + fetchAndDisplayItems() + } else { + fetchAndDisplayItems(lastURL.pop(), true); + } + toggleControlPanel(true); +} + +function addPhotoAction() { + const addPhotoBtn = document.getElementById('addPhoto'); + addPhotoBtn.style.display = 'none'; // Hide the button + + const input = document.createElement('input'); + input.type = 'text'; + input.id = 'folderNameInput'; + input.className = 'searchInput'; + input.placeholder = 'Enter file URL'; + input.style.width = '150px'; + + const submitNewFile = () => { + const fetchFileURL = input.value.trim(); + if (fetchFileURL) { + console.log(`Adding file from: ${fetchFileURL}`); + addFile(fetchFileURL).then(() => { + alert('File added successfully!'); + input.remove(); // Remove the input field + addPhotoBtn.style.display = ''; // Show the button again + }).catch(error => { + console.error('Error adding folder:', error); + alert('Failed to add file.'); + }); + } + }; + + // Listen for the Enter key in the input field + input.addEventListener('keypress', function(e) { + if (e.key === 'Enter') { + submitNewFile(); + } + }); + + // Insert the input field into the DOM, before the back button + addPhotoBtn.parentNode.insertBefore(input, addPhotoBtn); + input.focus(); // Automatically focus the input field +} + +function addFolderAction() { + const addFolderBtn = document.getElementById('addFolder'); + addFolderBtn.style.display = 'none'; // Hide the button + + const input = document.createElement('input'); + input.type = 'text'; + input.id = 'folderNameInput'; + input.className = 'searchInput'; + input.placeholder = 'Enter folder name'; + input.style.width = '150px'; + + const submitNewFolder = () => { + const folderName = input.value.trim(); + if (folderName) { + console.log(`Adding folder: ${folderName}`); + addFolder(folderName).then(() => { + alert('Folder added successfully!'); + input.remove(); // Remove the input field + addFolderBtn.style.display = ''; // Show the button again + }).catch(error => { + console.error('Error adding folder:', error); + alert('Failed to add folder.'); + }); + } + }; + + // Listen for the Enter key in the input field + input.addEventListener('keypress', function(e) { + if (e.key === 'Enter') { + submitNewFolder(); + } + }); + + // Insert the input field into the DOM, before the add folder button + addFolderBtn.parentNode.insertBefore(input, addFolderBtn); + input.focus(); // Automatically focus the input field +} + +async function deletFolderAction() { + const listEvent = listURL + currentPath; + if (currentPath == '') { + alert('You cannot delete the root folder!'); + return; + } + const listResponse = await fetch(listEvent); + if (!listResponse.ok) { + throw new Error(`List folder failed: ${response.status}`); + } + const json = await listResponse.json(); + const items = json.directives[0].name; + if (items.length != 0) { + alert('You can only delete a empty folder!'); + return; + } + const deleteEvent = deleteFolderURL + currentPath; + const deleteResponse = await fetch(deleteEvent); + if (!deleteResponse.ok) { + throw new Error(`Delete folder failed: ${response.status}`); + } + // Success message + alert('Folder deleted successfully!'); + fetchAndDisplayItems(lastURL.pop(), true); +} + +function sampleAction() { + document.getElementById('fileInput').click(); +} + +// Handle file selection and upload +async function handleFileSelect(event) { + const file = event.target.files[0]; + if (file) { + console.log(file); + const formData = new FormData(); + formData.append('file', file); + + try { + const response = await fetch('YOUR_API_ENDPOINT', { + method: 'POST', + body: formData, + }); + + if (!response.ok) { + throw new Error('Network response was not ok'); + } + + // Success feedback + console.log('File uploaded successfully'); + alert('File uploaded successfully'); + } catch (error) { + console.error('Error uploading file:', error); + } + } +} + +function deleteFileAction() { + +} + +function copyAction() { + +} + +function grantAccessAction() { + +} + +function grantAccessToAction() { + +} + +function removeAccessFromAction() { + +} + +async function addFolder(folderName) { + if (!folderName.endsWith('/')) { + folderName += '/'; + } + const newPath = currentPath + folderName; + const event = addFolderURL + newPath; + fetch(event) + .then(response => { + if (!response.ok) { + throw new Error(`Add folder failed: ${response.status}`); + } + fetchAndDisplayItems(newPath); + }) +} + +async function getFileURL(item) { + const event = fetchFileURL + currentPath + item; + const response = await fetch(event); + if (!response.ok) { + throw new Error(`Fetch file failed: ${response.status}`); + } + const json = await response.json(); + return json.directives[0].name; +} + +async function prefetchFileURLs(items) { + const urlPromises = items.map(item => { + if (getItemType(item) === 'photo') { + return getFileURL(item).then(url => ({ itemName: item, url })); + } + return Promise.resolve({ itemName: item, url: undefined }); + }); + + const urls = await Promise.all(urlPromises); + const urlMap = urls.reduce((acc, { itemName, url }) => { + acc[itemName] = url; + return acc; + }, {}); + + return urlMap; +} + +async function addFile(fetchFileURL) { + const storeLocation = podURL + currentPath; + const queryParams = new URLSearchParams({ + fetchFileURL: fetchFileURL, + storeLocation: storeLocation + }).toString(); + const event = `${addFileURL}?${queryParams}`; + fetch(event) + .then(response => { + if (!response.ok) { + throw new Error(`Add file failed: ${response.status}`); + } + fetchAndDisplayItems(currentPath, true); + }) +} + +function displayCurrentPath(path) { + const currentPathElement = document.getElementById('currentPath'); + let pathToDisplay = podURL + path; + const formattedPath = pathToDisplay.replace(/^https?:\/\//, ''); // Remove http:// or https:// + currentPathElement.textContent = formattedPath; +}