mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-04 05:28:59 +01:00 
			
		
		
		
	refactor uploading files
This commit is contained in:
		
							parent
							
								
									0802b81807
								
							
						
					
					
						commit
						a0d958bf12
					
				@ -315,14 +315,25 @@ class Froca {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @returns {Promise<FAttachment>} */
 | 
			
		||||
    async getAttachment(attachmentId) {
 | 
			
		||||
    async getAttachment(attachmentId, silentNotFoundError = false) {
 | 
			
		||||
        const attachment = this.attachments[attachmentId];
 | 
			
		||||
        if (attachment) {
 | 
			
		||||
            return attachment;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // load all attachments for the given note even if one is requested, don't load one by one
 | 
			
		||||
        const attachmentRows = await server.get(`attachments/${attachmentId}/all`);
 | 
			
		||||
        let attachmentRows;
 | 
			
		||||
        try {
 | 
			
		||||
            attachmentRows = await server.get(`attachments/${attachmentId}/all`);
 | 
			
		||||
        }
 | 
			
		||||
        catch (e) {
 | 
			
		||||
            if (silentNotFoundError) {
 | 
			
		||||
                logInfo(`Attachment '${attachmentId} not found, but silentNotFoundError is enabled: ` + e.message);
 | 
			
		||||
            } else {
 | 
			
		||||
                throw e;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const attachments = this.processAttachmentRows(attachmentRows);
 | 
			
		||||
 | 
			
		||||
        if (attachments.length) {
 | 
			
		||||
 | 
			
		||||
@ -7,8 +7,6 @@ import froca from "./froca.js";
 | 
			
		||||
import linkService from "./link.js";
 | 
			
		||||
 | 
			
		||||
function setupGlobs() {
 | 
			
		||||
    window.glob.PROFILING_LOG = false;
 | 
			
		||||
 | 
			
		||||
    window.glob.isDesktop = utils.isDesktop;
 | 
			
		||||
    window.glob.isMobile = utils.isMobile;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,6 @@
 | 
			
		||||
import utils from './utils.js';
 | 
			
		||||
import ValidationError from "./validation_error.js";
 | 
			
		||||
 | 
			
		||||
const REQUEST_LOGGING_ENABLED = false;
 | 
			
		||||
 | 
			
		||||
async function getHeaders(headers) {
 | 
			
		||||
    const appContext = (await import('../components/app_context.js')).default;
 | 
			
		||||
    const activeNoteContext = appContext.tabManager ? appContext.tabManager.getActiveContext() : null;
 | 
			
		||||
@ -50,6 +48,21 @@ async function remove(url, componentId) {
 | 
			
		||||
    return await call('DELETE', url, null, {'trilium-component-id': componentId});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function upload(url, fileToUpload) {
 | 
			
		||||
    const formData = new FormData();
 | 
			
		||||
    formData.append('upload', fileToUpload);
 | 
			
		||||
 | 
			
		||||
    return await $.ajax({
 | 
			
		||||
        url: window.glob.baseApiUrl + url,
 | 
			
		||||
        headers: await getHeaders(),
 | 
			
		||||
        data: formData,
 | 
			
		||||
        type: 'PUT',
 | 
			
		||||
        timeout: 60 * 60 * 1000,
 | 
			
		||||
        contentType: false, // NEEDED, DON'T REMOVE THIS
 | 
			
		||||
        processData: false, // NEEDED, DON'T REMOVE THIS
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let i = 1;
 | 
			
		||||
const reqResolves = {};
 | 
			
		||||
const reqRejects = {};
 | 
			
		||||
@ -59,8 +72,6 @@ let maxKnownEntityChangeId = 0;
 | 
			
		||||
async function call(method, url, data, headers = {}) {
 | 
			
		||||
    let resp;
 | 
			
		||||
 | 
			
		||||
    const start = Date.now();
 | 
			
		||||
 | 
			
		||||
    headers = await getHeaders(headers);
 | 
			
		||||
 | 
			
		||||
    if (utils.isElectron()) {
 | 
			
		||||
@ -71,10 +82,6 @@ async function call(method, url, data, headers = {}) {
 | 
			
		||||
            reqResolves[requestId] = resolve;
 | 
			
		||||
            reqRejects[requestId] = reject;
 | 
			
		||||
 | 
			
		||||
            if (REQUEST_LOGGING_ENABLED) {
 | 
			
		||||
                console.log(utils.now(), `Request #${requestId} to ${method} ${url}`);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            ipc.send('server-request', {
 | 
			
		||||
                requestId: requestId,
 | 
			
		||||
                headers: headers,
 | 
			
		||||
@ -88,12 +95,6 @@ async function call(method, url, data, headers = {}) {
 | 
			
		||||
        resp = await ajax(url, method, data, headers);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const end = Date.now();
 | 
			
		||||
 | 
			
		||||
    if (glob.PROFILING_LOG) {
 | 
			
		||||
        console.log(`${method} ${url} took ${end - start}ms`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const maxEntityChangeIdStr = resp.headers['trilium-max-entity-change-id'];
 | 
			
		||||
 | 
			
		||||
    if (maxEntityChangeIdStr && maxEntityChangeIdStr.trim()) {
 | 
			
		||||
@ -103,33 +104,6 @@ async function call(method, url, data, headers = {}) {
 | 
			
		||||
    return resp.body;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function reportError(method, url, statusCode, response) {
 | 
			
		||||
    const toastService = (await import("./toast.js")).default;
 | 
			
		||||
    let message = response;
 | 
			
		||||
 | 
			
		||||
    if (typeof response === 'string') {
 | 
			
		||||
        try {
 | 
			
		||||
            response = JSON.parse(response);
 | 
			
		||||
            message = response.message;
 | 
			
		||||
        }
 | 
			
		||||
        catch (e) {}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ([400, 404].includes(statusCode) && response && typeof response === 'object') {
 | 
			
		||||
        toastService.showError(message);
 | 
			
		||||
        throw new ValidationError({
 | 
			
		||||
            requestUrl: url,
 | 
			
		||||
            method,
 | 
			
		||||
            statusCode,
 | 
			
		||||
            ...response
 | 
			
		||||
        });
 | 
			
		||||
    } else {
 | 
			
		||||
        const title = `${statusCode} ${method} ${url}`;
 | 
			
		||||
        toastService.showErrorTitleAndMessage(title, message);
 | 
			
		||||
        toastService.throwError(`${title} - ${message}`);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function ajax(url, method, data, headers) {
 | 
			
		||||
    return new Promise((res, rej) => {
 | 
			
		||||
        const options = {
 | 
			
		||||
@ -175,11 +149,20 @@ if (utils.isElectron()) {
 | 
			
		||||
    const ipc = utils.dynamicRequire('electron').ipcRenderer;
 | 
			
		||||
 | 
			
		||||
    ipc.on('server-response', async (event, arg) => {
 | 
			
		||||
        if (REQUEST_LOGGING_ENABLED) {
 | 
			
		||||
            console.log(utils.now(), `Response #${arg.requestId}: ${arg.statusCode}`);
 | 
			
		||||
        if (arg.statusCode >= 200 && arg.statusCode < 300) {
 | 
			
		||||
            handleSuccessfulResponse(arg);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            await reportError(arg.method, arg.url, arg.statusCode, arg.body);
 | 
			
		||||
 | 
			
		||||
            reqRejects[arg.requestId]();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (arg.statusCode >= 200 && arg.statusCode < 300) {
 | 
			
		||||
        delete reqResolves[arg.requestId];
 | 
			
		||||
        delete reqRejects[arg.requestId];
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    function handleSuccessfulResponse(arg) {
 | 
			
		||||
        if (arg.headers['Content-Type'] === 'application/json') {
 | 
			
		||||
            arg.body = JSON.parse(arg.body);
 | 
			
		||||
        }
 | 
			
		||||
@ -194,15 +177,33 @@ if (utils.isElectron()) {
 | 
			
		||||
            headers: arg.headers
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
        else {
 | 
			
		||||
            await reportError(arg.method, arg.url, arg.statusCode, arg.body);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
            reqRejects[arg.requestId]();
 | 
			
		||||
async function reportError(method, url, statusCode, response) {
 | 
			
		||||
    const toastService = (await import("./toast.js")).default;
 | 
			
		||||
    let message = response;
 | 
			
		||||
 | 
			
		||||
    if (typeof response === 'string') {
 | 
			
		||||
        try {
 | 
			
		||||
            response = JSON.parse(response);
 | 
			
		||||
            message = response.message;
 | 
			
		||||
        }
 | 
			
		||||
        catch (e) {}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        delete reqResolves[arg.requestId];
 | 
			
		||||
        delete reqRejects[arg.requestId];
 | 
			
		||||
    if ([400, 404].includes(statusCode) && response && typeof response === 'object') {
 | 
			
		||||
        toastService.showError(message);
 | 
			
		||||
        throw new ValidationError({
 | 
			
		||||
            requestUrl: url,
 | 
			
		||||
            method,
 | 
			
		||||
            statusCode,
 | 
			
		||||
            ...response
 | 
			
		||||
        });
 | 
			
		||||
    } else {
 | 
			
		||||
        const title = `${statusCode} ${method} ${url}`;
 | 
			
		||||
        toastService.showErrorTitleAndMessage(title, message);
 | 
			
		||||
        toastService.throwError(`${title} - ${message}`);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
@ -211,7 +212,7 @@ export default {
 | 
			
		||||
    put,
 | 
			
		||||
    patch,
 | 
			
		||||
    remove,
 | 
			
		||||
    ajax,
 | 
			
		||||
    upload,
 | 
			
		||||
    // don't remove, used from CKEditor image upload!
 | 
			
		||||
    getHeaders,
 | 
			
		||||
    getMaxKnownEntityChangeId: () => maxKnownEntityChangeId
 | 
			
		||||
 | 
			
		||||
@ -64,18 +64,7 @@ export default class AttachmentActionsWidget extends BasicWidget {
 | 
			
		||||
            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
 | 
			
		||||
            });
 | 
			
		||||
            const result = await server.upload(`attachments/${this.attachmentId}/file`, fileToUpload);
 | 
			
		||||
 | 
			
		||||
            if (result.uploaded) {
 | 
			
		||||
                toastService.showMessage("New attachment revision has been uploaded.");
 | 
			
		||||
 | 
			
		||||
@ -49,16 +49,8 @@ export default class NoteContextAwareWidget extends BasicWidget {
 | 
			
		||||
 | 
			
		||||
    async refresh() {
 | 
			
		||||
        if (this.isEnabled()) {
 | 
			
		||||
            const start = Date.now();
 | 
			
		||||
 | 
			
		||||
            this.toggleInt(true);
 | 
			
		||||
            await this.refreshWithNote(this.note);
 | 
			
		||||
 | 
			
		||||
            const end = Date.now();
 | 
			
		||||
 | 
			
		||||
            if (glob.PROFILING_LOG && end - start > 10) {
 | 
			
		||||
                console.log(`Refresh of ${this.componentId} took ${end-start}ms`);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            this.toggleInt(false);
 | 
			
		||||
 | 
			
		||||
@ -100,18 +100,7 @@ export default class FilePropertiesWidget extends NoteContextAwareWidget {
 | 
			
		||||
            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}notes/${this.noteId}/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
 | 
			
		||||
            });
 | 
			
		||||
            const result = await server.upload(`notes/${this.noteId}/file`, fileToUpload);
 | 
			
		||||
 | 
			
		||||
            if (result.uploaded) {
 | 
			
		||||
                toastService.showMessage("New file revision has been uploaded.");
 | 
			
		||||
 | 
			
		||||
@ -84,18 +84,7 @@ export default class ImagePropertiesWidget extends NoteContextAwareWidget {
 | 
			
		||||
            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}images/${this.noteId}`,
 | 
			
		||||
                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
 | 
			
		||||
            });
 | 
			
		||||
            const result = await server.upload(`images/${this.noteId}`, fileToUpload);
 | 
			
		||||
 | 
			
		||||
            if (result.uploaded) {
 | 
			
		||||
                toastService.showMessage("New image revision has been uploaded.");
 | 
			
		||||
 | 
			
		||||
@ -57,7 +57,7 @@ export default class AttachmentDetailTypeWidget extends TypeWidget {
 | 
			
		||||
            })
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        const attachment = await froca.getAttachment(this.attachmentId);
 | 
			
		||||
        const attachment = await froca.getAttachment(this.attachmentId, true);
 | 
			
		||||
 | 
			
		||||
        if (!attachment) {
 | 
			
		||||
            this.$wrapper.html("<strong>This attachment has been deleted.</strong>");
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user