diff --git a/src/rethink/controllers/node/node_ops.py b/src/rethink/controllers/node/node_ops.py index b6282f2..4f18a28 100644 --- a/src/rethink/controllers/node/node_ops.py +++ b/src/rethink/controllers/node/node_ops.py @@ -29,6 +29,7 @@ def __get_node_data(n: models.tps.Node) -> schemas.node.NodeData: id=n["id"], md=n["md"], title=n["title"], + snippet=n["snippet"], type=n["type"], disabled=n["disabled"], createdAt=datetime2str(n["_id"].generation_time), @@ -71,6 +72,28 @@ def put_node( ) +async def put_quick_node( + td: TokenDecode, + req: schemas.node.PutRequest, +) -> schemas.node.PutResponse: + if td.code != const.Code.OK: + return schemas.node.PutResponse( + code=td.code.value, + message=const.get_msg_by_code(td.code, td.language), + requestId=req.requestId, + node=None + ) + + if models.utils.contain_only_http_link(req.md) != "": + title, description = await models.utils.get_title_description_from_link(req.md) + req.md = f"{title}\n\n{description}\n\n[{req.md}]({req.md})" + + return put_node( + td=td, + req=req, + ) + + def get_node( td: TokenDecode, req_id: str, diff --git a/src/rethink/controllers/schemas/node.py b/src/rethink/controllers/schemas/node.py index 81f2722..ed75781 100644 --- a/src/rethink/controllers/schemas/node.py +++ b/src/rethink/controllers/schemas/node.py @@ -20,6 +20,7 @@ class LinkedNode(BaseModel): id: str md: str title: str + snippet: str type: NonNegativeInt disabled: bool createdAt: str diff --git a/src/rethink/dist-local/css/app.8fc24017.css b/src/rethink/dist-local/css/app.8fc24017.css index cb50428..a911865 100644 --- a/src/rethink/dist-local/css/app.8fc24017.css +++ b/src/rethink/dist-local/css/app.8fc24017.css @@ -4183,7 +4183,6 @@ tr.tr-sm .node-more-ops { width: 1px; height: 1px; } - .file-label[data-v-a421d7c6] { font-size: 1.3em; font-weight: 300; @@ -4191,24 +4190,20 @@ tr.tr-sm .node-more-ops { text-align: center; cursor: pointer; } - .file-label img[data-v-a421d7c6] { width: 50px; height: 50px; margin-bottom: 1rem; } - .center[data-v-a421d7c6] { display: flex; justify-content: center; align-items: center; } - .click-upload[data-v-a421d7c6] { text-underline-offset: 0.1em; text-decoration: underline; } - .preview-container[data-v-a421d7c6] { display: flex; margin-top: 2rem; @@ -4413,23 +4408,19 @@ h2[data-v-05a72108] { font-size: 1.2em; font-weight: bold; } - .start-at[data-v-05a72108] { font-size: 1em; color: #666; } - .stopped[data-v-05a72108] { font-size: 1em; color: #f44336; } - .error-msg[data-v-05a72108] { font-size: 1em; color: #f44336; padding-left: 20px; } - .process[data-v-05a72108] { width: 100%; height: 20px; diff --git a/src/rethink/dist-local/js/app.js b/src/rethink/dist-local/js/app.js index c093a37..4abc4d4 100644 --- a/src/rethink/dist-local/js/app.js +++ b/src/rethink/dist-local/js/app.js @@ -1760,7 +1760,7 @@ \*****************************/ /***/ (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { - eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var vue_router__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! vue-router */ \"./node_modules/vue-router/dist/vue-router.mjs\");\n/* harmony import */ var _views_HomeView_vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @/views/HomeView.vue */ \"./src/views/HomeView.vue\");\n/* harmony import */ var _views_AboutView_vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @/views/AboutView.vue */ \"./src/views/AboutView.vue\");\n/* harmony import */ var _views_app_UserProfileView_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @/views/app/UserProfileView.vue */ \"./src/views/app/UserProfileView.vue\");\n/* harmony import */ var _views_LoginView_vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @/views/LoginView.vue */ \"./src/views/LoginView.vue\");\n/* harmony import */ var _views_NotFoundView_vue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @/views/NotFoundView.vue */ \"./src/views/NotFoundView.vue\");\n/* harmony import */ var _views_ForgetPasswordView_vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @/views/ForgetPasswordView.vue */ \"./src/views/ForgetPasswordView.vue\");\n/* harmony import */ var _utils_configs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @/utils/configs */ \"./src/utils/configs.ts\");\n/* harmony import */ var _utils_account_login__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @/utils/account/login */ \"./src/utils/account/login.ts\");\n/* harmony import */ var _views_OAuthView_vue__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @/views/OAuthView.vue */ \"./src/views/OAuthView.vue\");\n/* harmony import */ var _views_app_SettingsView_vue__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @/views/app/SettingsView.vue */ \"./src/views/app/SettingsView.vue\");\n/* harmony import */ var _views_app_EditorView_vue__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @/views/app/EditorView.vue */ \"./src/views/app/EditorView.vue\");\n/* harmony import */ var _views_app_AppView_vue__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @/views/app/AppView.vue */ \"./src/views/app/AppView.vue\");\n/* harmony import */ var _views_app_TrashView_vue__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @/views/app/TrashView.vue */ \"./src/views/app/TrashView.vue\");\n/* harmony import */ var _utils_account_token__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @/utils/account/token */ \"./src/utils/account/token.ts\");\n/* harmony import */ var _views_app_MobileSearchView_vue__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! @/views/app/MobileSearchView.vue */ \"./src/views/app/MobileSearchView.vue\");\n/* harmony import */ var _views_app_ImportDataView_vue__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! @/views/app/ImportDataView.vue */ \"./src/views/app/ImportDataView.vue\");\n/* harmony import */ var _utils_multiLang__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! @/utils/multiLang */ \"./src/utils/multiLang.ts\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst authBeforeEnter = () => {\n if ((0,_utils_account_token__WEBPACK_IMPORTED_MODULE_13__.getToken)() === \"\") {\n return {\n name: \"login\"\n };\n }\n};\nconst checkSingleMode = async () => {\n if (_utils_configs__WEBPACK_IMPORTED_MODULE_6__[\"default\"].oneUser) {\n await (0,_utils_account_login__WEBPACK_IMPORTED_MODULE_7__.tryLogin)(\"rethink@rethink.run\", \"no-password\");\n return {\n name: \"rethink\"\n };\n }\n};\nconst routes = [{\n path: '/',\n name: 'home',\n meta: {\n titleZH: \"Rethink\",\n titleEN: \"Rethink\"\n },\n component: _views_HomeView_vue__WEBPACK_IMPORTED_MODULE_0__[\"default\"],\n beforeEnter: checkSingleMode\n}, {\n path: '/about',\n name: 'about',\n meta: {\n titleZH: \"关于\",\n titleEN: \"About\"\n },\n component: _views_AboutView_vue__WEBPACK_IMPORTED_MODULE_1__[\"default\"],\n beforeEnter: checkSingleMode\n}, {\n path: '/login',\n name: 'login',\n meta: {\n titleZH: \"登录\",\n titleEN: \"Login\"\n },\n component: _views_LoginView_vue__WEBPACK_IMPORTED_MODULE_3__[\"default\"],\n beforeEnter: checkSingleMode\n}, {\n path: '/forget-password',\n name: 'forget-password',\n meta: {\n titleZH: \"忘记密码\",\n titleEN: \"Forget Password\"\n },\n component: _views_ForgetPasswordView_vue__WEBPACK_IMPORTED_MODULE_5__[\"default\"],\n beforeEnter: checkSingleMode\n}, {\n path: '/oauth-callback/:provider',\n name: 'oauth-callback',\n component: _views_OAuthView_vue__WEBPACK_IMPORTED_MODULE_8__[\"default\"],\n beforeEnter: checkSingleMode,\n props: route => ({\n provider: route.params.provider,\n code: route.query.code\n })\n}, {\n path: '/:catchAll(.*)',\n name: 'not-found',\n meta: {\n titleZH: \"404\",\n titleEN: \"404\"\n },\n component: _views_NotFoundView_vue__WEBPACK_IMPORTED_MODULE_4__[\"default\"]\n}, {\n path: '/404',\n name: '404',\n meta: {\n titleZH: \"404\",\n titleEN: \"404\"\n },\n component: _views_NotFoundView_vue__WEBPACK_IMPORTED_MODULE_4__[\"default\"]\n}, {\n path: '/r',\n name: 'rethink',\n meta: {\n titleZH: \"想法\",\n titleEN: \"Thoughts\"\n },\n component: _views_app_AppView_vue__WEBPACK_IMPORTED_MODULE_11__[\"default\"],\n beforeEnter: authBeforeEnter\n}, {\n path: '/n/:id',\n name: 'node',\n meta: {\n titleZH: \"想法\",\n titleEN: \"Thought\"\n },\n component: _views_app_EditorView_vue__WEBPACK_IMPORTED_MODULE_10__[\"default\"],\n beforeEnter: authBeforeEnter,\n props: route => ({\n nid: route.params.id\n })\n}, {\n path: '/r/trash',\n name: 'trash',\n meta: {\n titleZH: \"回收站\",\n titleEN: \"Trash\"\n },\n component: _views_app_TrashView_vue__WEBPACK_IMPORTED_MODULE_12__[\"default\"],\n beforeEnter: authBeforeEnter\n}, {\n path: '/r/search',\n name: 'search',\n meta: {\n titleZH: \"搜索\",\n titleEN: \"Search\"\n },\n component: _views_app_MobileSearchView_vue__WEBPACK_IMPORTED_MODULE_14__[\"default\"],\n beforeEnter: authBeforeEnter,\n props: route => ({\n q: 'q' in route.query ? route.query.q : ''\n })\n}, {\n path: '/r/user',\n name: 'user',\n meta: {\n titleZH: \"用户设置\",\n titleEN: \"User Profile\"\n },\n component: _views_app_UserProfileView_vue__WEBPACK_IMPORTED_MODULE_2__[\"default\"],\n beforeEnter: authBeforeEnter\n}, {\n path: '/r/settings',\n name: 'settings',\n meta: {\n titleZH: \"应用设置\",\n titleEN: \"Settings\"\n },\n component: _views_app_SettingsView_vue__WEBPACK_IMPORTED_MODULE_9__[\"default\"],\n beforeEnter: authBeforeEnter\n}, {\n path: '/r/import',\n name: 'import',\n meta: {\n titleZH: \"导入数据\",\n titleEN: \"Import Data\"\n },\n component: _views_app_ImportDataView_vue__WEBPACK_IMPORTED_MODULE_15__[\"default\"],\n beforeEnter: authBeforeEnter\n}];\nconst router = (0,vue_router__WEBPACK_IMPORTED_MODULE_17__.createRouter)({\n history: (0,vue_router__WEBPACK_IMPORTED_MODULE_17__.createWebHistory)(\"/\"),\n routes\n});\nrouter.beforeEach(to => {\n let t = \"Rethink\";\n if (_utils_multiLang__WEBPACK_IMPORTED_MODULE_16__[\"default\"].getGlobalLang() === \"zh\") {\n if (!(\"titleZH\" in to.meta)) return;\n t = to.meta.titleZH;\n } else if (_utils_multiLang__WEBPACK_IMPORTED_MODULE_16__[\"default\"].getGlobalLang() === \"en\") {\n if (!(\"titleEN\" in to.meta)) return;\n t = to.meta.titleEN;\n }\n if (to.name !== \"home\") {\n t += \" - Rethink\";\n }\n document.title = t;\n});\n/* harmony default export */ __webpack_exports__[\"default\"] = (router);\n\n//# sourceURL=webpack://rethink/./src/router/index.ts?"); + eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var vue_router__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! vue-router */ \"./node_modules/vue-router/dist/vue-router.mjs\");\n/* harmony import */ var _views_HomeView_vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @/views/HomeView.vue */ \"./src/views/HomeView.vue\");\n/* harmony import */ var _views_AboutView_vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @/views/AboutView.vue */ \"./src/views/AboutView.vue\");\n/* harmony import */ var _views_app_UserProfileView_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @/views/app/UserProfileView.vue */ \"./src/views/app/UserProfileView.vue\");\n/* harmony import */ var _views_LoginView_vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @/views/LoginView.vue */ \"./src/views/LoginView.vue\");\n/* harmony import */ var _views_NotFoundView_vue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @/views/NotFoundView.vue */ \"./src/views/NotFoundView.vue\");\n/* harmony import */ var _views_ForgetPasswordView_vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @/views/ForgetPasswordView.vue */ \"./src/views/ForgetPasswordView.vue\");\n/* harmony import */ var _utils_configs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @/utils/configs */ \"./src/utils/configs.ts\");\n/* harmony import */ var _utils_account_login__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @/utils/account/login */ \"./src/utils/account/login.ts\");\n/* harmony import */ var _views_OAuthView_vue__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @/views/OAuthView.vue */ \"./src/views/OAuthView.vue\");\n/* harmony import */ var _views_app_SettingsView_vue__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @/views/app/SettingsView.vue */ \"./src/views/app/SettingsView.vue\");\n/* harmony import */ var _views_app_EditorView_vue__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @/views/app/EditorView.vue */ \"./src/views/app/EditorView.vue\");\n/* harmony import */ var _views_app_AppView_vue__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @/views/app/AppView.vue */ \"./src/views/app/AppView.vue\");\n/* harmony import */ var _views_app_TrashView_vue__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @/views/app/TrashView.vue */ \"./src/views/app/TrashView.vue\");\n/* harmony import */ var _utils_account_token__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @/utils/account/token */ \"./src/utils/account/token.ts\");\n/* harmony import */ var _views_app_MobileSearchView_vue__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! @/views/app/MobileSearchView.vue */ \"./src/views/app/MobileSearchView.vue\");\n/* harmony import */ var _views_app_ImportDataView_vue__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! @/views/app/ImportDataView.vue */ \"./src/views/app/ImportDataView.vue\");\n/* harmony import */ var _utils_multiLang__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! @/utils/multiLang */ \"./src/utils/multiLang.ts\");\n/* harmony import */ var _utils_meta__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! @/utils/meta */ \"./src/utils/meta.ts\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst authBeforeEnter = () => {\n if ((0,_utils_account_token__WEBPACK_IMPORTED_MODULE_13__.getToken)() === \"\") {\n return {\n name: \"login\"\n };\n }\n};\nconst checkSingleMode = async () => {\n if (_utils_configs__WEBPACK_IMPORTED_MODULE_6__[\"default\"].oneUser) {\n await (0,_utils_account_login__WEBPACK_IMPORTED_MODULE_7__.tryLogin)(\"rethink@rethink.run\", \"no-password\");\n return {\n name: \"rethink\"\n };\n }\n};\nconst routes = [{\n path: '/',\n name: 'home',\n meta: {\n titleZH: \"Rethink\",\n titleEN: \"Rethink\",\n description: \"Rethink\"\n },\n component: _views_HomeView_vue__WEBPACK_IMPORTED_MODULE_0__[\"default\"],\n beforeEnter: checkSingleMode\n}, {\n path: '/about',\n name: 'about',\n meta: {\n titleZH: \"关于\",\n titleEN: \"About\",\n description: \"关于 Rethink\"\n },\n component: _views_AboutView_vue__WEBPACK_IMPORTED_MODULE_1__[\"default\"],\n beforeEnter: checkSingleMode\n}, {\n path: '/login',\n name: 'login',\n meta: {\n titleZH: \"登录\",\n titleEN: \"Login\",\n description: \"登录\"\n },\n component: _views_LoginView_vue__WEBPACK_IMPORTED_MODULE_3__[\"default\"],\n beforeEnter: checkSingleMode\n}, {\n path: '/forget-password',\n name: 'forget-password',\n meta: {\n titleZH: \"忘记密码\",\n titleEN: \"Forget Password\",\n description: \"忘记密码\"\n },\n component: _views_ForgetPasswordView_vue__WEBPACK_IMPORTED_MODULE_5__[\"default\"],\n beforeEnter: checkSingleMode\n}, {\n path: '/oauth-callback/:provider',\n name: 'oauth-callback',\n component: _views_OAuthView_vue__WEBPACK_IMPORTED_MODULE_8__[\"default\"],\n beforeEnter: checkSingleMode,\n props: route => ({\n provider: route.params.provider,\n code: route.query.code\n })\n}, {\n path: '/:catchAll(.*)',\n name: 'not-found',\n meta: {\n titleZH: \"404\",\n titleEN: \"404\",\n description: \"404\"\n },\n component: _views_NotFoundView_vue__WEBPACK_IMPORTED_MODULE_4__[\"default\"]\n}, {\n path: '/404',\n name: '404',\n meta: {\n titleZH: \"404\",\n titleEN: \"404\",\n description: \"404\"\n },\n component: _views_NotFoundView_vue__WEBPACK_IMPORTED_MODULE_4__[\"default\"]\n}, {\n path: '/r',\n name: 'rethink',\n meta: {\n titleZH: \"想法\",\n titleEN: \"Thoughts\",\n description: \"想法\"\n },\n component: _views_app_AppView_vue__WEBPACK_IMPORTED_MODULE_11__[\"default\"],\n beforeEnter: authBeforeEnter\n}, {\n path: '/n/:id',\n name: 'node',\n meta: {\n titleZH: \"想法\",\n titleEN: \"Thought\",\n description: \"想法\"\n },\n component: _views_app_EditorView_vue__WEBPACK_IMPORTED_MODULE_10__[\"default\"],\n beforeEnter: authBeforeEnter,\n props: route => ({\n nid: route.params.id\n })\n}, {\n path: '/r/trash',\n name: 'trash',\n meta: {\n titleZH: \"回收站\",\n titleEN: \"Trash\",\n description: \"回收站\"\n },\n component: _views_app_TrashView_vue__WEBPACK_IMPORTED_MODULE_12__[\"default\"],\n beforeEnter: authBeforeEnter\n}, {\n path: '/r/search',\n name: 'search',\n meta: {\n titleZH: \"搜索\",\n titleEN: \"Search\",\n description: \"搜索想法\"\n },\n component: _views_app_MobileSearchView_vue__WEBPACK_IMPORTED_MODULE_14__[\"default\"],\n beforeEnter: authBeforeEnter,\n props: route => ({\n q: 'q' in route.query ? route.query.q : ''\n })\n}, {\n path: '/r/user',\n name: 'user',\n meta: {\n titleZH: \"用户设置\",\n titleEN: \"User Profile\",\n description: \"用户设置\"\n },\n component: _views_app_UserProfileView_vue__WEBPACK_IMPORTED_MODULE_2__[\"default\"],\n beforeEnter: authBeforeEnter\n}, {\n path: '/r/settings',\n name: 'settings',\n meta: {\n titleZH: \"应用设置\",\n titleEN: \"Settings\"\n },\n component: _views_app_SettingsView_vue__WEBPACK_IMPORTED_MODULE_9__[\"default\"],\n beforeEnter: authBeforeEnter\n}, {\n path: '/r/import',\n name: 'import',\n meta: {\n titleZH: \"导入数据\",\n titleEN: \"Import Data\",\n description: \"导入数据到 Rethink\"\n },\n component: _views_app_ImportDataView_vue__WEBPACK_IMPORTED_MODULE_15__[\"default\"],\n beforeEnter: authBeforeEnter\n}];\nconst router = (0,vue_router__WEBPACK_IMPORTED_MODULE_18__.createRouter)({\n history: (0,vue_router__WEBPACK_IMPORTED_MODULE_18__.createWebHistory)(\"/\"),\n routes\n});\nrouter.beforeEach(to => {\n let t = \"Rethink\";\n if (_utils_multiLang__WEBPACK_IMPORTED_MODULE_16__[\"default\"].getGlobalLang() === \"zh\") {\n if (!(\"titleZH\" in to.meta)) return;\n t = to.meta.titleZH;\n } else if (_utils_multiLang__WEBPACK_IMPORTED_MODULE_16__[\"default\"].getGlobalLang() === \"en\") {\n if (!(\"titleEN\" in to.meta)) return;\n t = to.meta.titleEN;\n }\n const metaTitle = t;\n if (to.name !== \"home\") {\n t += \" - Rethink\";\n }\n const desc = \"description\" in to.meta ? to.meta.description : \"https://rethink.run\";\n (0,_utils_meta__WEBPACK_IMPORTED_MODULE_17__[\"default\"])(t, metaTitle, desc);\n});\n/* harmony default export */ __webpack_exports__[\"default\"] = (router);\n\n//# sourceURL=webpack://rethink/./src/router/index.ts?"); /***/ }), @@ -1928,7 +1928,7 @@ \****************************************/ /***/ (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { - eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var vditor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vditor */ \"./node_modules/vditor/dist/index.min.js\");\n/* harmony import */ var vditor__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(vditor__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _assets_css_vditor_vditor_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @/assets/css/vditor/vditor.css */ \"./src/assets/css/vditor/vditor.css\");\n/* harmony import */ var vue_router__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! vue-router */ \"./node_modules/vue-router/dist/vue-router.mjs\");\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n/* harmony import */ var _utils_app_node__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @/utils/app/node */ \"./src/utils/app/node.ts\");\n/* harmony import */ var _router__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @/router */ \"./src/router/index.ts\");\n/* harmony import */ var _utils_multiLang__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @/utils/multiLang */ \"./src/utils/multiLang.ts\");\n/* harmony import */ var _utils_configs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @/utils/configs */ \"./src/utils/configs.ts\");\n/* harmony import */ var _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @/utils/app/editor/refs */ \"./src/utils/app/editor/refs.ts\");\n/* harmony import */ var _utils_app_editor_utils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @/utils/app/editor/utils */ \"./src/utils/app/editor/utils.ts\");\n/* harmony import */ var _utils_app_editor_atTag__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @/utils/app/editor/atTag */ \"./src/utils/app/editor/atTag.ts\");\n/* harmony import */ var _utils_mq__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @/utils/mq */ \"./src/utils/mq.ts\");\n/* harmony import */ var _utils_app_editor_keyEvent__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @/utils/app/editor/keyEvent */ \"./src/utils/app/editor/keyEvent.ts\");\n/* harmony import */ var _utils_account_token__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @/utils/account/token */ \"./src/utils/account/token.ts\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst ready = (0,vue__WEBPACK_IMPORTED_MODULE_2__.ref)(false);\nasync function updateTextEl() {\n if (!_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value || !_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value) return;\n (0,_utils_app_editor_atTag__WEBPACK_IMPORTED_MODULE_9__.replaceATag)();\n}\nconst syncTimeString = utcDateStr => {\n // var utcDate = \"2022-03-19T20:15:50.000Z\";\n const utcDate = new Date(utcDateStr);\n const now = new Date();\n const year = utcDate.getFullYear();\n const month = `0${utcDate.getMonth() + 1}`.slice(-2);\n const day = `0${utcDate.getDate()}`.slice(-2);\n const hour = `0${utcDate.getHours()}`.slice(-2);\n const minute = `0${utcDate.getMinutes()}`.slice(-2);\n const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n const dayDelta = (today.getTime() - utcDate.getTime()) / 1000 / 60 / 60 / 24;\n if (dayDelta >= 365) {\n // >= 1 year\n return `${year}-${month}-${day}`;\n } else if (dayDelta >= 0) {\n // >= 1 day\n return `${month}-${day}`;\n } else {\n // today\n return `${hour}:${minute}`;\n }\n};\nfunction updateSyncStatue() {\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editorSyncStatus.value = _utils_multiLang__WEBPACK_IMPORTED_MODULE_5__[\"default\"].get(\"editorSyncStatusSaved\");\n // 5 seconds later, update the editorSyncStatus\n setInterval(() => {\n if (!_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value) return;\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editorSyncStatus.value = _utils_multiLang__WEBPACK_IMPORTED_MODULE_5__[\"default\"].get(\"editorSyncStatusLastSaved\") + syncTimeString(_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.modifiedAt);\n }, 5000);\n}\nfunction createEditor(id) {\n if (!_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value) return;\n const text = (0,_utils_app_editor_utils__WEBPACK_IMPORTED_MODULE_8__.stripWhitespace)(_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.md);\n let height, toolbar;\n if ((0,_utils_mq__WEBPACK_IMPORTED_MODULE_10__.getMQ)() === \"sm\") {\n height = \"calc(100% - 180px)\";\n toolbar = [\"|\", \"undo\", \"redo\", \"|\", \"upload\"];\n } else {\n height = \"calc(100% - 60px)\";\n toolbar = [\"|\", \"outline\", \"|\", \"undo\", \"redo\", \"|\", \"code\", \"table\", \"upload\", \"|\", \"fullscreen\"];\n }\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value = new (vditor__WEBPACK_IMPORTED_MODULE_0___default())(id, {\n // minHeight: 200,\n icon: \"material\",\n height: height,\n width: \"98vw\",\n lang: _utils_multiLang__WEBPACK_IMPORTED_MODULE_5__[\"default\"].getGlobalLang() === \"zh\" ? \"zh_CN\" : \"en_US\",\n mode: \"wysiwyg\",\n placeholder: _utils_multiLang__WEBPACK_IMPORTED_MODULE_5__[\"default\"].get(\"editorContentPlaceholder\"),\n outline: {\n enable: false,\n position: \"left\"\n },\n tab: \" \",\n // comment: {enable: true,},\n toolbar: [{\n name: _utils_multiLang__WEBPACK_IMPORTED_MODULE_5__[\"default\"].get(\"goBackIcon\"),\n tipPosition: \"nw\",\n tip: _utils_multiLang__WEBPACK_IMPORTED_MODULE_5__[\"default\"].get(\"goBackIcon\"),\n icon: '\\n' + ' \\n' + ' \\n' + '',\n click: () => _router__WEBPACK_IMPORTED_MODULE_4__[\"default\"].go(-1)\n }, ...toolbar],\n toolbarConfig: {\n hide: false,\n pin: true\n },\n undoDelay: 500,\n upload: {\n accept: 'image/*',\n max: 10 * 1024 * 1024,\n headers: {\n token: (0,_utils_account_token__WEBPACK_IMPORTED_MODULE_12__.getToken)()\n },\n multiple: false,\n url: `${_utils_configs__WEBPACK_IMPORTED_MODULE_6__[\"default\"].apiUrl}/api/files/imageUploadVditor`,\n linkToImgUrl: `${_utils_configs__WEBPACK_IMPORTED_MODULE_6__[\"default\"].apiUrl}/api/files/imageFetchVditor`,\n filename(name) {\n // eslint-disable-next-line no-useless-escape\n return name.replace(/[^(a-zA-Z0-9\\u4e00-\\u9fa5\\.)]/g, '').\n // eslint-disable-next-line no-useless-escape\n replace(/[\\?\\\\/:|<>\\*\\[\\]\\(\\)\\$%\\{\\}@~]/g, '').replace('/\\\\s/g', '');\n }\n },\n preview: {\n markdown: {\n sanitize: true,\n // gfmAutoLink: true,\n mark: true,\n codeBlockPreview: true\n // linkPrefix: \"https://\",\n },\n\n hljs: {\n enable: true,\n lineNumber: true,\n defaultLang: \"python\",\n // style: \"github\",\n style: \"dracula\"\n }\n },\n cache: {\n enable: true,\n id: _utils_configs__WEBPACK_IMPORTED_MODULE_6__[\"default\"].mdCacheId,\n after: async md => {\n if (!_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value) return;\n md = (0,_utils_app_editor_utils__WEBPACK_IMPORTED_MODULE_8__.stripWhitespace)(md.trim());\n // skip if not changed\n const oldMd = (0,_utils_app_editor_utils__WEBPACK_IMPORTED_MODULE_8__.stripWhitespace)(_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.md);\n if (oldMd === md) return;\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value = await (0,_utils_app_node__WEBPACK_IMPORTED_MODULE_3__.updateNode)(_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.id, md);\n await updateTextEl();\n updateSyncStatue();\n }\n },\n after: async () => {\n if (!_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value) return;\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value.setValue(text);\n await updateTextEl();\n const el = _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value.vditor.element;\n el.addEventListener(\"mouseup\", _utils_app_editor_atTag__WEBPACK_IMPORTED_MODULE_9__.moveCursorOutATag);\n el.addEventListener(\"keyup\", _utils_app_editor_keyEvent__WEBPACK_IMPORTED_MODULE_11__.onKeyup);\n // check @ input\n el.addEventListener(\"beforeinput\", _utils_app_editor_keyEvent__WEBPACK_IMPORTED_MODULE_11__.beforeInput);\n if ((0,_utils_mq__WEBPACK_IMPORTED_MODULE_10__.getMQ)() === \"sm\") {\n el.blur();\n }\n ready.value = true;\n }\n });\n}\nfunction useEditor(id, nid) {\n (0,vue__WEBPACK_IMPORTED_MODULE_2__.onBeforeMount)(() => {\n ready.value = false;\n });\n (0,vue__WEBPACK_IMPORTED_MODULE_2__.onMounted)(async () => {\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value = await (0,_utils_app_node__WEBPACK_IMPORTED_MODULE_3__.getNode)(nid);\n if (!_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value) {\n _router__WEBPACK_IMPORTED_MODULE_4__[\"default\"].go(-1);\n return;\n }\n createEditor(id);\n document.title = _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.title + \" - Rethink\";\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editorSyncStatus.value = _utils_multiLang__WEBPACK_IMPORTED_MODULE_5__[\"default\"].get(\"editorSyncStatusLastSaved\") + syncTimeString(_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.modifiedAt);\n });\n (0,vue_router__WEBPACK_IMPORTED_MODULE_13__.onBeforeRouteUpdate)(async (to, from, next) => {\n if (to.params.id === from.params.id) return next();\n // for the case that the node is changed\n // hide the at-search-result\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.isAtSearch.value = false;\n // reset the linedNodeExpanded\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.linedNodeExpanded.value.forEach((_, i) => {\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.linedNodeExpanded.value[i] = false;\n });\n if (typeof to.params.id !== \"string\") return next(false);\n // get new node\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value = await (0,_utils_app_node__WEBPACK_IMPORTED_MODULE_3__.getNode)(to.params.id);\n if (!_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value) {\n _router__WEBPACK_IMPORTED_MODULE_4__[\"default\"].go(-1);\n return next(false);\n }\n // reset editor\n if (_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value) {\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value.setValue((0,_utils_app_editor_utils__WEBPACK_IMPORTED_MODULE_8__.stripWhitespace)(_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.md));\n const e = _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value.vditor.element.querySelector(\".vditor-reset\");\n if (e) {\n e.scrollTop = 0;\n }\n document.title = _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.title + \" - Rethink\";\n await updateTextEl();\n }\n return next();\n });\n (0,vue__WEBPACK_IMPORTED_MODULE_2__.onUnmounted)(async () => {\n if (!_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value) return;\n if (_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value) {\n const md = (0,_utils_app_editor_utils__WEBPACK_IMPORTED_MODULE_8__.stripWhitespace)(_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value.getValue().trim());\n // skip if not changed\n const oldMd = (0,_utils_app_editor_utils__WEBPACK_IMPORTED_MODULE_8__.stripWhitespace)(_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.md);\n if (oldMd !== md) {\n await (0,_utils_app_node__WEBPACK_IMPORTED_MODULE_3__.updateNode)(_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.id, md);\n }\n }\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value.vditor.element.removeEventListener(\"selectionchange\", _utils_app_editor_atTag__WEBPACK_IMPORTED_MODULE_9__.moveCursorOutATag);\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value.vditor.element.removeEventListener(\"keyup\", _utils_app_editor_keyEvent__WEBPACK_IMPORTED_MODULE_11__.onKeyup);\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value.vditor.element.removeEventListener(\"beforeinput\", _utils_app_editor_keyEvent__WEBPACK_IMPORTED_MODULE_11__.beforeInput);\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value.destroy();\n });\n return {\n node: _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node,\n ready\n };\n}\n/* harmony default export */ __webpack_exports__[\"default\"] = (useEditor);\n\n//# sourceURL=webpack://rethink/./src/utils/app/editor/editor.ts?"); + eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var vditor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vditor */ \"./node_modules/vditor/dist/index.min.js\");\n/* harmony import */ var vditor__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(vditor__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _assets_css_vditor_vditor_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @/assets/css/vditor/vditor.css */ \"./src/assets/css/vditor/vditor.css\");\n/* harmony import */ var vue_router__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! vue-router */ \"./node_modules/vue-router/dist/vue-router.mjs\");\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n/* harmony import */ var _utils_app_node__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @/utils/app/node */ \"./src/utils/app/node.ts\");\n/* harmony import */ var _router__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @/router */ \"./src/router/index.ts\");\n/* harmony import */ var _utils_multiLang__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @/utils/multiLang */ \"./src/utils/multiLang.ts\");\n/* harmony import */ var _utils_configs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @/utils/configs */ \"./src/utils/configs.ts\");\n/* harmony import */ var _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @/utils/app/editor/refs */ \"./src/utils/app/editor/refs.ts\");\n/* harmony import */ var _utils_app_editor_utils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @/utils/app/editor/utils */ \"./src/utils/app/editor/utils.ts\");\n/* harmony import */ var _utils_app_editor_atTag__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @/utils/app/editor/atTag */ \"./src/utils/app/editor/atTag.ts\");\n/* harmony import */ var _utils_mq__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @/utils/mq */ \"./src/utils/mq.ts\");\n/* harmony import */ var _utils_app_editor_keyEvent__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @/utils/app/editor/keyEvent */ \"./src/utils/app/editor/keyEvent.ts\");\n/* harmony import */ var _utils_account_token__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @/utils/account/token */ \"./src/utils/account/token.ts\");\n/* harmony import */ var _utils_meta__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @/utils/meta */ \"./src/utils/meta.ts\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst ready = (0,vue__WEBPACK_IMPORTED_MODULE_2__.ref)(false);\nasync function updateTextEl() {\n if (!_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value || !_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value) return;\n (0,_utils_app_editor_atTag__WEBPACK_IMPORTED_MODULE_9__.replaceATag)();\n}\nconst syncTimeString = utcDateStr => {\n // var utcDate = \"2022-03-19T20:15:50.000Z\";\n const utcDate = new Date(utcDateStr);\n const now = new Date();\n const year = utcDate.getFullYear();\n const month = `0${utcDate.getMonth() + 1}`.slice(-2);\n const day = `0${utcDate.getDate()}`.slice(-2);\n const hour = `0${utcDate.getHours()}`.slice(-2);\n const minute = `0${utcDate.getMinutes()}`.slice(-2);\n const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n const dayDelta = (today.getTime() - utcDate.getTime()) / 1000 / 60 / 60 / 24;\n if (dayDelta >= 365) {\n // >= 1 year\n return `${year}-${month}-${day}`;\n } else if (dayDelta >= 0) {\n // >= 1 day\n return `${month}-${day}`;\n } else {\n // today\n return `${hour}:${minute}`;\n }\n};\nfunction updateSyncStatue() {\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editorSyncStatus.value = _utils_multiLang__WEBPACK_IMPORTED_MODULE_5__[\"default\"].get(\"editorSyncStatusSaved\");\n // 5 seconds later, update the editorSyncStatus\n setInterval(() => {\n if (!_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value) return;\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editorSyncStatus.value = _utils_multiLang__WEBPACK_IMPORTED_MODULE_5__[\"default\"].get(\"editorSyncStatusLastSaved\") + syncTimeString(_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.modifiedAt);\n }, 5000);\n}\nfunction createEditor(id) {\n if (!_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value) return;\n const text = (0,_utils_app_editor_utils__WEBPACK_IMPORTED_MODULE_8__.stripWhitespace)(_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.md);\n let height, toolbar;\n if ((0,_utils_mq__WEBPACK_IMPORTED_MODULE_10__.getMQ)() === \"sm\") {\n height = \"calc(100% - 180px)\";\n toolbar = [\"|\", \"undo\", \"redo\", \"|\", \"upload\"];\n } else {\n height = \"calc(100% - 60px)\";\n toolbar = [\"|\", \"outline\", \"|\", \"undo\", \"redo\", \"|\", \"code\", \"table\", \"upload\", \"|\", \"fullscreen\"];\n }\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value = new (vditor__WEBPACK_IMPORTED_MODULE_0___default())(id, {\n // minHeight: 200,\n icon: \"material\",\n height: height,\n width: \"98vw\",\n lang: _utils_multiLang__WEBPACK_IMPORTED_MODULE_5__[\"default\"].getGlobalLang() === \"zh\" ? \"zh_CN\" : \"en_US\",\n mode: \"wysiwyg\",\n placeholder: _utils_multiLang__WEBPACK_IMPORTED_MODULE_5__[\"default\"].get(\"editorContentPlaceholder\"),\n outline: {\n enable: false,\n position: \"left\"\n },\n tab: \" \",\n // comment: {enable: true,},\n toolbar: [{\n name: _utils_multiLang__WEBPACK_IMPORTED_MODULE_5__[\"default\"].get(\"goBackIcon\"),\n tipPosition: \"nw\",\n tip: _utils_multiLang__WEBPACK_IMPORTED_MODULE_5__[\"default\"].get(\"goBackIcon\"),\n icon: '\\n' + ' \\n' + ' \\n' + '',\n click: () => _router__WEBPACK_IMPORTED_MODULE_4__[\"default\"].go(-1)\n }, ...toolbar],\n toolbarConfig: {\n hide: false,\n pin: true\n },\n undoDelay: 500,\n upload: {\n accept: 'image/*',\n max: 10 * 1024 * 1024,\n headers: {\n token: (0,_utils_account_token__WEBPACK_IMPORTED_MODULE_12__.getToken)()\n },\n multiple: false,\n url: `${_utils_configs__WEBPACK_IMPORTED_MODULE_6__[\"default\"].apiUrl}/api/files/imageUploadVditor`,\n linkToImgUrl: `${_utils_configs__WEBPACK_IMPORTED_MODULE_6__[\"default\"].apiUrl}/api/files/imageFetchVditor`,\n filename(name) {\n // eslint-disable-next-line no-useless-escape\n return name.replace(/[^(a-zA-Z0-9\\u4e00-\\u9fa5\\.)]/g, '').\n // eslint-disable-next-line no-useless-escape\n replace(/[\\?\\\\/:|<>\\*\\[\\]\\(\\)\\$%\\{\\}@~]/g, '').replace('/\\\\s/g', '');\n }\n },\n preview: {\n markdown: {\n sanitize: true,\n // gfmAutoLink: true,\n mark: true,\n codeBlockPreview: true\n // linkPrefix: \"https://\",\n },\n\n hljs: {\n enable: true,\n lineNumber: true,\n defaultLang: \"python\",\n // style: \"github\",\n style: \"dracula\"\n }\n },\n cache: {\n enable: true,\n id: _utils_configs__WEBPACK_IMPORTED_MODULE_6__[\"default\"].mdCacheId,\n after: async md => {\n if (!_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value) return;\n md = (0,_utils_app_editor_utils__WEBPACK_IMPORTED_MODULE_8__.stripWhitespace)(md.trim());\n // skip if not changed\n const oldMd = (0,_utils_app_editor_utils__WEBPACK_IMPORTED_MODULE_8__.stripWhitespace)(_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.md);\n if (oldMd === md) return;\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value = await (0,_utils_app_node__WEBPACK_IMPORTED_MODULE_3__.updateNode)(_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.id, md);\n await updateTextEl();\n updateSyncStatue();\n }\n },\n after: async () => {\n if (!_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value) return;\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value.setValue(text);\n await updateTextEl();\n const el = _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value.vditor.element;\n el.addEventListener(\"mouseup\", _utils_app_editor_atTag__WEBPACK_IMPORTED_MODULE_9__.moveCursorOutATag);\n el.addEventListener(\"keyup\", _utils_app_editor_keyEvent__WEBPACK_IMPORTED_MODULE_11__.onKeyup);\n // check @ input\n el.addEventListener(\"beforeinput\", _utils_app_editor_keyEvent__WEBPACK_IMPORTED_MODULE_11__.beforeInput);\n if ((0,_utils_mq__WEBPACK_IMPORTED_MODULE_10__.getMQ)() === \"sm\") {\n el.blur();\n }\n ready.value = true;\n }\n });\n}\nfunction useEditor(id, nid) {\n (0,vue__WEBPACK_IMPORTED_MODULE_2__.onBeforeMount)(() => {\n ready.value = false;\n });\n (0,vue__WEBPACK_IMPORTED_MODULE_2__.onMounted)(async () => {\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value = await (0,_utils_app_node__WEBPACK_IMPORTED_MODULE_3__.getNode)(nid);\n if (!_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value) {\n _router__WEBPACK_IMPORTED_MODULE_4__[\"default\"].go(-1);\n return;\n }\n createEditor(id);\n (0,_utils_meta__WEBPACK_IMPORTED_MODULE_13__[\"default\"])(_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.title + \" - Rethink\", _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.title, _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.snippet);\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editorSyncStatus.value = _utils_multiLang__WEBPACK_IMPORTED_MODULE_5__[\"default\"].get(\"editorSyncStatusLastSaved\") + syncTimeString(_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.modifiedAt);\n });\n (0,vue_router__WEBPACK_IMPORTED_MODULE_14__.onBeforeRouteUpdate)(async (to, from, next) => {\n if (to.params.id === from.params.id) return next();\n // for the case that the node is changed\n // hide the at-search-result\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.isAtSearch.value = false;\n // reset the linedNodeExpanded\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.linedNodeExpanded.value.forEach((_, i) => {\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.linedNodeExpanded.value[i] = false;\n });\n if (typeof to.params.id !== \"string\") return next(false);\n // get new node\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value = await (0,_utils_app_node__WEBPACK_IMPORTED_MODULE_3__.getNode)(to.params.id);\n if (!_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value) {\n _router__WEBPACK_IMPORTED_MODULE_4__[\"default\"].go(-1);\n return next(false);\n }\n // reset editor\n if (_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value) {\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value.setValue((0,_utils_app_editor_utils__WEBPACK_IMPORTED_MODULE_8__.stripWhitespace)(_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.md));\n const e = _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value.vditor.element.querySelector(\".vditor-reset\");\n if (e) {\n e.scrollTop = 0;\n }\n // change HTML document\n (0,_utils_meta__WEBPACK_IMPORTED_MODULE_13__[\"default\"])(_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.title + \" - Rethink\", _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.title, _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.snippet);\n await updateTextEl();\n }\n return next();\n });\n (0,vue__WEBPACK_IMPORTED_MODULE_2__.onUnmounted)(async () => {\n if (!_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value) return;\n if (_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value) {\n const md = (0,_utils_app_editor_utils__WEBPACK_IMPORTED_MODULE_8__.stripWhitespace)(_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value.getValue().trim());\n // skip if not changed\n const oldMd = (0,_utils_app_editor_utils__WEBPACK_IMPORTED_MODULE_8__.stripWhitespace)(_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.md);\n if (oldMd !== md) {\n await (0,_utils_app_node__WEBPACK_IMPORTED_MODULE_3__.updateNode)(_utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node.value.id, md);\n }\n }\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value.vditor.element.removeEventListener(\"selectionchange\", _utils_app_editor_atTag__WEBPACK_IMPORTED_MODULE_9__.moveCursorOutATag);\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value.vditor.element.removeEventListener(\"keyup\", _utils_app_editor_keyEvent__WEBPACK_IMPORTED_MODULE_11__.onKeyup);\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value.vditor.element.removeEventListener(\"beforeinput\", _utils_app_editor_keyEvent__WEBPACK_IMPORTED_MODULE_11__.beforeInput);\n _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.editor.value.destroy();\n });\n return {\n node: _utils_app_editor_refs__WEBPACK_IMPORTED_MODULE_7__.node,\n ready\n };\n}\n/* harmony default export */ __webpack_exports__[\"default\"] = (useEditor);\n\n//# sourceURL=webpack://rethink/./src/utils/app/editor/editor.ts?"); /***/ }), @@ -2000,7 +2000,7 @@ \*******************************/ /***/ (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { - eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ cursorQuery: function() { return /* binding */ cursorQuery; },\n/* harmony export */ cursorSearchSelect: function() { return /* binding */ cursorSearchSelect; },\n/* harmony export */ deleteNodeInTrash: function() { return /* binding */ deleteNodeInTrash; },\n/* harmony export */ getNode: function() { return /* binding */ getNode; },\n/* harmony export */ getNodesInTrash: function() { return /* binding */ getNodesInTrash; },\n/* harmony export */ goNewNodePage: function() { return /* binding */ goNewNodePage; },\n/* harmony export */ node2Trash: function() { return /* binding */ node2Trash; },\n/* harmony export */ putNode: function() { return /* binding */ putNode; },\n/* harmony export */ restoreNodeFromTrash: function() { return /* binding */ restoreNodeFromTrash; },\n/* harmony export */ searchUserNodes: function() { return /* binding */ searchUserNodes; },\n/* harmony export */ updateNode: function() { return /* binding */ updateNode; },\n/* harmony export */ useNode: function() { return /* binding */ useNode; }\n/* harmony export */ });\n/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array.push.js */ \"./node_modules/core-js/modules/es.array.push.js\");\n/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _utils_const__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @/utils/const */ \"./src/utils/const.ts\");\n/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! axios */ \"./node_modules/axios/lib/axios.js\");\n/* harmony import */ var _utils_configs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @/utils/configs */ \"./src/utils/configs.ts\");\n/* harmony import */ var _utils_requestId__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @/utils/requestId */ \"./src/utils/requestId.ts\");\n/* harmony import */ var _utils_msgBox__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @/utils/msgBox */ \"./src/utils/msgBox.ts\");\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n/* harmony import */ var _router__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @/router */ \"./src/router/index.ts\");\n/* harmony import */ var _utils_account_token__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @/utils/account/token */ \"./src/utils/account/token.ts\");\n\n\n\n\n\n\n\n\n\nasync function updateNode(nid, md) {\n try {\n const resp = await axios__WEBPACK_IMPORTED_MODULE_8__[\"default\"].post(`${_utils_configs__WEBPACK_IMPORTED_MODULE_2__[\"default\"].apiUrl}/api/node`, {\n nid: nid,\n requestId: (0,_utils_requestId__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(),\n md: md\n }, {\n headers: {\n ContentType: 'application/json',\n token: (0,_utils_account_token__WEBPACK_IMPORTED_MODULE_7__.getToken)()\n }\n });\n if (resp.data.code !== 0) {\n (0,_utils_msgBox__WEBPACK_IMPORTED_MODULE_4__.showErrorMsgBox)(resp.data.message);\n return null;\n }\n return resp.data.node;\n } catch (err) {\n console.log(err);\n }\n return null;\n}\nasync function cursorQuery(nid, textBeforeCursor) {\n try {\n const resp = await axios__WEBPACK_IMPORTED_MODULE_8__[\"default\"].post(`${_utils_configs__WEBPACK_IMPORTED_MODULE_2__[\"default\"].apiUrl}/api/search/cursor`, {\n nid: nid,\n requestId: (0,_utils_requestId__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(),\n textBeforeCursor: textBeforeCursor\n }, {\n headers: {\n ContentType: 'application/json',\n token: (0,_utils_account_token__WEBPACK_IMPORTED_MODULE_7__.getToken)()\n }\n });\n if (resp.data.code !== 0) {\n (0,_utils_msgBox__WEBPACK_IMPORTED_MODULE_4__.showErrorMsgBox)(resp.data.message);\n return [];\n }\n return resp.data.nodes;\n } catch (err) {\n console.log(err);\n }\n return [];\n}\nasync function putNode(md, fromNid = \"\") {\n try {\n const resp = await axios__WEBPACK_IMPORTED_MODULE_8__[\"default\"].put(`${_utils_configs__WEBPACK_IMPORTED_MODULE_2__[\"default\"].apiUrl}/api/node`, {\n fromNid: fromNid,\n requestId: (0,_utils_requestId__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(),\n md: md,\n type: _utils_const__WEBPACK_IMPORTED_MODULE_1__[\"default\"].nodeType.Markdown\n }, {\n headers: {\n ContentType: 'application/json',\n token: (0,_utils_account_token__WEBPACK_IMPORTED_MODULE_7__.getToken)()\n }\n });\n if (resp.data.code !== 0) {\n (0,_utils_msgBox__WEBPACK_IMPORTED_MODULE_4__.showErrorMsgBox)(resp.data.message);\n return null;\n }\n return resp.data.node;\n } catch (err) {\n console.log(err);\n }\n return null;\n}\nasync function node2Trash(nid) {\n try {\n const resp = await axios__WEBPACK_IMPORTED_MODULE_8__[\"default\"].put(`${_utils_configs__WEBPACK_IMPORTED_MODULE_2__[\"default\"].apiUrl}/api/trash`, {\n nid: nid,\n requestId: (0,_utils_requestId__WEBPACK_IMPORTED_MODULE_3__[\"default\"])()\n }, {\n headers: {\n token: (0,_utils_account_token__WEBPACK_IMPORTED_MODULE_7__.getToken)()\n }\n });\n if (resp.data.code !== 0) {\n (0,_utils_msgBox__WEBPACK_IMPORTED_MODULE_4__.showErrorMsgBox)(resp.data.message);\n return false;\n }\n return true;\n } catch (err) {\n console.log(err);\n return false;\n }\n}\nasync function getNodesInTrash(page, pageSize) {\n const defaultPagedNodeInfo = {\n nodes: [],\n total: 0\n };\n try {\n const resp = await axios__WEBPACK_IMPORTED_MODULE_8__[\"default\"].get(`${_utils_configs__WEBPACK_IMPORTED_MODULE_2__[\"default\"].apiUrl}/api/trash`, {\n params: {\n p: page,\n ps: pageSize\n },\n headers: {\n token: (0,_utils_account_token__WEBPACK_IMPORTED_MODULE_7__.getToken)(),\n rid: (0,_utils_requestId__WEBPACK_IMPORTED_MODULE_3__[\"default\"])()\n }\n });\n if (resp.data.code !== 0) {\n (0,_utils_msgBox__WEBPACK_IMPORTED_MODULE_4__.showErrorMsgBox)(resp.data.message);\n return defaultPagedNodeInfo;\n }\n return resp.data.data;\n } catch (err) {\n console.log(err);\n return defaultPagedNodeInfo;\n }\n}\nasync function restoreNodeFromTrash(nid) {\n try {\n const resp = await axios__WEBPACK_IMPORTED_MODULE_8__[\"default\"].post(`${_utils_configs__WEBPACK_IMPORTED_MODULE_2__[\"default\"].apiUrl}/api/trashRestore`, {\n requestId: (0,_utils_requestId__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(),\n nid: nid\n }, {\n headers: {\n token: (0,_utils_account_token__WEBPACK_IMPORTED_MODULE_7__.getToken)()\n }\n });\n if (resp.data.code !== 0) {\n (0,_utils_msgBox__WEBPACK_IMPORTED_MODULE_4__.showErrorMsgBox)(resp.data.message);\n return false;\n }\n return true;\n } catch (err) {\n console.log(err);\n return false;\n }\n}\nasync function deleteNodeInTrash(nid) {\n try {\n const resp = await axios__WEBPACK_IMPORTED_MODULE_8__[\"default\"].delete(`${_utils_configs__WEBPACK_IMPORTED_MODULE_2__[\"default\"].apiUrl}/api/trash/${nid}`, {\n headers: {\n token: (0,_utils_account_token__WEBPACK_IMPORTED_MODULE_7__.getToken)()\n }\n });\n if (resp.data.code !== 0) {\n (0,_utils_msgBox__WEBPACK_IMPORTED_MODULE_4__.showErrorMsgBox)(resp.data.message);\n return false;\n }\n return true;\n } catch (err) {\n console.log(err);\n return false;\n }\n}\nasync function goNewNodePage() {\n const n = await putNode(\"\", \"\");\n if (n === null) {\n return;\n }\n await _router__WEBPACK_IMPORTED_MODULE_6__[\"default\"].push({\n name: \"node\",\n params: {\n id: n.id\n }\n });\n}\nconst getNode = async nid => {\n try {\n const resp = await axios__WEBPACK_IMPORTED_MODULE_8__[\"default\"].get(`${_utils_configs__WEBPACK_IMPORTED_MODULE_2__[\"default\"].apiUrl}/api/node`, {\n params: {\n nid: nid\n },\n headers: {\n token: (0,_utils_account_token__WEBPACK_IMPORTED_MODULE_7__.getToken)(),\n rid: (0,_utils_requestId__WEBPACK_IMPORTED_MODULE_3__[\"default\"])()\n }\n });\n if (resp.data.code !== 0) {\n (0,_utils_msgBox__WEBPACK_IMPORTED_MODULE_4__.showErrorMsgBox)(resp.data.message);\n return null;\n }\n return resp.data.node;\n } catch (err) {\n console.log(err);\n }\n return null;\n};\nconst searchUserNodes = async (query, sortKey = \"createdAt\", sortOrder = -1, page = 0, pageSize = 0, nidExclude = []) => {\n const defaultPagedNodeInfo = {\n nodes: [],\n total: 0\n };\n try {\n const resp = await axios__WEBPACK_IMPORTED_MODULE_8__[\"default\"].post(`${_utils_configs__WEBPACK_IMPORTED_MODULE_2__[\"default\"].apiUrl}/api/search/node`, {\n requestId: (0,_utils_requestId__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(),\n query: query,\n sortKey: sortKey,\n sortOrder: sortOrder,\n page: page,\n pageSize: pageSize,\n nidExclude: nidExclude\n }, {\n headers: {\n ContentType: 'application/json',\n token: (0,_utils_account_token__WEBPACK_IMPORTED_MODULE_7__.getToken)()\n }\n });\n if (resp.data.code !== 0) {\n (0,_utils_msgBox__WEBPACK_IMPORTED_MODULE_4__.showErrorMsgBox)(resp.data.message);\n return defaultPagedNodeInfo;\n }\n return resp.data.data;\n } catch (err) {\n console.log(err);\n return defaultPagedNodeInfo;\n }\n};\nconst cursorSearchSelect = async (nid, toNid) => {\n try {\n const resp = await axios__WEBPACK_IMPORTED_MODULE_8__[\"default\"].put(`${_utils_configs__WEBPACK_IMPORTED_MODULE_2__[\"default\"].apiUrl}/api/search/cursorSelect`, {\n requestId: (0,_utils_requestId__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(),\n nid: nid,\n toNid: toNid\n }, {\n headers: {\n ContentType: 'application/json',\n token: (0,_utils_account_token__WEBPACK_IMPORTED_MODULE_7__.getToken)()\n }\n });\n if (resp.data.code !== 0) {\n (0,_utils_msgBox__WEBPACK_IMPORTED_MODULE_4__.showErrorMsgBox)(resp.data.message);\n return false;\n }\n return true;\n } catch (err) {\n console.log(err);\n return false;\n }\n};\nfunction useNode(nid) {\n const nodeData = (0,vue__WEBPACK_IMPORTED_MODULE_5__.ref)(null);\n (0,vue__WEBPACK_IMPORTED_MODULE_5__.onBeforeMount)(async () => {\n nodeData.value = await getNode(nid);\n if (nodeData.value === null) {\n await _router__WEBPACK_IMPORTED_MODULE_6__[\"default\"].go(-1);\n }\n });\n return nodeData;\n}\n\n\n//# sourceURL=webpack://rethink/./src/utils/app/node.ts?"); + eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ cursorQuery: function() { return /* binding */ cursorQuery; },\n/* harmony export */ cursorSearchSelect: function() { return /* binding */ cursorSearchSelect; },\n/* harmony export */ deleteNodeInTrash: function() { return /* binding */ deleteNodeInTrash; },\n/* harmony export */ getNode: function() { return /* binding */ getNode; },\n/* harmony export */ getNodesInTrash: function() { return /* binding */ getNodesInTrash; },\n/* harmony export */ goNewNodePage: function() { return /* binding */ goNewNodePage; },\n/* harmony export */ node2Trash: function() { return /* binding */ node2Trash; },\n/* harmony export */ putNode: function() { return /* binding */ putNode; },\n/* harmony export */ restoreNodeFromTrash: function() { return /* binding */ restoreNodeFromTrash; },\n/* harmony export */ searchUserNodes: function() { return /* binding */ searchUserNodes; },\n/* harmony export */ updateNode: function() { return /* binding */ updateNode; },\n/* harmony export */ useNode: function() { return /* binding */ useNode; }\n/* harmony export */ });\n/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array.push.js */ \"./node_modules/core-js/modules/es.array.push.js\");\n/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _utils_const__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @/utils/const */ \"./src/utils/const.ts\");\n/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! axios */ \"./node_modules/axios/lib/axios.js\");\n/* harmony import */ var _utils_configs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @/utils/configs */ \"./src/utils/configs.ts\");\n/* harmony import */ var _utils_requestId__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @/utils/requestId */ \"./src/utils/requestId.ts\");\n/* harmony import */ var _utils_msgBox__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @/utils/msgBox */ \"./src/utils/msgBox.ts\");\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n/* harmony import */ var _router__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @/router */ \"./src/router/index.ts\");\n/* harmony import */ var _utils_account_token__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @/utils/account/token */ \"./src/utils/account/token.ts\");\n\n\n\n\n\n\n\n\n\nasync function updateNode(nid, md) {\n try {\n const resp = await axios__WEBPACK_IMPORTED_MODULE_8__[\"default\"].post(`${_utils_configs__WEBPACK_IMPORTED_MODULE_2__[\"default\"].apiUrl}/api/node`, {\n nid: nid,\n requestId: (0,_utils_requestId__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(),\n md: md\n }, {\n headers: {\n ContentType: 'application/json',\n token: (0,_utils_account_token__WEBPACK_IMPORTED_MODULE_7__.getToken)()\n }\n });\n if (resp.data.code !== 0) {\n (0,_utils_msgBox__WEBPACK_IMPORTED_MODULE_4__.showErrorMsgBox)(resp.data.message);\n return null;\n }\n return resp.data.node;\n } catch (err) {\n console.log(err);\n }\n return null;\n}\nasync function cursorQuery(nid, textBeforeCursor) {\n try {\n const resp = await axios__WEBPACK_IMPORTED_MODULE_8__[\"default\"].post(`${_utils_configs__WEBPACK_IMPORTED_MODULE_2__[\"default\"].apiUrl}/api/search/cursor`, {\n nid: nid,\n requestId: (0,_utils_requestId__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(),\n textBeforeCursor: textBeforeCursor\n }, {\n headers: {\n ContentType: 'application/json',\n token: (0,_utils_account_token__WEBPACK_IMPORTED_MODULE_7__.getToken)()\n }\n });\n if (resp.data.code !== 0) {\n (0,_utils_msgBox__WEBPACK_IMPORTED_MODULE_4__.showErrorMsgBox)(resp.data.message);\n return [];\n }\n return resp.data.nodes;\n } catch (err) {\n console.log(err);\n }\n return [];\n}\nasync function putNode(md, fromNid = \"\") {\n try {\n const resp = await axios__WEBPACK_IMPORTED_MODULE_8__[\"default\"].put(`${_utils_configs__WEBPACK_IMPORTED_MODULE_2__[\"default\"].apiUrl}/api/node/quick`, {\n fromNid: fromNid,\n requestId: (0,_utils_requestId__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(),\n md: md,\n type: _utils_const__WEBPACK_IMPORTED_MODULE_1__[\"default\"].nodeType.Markdown\n }, {\n headers: {\n ContentType: 'application/json',\n token: (0,_utils_account_token__WEBPACK_IMPORTED_MODULE_7__.getToken)()\n }\n });\n if (resp.data.code !== 0) {\n (0,_utils_msgBox__WEBPACK_IMPORTED_MODULE_4__.showErrorMsgBox)(resp.data.message);\n return null;\n }\n return resp.data.node;\n } catch (err) {\n console.log(err);\n }\n return null;\n}\nasync function node2Trash(nid) {\n try {\n const resp = await axios__WEBPACK_IMPORTED_MODULE_8__[\"default\"].put(`${_utils_configs__WEBPACK_IMPORTED_MODULE_2__[\"default\"].apiUrl}/api/trash`, {\n nid: nid,\n requestId: (0,_utils_requestId__WEBPACK_IMPORTED_MODULE_3__[\"default\"])()\n }, {\n headers: {\n token: (0,_utils_account_token__WEBPACK_IMPORTED_MODULE_7__.getToken)()\n }\n });\n if (resp.data.code !== 0) {\n (0,_utils_msgBox__WEBPACK_IMPORTED_MODULE_4__.showErrorMsgBox)(resp.data.message);\n return false;\n }\n return true;\n } catch (err) {\n console.log(err);\n return false;\n }\n}\nasync function getNodesInTrash(page, pageSize) {\n const defaultPagedNodeInfo = {\n nodes: [],\n total: 0\n };\n try {\n const resp = await axios__WEBPACK_IMPORTED_MODULE_8__[\"default\"].get(`${_utils_configs__WEBPACK_IMPORTED_MODULE_2__[\"default\"].apiUrl}/api/trash`, {\n params: {\n p: page,\n ps: pageSize\n },\n headers: {\n token: (0,_utils_account_token__WEBPACK_IMPORTED_MODULE_7__.getToken)(),\n rid: (0,_utils_requestId__WEBPACK_IMPORTED_MODULE_3__[\"default\"])()\n }\n });\n if (resp.data.code !== 0) {\n (0,_utils_msgBox__WEBPACK_IMPORTED_MODULE_4__.showErrorMsgBox)(resp.data.message);\n return defaultPagedNodeInfo;\n }\n return resp.data.data;\n } catch (err) {\n console.log(err);\n return defaultPagedNodeInfo;\n }\n}\nasync function restoreNodeFromTrash(nid) {\n try {\n const resp = await axios__WEBPACK_IMPORTED_MODULE_8__[\"default\"].post(`${_utils_configs__WEBPACK_IMPORTED_MODULE_2__[\"default\"].apiUrl}/api/trashRestore`, {\n requestId: (0,_utils_requestId__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(),\n nid: nid\n }, {\n headers: {\n token: (0,_utils_account_token__WEBPACK_IMPORTED_MODULE_7__.getToken)()\n }\n });\n if (resp.data.code !== 0) {\n (0,_utils_msgBox__WEBPACK_IMPORTED_MODULE_4__.showErrorMsgBox)(resp.data.message);\n return false;\n }\n return true;\n } catch (err) {\n console.log(err);\n return false;\n }\n}\nasync function deleteNodeInTrash(nid) {\n try {\n const resp = await axios__WEBPACK_IMPORTED_MODULE_8__[\"default\"].delete(`${_utils_configs__WEBPACK_IMPORTED_MODULE_2__[\"default\"].apiUrl}/api/trash/${nid}`, {\n headers: {\n token: (0,_utils_account_token__WEBPACK_IMPORTED_MODULE_7__.getToken)()\n }\n });\n if (resp.data.code !== 0) {\n (0,_utils_msgBox__WEBPACK_IMPORTED_MODULE_4__.showErrorMsgBox)(resp.data.message);\n return false;\n }\n return true;\n } catch (err) {\n console.log(err);\n return false;\n }\n}\nasync function goNewNodePage() {\n const n = await putNode(\"\", \"\");\n if (n === null) {\n return;\n }\n await _router__WEBPACK_IMPORTED_MODULE_6__[\"default\"].push({\n name: \"node\",\n params: {\n id: n.id\n }\n });\n}\nconst getNode = async nid => {\n try {\n const resp = await axios__WEBPACK_IMPORTED_MODULE_8__[\"default\"].get(`${_utils_configs__WEBPACK_IMPORTED_MODULE_2__[\"default\"].apiUrl}/api/node`, {\n params: {\n nid: nid\n },\n headers: {\n token: (0,_utils_account_token__WEBPACK_IMPORTED_MODULE_7__.getToken)(),\n rid: (0,_utils_requestId__WEBPACK_IMPORTED_MODULE_3__[\"default\"])()\n }\n });\n if (resp.data.code !== 0) {\n (0,_utils_msgBox__WEBPACK_IMPORTED_MODULE_4__.showErrorMsgBox)(resp.data.message);\n return null;\n }\n return resp.data.node;\n } catch (err) {\n console.log(err);\n }\n return null;\n};\nconst searchUserNodes = async (query, sortKey = \"createdAt\", sortOrder = -1, page = 0, pageSize = 0, nidExclude = []) => {\n const defaultPagedNodeInfo = {\n nodes: [],\n total: 0\n };\n try {\n const resp = await axios__WEBPACK_IMPORTED_MODULE_8__[\"default\"].post(`${_utils_configs__WEBPACK_IMPORTED_MODULE_2__[\"default\"].apiUrl}/api/search/node`, {\n requestId: (0,_utils_requestId__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(),\n query: query,\n sortKey: sortKey,\n sortOrder: sortOrder,\n page: page,\n pageSize: pageSize,\n nidExclude: nidExclude\n }, {\n headers: {\n ContentType: 'application/json',\n token: (0,_utils_account_token__WEBPACK_IMPORTED_MODULE_7__.getToken)()\n }\n });\n if (resp.data.code !== 0) {\n (0,_utils_msgBox__WEBPACK_IMPORTED_MODULE_4__.showErrorMsgBox)(resp.data.message);\n return defaultPagedNodeInfo;\n }\n return resp.data.data;\n } catch (err) {\n console.log(err);\n return defaultPagedNodeInfo;\n }\n};\nconst cursorSearchSelect = async (nid, toNid) => {\n try {\n const resp = await axios__WEBPACK_IMPORTED_MODULE_8__[\"default\"].put(`${_utils_configs__WEBPACK_IMPORTED_MODULE_2__[\"default\"].apiUrl}/api/search/cursorSelect`, {\n requestId: (0,_utils_requestId__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(),\n nid: nid,\n toNid: toNid\n }, {\n headers: {\n ContentType: 'application/json',\n token: (0,_utils_account_token__WEBPACK_IMPORTED_MODULE_7__.getToken)()\n }\n });\n if (resp.data.code !== 0) {\n (0,_utils_msgBox__WEBPACK_IMPORTED_MODULE_4__.showErrorMsgBox)(resp.data.message);\n return false;\n }\n return true;\n } catch (err) {\n console.log(err);\n return false;\n }\n};\nfunction useNode(nid) {\n const nodeData = (0,vue__WEBPACK_IMPORTED_MODULE_5__.ref)(null);\n (0,vue__WEBPACK_IMPORTED_MODULE_5__.onBeforeMount)(async () => {\n nodeData.value = await getNode(nid);\n if (nodeData.value === null) {\n await _router__WEBPACK_IMPORTED_MODULE_6__[\"default\"].go(-1);\n }\n });\n return nodeData;\n}\n\n\n//# sourceURL=webpack://rethink/./src/utils/app/node.ts?"); /***/ }), @@ -2125,6 +2125,18 @@ /***/ }), + /***/ + "./src/utils/meta.ts": + /*!***************************!*\ + !*** ./src/utils/meta.ts ***! + \***************************/ + /***/ (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { + + eval("__webpack_require__.r(__webpack_exports__);\nfunction resetMeta(title, metaTitle, metaDesc) {\n document.title = title;\n const metaTitleEl = document.querySelector('meta[name=\"title\"]');\n if (metaTitleEl) {\n metaTitleEl.setAttribute(\"content\", metaTitle);\n }\n const metaDescEl = document.querySelector('meta[name=\"description\"]');\n if (metaDescEl) {\n metaDescEl.setAttribute(\"content\", metaDesc);\n }\n}\n/* harmony default export */ __webpack_exports__[\"default\"] = (resetMeta);\n\n//# sourceURL=webpack://rethink/./src/utils/meta.ts?"); + + /***/ + }), + /***/ "./src/utils/mq.ts": /*!*************************!*\ @@ -2156,7 +2168,7 @@ \********************************/ /***/ (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) { - eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _Users_morvanzhou_Documents_repo_rethink_frontend_node_modules_babel_runtime_helpers_esm_defineProperty_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/defineProperty.js */ \"./node_modules/@babel/runtime/helpers/esm/defineProperty.js\");\n/* harmony import */ var _utils_msgBox__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @/utils/msgBox */ \"./src/utils/msgBox.ts\");\n\n\nclass MultiLang {\n constructor(data) {\n (0,_Users_morvanzhou_Documents_repo_rethink_frontend_node_modules_babel_runtime_helpers_esm_defineProperty_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(this, \"langData\", void 0);\n (0,_Users_morvanzhou_Documents_repo_rethink_frontend_node_modules_babel_runtime_helpers_esm_defineProperty_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(this, \"availableLangCodes\", [\"zh\", \"en\"]);\n (0,_Users_morvanzhou_Documents_repo_rethink_frontend_node_modules_babel_runtime_helpers_esm_defineProperty_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(this, \"langCodeMap\", {\n zh: \"中文\",\n en: \"English\"\n });\n this.langData = data;\n }\n get(key) {\n const l = this.langData[key];\n if (!l) {\n (0,_utils_msgBox__WEBPACK_IMPORTED_MODULE_1__.showErrorMsgBox)(`Lang key ${key} not found`);\n return \"\";\n }\n return this.getGlobalLang() === \"zh\" ? l.zh : l.en;\n }\n setGlobalLang(lang) {\n localStorage.setItem(\"rethinkLang\", lang);\n }\n getGlobalLang() {\n return localStorage.getItem(\"rethinkLang\") || \"en\";\n }\n}\nconst mLang = new MultiLang({\n navbarHome: {\n zh: \"首页\",\n en: \"Home\"\n },\n navbarAbout: {\n zh: \"关于\",\n en: \"About\"\n },\n navbarLogin: {\n zh: \"登录\",\n en: \"Login\"\n },\n navbarStart: {\n zh: \"开始\",\n en: \"Start\"\n },\n goBackIcon: {\n zh: \"返回\",\n en: \"Back\"\n },\n sideBarHome: {\n zh: \"首页\",\n en: \"Home\"\n },\n importDataH1: {\n zh: \"导入数据\",\n en: \"Import Data\"\n },\n sideBarTrash: {\n zh: \"回收站\",\n en: \"Trash\"\n },\n sideBarImport: {\n zh: \"导入数据\",\n en: \"Import Data\"\n },\n arrangeNodeList: {\n zh: \"列表\",\n en: \"List\"\n },\n arrangeNodeGrid: {\n zh: \"网格\",\n en: \"Grid\"\n },\n sortNodeByTime: {\n zh: \"时间\",\n en: \"Time\"\n },\n sortNodeByCreatedAt: {\n zh: \"最新\",\n en: \"Create\"\n },\n sortNodeByModifiedAt: {\n zh: \"最后修改\",\n en: \"Update\"\n },\n sortNodeByTitle: {\n zh: \"名称\",\n en: \"Title\"\n },\n node2Trash: {\n zh: \"移至回收桶\",\n en: \"Move To Trash\"\n },\n nodeDelete: {\n zh: \"删除\",\n en: \"Delete\"\n },\n nodeDeleteConformation: {\n zh: \"确认删除\",\n en: \"Delete this thought\"\n },\n nodeRestoreFromTrash: {\n zh: \"恢复\",\n en: \"Restore\"\n },\n searchBarPlaceholder: {\n zh: \"搜想法...\",\n en: \"Search...\"\n },\n searchWindowSMSubmit: {\n zh: \"搜索\",\n en: \"Search\"\n },\n searchWindowSMCollapse: {\n zh: \"收起\",\n en: \"Collapse\"\n },\n noSearchResult: {\n zh: \"没有搜索结果\",\n en: \"No search result\"\n },\n search: {\n zh: \"搜索\",\n en: \"Search\"\n },\n headerBarNewThink: {\n zh: \"新想法\",\n en: \"New Thought\"\n },\n nodeTimeJustNow: {\n zh: \"刚刚\",\n en: \"Just now\"\n },\n nodeTimeYesterdayPrefix: {\n zh: \"昨天\",\n en: \"Yesterday\"\n },\n nodeTimeTodayPrefix: {\n zh: \"今天\",\n en: \"Today\"\n },\n nodeViewHeaderTitle: {\n zh: \"标题\",\n en: \"Title\"\n },\n nodeViewHeaderSnippet: {\n zh: \"内容\",\n en: \"Content\"\n },\n nodeViewHeaderTime: {\n zh: \"时间\",\n en: \"Time\"\n },\n sortNodeBySimilarity: {\n zh: \"相似度\",\n en: \"Similarity\"\n },\n cursorSearchDropdownSearchResult: {\n zh: \"Rethink\",\n en: \"Rethink\"\n },\n cursorSearchDropdownSearchRecent: {\n zh: \"最近链接的想法\",\n en: \"Recent linked thoughts\"\n },\n cursorSearchDropdownCreateNew: {\n zh: \"新建\",\n en: \"Create new\"\n },\n cursorSearchDropdownTitle: {\n zh: \"选择连接的想法\",\n en: \"Select a thought to link\"\n },\n emptyNodeTitle: {\n zh: \"无标题\",\n en: \"Untitled\"\n },\n settingsViewHeading: {\n zh: \"设置\",\n en: \"Settings\"\n },\n settingsViewLanguage: {\n zh: \"语言\",\n en: \"Language\"\n },\n userViewProfilePage: {\n zh: \"个人信息\",\n en: \"Profile\"\n },\n userViewName: {\n zh: \"名字\",\n en: \"Name\"\n },\n userViewEmail: {\n zh: \"邮箱\",\n en: \"Email\"\n },\n userViewAvatar: {\n zh: \"头像\",\n en: \"Picture\"\n },\n userViewStorageUsage: {\n zh: \"已使用:\",\n en: \"Used Space:\"\n },\n loginViewHeading: {\n zh: \"登录\",\n en: \"Login\"\n },\n loginViewHeadingSignup: {\n zh: \"新用户注册\",\n en: \"New User Register\"\n },\n loginViewAccountLabel: {\n zh: \"账号\",\n en: \"Account\"\n },\n loginViewAccountPlaceholder: {\n zh: \"邮箱\",\n en: \"email\"\n },\n loginViewAccountInputTitle: {\n zh: \"请输入正确的邮箱\",\n en: \"Please input a valid email\"\n },\n loginViewPasswordLabel: {\n zh: \"密码\",\n en: \"Password\"\n },\n loginViewNoUserOrPassword: {\n zh: \"账号或密码错误\",\n en: \"Account or password error\"\n },\n loginViewAccountPasswordEmpty: {\n zh: \"账号或密码不能为空\",\n en: \"Account or password can not be empty\"\n },\n loginViewPasswordInputTitle: {\n zh: \"必须包含至少 1 位数字和 1 位字母\",\n en: \"Must contain at least one number and one letter, and at least 6 or more characters\"\n },\n loginViewComformPasswordLabel: {\n zh: \"确认密码\",\n en: \"Comform password\"\n },\n loginViewComformPasswordNotMatch: {\n zh: \"两次密码不一致\",\n en: \"Comform password not match\"\n },\n loginViewLoginButton: {\n zh: \"登录\",\n en: \"Log In\"\n },\n loginViewSignupButton: {\n zh: \"注册\",\n en: \"Create new account\"\n },\n loginViewSignupHasAccount: {\n zh: \"已有账号?\",\n en: \"Already have an account?\"\n },\n loginViewForgetPassword: {\n zh: \"忘记密码\",\n en: \"Forget password\"\n },\n loginViewOAuthLogin: {\n zh: \"其他方式登录\",\n en: \"Other Login\"\n },\n registerCaptchaLabel: {\n zh: \"验证码\",\n en: \"Verification code\"\n },\n loginViewCaptchaEmpty: {\n zh: \"验证码不能为空\",\n en: \"Verification code can not be empty\"\n },\n headerMenuLogout: {\n zh: \"登出\",\n en: \"Logout\"\n },\n headerMenuProfile: {\n zh: \"个人信息\",\n en: \"Profile\"\n },\n headerMenuSettings: {\n zh: \"设置\",\n en: \"Settings\"\n },\n oauthPageHeading: {\n zh: \"账号正在验证中...\",\n en: \"Verifying your account...\"\n },\n msgBoxComformButton: {\n zh: \"确定\",\n en: \"OK\"\n },\n msgBoxCancelButton: {\n zh: \"取消\",\n en: \"Cancel\"\n },\n errorBoxTitle: {\n zh: \"错误\",\n en: \"Error\"\n },\n infoBoxTitle: {\n zh: \"提示\",\n en: \"Info\"\n },\n conformBoxTitle: {\n zh: \"请确认\",\n en: \"Please confirm\"\n },\n modificationSuccessful: {\n zh: \"修改成功\",\n en: \"Modification successful\"\n },\n cancel: {\n zh: \"取消\",\n en: \"Cancel\"\n },\n recentSearchedTitle: {\n zh: \"最近搜索\",\n en: \"Recent Queries\"\n },\n editorContentPlaceholder: {\n zh: \"记录我的新想法...\",\n en: \"Record my new thought...\"\n },\n editorSyncStatusSaved: {\n zh: \"已自动保存\",\n en: \"Auto saved\"\n },\n editorSyncStatusLastSaved: {\n zh: \"最近保存 \",\n en: \"Last saved \"\n },\n quickPostPanelPlaceholder: {\n zh: \"想法速记...\",\n en: \"Quick thought...\"\n },\n quickPostBtn: {\n zh: \"记下\",\n en: \"Send\"\n },\n quickPostTooLong: {\n zh: \"用编辑器记长想法 >\",\n en: \"Use editor for long thought >\"\n },\n quickPostEditInNodePage: {\n zh: \"在新页面编辑\",\n en: \"Edit in new page\"\n },\n quickPostBtnTitle: {\n zh: \"快速记录\",\n en: \"Quick post\"\n },\n tryRestoreFromTrash: {\n zh: \"此想法被放在回收站中,是否要从回收站恢复?\",\n en: \"This thought is in trash, do you want to restore it?\"\n },\n nodeIsDeleted: {\n zh: \"此想法已被您删除\",\n en: \"This thought is deleted\"\n },\n noLinkedNode: {\n zh: \"还没有链接到任何想法,尝试 @ 一些吧\",\n en: \"No linked thought yet, try @ some\"\n },\n batchFileOpsShare: {\n zh: \"分享\",\n en: \"Share\"\n },\n batchFileOpsDelete: {\n zh: \"删除\",\n en: \"Delete\"\n },\n batchFileOpsTrash: {\n zh: \"回收\",\n en: \"To Trash\"\n },\n batchFileOpsCancel: {\n zh: \"取消\",\n en: \"Cancel\"\n },\n batchFileOpsDownload: {\n zh: \"下载\",\n en: \"Download\"\n },\n batchFileOpsRestore: {\n zh: \"恢复\",\n en: \"Restore\"\n },\n deleteConfirm: {\n zh: \"确认删除?\",\n en: \"Confirm delete?\"\n },\n nodeNeedRestoreToView: {\n zh: \"需要恢复后才能查看,确认恢复并查看?\",\n en: \"Need restore to be viewed, confirm restore?\"\n },\n uploadFilesLabel: {\n zh: \"上传文件\",\n en: \"Upload files\"\n },\n uploadFilesEmptyTask: {\n zh: \"无任务\",\n en: \"No Task\"\n },\n fileDropIsDragging: {\n zh: \"放入文件\",\n en: \"Release to drop files here.\"\n },\n fileDropNotDraggingPre: {\n zh: \"拖拽文件到此处或\",\n en: \"Drag and drop files here, or \"\n },\n fileDropNotDraggingClick: {\n zh: \"点此\",\n en: \"click here\"\n },\n fileDropNotDraggingPost: {\n zh: \" 上传\",\n en: \" to upload\"\n },\n fileDropInvalidFile: {\n zh: \"文件格式错误\",\n en: \"Invalid file format\"\n },\n fileDropTooLarge: {\n zh: \"文件过大\",\n en: \"File too large\"\n },\n fileDropTooManyPre: {\n zh: \"文件个数超过上限: \",\n en: \"File count exceeds limit: \"\n },\n fileDropTooManyPost: {\n zh: \",请分批上传\",\n en: \", please upload in batches\"\n },\n filesSubmitBtn: {\n zh: \"上传\",\n en: \"Upload\"\n },\n fileDropPreviewFileCount: {\n zh: \"已加载文件数:\",\n en: \"Loaded file count: \"\n },\n uploadFilesTaskNotFinished: {\n zh: \"任务未完成,请检查失败文件\",\n en: \"Task not finished, please check failed files\"\n },\n newJobProgress: {\n zh: \"最新任务进度\",\n en: \"The latest job progress\"\n }\n});\n/* harmony default export */ __webpack_exports__[\"default\"] = (mLang);\n\n//# sourceURL=webpack://rethink/./src/utils/multiLang.ts?"); + eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _Users_morvanzhou_Documents_repo_rethink_frontend_node_modules_babel_runtime_helpers_esm_defineProperty_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/defineProperty.js */ \"./node_modules/@babel/runtime/helpers/esm/defineProperty.js\");\n/* harmony import */ var _utils_msgBox__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @/utils/msgBox */ \"./src/utils/msgBox.ts\");\n\n\nclass MultiLang {\n constructor(data) {\n (0,_Users_morvanzhou_Documents_repo_rethink_frontend_node_modules_babel_runtime_helpers_esm_defineProperty_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(this, \"langData\", void 0);\n (0,_Users_morvanzhou_Documents_repo_rethink_frontend_node_modules_babel_runtime_helpers_esm_defineProperty_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(this, \"availableLangCodes\", [\"zh\", \"en\"]);\n (0,_Users_morvanzhou_Documents_repo_rethink_frontend_node_modules_babel_runtime_helpers_esm_defineProperty_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(this, \"langCodeMap\", {\n zh: \"中文\",\n en: \"English\"\n });\n this.langData = data;\n }\n get(key) {\n const l = this.langData[key];\n if (!l) {\n (0,_utils_msgBox__WEBPACK_IMPORTED_MODULE_1__.showErrorMsgBox)(`Lang key ${key} not found`);\n return \"\";\n }\n return this.getGlobalLang() === \"zh\" ? l.zh : l.en;\n }\n setGlobalLang(lang) {\n localStorage.setItem(\"rethinkLang\", lang);\n }\n getGlobalLang() {\n return localStorage.getItem(\"rethinkLang\") || \"en\";\n }\n}\nconst mLang = new MultiLang({\n navbarHome: {\n zh: \"首页\",\n en: \"Home\"\n },\n navbarAbout: {\n zh: \"关于\",\n en: \"About\"\n },\n navbarLogin: {\n zh: \"登录\",\n en: \"Login\"\n },\n navbarStart: {\n zh: \"开始\",\n en: \"Start\"\n },\n goBackIcon: {\n zh: \"返回\",\n en: \"Back\"\n },\n sideBarHome: {\n zh: \"首页\",\n en: \"Home\"\n },\n importDataH1: {\n zh: \"导入数据\",\n en: \"Import Data\"\n },\n sideBarTrash: {\n zh: \"回收站\",\n en: \"Trash\"\n },\n sideBarImport: {\n zh: \"导入数据\",\n en: \"Import Data\"\n },\n arrangeNodeList: {\n zh: \"列表\",\n en: \"List\"\n },\n arrangeNodeGrid: {\n zh: \"网格\",\n en: \"Grid\"\n },\n sortNodeByTime: {\n zh: \"时间\",\n en: \"Time\"\n },\n sortNodeByCreatedAt: {\n zh: \"最新\",\n en: \"Create\"\n },\n sortNodeByModifiedAt: {\n zh: \"最后修改\",\n en: \"Update\"\n },\n sortNodeByTitle: {\n zh: \"名称\",\n en: \"Title\"\n },\n node2Trash: {\n zh: \"移至回收桶\",\n en: \"Move To Trash\"\n },\n nodeDelete: {\n zh: \"删除\",\n en: \"Delete\"\n },\n nodeDeleteConformation: {\n zh: \"确认删除\",\n en: \"Delete this thought\"\n },\n nodeRestoreFromTrash: {\n zh: \"恢复\",\n en: \"Restore\"\n },\n searchBarPlaceholder: {\n zh: \"搜想法...\",\n en: \"Search...\"\n },\n searchWindowSMSubmit: {\n zh: \"搜索\",\n en: \"Search\"\n },\n searchWindowSMCollapse: {\n zh: \"收起\",\n en: \"Collapse\"\n },\n noSearchResult: {\n zh: \"没有搜索结果\",\n en: \"No search result\"\n },\n search: {\n zh: \"搜索\",\n en: \"Search\"\n },\n headerBarNewThink: {\n zh: \"新想法\",\n en: \"New Thought\"\n },\n nodeTimeJustNow: {\n zh: \"刚刚\",\n en: \"Just now\"\n },\n nodeTimeYesterdayPrefix: {\n zh: \"昨天\",\n en: \"Yesterday\"\n },\n nodeTimeTodayPrefix: {\n zh: \"今天\",\n en: \"Today\"\n },\n nodeViewHeaderTitle: {\n zh: \"标题\",\n en: \"Title\"\n },\n nodeViewHeaderSnippet: {\n zh: \"内容\",\n en: \"Content\"\n },\n nodeViewHeaderTime: {\n zh: \"时间\",\n en: \"Time\"\n },\n sortNodeBySimilarity: {\n zh: \"相似度\",\n en: \"Similarity\"\n },\n cursorSearchDropdownSearchResult: {\n zh: \"Rethink\",\n en: \"Rethink\"\n },\n cursorSearchDropdownSearchRecent: {\n zh: \"最近链接的想法\",\n en: \"Recent linked thoughts\"\n },\n cursorSearchDropdownCreateNew: {\n zh: \"新建\",\n en: \"Create new\"\n },\n cursorSearchDropdownTitle: {\n zh: \"选择连接的想法\",\n en: \"Select a thought to link\"\n },\n emptyNodeTitle: {\n zh: \"无标题\",\n en: \"Untitled\"\n },\n settingsViewHeading: {\n zh: \"设置\",\n en: \"Settings\"\n },\n settingsViewLanguage: {\n zh: \"语言\",\n en: \"Language\"\n },\n userViewProfilePage: {\n zh: \"个人信息\",\n en: \"Profile\"\n },\n userViewName: {\n zh: \"名字\",\n en: \"Name\"\n },\n userViewEmail: {\n zh: \"邮箱\",\n en: \"Email\"\n },\n userViewAvatar: {\n zh: \"头像\",\n en: \"Picture\"\n },\n userViewStorageUsage: {\n zh: \"已使用:\",\n en: \"Used Space:\"\n },\n loginViewHeading: {\n zh: \"登录\",\n en: \"Login\"\n },\n loginViewHeadingSignup: {\n zh: \"新用户注册\",\n en: \"New User Register\"\n },\n loginViewAccountLabel: {\n zh: \"账号\",\n en: \"Account\"\n },\n loginViewAccountPlaceholder: {\n zh: \"邮箱\",\n en: \"email\"\n },\n loginViewAccountInputTitle: {\n zh: \"请输入正确的邮箱\",\n en: \"Please input a valid email\"\n },\n loginViewPasswordLabel: {\n zh: \"密码\",\n en: \"Password\"\n },\n loginViewNoUserOrPassword: {\n zh: \"账号或密码错误\",\n en: \"Account or password error\"\n },\n loginViewAccountPasswordEmpty: {\n zh: \"账号或密码不能为空\",\n en: \"Account or password can not be empty\"\n },\n loginViewPasswordInputTitle: {\n zh: \"必须包含至少 1 位数字和 1 位字母\",\n en: \"Must contain at least one number and one letter, and at least 6 or more characters\"\n },\n loginViewComformPasswordLabel: {\n zh: \"确认密码\",\n en: \"Comform password\"\n },\n loginViewComformPasswordNotMatch: {\n zh: \"两次密码不一致\",\n en: \"Comform password not match\"\n },\n loginViewLoginButton: {\n zh: \"登录\",\n en: \"Log In\"\n },\n loginViewSignupButton: {\n zh: \"注册\",\n en: \"Create new account\"\n },\n loginViewSignupHasAccount: {\n zh: \"已有账号?\",\n en: \"Already have an account?\"\n },\n loginViewForgetPassword: {\n zh: \"忘记密码\",\n en: \"Forget password\"\n },\n loginViewOAuthLogin: {\n zh: \"其他方式登录\",\n en: \"Other Login\"\n },\n registerCaptchaLabel: {\n zh: \"验证码\",\n en: \"Verification code\"\n },\n loginViewCaptchaEmpty: {\n zh: \"验证码不能为空\",\n en: \"Verification code can not be empty\"\n },\n headerMenuLogout: {\n zh: \"登出\",\n en: \"Logout\"\n },\n headerMenuProfile: {\n zh: \"个人信息\",\n en: \"Profile\"\n },\n headerMenuSettings: {\n zh: \"设置\",\n en: \"Settings\"\n },\n oauthPageHeading: {\n zh: \"账号正在验证中...\",\n en: \"Verifying your account...\"\n },\n msgBoxComformButton: {\n zh: \"确定\",\n en: \"OK\"\n },\n msgBoxCancelButton: {\n zh: \"取消\",\n en: \"Cancel\"\n },\n errorBoxTitle: {\n zh: \"错误\",\n en: \"Error\"\n },\n infoBoxTitle: {\n zh: \"提示\",\n en: \"Info\"\n },\n conformBoxTitle: {\n zh: \"请确认\",\n en: \"Please confirm\"\n },\n modificationSuccessful: {\n zh: \"修改成功\",\n en: \"Modification successful\"\n },\n cancel: {\n zh: \"取消\",\n en: \"Cancel\"\n },\n recentSearchedTitle: {\n zh: \"最近搜索\",\n en: \"Recent Queries\"\n },\n editorContentPlaceholder: {\n zh: \"记录我的新想法...\",\n en: \"Record my new thought...\"\n },\n editorSyncStatusSaved: {\n zh: \"已自动保存\",\n en: \"Auto saved\"\n },\n editorSyncStatusLastSaved: {\n zh: \"最近保存 \",\n en: \"Last saved \"\n },\n quickPostPanelPlaceholder: {\n zh: \"速记想法 / 解析链接 ...\",\n en: \"Quick thought / Parse URL ...\"\n },\n quickPostBtn: {\n zh: \"记下\",\n en: \"Send\"\n },\n quickPostTooLong: {\n zh: \"用编辑器记长想法 >\",\n en: \"Use editor for long thought >\"\n },\n quickPostEditInNodePage: {\n zh: \"在新页面编辑\",\n en: \"Edit in new page\"\n },\n quickPostBtnTitle: {\n zh: \"快速记录\",\n en: \"Quick post\"\n },\n tryRestoreFromTrash: {\n zh: \"此想法被放在回收站中,是否要从回收站恢复?\",\n en: \"This thought is in trash, do you want to restore it?\"\n },\n nodeIsDeleted: {\n zh: \"此想法已被您删除\",\n en: \"This thought is deleted\"\n },\n noLinkedNode: {\n zh: \"还没有链接到任何想法,尝试 @ 一些吧\",\n en: \"No linked thought yet, try @ some\"\n },\n batchFileOpsShare: {\n zh: \"分享\",\n en: \"Share\"\n },\n batchFileOpsDelete: {\n zh: \"删除\",\n en: \"Delete\"\n },\n batchFileOpsTrash: {\n zh: \"回收\",\n en: \"To Trash\"\n },\n batchFileOpsCancel: {\n zh: \"取消\",\n en: \"Cancel\"\n },\n batchFileOpsDownload: {\n zh: \"下载\",\n en: \"Download\"\n },\n batchFileOpsRestore: {\n zh: \"恢复\",\n en: \"Restore\"\n },\n deleteConfirm: {\n zh: \"确认删除?\",\n en: \"Confirm delete?\"\n },\n nodeNeedRestoreToView: {\n zh: \"需要恢复后才能查看,确认恢复并查看?\",\n en: \"Need restore to be viewed, confirm restore?\"\n },\n uploadFilesLabel: {\n zh: \"上传文件\",\n en: \"Upload files\"\n },\n uploadFilesEmptyTask: {\n zh: \"无任务\",\n en: \"No Task\"\n },\n fileDropIsDragging: {\n zh: \"放入文件\",\n en: \"Release to drop files here.\"\n },\n fileDropNotDraggingPre: {\n zh: \"拖拽文件到此处或\",\n en: \"Drag and drop files here, or \"\n },\n fileDropNotDraggingClick: {\n zh: \"点此\",\n en: \"click here\"\n },\n fileDropNotDraggingPost: {\n zh: \" 上传\",\n en: \" to upload\"\n },\n fileDropInvalidFile: {\n zh: \"文件格式错误\",\n en: \"Invalid file format\"\n },\n fileDropTooLarge: {\n zh: \"文件过大\",\n en: \"File too large\"\n },\n fileDropTooManyPre: {\n zh: \"文件个数超过上限: \",\n en: \"File count exceeds limit: \"\n },\n fileDropTooManyPost: {\n zh: \",请分批上传\",\n en: \", please upload in batches\"\n },\n filesSubmitBtn: {\n zh: \"上传\",\n en: \"Upload\"\n },\n fileDropPreviewFileCount: {\n zh: \"已加载文件数:\",\n en: \"Loaded file count: \"\n },\n uploadFilesTaskNotFinished: {\n zh: \"任务未完成,请检查失败文件\",\n en: \"Task not finished, please check failed files\"\n },\n newJobProgress: {\n zh: \"最新任务进度\",\n en: \"The latest job progress\"\n }\n});\n/* harmony default export */ __webpack_exports__[\"default\"] = (mLang);\n\n//# sourceURL=webpack://rethink/./src/utils/multiLang.ts?"); /***/ }), diff --git a/src/rethink/models/node.py b/src/rethink/models/node.py index e3ce19a..a9b04b3 100644 --- a/src/rethink/models/node.py +++ b/src/rethink/models/node.py @@ -76,6 +76,7 @@ def add( md = md.strip() if len(md) > const.MD_MAX_LENGTH: return None, const.Code.NOTE_EXCEED_MAX_LENGTH + u, code = user.get(uid=uid) if code != const.Code.OK: return None, code diff --git a/src/rethink/models/utils.py b/src/rethink/models/utils.py index 1dfd8e1..0227296 100644 --- a/src/rethink/models/utils.py +++ b/src/rethink/models/utils.py @@ -5,11 +5,13 @@ import uuid from typing import Tuple +import httpx import jwt import pypinyin from markdown import Markdown from rethink import config +from rethink.logger import logger HEADERS = { 'typ': 'jwt', @@ -128,3 +130,60 @@ def change_link_title(md: str, nid: str, new_title: str) -> str: md, ) return new_md + + +ONLY_HTTP_LINK_PTN = re.compile(r"^https?://\S*$") + + +def contain_only_http_link(md: str) -> str: + content = md.strip() + if ONLY_HTTP_LINK_PTN.match(content) is None: + return "" + return content + + +ASYNC_CLIENT_HEADERS = { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) " + "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36", +} + + +async def get_title_description_from_link(url: str) -> Tuple[str, str]: + async with httpx.AsyncClient() as client: + try: + response = await client.get( + url=url, + headers=ASYNC_CLIENT_HEADERS, + timeout=3. + ) + except ( + httpx.ConnectTimeout, + RuntimeError, + httpx.ConnectError, + httpx.ReadTimeout, + httpx.HTTPError + ) as e: + logger.info(f"failed to get {url}: {e}") + return "", "" + if response.status_code in [302, 301]: + url = response.headers["Location"] + return await get_title_description_from_link(url) + if response.status_code != 200: + return "", "" + html = response.text[:10000] + + title, description = "", "" + found = re.search(r']*name="title"[^>]*content="([^"]*)"[^>]*>', html, re.DOTALL) + if found is None: + found = re.search(r']*content="([^"]*)"[^>]*name="title"[^>]*>', html, re.DOTALL) + if found is None: + found = re.search(r"(.*?)", html, re.DOTALL) + if found: + title = found.group(1).strip() + + found = re.search(r']*name="description"[^>]*content="([^"]*)"[^>]*>', html, re.DOTALL) + if found is None: + found = re.search(r']*content="([^"]*)"[^>]*name="description"[^>]*>', html, re.DOTALL) + if found: + description = found.group(1).strip()[:400] + return title, description diff --git a/src/rethink/routes/node.py b/src/rethink/routes/node.py index bdfb4ad..065d4bf 100644 --- a/src/rethink/routes/node.py +++ b/src/rethink/routes/node.py @@ -31,6 +31,21 @@ async def put_node( ) +@router.put( + path="/node/quick", + response_model=schemas.node.PutResponse, +) +@measure_time_spend +async def put_node( + req: schemas.node.PutRequest, + token_decode: Annotated[TokenDecode, Depends(token2uid)] +) -> schemas.node.PutResponse: + return await node_ops.put_quick_node( + td=token_decode, + req=req, + ) + + @router.get( path="/node", response_model=schemas.node.GetResponse, diff --git a/tests/test_api.py b/tests/test_api.py index c129e2f..71fcd52 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -411,7 +411,7 @@ def test_update_obsidian(self): rj = resp.json() self.assertEqual(0, rj["code"], msg=rj) - for _ in range(8): + for _ in range(10): time.sleep(0.1) resp = self.client.get( "/api/files/uploadProcess", @@ -511,3 +511,37 @@ def test_upload_image(self): f1.close() os.remove("temp/test.png") os.rmdir("temp") + + def test_put_quick_node(self): + resp = self.client.put( + "/api/node/quick", + json={ + "requestId": "xxx", + "md": "node1\ntext", + "type": const.NodeType.MARKDOWN.value, + }, + headers={"token": self.token} + ) + rj = resp.json() + self.assertEqual(0, rj["code"]) + self.assertEqual("xxx", rj["requestId"]) + node = rj["node"] + self.assertEqual("node1", node["title"]) + self.assertEqual("node1\ntext", node["md"]) + self.assertEqual(const.NodeType.MARKDOWN.value, node["type"]) + + resp = self.client.put( + "/api/node/quick", + json={ + "requestId": "xxx", + "md": "https://baidu.com", + "type": const.NodeType.MARKDOWN.value, + }, + headers={"token": self.token} + ) + rj = resp.json() + self.assertEqual(0, rj["code"]) + self.assertEqual("xxx", rj["requestId"]) + node = rj["node"] + self.assertIn("https://baidu.com", node["md"]) + self.assertIn("百度", node["md"]) diff --git a/tests/test_models_utils.py b/tests/test_models_utils.py index b70d0f5..ec7b796 100644 --- a/tests/test_models_utils.py +++ b/tests/test_models_utils.py @@ -63,3 +63,35 @@ def test_change_link_title(self): [@我](/n/1) [@哇塞](/n/2) """), new_md) + def test_contain_only_link(self): + for md, res in [ + ("http://rethink.run", "http://rethink.run"), + ("[123](/n/123)", ""), + ("few", ""), + ("c https://rethink.run", ""), + (" https://rethink.run ", "https://rethink.run"), + ("https://rethink.run ", "https://rethink.run"), + ("https://rethink.run", "https://rethink.run"), + ("https://rethink.run wwq", ""), + + ]: + self.assertEqual(res, utils.contain_only_http_link(md)) + + +class TestAsync(unittest.IsolatedAsyncioTestCase): + async def test_get_title_description_from_link(self): + for url, res in [ + ("https://waa.fffffffff", False), + ("https://baidu.com", True), + ("https://rethink.run", True), + ("https://rethink.run/about", True), + ("https://baidu.com/wqwqqqqq", False), + ("https://mp.weixin.qq.com/s/fHrDf4XQ00a8IG-VF8-VwQ", False), + ]: + title, desc = await utils.get_title_description_from_link(url) + if res: + self.assertNotEqual(title, "", msg=f"{url} {title}") + self.assertNotEqual(desc, "", msg=f"{url} {desc}") + else: + self.assertEqual(title, "") + self.assertEqual(desc, "")