From ccac46527c818fc28a22e77b55940e0be71a6c9b Mon Sep 17 00:00:00 2001 From: zadam Date: Sat, 24 Apr 2021 21:56:44 +0200 Subject: [PATCH] opened file change detection now useable on all note types --- src/public/app/layouts/desktop_layout.js | 2 + src/public/app/services/file_watcher.js | 7 +- .../app/services/note_content_renderer.js | 2 +- src/public/app/services/open.js | 6 +- src/public/app/widgets/note_actions.js | 7 +- src/public/app/widgets/note_update_status.js | 64 +++++++++++++++++++ .../type_property_widgets/file_properties.js | 2 +- .../type_property_widgets/image_properties.js | 5 ++ src/public/app/widgets/type_widgets/file.js | 39 ----------- src/routes/api/files.js | 5 +- src/routes/api/notes.js | 2 + src/routes/routes.js | 2 +- src/services/keyboard_actions.js | 6 ++ 13 files changed, 100 insertions(+), 49 deletions(-) create mode 100644 src/public/app/widgets/note_update_status.js diff --git a/src/public/app/layouts/desktop_layout.js b/src/public/app/layouts/desktop_layout.js index a6be0959e..257432374 100644 --- a/src/public/app/layouts/desktop_layout.js +++ b/src/public/app/layouts/desktop_layout.js @@ -36,6 +36,7 @@ import SearchResultWidget from "../widgets/search_result.js"; import SyncStatusWidget from "../widgets/sync_status.js"; import ScrollingContainer from "../widgets/containers/scrolling_container.js"; import RootContainer from "../widgets/containers/root_container.js"; +import NoteUpdateStatusWidget from "../widgets/note_update_status.js"; const RIGHT_PANE_CSS = ` + +

File has been last modified on .

+ +
+ + + +
+`; + +export default class NoteUpdateStatusWidget extends TabAwareWidget { + isEnabled() { + return super.isEnabled() + && !!fileWatcher.getFileModificationStatus(this.noteId); + } + + doRender() { + this.$widget = $(TPL); + this.overflowing(); + + this.$filePath = this.$widget.find(".file-path"); + this.$fileLastModified = this.$widget.find(".file-last-modified"); + this.$fileUploadButton = this.$widget.find(".file-upload-button"); + + this.$fileUploadButton.on("click", async () => { + await server.post(`notes/${this.noteId}/upload-modified-file`, { + filePath: this.$filePath.text() + }); + + fileWatcher.fileModificationUploaded(this.noteId); + this.refresh(); + }); + + this.$ignoreThisChangeButton = this.$widget.find(".ignore-this-change-button"); + this.$ignoreThisChangeButton.on('click', () => { + fileWatcher.ignoreModification(this.noteId); + this.refresh(); + }); + } + + refreshWithNote(note) { + const status = fileWatcher.getFileModificationStatus(note.noteId); + + this.$filePath.text(status.filePath); + this.$fileLastModified.text(dayjs.unix(status.lastModifiedMs / 1000).format("HH:mm:ss")); + } + + openedFileUpdatedEvent(data) { + if (data.noteId === this.noteId) { + this.refresh(); + } + } +} diff --git a/src/public/app/widgets/type_property_widgets/file_properties.js b/src/public/app/widgets/type_property_widgets/file_properties.js index 6af0816e1..ec39c684e 100644 --- a/src/public/app/widgets/type_property_widgets/file_properties.js +++ b/src/public/app/widgets/type_property_widgets/file_properties.js @@ -82,7 +82,7 @@ export default class FilePropertiesWidget extends TabAwareWidget { this.$uploadNewRevisionInput = this.$widget.find(".file-upload-new-revision-input"); this.$downloadButton.on('click', () => openService.downloadFileNote(this.noteId)); - this.$openButton.on('click', () => openService.openFileNote(this.noteId)); + this.$openButton.on('click', () => openService.openNoteExternally(this.noteId)); this.$uploadNewRevisionButton.on("click", () => { this.$uploadNewRevisionInput.trigger("click"); diff --git a/src/public/app/widgets/type_property_widgets/image_properties.js b/src/public/app/widgets/type_property_widgets/image_properties.js index 0359d24ad..9f8e1335a 100644 --- a/src/public/app/widgets/type_property_widgets/image_properties.js +++ b/src/public/app/widgets/type_property_widgets/image_properties.js @@ -26,6 +26,8 @@ const TPL = `
+ + @@ -59,6 +61,9 @@ export default class ImagePropertiesWidget extends TabAwareWidget { this.$fileType = this.$widget.find(".image-filetype"); this.$fileSize = this.$widget.find(".image-filesize"); + this.$openButton = this.$widget.find(".image-open"); + this.$openButton.on('click', () => openService.openNoteExternally(this.noteId)); + this.$imageDownloadButton = this.$widget.find(".image-download"); this.$imageDownloadButton.on('click', () => openService.downloadFileNote(this.noteId)); diff --git a/src/public/app/widgets/type_widgets/file.js b/src/public/app/widgets/type_widgets/file.js index a5e7410bd..a87a21b69 100644 --- a/src/public/app/widgets/type_widgets/file.js +++ b/src/public/app/widgets/type_widgets/file.js @@ -24,12 +24,6 @@ const TPL = ` } -
-

File has been last modified on .

- - -
-

     
     
@@ -54,22 +48,6 @@ export default class FileTypeWidget extends TypeWidget { this.$pdfPreview = this.$widget.find(".pdf-preview"); this.$videoPreview = this.$widget.find(".video-preview"); this.$audioPreview = this.$widget.find(".audio-preview"); - - this.$fileWatcherWrapper = this.$widget.find(".file-watcher-wrapper"); - this.$fileWatcherWrapper.hide(); - - this.$fileWatcherPath = this.$widget.find(".file-watcher-path"); - this.$fileWatcherLastModified = this.$widget.find(".file-watcher-last-modified"); - this.$fileWatcherUploadButton = this.$widget.find(".file-watcher-upload-button"); - - this.$fileWatcherUploadButton.on("click", async () => { - await server.post(`notes/${this.noteId}/upload-modified-file`, { - filePath: this.$fileWatcherPath.text() - }); - - fileWatcher.fileModificationUploaded(this.noteId); - this.refreshFileWatchingStatus(); - }); } async doRefresh(note) { @@ -107,22 +85,5 @@ export default class FileTypeWidget extends TypeWidget { else { this.$previewNotAvailable.show(); } - - this.refreshFileWatchingStatus(); - } - - refreshFileWatchingStatus() { - const status = fileWatcher.getFileModificationStatus(this.noteId); - - this.$fileWatcherWrapper.toggle(!!status); - - if (status) { - this.$fileWatcherPath.text(status.filePath); - this.$fileWatcherLastModified.text(dayjs.unix(status.lastModifiedMs / 1000).format("HH:mm:ss")); - } - } - - openedFileUpdatedEvent(data) { - this.refreshFileWatchingStatus(); } } diff --git a/src/routes/api/files.js b/src/routes/api/files.js index 7a4a10251..2a9f90e83 100644 --- a/src/routes/api/files.js +++ b/src/routes/api/files.js @@ -3,6 +3,7 @@ const protectedSessionService = require('../../services/protected_session'); const repository = require('../../services/repository'); const utils = require('../../services/utils'); +const log = require('../../services/log'); const noteRevisionService = require('../../services/note_revisions'); const tmp = require('tmp'); const fs = require('fs'); @@ -122,6 +123,8 @@ function saveToTmpDir(req) { fs.writeSync(tmpObj.fd, note.getContent()); fs.closeSync(tmpObj.fd); + log.info(`Saved temporary file for note ${noteId} into ${tmpObj.name}`); + if (utils.isElectron()) { chokidar.watch(tmpObj.name).on('change', (path, stats) => { ws.sendMessageToAllClients({ @@ -130,8 +133,6 @@ function saveToTmpDir(req) { lastModifiedMs: stats.atimeMs, filePath: tmpObj.name }); - - console.log(stats, path); }); } diff --git a/src/routes/api/notes.js b/src/routes/api/notes.js index a8df5b166..b8710ae7b 100644 --- a/src/routes/api/notes.js +++ b/src/routes/api/notes.js @@ -285,6 +285,8 @@ function uploadModifiedFile(req) { return [404, `Note ${noteId} has not been found`]; } + log.info(`Updating note ${noteId} with content from ${filePath}`); + noteRevisionService.createNoteRevision(note); const fileContent = fs.readFileSync(filePath); diff --git a/src/routes/routes.js b/src/routes/routes.js index 681c6afe5..d12f1b003 100644 --- a/src/routes/routes.js +++ b/src/routes/routes.js @@ -186,7 +186,7 @@ function register(app) { route(GET, '/api/notes/:noteId/download', [auth.checkApiAuthOrElectron], filesRoute.downloadFile); // this "hacky" path is used for easier referencing of CSS resources route(GET, '/api/notes/download/:noteId', [auth.checkApiAuthOrElectron], filesRoute.downloadFile); - apiRoute(POST, '/api/notes/:noteId/saveToTmpDir', filesRoute.saveToTmpDir); + apiRoute(POST, '/api/notes/:noteId/save-to-tmp-dir', filesRoute.saveToTmpDir); apiRoute(GET, '/api/notes/:noteId/attributes', attributesRoute.getEffectiveNoteAttributes); apiRoute(POST, '/api/notes/:noteId/attributes', attributesRoute.addNoteAttribute); diff --git a/src/services/keyboard_actions.js b/src/services/keyboard_actions.js index c9c61dcad..5c3d46ed5 100644 --- a/src/services/keyboard_actions.js +++ b/src/services/keyboard_actions.js @@ -352,6 +352,12 @@ const DEFAULT_KEYBOARD_ACTIONS = [ defaultShortcuts: [], scope: "window" }, + { + actionName: "openNoteExternally", + defaultShortcuts: [], + description: "Open note as a file with default application", + scope: "window" + }, { actionName: "renderActiveNote", defaultShortcuts: [],