diff --git a/.gitmodules b/.gitmodules index 5704b2d..86bb40b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,6 +10,3 @@ [submodule "thirdparty/libwebview"] path = thirdparty/libwebview url = https://github.com/a3st/libwebview -[submodule "thirdparty/cppcoro"] - path = thirdparty/cppcoro - url = https://github.com/lewissbaker/cppcoro diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ac4ecf..97298bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,10 +21,22 @@ add_subdirectory(thirdparty/base64pp) endif() add_executable(Notes + src/exporters/txt.cpp src/main.cpp src/view_model.cpp src/note_storage.cpp - src/note.cpp) + src/note.cpp + app.rc) + +if(WIN32) +set_target_properties(Notes + PROPERTIES + LINK_FLAGS_DEBUG "/SUBSYSTEM:CONSOLE" + LINK_FLAGS_RELEASE "/SUBSYSTEM:windows /ENTRY:mainCRTStartup" + LINK_FLAGS_RELWITHDEBINFO "/SUBSYSTEM:windows /ENTRY:mainCRTStartup" + LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:windows /ENTRY:mainCRTStartup" + ) +endif() target_include_directories(Notes PRIVATE ${PROJECT_SOURCE_DIR}/src diff --git a/app.rc b/app.rc new file mode 100644 index 0000000..da3e7bc --- /dev/null +++ b/app.rc @@ -0,0 +1 @@ +IDI_ICON1 ICON DISCARDABLE "favicon.ico" \ No newline at end of file diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..4843528 Binary files /dev/null and b/favicon.ico differ diff --git a/include/exporter.hpp b/include/exporter.hpp new file mode 100644 index 0000000..d44eb66 --- /dev/null +++ b/include/exporter.hpp @@ -0,0 +1,10 @@ +#pragma once + +namespace notes +{ + class Exporter + { + public: + virtual bool saveFileAs(std::filesystem::path const& filePath) = 0; + }; +} // namespace notes \ No newline at end of file diff --git a/include/exporters/txt.hpp b/include/exporters/txt.hpp new file mode 100644 index 0000000..d2e6aae --- /dev/null +++ b/include/exporters/txt.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include "exporter.hpp" + +namespace notes::exporters +{ + class TxtExport : public Exporter + { + public: + TxtExport(std::string_view const text); + + bool saveFileAs(std::filesystem::path const& filePath) override; + + private: + std::string text; + }; +} // namespace notes::exporters \ No newline at end of file diff --git a/include/note.hpp b/include/note.hpp index e327260..89b9ee9 100644 --- a/include/note.hpp +++ b/include/note.hpp @@ -4,6 +4,8 @@ namespace notes { struct Note { + Note() = default; + Note(uint32_t const noteID, std::string_view const noteName, std::string_view const noteData); /*! diff --git a/include/note_storage.hpp b/include/note_storage.hpp index 719ef30..6bdbd76 100644 --- a/include/note_storage.hpp +++ b/include/note_storage.hpp @@ -12,10 +12,12 @@ namespace notes std::string getNotesData() const; - void saveNoteToDB(Note const& note); + int32_t saveNoteToDB(Note const& note); void removeNoteFromDB(uint32_t const ID); + bool exportNoteAsFile(uint32_t const ID, std::string_view const format, std::filesystem::path const& filePath); + private: SQLite::Database database; diff --git a/include/precompiled.hpp b/include/precompiled.hpp index 11d8a54..dc910d8 100644 --- a/include/precompiled.hpp +++ b/include/precompiled.hpp @@ -3,4 +3,6 @@ #include #include #include -#include \ No newline at end of file +#include +#include +#include \ No newline at end of file diff --git a/include/view_model.hpp b/include/view_model.hpp index 5c5083a..bfe3598 100644 --- a/include/view_model.hpp +++ b/include/view_model.hpp @@ -12,10 +12,12 @@ namespace notes std::string getNotes(); - void saveNote(uint32_t ID, std::string noteName, std::string noteData); + int32_t saveNote(uint32_t ID, std::string noteName, std::string noteData); void removeNote(uint32_t ID); + void exportNote(uint32_t ID, std::string format); + private: libwebview::App* app; NoteStorage noteStorage; diff --git a/src/exporters/txt.cpp b/src/exporters/txt.cpp new file mode 100644 index 0000000..6f8f40f --- /dev/null +++ b/src/exporters/txt.cpp @@ -0,0 +1,21 @@ +#include "exporters/txt.hpp" +#include "precompiled.hpp" + +namespace notes::exporters +{ + TxtExport::TxtExport(std::string_view const text) : text(text) + { + } + + bool TxtExport::saveFileAs(std::filesystem::path const& filePath) + { + std::ofstream stream(filePath, std::ios::out); + if (!stream.is_open()) + { + return false; + } + + stream << text; + return true; + } +} // namespace notes::exporters \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index ccbefec..659b1bb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,7 +16,7 @@ int32_t main(int32_t argc, char** argv) } catch (std::exception e) { - std::cerr << e.what() << std::endl; + libwebview::showMessageDialog("Notes", e.what(), libwebview::MessageDialogType::Error); return EXIT_FAILURE; } } \ No newline at end of file diff --git a/src/note_storage.cpp b/src/note_storage.cpp index 1f834bf..b3eef26 100644 --- a/src/note_storage.cpp +++ b/src/note_storage.cpp @@ -1,5 +1,8 @@ #include "note_storage.hpp" #include "precompiled.hpp" +#include + +#include "exporters/txt.hpp" namespace notes { @@ -55,7 +58,7 @@ namespace notes return true; } - void NoteStorage::saveNoteToDB(Note const& note) + int32_t NoteStorage::saveNoteToDB(Note const& note) { std::string const dbCheckNoteSQL = std::format("SELECT count(*) FROM `notes` WHERE `id`={}", note.noteID); @@ -65,11 +68,7 @@ namespace notes std::string const dbAddNoteSQL = std::format( "INSERT INTO `notes` (`name`, `data`) VALUES ('{}', '{}') RETURNING id", note.noteName, note.noteData); - int32_t const result = database.tryExec(dbAddNoteSQL); - if (result != SQLite::OK) - { - throw std::runtime_error("An error occurred when adding a row to the database"); - } + return database.execAndGet(dbAddNoteSQL).getInt(); } else { @@ -81,6 +80,8 @@ namespace notes { throw std::runtime_error("An error occurred when updating a row to the database"); } + + return note.noteID; } } @@ -99,7 +100,7 @@ namespace notes { std::stringstream stream; stream << "{\"notes\":["; - + bool isFirst = true; for (auto const& note : this->loadNotesFromDB()) { @@ -113,4 +114,48 @@ namespace notes stream << "]}"; return stream.str(); } + + bool NoteStorage::exportNoteAsFile(uint32_t const ID, std::string_view const format, + std::filesystem::path const& filePath) + { + std::string const dbSelectSQL = std::format("SELECT `name`, `data` FROM `notes` WHERE `id`={}", ID); + + SQLite::Statement query(database, dbSelectSQL); + + Note note; + if (query.executeStep()) + { + std::string const noteName = query.getColumn(0).getString(); + std::string const noteData = query.getColumn(1).getString(); + + note.noteID = ID; + note.noteName = noteName; + note.noteData = noteData; + } + + if (query.hasRow()) + { + std::unique_ptr exporter; + + std::string text; + + auto result = base64pp::decode(note.noteData); + if (!result.has_value()) + { + text = ""; + } + else + { + auto decodedData = result.value(); + text = std::string(reinterpret_cast(decodedData.data()), decodedData.size()); + } + + if (format.compare("txt") == 0) + { + exporter = std::make_unique(text); + } + + return exporter->saveFileAs(filePath); + } + } } // namespace notes \ No newline at end of file diff --git a/src/view_model.cpp b/src/view_model.cpp index 886e25b..33f4912 100644 --- a/src/view_model.cpp +++ b/src/view_model.cpp @@ -3,13 +3,14 @@ namespace notes { - ViewModel::ViewModel(libwebview::App* app) + ViewModel::ViewModel(libwebview::App* app) : app(app) { app->bind("getNotes", [this]() -> std::string { return getNotes(); }); - app->bind("saveNote", [this](uint32_t ID, std::string noteName, std::string noteData) -> void { - saveNote(ID, noteName, noteData); + app->bind("saveNote", [this](uint32_t ID, std::string noteName, std::string noteData) -> int32_t { + return saveNote(ID, noteName, noteData); }); app->bind("removeNote", [this](uint32_t ID) -> void { removeNote(ID); }); + app->bind("exportNote", [this](uint32_t ID, std::string format) -> void { exportNote(ID, format); }); } std::string ViewModel::getNotes() @@ -17,13 +18,27 @@ namespace notes return noteStorage.getNotesData(); } - void ViewModel::saveNote(uint32_t ID, std::string noteName, std::string noteData) + int32_t ViewModel::saveNote(uint32_t ID, std::string noteName, std::string noteData) { - noteStorage.saveNoteToDB(Note(ID, noteName, noteData)); + return noteStorage.saveNoteToDB(Note(ID, noteName, noteData)); } void ViewModel::removeNote(uint32_t ID) { noteStorage.removeNoteFromDB(ID); } + + void ViewModel::exportNote(uint32_t ID, std::string format) + { + auto result = app->showSaveDialog(std::filesystem::current_path(), ""); + if (result.has_value()) + { + if (!noteStorage.exportNoteAsFile(ID, format, result.value())) + { + libwebview::showMessageDialog("Notes", + "Произошла ошибка во время сохранения файла. Попробуйте еще раз!", + libwebview::MessageDialogType::Error); + } + } + } } // namespace notes \ No newline at end of file diff --git a/thirdparty/libwebview b/thirdparty/libwebview index 6767356..6144e20 160000 --- a/thirdparty/libwebview +++ b/thirdparty/libwebview @@ -1 +1 @@ -Subproject commit 6767356e2dbe62a068715451652e091d080b5ff9 +Subproject commit 6144e20aaeea3c5ab7d34be89accbf0c85c0c5e5 diff --git a/ui/dist/app.bundle.js b/ui/dist/app.bundle.js index e531414..5151714 100644 --- a/ui/dist/app.bundle.js +++ b/ui/dist/app.bundle.js @@ -16,7 +16,7 @@ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var marked__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! marked */ \"./node_modules/marked/lib/marked.esm.js\");\n/* harmony import */ var ctxmenu__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ctxmenu */ \"./node_modules/ctxmenu/index.js\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_2__);\n\n\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({\n emits: ['save'],\n data() {\n return {\n isOpenEditor: false,\n isPreview: false,\n content: \"\",\n title: \"\",\n id: -1\n };\n },\n computed: {\n previewText() {\n return (0,marked__WEBPACK_IMPORTED_MODULE_0__.marked)(this.content);\n }\n },\n mounted() {},\n methods: {\n onFocusInput(e) {\n jquery__WEBPACK_IMPORTED_MODULE_2___default()('.header-input-container input').attr('placeholder', 'Заголовок');\n this.isOpenEditor = true;\n },\n onCloseClick(e) {\n jquery__WEBPACK_IMPORTED_MODULE_2___default()('.header-input-container input').attr('placeholder', 'Придумайте что написать...');\n this.title = \"\";\n this.content = \"\";\n this.isOpenEditor = false;\n this.isPreview = false;\n this.id = -1;\n },\n onSaveClick(e) {\n this.$emit('save', {\n 'id': this.id,\n 'title': this.title,\n 'content': this.content\n });\n this.onCloseClick();\n },\n onExportClick(e) {\n e.stopPropagation();\n ctxmenu__WEBPACK_IMPORTED_MODULE_1__.ctxmenu.show([{\n text: \"Экспорт\"\n }, {\n text: \".TXT\",\n action: () => alert(\"Hello World!\")\n }, {\n text: \".PDF\",\n action: () => alert(\"Hello World!\")\n }, {\n text: \".DOCX\",\n action: () => alert(\"Hello World!\")\n }], e.target);\n },\n open(preview) {\n this.isOpenEditor = true;\n this.isPreview = preview;\n },\n isOpen() {\n return this.isOpenEditor;\n },\n setID(id) {\n this.id = id;\n },\n setTitle(title) {\n this.title = title;\n },\n setContent(content) {\n this.content = content;\n },\n onSwitchVisibleClick(e) {\n this.isPreview = !this.isPreview;\n },\n onSwitchVisibleEditorClick(e) {\n const containerElement = jquery__WEBPACK_IMPORTED_MODULE_2___default()('.markdown-container');\n if (e.offsetX >= containerElement.width() - 15 || e.offsetY >= containerElement.height() - 15) {\n return;\n }\n this.isPreview = false;\n }\n }\n});\n\n//# sourceURL=webpack://ui/./src/components/editor.vue?./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/dist/index.js??ruleSet%5B1%5D.rules%5B7%5D.use%5B0%5D"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var marked__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! marked */ \"./node_modules/marked/lib/marked.esm.js\");\n/* harmony import */ var ctxmenu__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ctxmenu */ \"./node_modules/ctxmenu/index.js\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_2__);\n\n\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({\n emits: ['save'],\n data() {\n return {\n isOpenEditor: false,\n isPreview: false,\n isChanged: false,\n content: \"\",\n title: \"\",\n id: -1\n };\n },\n computed: {\n previewText() {\n return (0,marked__WEBPACK_IMPORTED_MODULE_0__.marked)(this.content);\n }\n },\n watch: {\n content: {\n handler(value, oldValue) {\n this.isChanged = true;\n }\n },\n title: {\n handler(value, oldValue) {\n this.isChanged = true;\n }\n }\n },\n methods: {\n onFocusInput(e) {\n jquery__WEBPACK_IMPORTED_MODULE_2___default()('.header-input-container input').attr('placeholder', 'Заголовок');\n this.isOpenEditor = true;\n },\n onCloseClick(e) {\n jquery__WEBPACK_IMPORTED_MODULE_2___default()('.header-input-container input').attr('placeholder', 'Придумайте что написать...');\n this.title = \"\";\n this.content = \"\";\n this.isOpenEditor = false;\n this.isPreview = false;\n this.id = -1;\n },\n onSaveClick(e) {\n webview.invoke('saveNote', this.id, this.title, btoa(unescape(encodeURIComponent(this.content)))).then(id => this.id = id);\n this.$emit('save', e);\n this.isChanged = false;\n },\n onExportClick(e) {\n e.stopPropagation();\n ctxmenu__WEBPACK_IMPORTED_MODULE_1__.ctxmenu.show([{\n text: \"Экспорт\"\n }, {\n text: \".TXT\",\n action: () => webview.invoke('exportNote', this.id, 'txt')\n }], e.target);\n },\n open(preview) {\n this.isOpenEditor = true;\n this.isPreview = preview;\n },\n isOpen() {\n return this.isOpenEditor;\n },\n setID(id) {\n this.id = id;\n },\n setTitle(title) {\n this.title = title;\n this.isChanged = false;\n },\n setContent(content) {\n this.content = content;\n this.isChanged = false;\n },\n onSwitchVisibleClick(e) {\n this.isPreview = !this.isPreview;\n },\n onSwitchVisibleEditorClick(e) {\n const containerElement = jquery__WEBPACK_IMPORTED_MODULE_2___default()('.markdown-container');\n if (e.offsetX >= containerElement.width() - 15 || e.offsetY >= containerElement.height() - 15) {\n return;\n }\n this.isPreview = false;\n }\n }\n});\n\n//# sourceURL=webpack://ui/./src/components/editor.vue?./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/dist/index.js??ruleSet%5B1%5D.rules%5B7%5D.use%5B0%5D"); /***/ }), @@ -27,7 +27,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var marked__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! marked */ \"./node_modules/marked/lib/marked.esm.js\");\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({\n emits: ['click', 'context'],\n props: {\n title: String,\n data: String\n },\n computed: {\n description() {\n return (0,marked__WEBPACK_IMPORTED_MODULE_0__.marked)(this.data);\n }\n },\n methods: {\n onContextClick(e) {\n this.$emit('context', e);\n }\n }\n});\n\n//# sourceURL=webpack://ui/./src/components/note.vue?./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/dist/index.js??ruleSet%5B1%5D.rules%5B7%5D.use%5B0%5D"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var marked__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! marked */ \"./node_modules/marked/lib/marked.esm.js\");\n/* harmony import */ var ctxmenu__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ctxmenu */ \"./node_modules/ctxmenu/index.js\");\n\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({\n emits: ['note-click', 'menu-click'],\n props: {\n id: Number,\n title: String,\n data: String\n },\n computed: {\n description() {\n return (0,marked__WEBPACK_IMPORTED_MODULE_0__.marked)(this.data);\n }\n },\n methods: {\n onMenuClick(e) {\n e.stopPropagation();\n ctxmenu__WEBPACK_IMPORTED_MODULE_1__.ctxmenu.show([{\n text: \"Удалить\",\n action: () => {\n webview.invoke('removeNote', this.id).then(() => this.$emit('menu-click', e));\n }\n }], e.target);\n }\n }\n});\n\n//# sourceURL=webpack://ui/./src/components/note.vue?./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/dist/index.js??ruleSet%5B1%5D.rules%5B7%5D.use%5B0%5D"); /***/ }), @@ -38,7 +38,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var ctxmenu__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ctxmenu */ \"./node_modules/ctxmenu/index.js\");\n/* harmony import */ var _components_note_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../components/note.vue */ \"./src/components/note.vue\");\n/* harmony import */ var _components_editor_vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../components/editor.vue */ \"./src/components/editor.vue\");\n\n\n\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({\n components: {\n 'note': _components_note_vue__WEBPACK_IMPORTED_MODULE_2__[\"default\"],\n 'editor': _components_editor_vue__WEBPACK_IMPORTED_MODULE_3__[\"default\"]\n },\n data() {\n return {\n isReady: true,\n notes: []\n };\n },\n created() {\n jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on('resize', e => {\n this.updateNoteGroupHeight(e.target.outerHeight);\n });\n },\n destroyed() {\n jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).off('resize');\n },\n mounted() {\n this.updateNoteList();\n },\n methods: {\n updateNoteGroupHeight(windowHeight) {\n jquery__WEBPACK_IMPORTED_MODULE_0___default()('.notegr-container').css('height', windowHeight - (jquery__WEBPACK_IMPORTED_MODULE_0___default()('.editor-container').height() + 80));\n },\n updateNoteList() {\n this.isReady = false;\n this.notes.splice(0, this.notes.length);\n webview.invoke('getNotes').then(data => {\n for (const note of Object.values(data.notes)) {\n const noteData = {\n 'id': note.id,\n 'title': note.name,\n 'content': decodeURIComponent(escape(atob(note.data)))\n };\n this.notes.push(noteData);\n }\n this.isReady = true;\n this.$nextTick(() => {\n this.updateNoteGroupHeight(jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).outerHeight());\n });\n });\n },\n onNoteClick(e, index) {\n const editor = this.$refs.editor;\n if (editor.isOpen()) {\n return;\n }\n editor.open(true);\n editor.setID(this.notes[index].id);\n editor.setTitle(this.notes[index].title);\n editor.setContent(this.notes[index].content);\n },\n onNoteContextClick(e, index) {\n e.stopPropagation();\n ctxmenu__WEBPACK_IMPORTED_MODULE_1__.ctxmenu.show([{\n text: \"Удалить\",\n action: () => {\n webview.invoke('removeNote', this.notes[index].id).then(() => {\n this.updateNoteList();\n });\n }\n }], e.target);\n },\n onEditorSaveClick(e) {\n this.isReady = false;\n webview.invoke('saveNote', e.id, e.title, btoa(unescape(encodeURIComponent(e.content)))).then(() => {\n this.updateNoteList();\n });\n }\n }\n});\n\n//# sourceURL=webpack://ui/./src/views/app.vue?./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/dist/index.js??ruleSet%5B1%5D.rules%5B7%5D.use%5B0%5D"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _components_note_vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../components/note.vue */ \"./src/components/note.vue\");\n/* harmony import */ var _components_editor_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../components/editor.vue */ \"./src/components/editor.vue\");\n\n\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({\n components: {\n 'note': _components_note_vue__WEBPACK_IMPORTED_MODULE_1__[\"default\"],\n 'editor': _components_editor_vue__WEBPACK_IMPORTED_MODULE_2__[\"default\"]\n },\n data() {\n return {\n isReady: true,\n notes: []\n };\n },\n created() {\n jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).on('resize', e => {\n this.updateNoteGroupHeight(e.target.outerHeight);\n });\n },\n destroyed() {\n jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).off('resize');\n },\n mounted() {\n this.updateNoteList();\n this.$nextTick(() => {\n this.updateNoteGroupHeight(jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).outerHeight());\n });\n },\n methods: {\n updateNoteGroupHeight(windowHeight) {\n jquery__WEBPACK_IMPORTED_MODULE_0___default()('.notegr-container').css('height', windowHeight - (jquery__WEBPACK_IMPORTED_MODULE_0___default()('.editor-container').height() + 80));\n },\n updateNoteList() {\n this.isReady = false;\n this.notes.splice(0, this.notes.length);\n webview.invoke('getNotes').then(data => {\n for (const note of Object.values(data.notes)) {\n const noteData = {\n 'id': note.id,\n 'title': note.name,\n 'content': decodeURIComponent(escape(atob(note.data)))\n };\n this.notes.push(noteData);\n }\n this.isReady = true;\n });\n },\n onNoteClick(e, index) {\n const editor = this.$refs.editor;\n if (editor.isOpen()) {\n return;\n }\n editor.open(true);\n editor.setID(this.notes[index].id);\n editor.setTitle(this.notes[index].title);\n editor.setContent(this.notes[index].content);\n },\n onNoteMenuClick(e) {\n this.updateNoteList();\n },\n onEditorSaveClick(e) {\n this.updateNoteList();\n }\n }\n});\n\n//# sourceURL=webpack://ui/./src/views/app.vue?./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/dist/index.js??ruleSet%5B1%5D.rules%5B7%5D.use%5B0%5D"); /***/ }), @@ -49,7 +49,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: () => (/* binding */ render)\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm-browser.js\");\n\nconst _hoisted_1 = {\n class: \"editor-container\"\n};\nconst _hoisted_2 = {\n class: \"header-input-container\"\n};\nconst _hoisted_3 = {\n class: \"body-input-container\"\n};\nconst _hoisted_4 = {\n key: 0,\n style: {\n \"display\": \"flex\",\n \"padding\": \"10px\",\n \"height\": \"calc(100% - 80px)\"\n }\n};\nconst _hoisted_5 = [\"innerHTML\"];\nconst _hoisted_6 = {\n key: 1,\n style: {\n \"display\": \"flex\",\n \"padding\": \"10px\",\n \"height\": \"calc(100% - 80px)\"\n }\n};\nconst _hoisted_7 = {\n class: \"footer-input-container\"\n};\nconst _hoisted_8 = {\n style: {\n \"display\": \"flex\",\n \"flex-direction\": \"row\",\n \"align-items\": \"center\",\n \"width\": \"100%\"\n }\n};\nconst _hoisted_9 = {\n style: {\n \"display\": \"flex\",\n \"flex-direction\": \"row\",\n \"gap\": \"10px\"\n }\n};\nconst _hoisted_10 = /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"object\", {\n style: {\n \"pointer-events\": \"none\"\n },\n data: \"images/eye.svg\",\n width: \"20\",\n height: \"20\"\n}, null, -1 /* HOISTED */);\nconst _hoisted_11 = [_hoisted_10];\nconst _hoisted_12 = /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"object\", {\n style: {\n \"pointer-events\": \"none\"\n },\n data: \"images/file-export.svg\",\n width: \"20\",\n height: \"20\"\n}, null, -1 /* HOISTED */);\nconst _hoisted_13 = [_hoisted_12];\nconst _hoisted_14 = {\n style: {\n \"display\": \"flex\",\n \"flex-direction\": \"row\",\n \"margin-left\": \"auto\"\n }\n};\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n type: \"text\",\n placeholder: \"Придумайте что написать...\",\n \"onUpdate:modelValue\": _cache[0] || (_cache[0] = $event => $data.title = $event),\n onFocus: _cache[1] || (_cache[1] = $event => $options.onFocusInput($event))\n }, null, 544 /* NEED_HYDRATION, NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $data.title]])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_3, [$data.isPreview ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_4, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", {\n class: \"markdown-container\",\n innerHTML: $options.previewText,\n onMousedown: _cache[2] || (_cache[2] = $event => $options.onSwitchVisibleEditorClick($event))\n }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_5)])) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_6, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"textarea\", {\n placeholder: \"Заметка...\",\n \"onUpdate:modelValue\": _cache[3] || (_cache[3] = $event => $data.content = $event)\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $data.content]])])), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_7, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_8, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_9, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n title: \"Предпросмотр\",\n class: \"btn-icon circle\",\n style: {\n \"width\": \"36px\",\n \"height\": \"36px\"\n },\n onClick: _cache[4] || (_cache[4] = $event => $options.onSwitchVisibleClick($event))\n }, [..._hoisted_11]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n id: \"export-btn\",\n title: \"Экспорт\",\n class: \"btn-icon circle\",\n style: {\n \"width\": \"36px\",\n \"height\": \"36px\"\n },\n onClick: _cache[5] || (_cache[5] = $event => $options.onExportClick($event))\n }, [..._hoisted_13])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_14, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: \"btn-text\",\n onClick: _cache[6] || (_cache[6] = $event => $options.onSaveClick($event)),\n style: {\n \"font-weight\": \"bold\"\n }\n }, \"Сохранить\", 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vShow, this.title.length > 0]]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: \"btn-text\",\n onClick: _cache[7] || (_cache[7] = $event => $options.onCloseClick($event)),\n style: {\n \"font-weight\": \"bold\"\n }\n }, \"Закрыть\")])])])], 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vShow, $data.isOpenEditor]])]);\n}\n\n//# sourceURL=webpack://ui/./src/components/editor.vue?./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B2%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B1%5D.rules%5B7%5D.use%5B0%5D"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: () => (/* binding */ render)\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm-browser.js\");\n\nconst _hoisted_1 = {\n class: \"editor-container\"\n};\nconst _hoisted_2 = {\n class: \"header-input-container\"\n};\nconst _hoisted_3 = {\n class: \"body-input-container\"\n};\nconst _hoisted_4 = {\n key: 0,\n style: {\n \"display\": \"flex\",\n \"padding\": \"10px\",\n \"height\": \"calc(100% - 80px)\"\n }\n};\nconst _hoisted_5 = [\"innerHTML\"];\nconst _hoisted_6 = {\n key: 1,\n style: {\n \"display\": \"flex\",\n \"padding\": \"10px\",\n \"height\": \"calc(100% - 80px)\"\n }\n};\nconst _hoisted_7 = {\n class: \"footer-input-container\"\n};\nconst _hoisted_8 = {\n style: {\n \"display\": \"flex\",\n \"flex-direction\": \"row\",\n \"align-items\": \"center\",\n \"width\": \"100%\"\n }\n};\nconst _hoisted_9 = {\n style: {\n \"display\": \"flex\",\n \"flex-direction\": \"row\",\n \"gap\": \"10px\"\n }\n};\nconst _hoisted_10 = /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"object\", {\n style: {\n \"pointer-events\": \"none\"\n },\n data: \"images/eye.svg\",\n width: \"20\",\n height: \"20\"\n}, null, -1 /* HOISTED */);\nconst _hoisted_11 = [_hoisted_10];\nconst _hoisted_12 = /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"object\", {\n style: {\n \"pointer-events\": \"none\"\n },\n data: \"images/file-export.svg\",\n width: \"20\",\n height: \"20\"\n}, null, -1 /* HOISTED */);\nconst _hoisted_13 = [_hoisted_12];\nconst _hoisted_14 = {\n style: {\n \"display\": \"flex\",\n \"flex-direction\": \"row\",\n \"margin-left\": \"auto\"\n }\n};\nconst _hoisted_15 = [\"disabled\"];\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"input\", {\n type: \"text\",\n placeholder: \"Придумайте что написать...\",\n \"onUpdate:modelValue\": _cache[0] || (_cache[0] = $event => $data.title = $event),\n onFocus: _cache[1] || (_cache[1] = $event => $options.onFocusInput($event))\n }, null, 544 /* NEED_HYDRATION, NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $data.title]])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_3, [$data.isPreview ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_4, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", {\n class: \"markdown-container\",\n innerHTML: $options.previewText,\n onMousedown: _cache[2] || (_cache[2] = $event => $options.onSwitchVisibleEditorClick($event))\n }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_5)])) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_6, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"textarea\", {\n placeholder: \"Заметка...\",\n \"onUpdate:modelValue\": _cache[3] || (_cache[3] = $event => $data.content = $event)\n }, null, 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $data.content]])])), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_7, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_8, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_9, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n title: \"Предпросмотр\",\n class: \"btn-icon circle\",\n style: {\n \"width\": \"36px\",\n \"height\": \"36px\"\n },\n onClick: _cache[4] || (_cache[4] = $event => $options.onSwitchVisibleClick($event))\n }, [..._hoisted_11]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n id: \"export-btn\",\n title: \"Экспорт\",\n class: \"btn-icon circle\",\n style: {\n \"width\": \"36px\",\n \"height\": \"36px\"\n },\n onClick: _cache[5] || (_cache[5] = $event => $options.onExportClick($event))\n }, [..._hoisted_13], 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vShow, this.id != -1]])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_14, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: \"btn-text\",\n onClick: _cache[6] || (_cache[6] = $event => $options.onSaveClick($event)),\n style: {\n \"font-weight\": \"bold\"\n },\n disabled: !$data.isChanged || this.title.length == 0\n }, \"Сохранить\", 8 /* PROPS */, _hoisted_15), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: \"btn-text\",\n onClick: _cache[7] || (_cache[7] = $event => $options.onCloseClick($event)),\n style: {\n \"font-weight\": \"bold\"\n }\n }, \"Закрыть\")])])])], 512 /* NEED_PATCH */), [[vue__WEBPACK_IMPORTED_MODULE_0__.vShow, $data.isOpenEditor]])]);\n}\n\n//# sourceURL=webpack://ui/./src/components/editor.vue?./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B2%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B1%5D.rules%5B7%5D.use%5B0%5D"); /***/ }), @@ -60,7 +60,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: () => (/* binding */ render)\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm-browser.js\");\n\nconst _hoisted_1 = {\n class: \"note-container\"\n};\nconst _hoisted_2 = {\n class: \"note-header-container\"\n};\nconst _hoisted_3 = {\n style: {\n \"display\": \"flex\",\n \"flex-direction\": \"row\",\n \"margin-left\": \"auto\"\n }\n};\nconst _hoisted_4 = /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"object\", {\n style: {\n \"pointer-events\": \"none\"\n },\n data: \"images/ellipsis.svg\",\n width: \"16\",\n height: \"16\"\n}, null, -1 /* HOISTED */);\nconst _hoisted_5 = [_hoisted_4];\nconst _hoisted_6 = [\"innerHTML\"];\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", {\n class: \"note-title\",\n onMousedown: _cache[0] || (_cache[0] = $event => _ctx.$emit('click', $event))\n }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($props.title), 33 /* TEXT, NEED_HYDRATION */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: \"btn-icon\",\n onClick: _cache[1] || (_cache[1] = $event => $options.onContextClick($event))\n }, [..._hoisted_5])])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", {\n class: \"note-body-container\",\n innerHTML: $options.description,\n onMousedown: _cache[2] || (_cache[2] = $event => _ctx.$emit('click', $event))\n }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_6)]);\n}\n\n//# sourceURL=webpack://ui/./src/components/note.vue?./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B2%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B1%5D.rules%5B7%5D.use%5B0%5D"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: () => (/* binding */ render)\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm-browser.js\");\n\nconst _hoisted_1 = {\n class: \"note-container\"\n};\nconst _hoisted_2 = {\n class: \"note-header-container\"\n};\nconst _hoisted_3 = {\n style: {\n \"display\": \"flex\",\n \"flex-direction\": \"row\",\n \"margin-left\": \"auto\"\n }\n};\nconst _hoisted_4 = /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"object\", {\n style: {\n \"pointer-events\": \"none\"\n },\n data: \"images/ellipsis.svg\",\n width: \"16\",\n height: \"16\"\n}, null, -1 /* HOISTED */);\nconst _hoisted_5 = [_hoisted_4];\nconst _hoisted_6 = [\"innerHTML\"];\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", {\n class: \"note-title\",\n onMousedown: _cache[0] || (_cache[0] = $event => _ctx.$emit('note-click', $event))\n }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($props.title), 33 /* TEXT, NEED_HYDRATION */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: \"btn-icon\",\n onClick: _cache[1] || (_cache[1] = $event => $options.onMenuClick($event))\n }, [..._hoisted_5])])]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", {\n class: \"note-body-container\",\n innerHTML: $options.description,\n onMousedown: _cache[2] || (_cache[2] = $event => _ctx.$emit('note-click', $event))\n }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_6)]);\n}\n\n//# sourceURL=webpack://ui/./src/components/note.vue?./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B2%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B1%5D.rules%5B7%5D.use%5B0%5D"); /***/ }), @@ -71,7 +71,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: () => (/* binding */ render)\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm-browser.js\");\n\nconst _hoisted_1 = {\n class: \"wrapper-container\"\n};\nconst _hoisted_2 = {\n key: 0,\n class: \"notegr-container\"\n};\nconst _hoisted_3 = {\n key: 1,\n class: \"notegr-loading-container\"\n};\nconst _hoisted_4 = /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", {\n class: \"loader\"\n}, null, -1 /* HOISTED */);\nconst _hoisted_5 = /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"Загрузка заметок...\", -1 /* HOISTED */);\nconst _hoisted_6 = [_hoisted_4, _hoisted_5];\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n const _component_editor = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)(\"editor\");\n const _component_note = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)(\"note\");\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_editor, {\n ref: \"editor\",\n onSave: _cache[0] || (_cache[0] = $event => $options.onEditorSaveClick($event))\n }, null, 512 /* NEED_PATCH */), $data.isReady ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_2, [((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($data.notes, (note, index) => {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createBlock)(_component_note, {\n title: note.title,\n data: note.content,\n onClick: $event => $options.onNoteClick($event, index),\n onContext: $event => $options.onNoteContextClick($event, index)\n }, null, 8 /* PROPS */, [\"title\", \"data\", \"onClick\", \"onContext\"]);\n }), 256 /* UNKEYED_FRAGMENT */))])) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_3, [..._hoisted_6]))]);\n}\n\n//# sourceURL=webpack://ui/./src/views/app.vue?./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B2%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B1%5D.rules%5B7%5D.use%5B0%5D"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: () => (/* binding */ render)\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm-browser.js\");\n\nconst _hoisted_1 = {\n class: \"wrapper-container\"\n};\nconst _hoisted_2 = {\n key: 0,\n class: \"notegr-container\"\n};\nconst _hoisted_3 = {\n key: 1,\n class: \"notegr-loading-container\"\n};\nconst _hoisted_4 = /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", {\n class: \"loader\"\n}, null, -1 /* HOISTED */);\nconst _hoisted_5 = /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", null, \"Загрузка заметок...\", -1 /* HOISTED */);\nconst _hoisted_6 = [_hoisted_4, _hoisted_5];\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n const _component_editor = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)(\"editor\");\n const _component_note = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)(\"note\");\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_editor, {\n ref: \"editor\",\n onSave: _cache[0] || (_cache[0] = $event => $options.onEditorSaveClick($event))\n }, null, 512 /* NEED_PATCH */), $data.isReady ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_2, [((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($data.notes, (note, index) => {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createBlock)(_component_note, {\n id: note.id,\n title: note.title,\n data: note.content,\n onNoteClick: $event => $options.onNoteClick($event, index),\n onMenuClick: _cache[1] || (_cache[1] = $event => $options.onNoteMenuClick($event))\n }, null, 8 /* PROPS */, [\"id\", \"title\", \"data\", \"onNoteClick\"]);\n }), 256 /* UNKEYED_FRAGMENT */))])) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_3, [..._hoisted_6]))]);\n}\n\n//# sourceURL=webpack://ui/./src/views/app.vue?./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B2%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B1%5D.rules%5B7%5D.use%5B0%5D"); /***/ }), diff --git a/ui/src/components/editor.vue b/ui/src/components/editor.vue index 8fd6d03..86837e5 100644 --- a/ui/src/components/editor.vue +++ b/ui/src/components/editor.vue @@ -19,12 +19,12 @@ -
- +
@@ -44,6 +44,7 @@ export default { return { isOpenEditor: false, isPreview: false, + isChanged: false, content: "", title: "", id: -1 @@ -54,8 +55,17 @@ export default { return marked(this.content); } }, - mounted() { - + watch: { + content: { + handler(value, oldValue) { + this.isChanged = true; + } + }, + title: { + handler(value, oldValue) { + this.isChanged = true; + } + } }, methods: { onFocusInput(e) { @@ -74,16 +84,16 @@ export default { this.id = -1; }, onSaveClick(e) { - this.$emit('save', { 'id': this.id, 'title': this.title, 'content': this.content }); - this.onCloseClick(); + webview.invoke('saveNote', this.id, this.title, btoa(unescape(encodeURIComponent(this.content)))).then( + id => this.id = id); + this.$emit('save', e); + this.isChanged = false; }, onExportClick(e) { e.stopPropagation(); ctxmenu.show([ { text: "Экспорт" }, - { text: ".TXT", action: () => alert("Hello World!") }, - { text: ".PDF", action: () => alert("Hello World!") }, - { text: ".DOCX", action: () => alert("Hello World!") }, + { text: ".TXT", action: () => webview.invoke('exportNote', this.id, 'txt') } ], e.target); }, open(preview) { @@ -98,9 +108,11 @@ export default { }, setTitle(title) { this.title = title; + this.isChanged = false; }, setContent(content) { this.content = content; + this.isChanged = false; }, onSwitchVisibleClick(e) { this.isPreview = !this.isPreview; diff --git a/ui/src/components/note.vue b/ui/src/components/note.vue index 65092b2..66183e8 100644 --- a/ui/src/components/note.vue +++ b/ui/src/components/note.vue @@ -1,25 +1,27 @@ diff --git a/ui/src/views/app.vue b/ui/src/views/app.vue index 45f8905..de7d7ac 100644 --- a/ui/src/views/app.vue +++ b/ui/src/views/app.vue @@ -4,7 +4,12 @@
+ v-bind:id="note.id" + v-bind:title="note.title" + v-bind:data="note.content" + @note-click="onNoteClick($event, index)" + @menu-click="onNoteMenuClick($event)"> +
@@ -16,7 +21,6 @@