attachment revision upload

This commit is contained in:
zadam 2023-05-03 22:49:24 +02:00
parent d8bc9c2982
commit cd01886eb2
11 changed files with 69 additions and 22 deletions

View File

@ -75,7 +75,6 @@ module.exports = {
glob: true,
log: true,
EditorWatchdog: true,
baseApiUrl: true,
// \src\share\canvas_share.js
React: true,
appState: true,

View File

@ -25,7 +25,7 @@ export async function uploadFiles(parentNoteId, files, options) {
}
await $.ajax({
url: `${baseApiUrl}notes/${parentNoteId}/import`,
url: `${window.glob.baseApiUrl}notes/${parentNoteId}/import`,
headers: await server.getHeaders(),
data: formData,
dataType: 'json',

View File

@ -79,7 +79,7 @@ async function call(method, url, data, headers = {}) {
requestId: requestId,
headers: headers,
method: method,
url: `/${baseApiUrl}${url}`,
url: `/${window.glob.baseApiUrl}${url}`,
data: data
});
});
@ -128,7 +128,7 @@ async function reportError(method, url, statusCode, response) {
function ajax(url, method, data, headers) {
return new Promise((res, rej) => {
const options = {
url: baseApiUrl + url,
url: window.glob.baseApiUrl + url,
type: method,
headers: headers,
timeout: 60000,

View File

@ -182,15 +182,15 @@ function randomString(len) {
}
function isMobile() {
return window.device === "mobile"
// window.device is not available in setup
|| (!window.device && /Mobi/.test(navigator.userAgent));
return window.glob?.device === "mobile"
// window.glob.device is not available in setup
|| (!window.glob?.device && /Mobi/.test(navigator.userAgent));
}
function isDesktop() {
return window.device === "desktop"
// window.device is not available in setup
|| (!window.device && !/Mobi/.test(navigator.userAgent));
return window.glob?.device === "desktop"
// window.glob.device is not available in setup
|| (!window.glob?.device && !/Mobi/.test(navigator.userAgent));
}
// cookie code below works for simple use cases only - ASCII only

View File

@ -39,6 +39,8 @@ const TPL = `
<a data-trigger-command="convertAttachmentIntoNote" class="dropdown-item">Convert attachment into note</a>
<a data-trigger-command="deleteAttachment" class="dropdown-item">Delete attachment</a>
</div>
<input type="file" class="attachment-upload-new-revision-input" style="display: none">
</div>`;
export default class AttachmentActionsWidget extends BasicWidget {
@ -56,6 +58,31 @@ export default class AttachmentActionsWidget extends BasicWidget {
this.$widget = $(TPL);
this.$widget.on('click', '.dropdown-item', () => this.$widget.find("[data-toggle='dropdown']").dropdown('toggle'));
this.$widget.find("[data-trigger-command='copyAttachmentReferenceToClipboard']").toggle(this.attachment.role === 'image');
this.$uploadNewRevisionInput = this.$widget.find(".attachment-upload-new-revision-input");
this.$uploadNewRevisionInput.on('change', async () => {
const fileToUpload = this.$uploadNewRevisionInput[0].files[0]; // copy to allow reset below
this.$uploadNewRevisionInput.val('');
const formData = new FormData();
formData.append('upload', fileToUpload);
const result = await $.ajax({
url: `${window.glob.baseApiUrl}attachments/${this.attachmentId}/file`,
headers: await server.getHeaders(),
data: formData,
type: 'PUT',
timeout: 60 * 60 * 1000,
contentType: false, // NEEDED, DON'T REMOVE THIS
processData: false, // NEEDED, DON'T REMOVE THIS
});
if (result.uploaded) {
toastService.showMessage("New attachment revision has been uploaded.");
} else {
toastService.showError("Upload of a new attachment revision failed.");
}
});
}
async openAttachmentCommand() {
@ -66,6 +93,10 @@ export default class AttachmentActionsWidget extends BasicWidget {
await openService.downloadAttachment(this.attachmentId);
}
async uploadNewAttachmentRevisionCommand() {
this.$uploadNewRevisionInput.trigger('click');
}
async copyAttachmentReferenceToClipboardCommand() {
this.parent.copyAttachmentReferenceToClipboard();
}

View File

@ -104,7 +104,7 @@ export default class FilePropertiesWidget extends NoteContextAwareWidget {
formData.append('upload', fileToUpload);
const result = await $.ajax({
url: `${baseApiUrl}notes/${this.noteId}/file`,
url: `${window.glob.baseApiUrl}notes/${this.noteId}/file`,
headers: await server.getHeaders(),
data: formData,
type: 'PUT',

View File

@ -88,7 +88,7 @@ export default class ImagePropertiesWidget extends NoteContextAwareWidget {
formData.append('upload', fileToUpload);
const result = await $.ajax({
url: `${baseApiUrl}images/${this.noteId}`,
url: `${window.glob.baseApiUrl}images/${this.noteId}`,
headers: await server.getHeaders(),
data: formData,
type: 'PUT',

View File

@ -14,15 +14,12 @@ const NotFoundError = require("../../errors/not_found_error");
const ValidationError = require("../../errors/validation_error.js");
function updateFile(req) {
const {noteId} = req.params;
const file = req.file;
const note = becca.getNote(noteId);
const note = becca.getNote(req.params.noteId);
if (!note) {
throw new NotFoundError(`Note '${noteId}' doesn't exist.`);
throw new NotFoundError(`Note '${req.params.noteId}' doesn't exist.`);
}
const file = req.file;
note.saveNoteRevision();
note.mime = file.mimetype.toLowerCase();
@ -39,6 +36,23 @@ function updateFile(req) {
};
}
function updateAttachment(req) {
const attachment = becca.getAttachment(req.params.attachmentId);
if (!attachment) {
throw new NotFoundError(`Attachment '${req.params.attachmentId}' doesn't exist.`);
}
const file = req.file;
attachment.getNote().saveNoteRevision();
attachment.mime = file.mimetype.toLowerCase();
attachment.setContent(file.buffer, {forceSave: true});
return {
uploaded: true
};
}
/**
* @param {BNote|BAttachment} noteOrAttachment
* @param res
@ -234,6 +248,7 @@ function uploadModifiedFileToAttachment(req) {
module.exports = {
updateFile,
updateAttachment,
openFile,
fileContentProvider,
downloadFile,

View File

@ -164,6 +164,8 @@ function register(app) {
route(GET, '/api/attachments/download/:attachmentId', [auth.checkApiAuthOrElectron], filesRoute.downloadAttachment);
apiRoute(PST, '/api/attachments/:attachmentId/save-to-tmp-dir', filesRoute.saveAttachmentToTmpDir);
apiRoute(PST, '/api/attachments/:attachmentId/upload-modified-file', filesRoute.uploadModifiedFileToAttachment);
route(PUT, '/api/attachments/:attachmentId/file', [auth.checkApiAuthOrElectron, uploadMiddlewareWithErrorHandling, csrfMiddleware],
filesRoute.updateAttachment, apiResultHandler);
apiRoute(GET, '/api/notes/:noteId/revisions', noteRevisionsApiRoute.getNoteRevisions);
apiRoute(DEL, '/api/notes/:noteId/revisions', noteRevisionsApiRoute.eraseAllNoteRevisions);

View File

@ -21,9 +21,9 @@
<script type="text/javascript">
global = globalThis; /* fixes https://github.com/webpack/webpack/issues/10035 */
window.baseApiUrl = 'api/';
window.device = "desktop";
window.glob = {
device: "desktop",
baseApiUrl: 'api/',
activeDialog: null,
maxEntityChangeIdAtLoad: <%= maxEntityChangeIdAtLoad %>,
maxEntityChangeSyncIdAtLoad: <%= maxEntityChangeSyncIdAtLoad %>,

View File

@ -105,9 +105,9 @@
<script type="text/javascript">
global = globalThis; /* fixes https://github.com/webpack/webpack/issues/10035 */
window.baseApiUrl = 'api/';
window.device = "mobile";
window.glob = {
device: "mobile",
baseApiUrl: 'api/',
activeDialog: null,
maxEntityChangeIdAtLoad: <%= maxEntityChangeIdAtLoad %>,
maxEntityChangeSyncIdAtLoad: <%= maxEntityChangeSyncIdAtLoad %>,