mirror of
https://github.com/amitwh/markdown-converter.git
synced 2026-08-24 07:20:16 +05:30
feat(media): add batch folder mode to Image/Audio/Video Tools dialog
Reviewer follow-up on Task 12: the task's own title/brief called for
batch support and no later task in the plan picks it up, so this closes
that gap. Adds a "Single File" / "Batch Folder" mode toggle to the
existing media-operations-dialog.js; batch mode swaps the per-file
input/output fields for an Input Folder + "Include subfolders" +
Output Folder trio while keeping every other parameter (width/height/
quality/angle/startTime/duration/crf/fps/format/fit) applied uniformly
to every matching file. Disabled for audio "Merge", which combines many
inputs into one output and doesn't fit a per-file batch model.
main.js: adds collectFilesByExtension() (src/main/collectFilesByExtension.js,
unit tested), a generalization of the inline collectFiles() closure inside
ipcMain.on('universal-convert-batch', ...) to match a set of extensions
instead of one format. runMediaBatchOperation() loops
ImageOperations/AudioOperations/VideoOperations.executeOperation() over
the matched files, reporting per-file progress via new
'media-batch-progress' events and a final 'media-batch-complete' event,
then shows a "Batch Conversion Complete" dialog.showMessageBox with
completed/failed counts, mirroring performBatchConversion()'s pattern.
Wired via three new ipcMain.on handlers: batch-image-operation,
batch-audio-operation, batch-video-operation.
preload.js: whitelists the three new send channels and the two new
receive channels (media-batch-progress, media-batch-complete).
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* collectFilesByExtension
|
||||
*
|
||||
* Recursively (optionally) collects files under a directory whose extension matches
|
||||
* one of a given set of extensions. Generalizes the `collectFiles()` closure defined
|
||||
* inside `ipcMain.on('universal-convert-batch', ...)` in main.js (which matches a
|
||||
* single `.${fromFormat}` extension) to match against an arbitrary extension list —
|
||||
* used by the batch-image/audio/video-operation handlers, which need to match several
|
||||
* possible input extensions per media kind (e.g. .jpg/.jpeg/.png/... for images).
|
||||
*
|
||||
* Pulled out as its own module (rather than an inline closure like the original) so it
|
||||
* can be unit tested without Electron.
|
||||
*
|
||||
* @module collectFilesByExtension
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
/**
|
||||
* @param {string} dir - Directory to scan.
|
||||
* @param {string[]} extensions - Extensions to match, each including the leading dot
|
||||
* (e.g. ['.jpg', '.png']). Matching is case-insensitive.
|
||||
* @param {boolean} [includeSubfolders=true] - Recurse into subdirectories.
|
||||
* @returns {string[]} Absolute paths of matching files, in directory-walk order.
|
||||
*/
|
||||
function collectFilesByExtension(dir, extensions, includeSubfolders = true) {
|
||||
const normalizedExts = (extensions || []).map((ext) => ext.toLowerCase());
|
||||
const results = [];
|
||||
|
||||
function walk(currentDir) {
|
||||
const entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
||||
for (const entry of entries) {
|
||||
const fullPath = path.join(currentDir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
if (includeSubfolders) {
|
||||
walk(fullPath);
|
||||
}
|
||||
} else if (entry.isFile()) {
|
||||
const ext = path.extname(entry.name).toLowerCase();
|
||||
if (normalizedExts.includes(ext)) {
|
||||
results.push(fullPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
walk(dir);
|
||||
return results;
|
||||
}
|
||||
|
||||
module.exports = { collectFilesByExtension };
|
||||
Reference in New Issue
Block a user