diff --git a/src/imgsort.php b/src/imgsort.php index ccf8e62..1e4346d 100644 --- a/src/imgsort.php +++ b/src/imgsort.php @@ -5,7 +5,10 @@ // All paths require trailing slashes! $rootDir = __DIR__ . '/../images/'; // The URI at which the rootDir will be served - $rootPath = 'images/'; + // Use /images/ for testing + // When the app is not served at the root https://example.com/ but at a sublocation like https://example.com/imgsort2/, + // you might need to set it to just `images` without the / + $rootPath = '/images/'; // Path of the directory containing all the files to be sorted, relative to $rootDir $stagingDirName = '.sort/'; @@ -77,27 +80,23 @@ /** * Move a file from staging to the destination directory * @param file relative to stagingDir - * @param dir relative to rootDir + * @param dest new filename relative to rootDir */ - function moveFile($file, $dir) { + function moveFile($file, $dest) { global $stagingDir, $rootDir; $fullFile = $stagingDir . $file; - $fullDir = $rootDir . $dir . "/"; - $fullDest = $fullDir . basename($fullFile); + $fullDest = $rootDir . $dest; return saveMove($fullFile, $fullDest); } /** - * Move a file from destination directory back to the staging directory - * @param dir relative to rootDir - * @param file relative to rootDir/dir + * Like movefile, except reversed */ - function undoFile($file, $dir) { + function undoFile($file, $dest) { global $stagingDir, $rootDir; - $fullDir = $rootDir . $dir . "/"; - $fullFile = $fullDir . $file; - $fullDest = $stagingDir . basename($fullFile); - return saveMove($fullFile, $fullDest); + $fullFile = $stagingDir . $file; + $fullDest = $rootDir . $dest; + return saveMove($fullDest, $fullFile); } diff --git a/src/index.html b/src/index.html index 9b10520..0ec6e23 100644 --- a/src/index.html +++ b/src/index.html @@ -22,6 +22,7 @@
+ No file diff --git a/src/index.js b/src/index.js index 8670d64..345edd1 100644 --- a/src/index.js +++ b/src/index.js @@ -2,6 +2,9 @@ const imageExtensions = ['gif','jpg','jpeg','png', 'webp']; const videoExtensions =['mpg', 'mp2', 'mpeg', 'mpe', 'mpv', 'mp4']; const audioExtensions =['mp3', 'ogg', 'wav', 'flac']; +const invalidFileNameCharsRe =/[^\\/\|:\*\?"<>]/; // dont allow \/|:*?<> +const invalidFileNameChars = "\\/|:*?<>"; + const mappings = new Map(JSON.parse(localStorage.getItem('mappings')) || []); let statusLine = document.getElementById('status'); // store for when done with sorting TODO display @@ -203,6 +206,11 @@ function setCurrentFile() { currentFile = ""; statusLine.textContent = "No more files to sort"; } + + // set filename in input field + const fileNameNoExt = currentFile.replace(/\.[^/.]+$/, ""); + document.getElementById('filename').value = fileNameNoExt; + renderCurrentFile(); renderFileList(); } @@ -211,15 +219,35 @@ function setCurrentFile() { async function moveFile(directory) { if (!currentFile) { - statusLine.innerHTML = "No file to process!"; - return + statusLine.textContent = "No file to process!"; + return; } - const response = await fetch(`imgsort.php?action=moveFile&file=${escape(currentFile)}&dest=${directory}`); + const userSetFilename = document.getElementById('filename').value; + if (!userSetFilename) { + statusLine.textContent = "Filename must not be empty"; + return; + } + // file names invalid on windows not handled + if (invalidFileNameCharsRe.test(userSetFilename)) { + statusLine.textContent = `Filename must not contain ${invalidFileNameChars}`; + return; + } + + // re-add the extension + const fileExt = currentFile.split('.').pop(); + let filename = userSetFilename + '.' + fileExt; + + let newFilePath = directory + '/' + filename; + const response = await fetch(`imgsort.php?action=moveFile&file=${escape(currentFile)}&dest=${escape(newFilePath)}`); const text = await response.text(); // console.log(text); if (response.ok) { - statusLine.textContent = `Moved '${currentFile}' to '${directory}'`; - history.push([currentFile, directory]); + if (filename != currentFile) { + statusLine.textContent = `Moved '${currentFile}' to '${directory}'`; + } else { + statusLine.textContent = `Moved '${currentFile}' to '${directory}' as '${filename}'`; + } + history.push([currentFile, newFilePath]); // remove file from list fileList.splice(currentFileIdx, 1); // set next file @@ -237,12 +265,12 @@ async function undo() { statusLine.textContent = "Nothing to undo" return; } - const [file, directory] = history.pop(); - const response = await fetch(`imgsort.php?action=undoFile&file=${escape(file)}&dest=${directory}`); + const [file, newFilePath] = history.pop(); + const response = await fetch(`imgsort.php?action=undoFile&file=${escape(file)}&dest=${escape(newFilePath)}`); const text = await response.text(); // console.log(text); if (response.ok) { - statusLine.innerHTML = `Undo: move '${file}' to '${directory}'`; + statusLine.textContent = `Undo: move '${file}' to '${newFilePath}'`; await setFileList() setCurrentFile(); } @@ -276,6 +304,11 @@ window.onload = function() { // handle keyboard document.onkeypress = function(e) { + // dont handle keys while user is typing in filename box + if (document.querySelector('input') === document.activeElement) { + return; + } + e = e || window.event; let keydebug = document.getElementById("keydebug"); if (keydebug) {