Skip to content

Commit

Permalink
[REFACTOR] Final touches + jsdoc update
Browse files Browse the repository at this point in the history
  • Loading branch information
Rishabhg71 committed Oct 19, 2023
1 parent 1ebf46e commit f9b3392
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 33 deletions.
1 change: 0 additions & 1 deletion www/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@
width: 100%;
font-size: large;
height: 2em;

}

/* Custom file input */
Expand Down
19 changes: 10 additions & 9 deletions www/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -1261,8 +1261,8 @@ function displayFileSelect () {
const isFileSystemAPISupported = typeof window.showOpenFilePicker === 'function'
const isWebkitSupported = 'webkitdirectory' in document.createElement('input')

console.log('[DEBUG]: File system api supported', isFileSystemAPISupported);
console.log('[DEBUG]: Webkit supported', isWebkitSupported);
console.debug('[DEBUG]: File system api supported', isFileSystemAPISupported);
console.debug('[DEBUG]: Webkit supported', isWebkitSupported);

document.getElementById('openLocalFiles').style.display = 'block';
if (isFileSystemAPISupported || isWebkitSupported) {
Expand All @@ -1287,13 +1287,11 @@ function displayFileSelect () {

document.getElementById('zimSelectDropdown').addEventListener('change', async function (e) {
// handle zim selection from dropdown if multiple files are loaded via webkitdirectory or filesystem api
console.log(e.target.value);
if (isFileSystemAPISupported) {
const files = await fileSystem.getSelectedZimFromCache(e.target.value)
setLocalArchiveFromFileList(files);
} else {
const files = fileSystem.getSelectedZimFromWebkitList(webKitFileList, e.target.value)
console.log(files);
setLocalArchiveFromFileList(files);
}
});
Expand All @@ -1302,7 +1300,7 @@ function displayFileSelect () {
// Handles Folder selection when showDirectoryPicker is supported
document.getElementById('folderSelect').addEventListener('click', async function (e) {
e.preventDefault();
await fileSystem.selectDirectoryFromPicker()
await fileSystem.selectDirectoryFromPickerViaFileSystemApi()
})
}
if (isWebkitSupported && !isFileSystemAPISupported) {
Expand All @@ -1315,17 +1313,17 @@ function displayFileSelect () {
}
webKitFileList = e.target.files
await fileSystem.updateZimDropdownOptions({ fileOrDirHandle: null, files: filenames }, '')
// setLocalArchiveFromFileList(e.target.files);
})
}
// This handles use of the file picker
if (isFileSystemAPISupported) {
// Handles File selection when showOpenFilePicker is supported and uses the filesystem api
document.getElementById('archiveFiles').addEventListener('click', async function (e) {
e.preventDefault();
const files = await fileSystem.selectFileFromPicker(e)
const files = await fileSystem.selectFileFromPickerViaFileSystemApi(e)
setLocalArchiveFromFileList(files);
});
} else {
// Fallbacks to simple file input with multi file selection
document.getElementById('archiveFiles').addEventListener('change', async function (e) {
if (isWebkitSupported || isFileSystemAPISupported) {
const activeFilename = e.target.files[0].name
Expand Down Expand Up @@ -1368,8 +1366,11 @@ async function handleFileDrop (packet) {
const isFSAPIsupported = typeof window.showOpenFilePicker === 'function'
const isWebkitSupported = 'webkitdirectory' in document.createElement('input')

// value will be set to true if a folder is dropped then there will be no need to
// call the `setLocalArchiveFromFileList`
let loadZim = false;
if (isFSAPIsupported) loadZim = await fileSystem.handleFolderDropViaFSAPI(packet)

if (isFSAPIsupported) loadZim = await fileSystem.handleFolderDropViaFileSystemAPI(packet)
if (isWebkitSupported) {
const ret = await fileSystem.handleFolderDropViaWebkit(packet)
loadZim = ret.loadZim
Expand Down
74 changes: 51 additions & 23 deletions www/js/lib/fileSystem.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// refer to this article for easy explanation of File System API https://developer.chrome.com/articles/file-system-access/

/**
* @typedef {Object} FileSystemHandlers
* @property {Array<string>} files All the File names to be shown in the dropdown
Expand All @@ -7,7 +9,8 @@
import cache from './cache.js';

/**
* @param {FileSystemHandlers} fileSystemHandler
* @param {FileSystemHandlers} fileSystemHandler The FileSystemHandlers object containing filenames and File/Directory handle
* @param {string} selectedFile The name of the file to be selected in the dropdown
*/
async function updateZimDropdownOptions (fileSystemHandler, selectedFile) {
const select = document.getElementById('zimSelectDropdown')
Expand All @@ -20,7 +23,10 @@ async function updateZimDropdownOptions (fileSystemHandler, selectedFile) {
document.getElementById('zimSelectDropdown').value = selectedFile
}

async function selectDirectoryFromPicker () {
/**
* Opens the File System API to select a directory
*/
async function selectDirectoryFromPickerViaFileSystemApi () {
const handle = await window.showDirectoryPicker();
const fileNames = []
for await (const entry of handle.values()) {
Expand All @@ -38,7 +44,11 @@ async function selectDirectoryFromPicker () {
});
}

async function selectFileFromPicker () {
/**
* Opens the File System API to select a file
* @returns {Promise<Array<File>>} The selected file from picker
*/
async function selectFileFromPickerViaFileSystemApi () {
const fileHandles = await window.showOpenFilePicker({ multiple: false })
const [selectedFile] = fileHandles
const file = await selectedFile.getFile();
Expand All @@ -55,10 +65,14 @@ async function selectFileFromPicker () {
return [file];
}

/**
* Gets the selected zim file from the IndexedDB
* @param {string} selectedFilename The name of the file to get back from DB
* @returns {Promise<Array<File>>} The selected File Object from cache
*/
function getSelectedZimFromCache (selectedFilename) {
return new Promise((resolve, reject) => {
return new Promise((resolve, _reject) => {
cache.idxDB('zimFiles', async function (FSHandler) {
// const selectedFile = FSHandler.fileOrDirHandle
if (await FSHandler.fileOrDirHandle.queryPermission() !== 'granted') await FSHandler.fileOrDirHandle.requestPermission()

if (FSHandler.fileOrDirHandle.kind === 'directory') {
Expand All @@ -70,8 +84,6 @@ function getSelectedZimFromCache (selectedFilename) {
files.push(await entry.getFile())
}
}
// files = await (await FSHandler.fileOrDirHandle.getFileHandle(selectedFilename)).getFile()
console.log(files);
resolve(files)
} else {
const file = await FSHandler.fileOrDirHandle.getFile();
Expand All @@ -81,6 +93,16 @@ function getSelectedZimFromCache (selectedFilename) {
})
}

/**
* @typedef {Object.<number, File>} WebkitFileList
*/

/**
* Gets the selected zim file from the WebkitFileList
* @param {WebkitFileList} webKitFileList The WebkitFileList to get the selected file from
* @param {string} filename The name of the file to get back from webkitFileList
* @returns {Array<File>} The selected Files Object from webkitFileList
*/
function getSelectedZimFromWebkitList (webKitFileList, filename) {
const filenameWithoutExtension = filename.replace(/\.zim\w\w$/i, '')

Expand All @@ -101,19 +123,22 @@ function loadPreviousZimFile () {
if (typeof window.showOpenFilePicker === 'function') {
cache.idxDB('zimFiles', async function (FSHandler) {
if (!FSHandler) return console.info('There is no previous zim file in DB')
console.log('Loading this handler from old time', FSHandler);
updateZimDropdownOptions(FSHandler, '')
// refer to this article for easy explanation https://developer.chrome.com/articles/file-system-access/
})
}
}

async function handleFolderDropViaFSAPI (packet) {
/**
* Handles the folder drop event via File System API
* @param {DragEvent} packet The DragEvent packet
* @returns {Promise<boolean>} Whether the dropped item is a file or directory
*/
async function handleFolderDropViaFileSystemAPI (packet) {
const isFSAPIsupported = typeof window.showOpenFilePicker === 'function'
if (!isFSAPIsupported) return true

// Only runs when browser support File System API
const fileInfo = await packet.dataTransfer.items[0]
const fileInfo = packet.dataTransfer.items[0]
const fileOrDirHandle = await fileInfo.getAsFileSystemHandle();
console.log(fileOrDirHandle, fileInfo);
if (fileOrDirHandle.kind === 'file') {
Expand All @@ -128,9 +153,7 @@ async function handleFolderDropViaFSAPI (packet) {
});
return true
}
// will be later on used
if (fileOrDirHandle.kind === 'directory') {
// const dirHandle = fileInfo.getAsFileSystemHandle();
const fileNames = []
for await (const entry of fileOrDirHandle.values()) {
fileNames.push(entry.name)
Expand All @@ -148,29 +171,35 @@ async function handleFolderDropViaFSAPI (packet) {
}
}

/**
* Handles the folder drop event via WebkitGetAsEntry
* @param {DragEvent} event The DragEvent packet
* @returns {Promise<{loadZim: boolean, files: Array<File>} | void>} Whether the dropped item is a file or directory and FileList
*/
async function handleFolderDropViaWebkit (event) {
var dt = event.dataTransfer;

var entry = dt.items[0].webkitGetAsEntry();
if (entry.isFile) {
// do whatever you want

return { loadZim: true, files: [entry.file] }
} else if (entry.isDirectory) {
// do whatever you want
var reader = entry.createReader();
const files = await getFilesFromReader(reader);
console.log('[DEBUG] After files', files);
const fileNames = []
files.forEach(file => fileNames.push(file.name));
await updateZimDropdownOptions({ files: fileNames }, '')
return { loadZim: false, files: files }
}
}

/**
* Gets the files from the FileSystemReader
* @param {FileSystemDirectoryReader} reader The FileSystemReader to get files from
* @returns {Promise<Array<File>>} The files from the reader
*/
async function getFilesFromReader (reader) {
const files = []
const promise = new Promise(function (resolve, reject) {
const promise = new Promise(function (resolve, _reject) {
reader.readEntries(function (entries) {
resolve(entries)
})
Expand All @@ -180,9 +209,8 @@ async function getFilesFromReader (reader) {
for (let index = 0; index < entries.length; index++) {
const fileOrDir = entries[index];
if (fileOrDir.isFile) {
const filePromise = await new Promise(function (resolve, reject) {
const filePromise = await new Promise(function (resolve, _reject) {
fileOrDir.file(function (file) {
// console.log(file);
resolve(file)
})
});
Expand All @@ -194,11 +222,11 @@ async function getFilesFromReader (reader) {

export default {
updateZimDropdownOptions,
selectDirectoryFromPicker,
selectFileFromPicker,
selectDirectoryFromPickerViaFileSystemApi,
selectFileFromPickerViaFileSystemApi,
getSelectedZimFromCache,
loadPreviousZimFile,
handleFolderDropViaWebkit,
handleFolderDropViaFSAPI,
handleFolderDropViaFileSystemAPI,
getSelectedZimFromWebkitList
}

0 comments on commit f9b3392

Please sign in to comment.