allow import of multiple files at the same time

This commit is contained in:
zadam 2019-02-24 09:34:50 +01:00
parent 936f85c09e
commit 886ea6c68c
8 changed files with 46 additions and 48 deletions

View File

@ -43,27 +43,45 @@ $form.submit(() => {
return false;
});
function importIntoNote(importNoteId) {
const formData = new FormData();
formData.append('upload', $fileUploadInput[0].files[0]);
async function importIntoNote(importNoteId) {
const files = Array.from($fileUploadInput[0].files); // shallow copy since we're resetting the upload button below
// we generate it here (and not on opening) for the case when you try to import multiple times from the same
// dialog (which shouldn't happen, but still ...)
importId = utils.randomString(10);
const safeImport = $safeImport.is(":checked") ? 1 : 0;
let noteId;
$.ajax({
url: baseApiUrl + 'notes/' + importNoteId + '/import/' + importId + '/safe/' + safeImport,
headers: server.getHeaders(),
data: formData,
dataType: 'json',
type: 'POST',
contentType: false, // NEEDED, DON'T REMOVE THIS
processData: false, // NEEDED, DON'T REMOVE THIS
})
for (const file of files) {
const formData = new FormData();
formData.append('upload', file);
noteId = await $.ajax({
url: baseApiUrl + 'notes/' + importNoteId + '/import/' + importId + '/safe/' + safeImport,
headers: server.getHeaders(),
data: formData,
dataType: 'json',
type: 'POST',
timeout: 60 * 60 * 1000,
contentType: false, // NEEDED, DON'T REMOVE THIS
processData: false, // NEEDED, DON'T REMOVE THIS
})
// we actually ignore the error since it can be caused by HTTP timeout and use WS messages instead.
.fail((xhr, status, error) => {});
.fail((xhr, status, error) => {});
}
$dialog.modal('hide');
infoService.showMessage("Import finished successfully.");
await treeService.reload();
if (noteId) {
const node = await treeService.activateNote(noteId);
node.setExpanded(true);
}
}
messagingService.subscribeToMessages(async message => {
@ -83,19 +101,6 @@ messagingService.subscribeToMessages(async message => {
$importProgressCount.text(message.progressCount);
}
else if (message.type === 'import-finished') {
$dialog.modal('hide');
infoService.showMessage("Import finished successfully.");
await treeService.reload();
if (message.noteId) {
const node = await treeService.activateNote(message.noteId);
node.setExpanded(true);
}
}
});
$fileUploadInput.change(() => {

View File

@ -36,7 +36,7 @@ async function importToBranch(req) {
let note; // typically root of the import - client can show it after finishing the import
const importContext = new ImportContext(importId, safeImport);
const importContext = ImportContext.getInstance(importId, safeImport);
try {
if (extension === '.tar') {

View File

@ -298,12 +298,7 @@ async function importEnex(importContext, file, parentNote) {
return new Promise((resolve, reject) =>
{
// resolve only when we parse the whole document AND saving of all notes have been finished
saxStream.on("end", () => { Promise.all(saveNotePromises).then(() => {
importContext.importFinished(rootNote.noteId);
resolve(rootNote);
});
});
saxStream.on("end", () => { Promise.all(saveNotePromises).then(() => resolve(rootNote)) });
const bufferStream = new stream.PassThrough();
bufferStream.end(file.buffer);

View File

@ -64,8 +64,6 @@ async function importOpml(importContext, fileBuffer, parentNote) {
returnNote = returnNote || note;
}
importContext.importFinished(returnNote.noteId);
return returnNote;
}

View File

@ -21,7 +21,6 @@ async function importMarkdown(importContext, file, parentNote) {
});
importContext.increaseProgressCount();
importContext.importFinished(note.noteId);
return note;
}
@ -36,7 +35,6 @@ async function importHtml(importContext, file, parentNote) {
});
importContext.increaseProgressCount();
importContext.importFinished(note.noteId);
return note;
}

View File

@ -386,8 +386,6 @@ async function importTar(importContext, fileBuffer, importRootNote) {
}
}
importContext.importFinished();
resolve(firstNote);
});

View File

@ -2,6 +2,9 @@
const messagingService = require('./messaging');
// importId => ImportContext
const importContexts = {};
class ImportContext {
constructor(importId, safeImport) {
// importId is to distinguish between different import events - it is possible (though not recommended)
@ -15,6 +18,15 @@ class ImportContext {
this.lastSentCountTs = Date.now();
}
/** @return {ImportContext} */
static getInstance(importId, safeImport) {
if (!importContexts[importId]) {
importContexts[importId] = new ImportContext(importId, safeImport);
}
return importContexts[importId];
}
async increaseProgressCount() {
this.progressCount++;
@ -29,14 +41,6 @@ class ImportContext {
}
}
async importFinished(noteId) {
await messagingService.sendMessageToAllClients({
importId: this.importId,
type: 'import-finished',
noteId: noteId
});
}
// must remaing non-static
async reportError(message) {
await messagingService.sendMessageToAllClients({

View File

@ -16,7 +16,7 @@
<div class="form-group">
<label for="import-file-upload-input"><strong>Choose import file</strong></label>
<input type="file" id="import-file-upload-input" class="form-control-file" />
<input type="file" id="import-file-upload-input" class="form-control-file" multiple />
<p>Content of the file will be imported as child note(s) into <strong class="note-title"></strong>. Import file must be of supported type and have correct extension - one of <code>.html</code>, <code>.md</code>, <code>.tar</code>, <code>.enex</code>.</p>
</div>