UNPKG

js-uploader

Version:
262 lines 13.4 kB
import { __awaiter, __generator, __read, __spread } from "tslib"; import { fromEvent, from, scheduled, asyncScheduler, merge, of } from 'rxjs'; import { tap, mergeMap, concatMap, map, mergeAll, publishReplay, mapTo, filter, catchError } from 'rxjs/operators'; import { Logger } from '../../shared'; import { getType as getMimeType } from 'mime'; import { basename, relative, join, dirname } from 'path'; import { isElectron } from '../..'; var FileDragger = /** @class */ (function () { function FileDragger(options, uploadOptions) { var _this = this; this.uploadOptions = uploadOptions; this.subscription = null; Logger.info('FileDragger', this); var $el = options.$el, onDragover = options.onDragover, onDragenter = options.onDragenter, onDragleave = options.onDragleave, onDrop = options.onDrop; if (!$el) { throw new Error(); } this.$el = $el; var wrap = function (_e, fn) { return function (e) { e.preventDefault(); e.stopPropagation(); fn === null || fn === void 0 ? void 0 : fn(e); }; }; // this.$el.addEventListener('dragover', (e: DragEvent) => wrap(e, onDragover)(e)) // this.$el.addEventListener('dragenter', (e: DragEvent) => wrap(e, onDragenter)(e)) // this.$el.addEventListener('dragleave', (e: DragEvent) => wrap(e, onDragleave)(e)) // this.$el.addEventListener('drop', (e: DragEvent) => wrap(e, onDrop)(e)) // this.file$ = fromEvent(this.$el, 'drop').pipe( // tap((e) => { // e.stopPropagation() // e.preventDefault() // }), // filter(() => { // return !this.subscription?.closed // }), // mergeMap((e) => // from(parseDataTransfer(e as DragEvent, this.uploadOptions?.fileStatFn, this.uploadOptions?.readdirFn)), // ), // ) this.file$ = merge(merge(fromEvent(this.$el, 'dragover').pipe(tap(function (event) { var e = event; wrap(e, onDragover)(e); })), fromEvent(this.$el, 'dragenter').pipe(tap(function (event) { var e = event; wrap(e, onDragenter)(e); })), fromEvent(this.$el, 'dragleave').pipe(tap(function (event) { var e = event; wrap(e, onDragleave)(e); })), fromEvent(this.$el, 'drop').pipe(tap(function (event) { var e = event; wrap(e, onDrop)(e); }))).pipe(mapTo([]), filter(function (val) { return !!val.length; })), fromEvent(this.$el, 'drop').pipe(tap(function (e) { e.stopPropagation(); e.preventDefault(); }), concatMap(function (e) { var _a, _b; var res = (_b = (_a = _this.uploadOptions) === null || _a === void 0 ? void 0 : _a.beforeParseDataTransfer) === null || _b === void 0 ? void 0 : _b.call(_a, e); var before = res instanceof Promise ? res : Promise.resolve(res); return from(before).pipe(mapTo(e), catchError(function () { return of(null); })); }), filter(function (e) { return !!e; }), mergeMap(function (e) { var _a, _b; return from(parseDataTransfer(e, (_a = _this.uploadOptions) === null || _a === void 0 ? void 0 : _a.fileStatFn, (_b = _this.uploadOptions) === null || _b === void 0 ? void 0 : _b.readdirFn)); }))).pipe(publishReplay(1)); this.bind(); } FileDragger.prototype.bind = function () { this.unbind(); this.subscription = this.file$.connect(); return this; }; FileDragger.prototype.unbind = function () { var _a; (_a = this.subscription) === null || _a === void 0 ? void 0 : _a.unsubscribe(); this.subscription = null; return this; }; return FileDragger; }()); export { FileDragger }; export function parseDataTransfer(e, fileStat, readdir) { var _a; var dataTransfer = e.dataTransfer; if (!dataTransfer) { return Promise.resolve([]); } Logger.info('parseDataTransfer', dataTransfer.files.length, dataTransfer.items.length); if (isElectron() && typeof fileStat === 'function' && typeof readdir === 'function') { return parseFilesByPath(dataTransfer, fileStat, readdir); } if (((_a = dataTransfer.items) === null || _a === void 0 ? void 0 : _a.length) && typeof dataTransfer.items[0].webkitGetAsEntry === 'function') { return webkitGetAsEntryApi(dataTransfer); } else { return Promise.resolve(Array.from(dataTransfer.files)); } } export function parseFilesByPath(dataTransfer, fileStat, readdir) { return __awaiter(this, void 0, void 0, function () { var list, rootDir, loop; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: console.time('parseFilesByPath'); list = []; rootDir = ''; loop = function (filePath) { return __awaiter(_this, void 0, void 0, function () { var stat, error_1, name_1, file, children; return __generator(this, function (_a) { switch (_a.label) { case 0: if (!filePath) { return [2 /*return*/]; } stat = null; _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); return [4 /*yield*/, toPromise(fileStat(filePath))]; case 2: stat = _a.sent(); return [3 /*break*/, 4]; case 3: error_1 = _a.sent(); Logger.warn(filePath + ' not exists'); return [3 /*break*/, 4]; case 4: if (!(stat === null || stat === void 0 ? void 0 : stat.isFile())) return [3 /*break*/, 5]; name_1 = basename(filePath); file = { lastModified: stat.mtimeMs, name: name_1, size: stat.size, type: getMimeType(filePath), path: filePath, relativePath: rootDir ? relative(rootDir, filePath) : name_1, }; list.push(file); return [3 /*break*/, 8]; case 5: if (!(stat === null || stat === void 0 ? void 0 : stat.isDirectory())) return [3 /*break*/, 8]; return [4 /*yield*/, toPromise(readdir(filePath))]; case 6: children = _a.sent(); return [4 /*yield*/, scheduled(children || [], asyncScheduler) .pipe(concatMap(function (name) { return from(loop(join(filePath, name))); })) .toPromise() // let promises = (await toPromise(readdir(filePath))).map((name) => loop(join(filePath, name))) // await Promise.all(promises) ]; case 7: _a.sent(); _a.label = 8; case 8: return [2 /*return*/]; } }); }); }; return [4 /*yield*/, Promise.all(Array.from(dataTransfer.files).map(function (file) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: rootDir = dirname(file.path); return [4 /*yield*/, loop(file.path)]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }))]; case 1: _a.sent(); console.timeEnd('parseFilesByPath'); return [2 /*return*/, list]; } }); }); } // function toObserverble<T>(input: TPromise<T>): Observable<T> { // return input && input instanceof Promise ? from(input) : of(input) // } function toPromise(input) { return input && input instanceof Promise ? input : Promise.resolve(input); } export function webkitGetAsEntryApi(dataTransfer) { return __awaiter(this, void 0, void 0, function () { var files, promises, createPromiseToAddFileOrParseDirectory, error_2; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: console.time('webkitGetAsEntryApi'); files = []; promises = []; createPromiseToAddFileOrParseDirectory = function (entry) { return new Promise(function (resolve) { return __awaiter(_this, void 0, void 0, function () { var entries; return __generator(this, function (_a) { switch (_a.label) { case 0: if (!entry.isFile) return [3 /*break*/, 1]; entry.file(function (file) { file.relativePath = getRelativePath(entry); files.push(file); resolve(); }, function () { return resolve(); }); return [3 /*break*/, 3]; case 1: if (!entry.isDirectory) return [3 /*break*/, 3]; return [4 /*yield*/, parseDir(entry.createReader(), [])]; case 2: entries = _a.sent(); scheduled(entries || [], asyncScheduler) .pipe(map(createPromiseToAddFileOrParseDirectory), mergeAll()) .subscribe({ complete: resolve, }); _a.label = 3; case 3: return [2 /*return*/]; } }); }); }); }; _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); Array.from(dataTransfer.items).forEach(function (item) { var entry = item.webkitGetAsEntry(); entry && promises.push(createPromiseToAddFileOrParseDirectory(entry)); }); return [4 /*yield*/, Promise.all(promises)]; case 2: _a.sent(); return [3 /*break*/, 4]; case 3: error_2 = _a.sent(); Logger.error(error_2); return [3 /*break*/, 4]; case 4: console.timeEnd('webkitGetAsEntryApi'); return [2 /*return*/, files]; } }); }); } function getRelativePath(fileEntry) { var p = (fileEntry.fullPath || fileEntry.name); return p.startsWith('/') ? p.substr(1) : p; // return String(fileEntry.fullPath || fileEntry.name).replace(/^\//, '') } function parseDir(directoryReader, oldEntries) { return new Promise(function (resolve) { return getFilesAndDirectoriesFromDirectory(directoryReader, oldEntries, resolve); }); } function getFilesAndDirectoriesFromDirectory(directoryReader, oldEntries, callback) { directoryReader.readEntries(function (entries) { var newEntries = __spread(oldEntries, entries); if (entries === null || entries === void 0 ? void 0 : entries.length) { setTimeout(function () { return getFilesAndDirectoriesFromDirectory(directoryReader, newEntries, callback); }); } else { callback(newEntries); } }, function () { return callback(oldEntries); }); } //# sourceMappingURL=FileDragger.js.map