mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 18:36:30 +01:00 
			
		
		
		
	attachment revision upload
This commit is contained in:
		| @@ -75,7 +75,6 @@ module.exports = { | ||||
|         glob: true, | ||||
|         log: true, | ||||
|         EditorWatchdog: true, | ||||
|         baseApiUrl: true, | ||||
|         // \src\share\canvas_share.js | ||||
|         React: true, | ||||
|         appState: true, | ||||
|   | ||||
| @@ -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', | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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(); | ||||
|     } | ||||
|   | ||||
| @@ -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', | ||||
|   | ||||
| @@ -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', | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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 %>, | ||||
|   | ||||
| @@ -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 %>, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user