From 6ee5503643fdf59d103e266a46e221c7401f6af1 Mon Sep 17 00:00:00 2001 From: Takagi <1103069291@qq.com> Date: Mon, 29 Jan 2024 17:32:25 +0800 Subject: [PATCH] pref: adapt auto save functionality for articles in the uc (#5272) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind improvement /area console /milestone 2.12.x #### What this PR does / why we need it: 为个人中心的文章适配自动保存功能 #### How to test it? 新建一个空白文章,测试当失去焦点、切换路由,或者在页面等待 20S 后,是否会自动创建文章草稿。 #### Which issue(s) this PR fixes: Fixes #5036 #### Does this PR introduce a user-facing change? ```release-note 为个人中心的文章适配自动保存功能 ``` --- .../contents/pages/SinglePageEditor.vue | 4 +- .../modules/contents/posts/PostEditor.vue | 4 +- .../composables/use-auto-save-content.ts | 0 .../composables/use-content-cache.ts | 0 .../modules/contents/posts/PostEditor.vue | 54 ++++++++++++++++++- 5 files changed, 56 insertions(+), 6 deletions(-) rename console/{console-src => src}/composables/use-auto-save-content.ts (100%) rename console/{console-src => src}/composables/use-content-cache.ts (100%) diff --git a/console/console-src/modules/contents/pages/SinglePageEditor.vue b/console/console-src/modules/contents/pages/SinglePageEditor.vue index 48bc15ccd..86aebacae 100644 --- a/console/console-src/modules/contents/pages/SinglePageEditor.vue +++ b/console/console-src/modules/contents/pages/SinglePageEditor.vue @@ -27,7 +27,7 @@ import { useRouteQuery } from "@vueuse/router"; import { cloneDeep } from "lodash-es"; import { useRouter } from "vue-router"; import { randomUUID } from "@/utils/id"; -import { useContentCache } from "@console/composables/use-content-cache"; +import { useContentCache } from "@/composables/use-content-cache"; import { useEditorExtensionPoints } from "@/composables/use-editor-extension-points"; import type { EditorProvider } from "@halo-dev/console-shared"; import { useLocalStorage } from "@vueuse/core"; @@ -36,7 +36,7 @@ import { useI18n } from "vue-i18n"; import UrlPreviewModal from "@/components/preview/UrlPreviewModal.vue"; import { contentAnnotations } from "@/constants/annotations"; import { usePageUpdateMutate } from "./composables/use-page-update-mutate"; -import { useAutoSaveContent } from "@console/composables/use-auto-save-content"; +import { useAutoSaveContent } from "@/composables/use-auto-save-content"; import { useContentSnapshot } from "@console/composables/use-content-snapshot"; import { useSaveKeybinding } from "@console/composables/use-save-keybinding"; import { useSessionKeepAlive } from "@/composables/use-session-keep-alive"; diff --git a/console/console-src/modules/contents/posts/PostEditor.vue b/console/console-src/modules/contents/posts/PostEditor.vue index 88fe5dacc..2d669cd0d 100644 --- a/console/console-src/modules/contents/posts/PostEditor.vue +++ b/console/console-src/modules/contents/posts/PostEditor.vue @@ -27,7 +27,7 @@ import { apiClient } from "@/utils/api-client"; import { useRouteQuery } from "@vueuse/router"; import { useRouter } from "vue-router"; import { randomUUID } from "@/utils/id"; -import { useContentCache } from "@console/composables/use-content-cache"; +import { useContentCache } from "@/composables/use-content-cache"; import { useEditorExtensionPoints } from "@/composables/use-editor-extension-points"; import type { EditorProvider } from "@halo-dev/console-shared"; import { useLocalStorage } from "@vueuse/core"; @@ -36,7 +36,7 @@ import { useI18n } from "vue-i18n"; import UrlPreviewModal from "@/components/preview/UrlPreviewModal.vue"; import { usePostUpdateMutate } from "./composables/use-post-update-mutate"; import { contentAnnotations } from "@/constants/annotations"; -import { useAutoSaveContent } from "@console/composables/use-auto-save-content"; +import { useAutoSaveContent } from "@/composables/use-auto-save-content"; import { useContentSnapshot } from "@console/composables/use-content-snapshot"; import { useSaveKeybinding } from "@console/composables/use-save-keybinding"; import { useSessionKeepAlive } from "@/composables/use-session-keep-alive"; diff --git a/console/console-src/composables/use-auto-save-content.ts b/console/src/composables/use-auto-save-content.ts similarity index 100% rename from console/console-src/composables/use-auto-save-content.ts rename to console/src/composables/use-auto-save-content.ts diff --git a/console/console-src/composables/use-content-cache.ts b/console/src/composables/use-content-cache.ts similarity index 100% rename from console/console-src/composables/use-content-cache.ts rename to console/src/composables/use-content-cache.ts diff --git a/console/uc-src/modules/contents/posts/PostEditor.vue b/console/uc-src/modules/contents/posts/PostEditor.vue index 8ae1b0e85..a75bbcf84 100644 --- a/console/uc-src/modules/contents/posts/PostEditor.vue +++ b/console/uc-src/modules/contents/posts/PostEditor.vue @@ -13,7 +13,7 @@ import { VSpace, } from "@halo-dev/components"; import EditorProviderSelector from "@/components/dropdown-selector/EditorProviderSelector.vue"; -import { ref } from "vue"; +import { ref, toRef } from "vue"; import { useLocalStorage } from "@vueuse/core"; import type { Post, Content, Snapshot } from "@halo-dev/api-client"; import { randomUUID } from "@/utils/id"; @@ -35,6 +35,8 @@ import type { ComputedRef } from "vue"; import { useSessionKeepAlive } from "@/composables/use-session-keep-alive"; import { usePermission } from "@/utils/permission"; import type { AxiosRequestConfig } from "axios"; +import { useContentCache } from "@/composables/use-content-cache"; +import { useAutoSaveContent } from "@/composables/use-auto-save-content"; const router = useRouter(); const { t } = useI18n(); @@ -126,6 +128,7 @@ onMounted(async () => { formState.value = post; await handleFetchContent(); + handleResetCache(); return; } @@ -142,6 +145,48 @@ onMounted(async () => { [contentAnnotations.PREFERRED_EDITOR]: provider.name, }; } + handleResetCache(); +}); + +const snapshotVersion = computed(() => snapshot.value?.metadata.version || 0); + +// Post content cache +const { + currentCache, + handleSetContentCache, + handleResetCache, + handleClearCache, +} = useContentCache( + "post-content-cache", + name, + toRef(content.value, "raw"), + snapshotVersion +); + +useAutoSaveContent(currentCache, toRef(content.value, "raw"), async () => { + // Do not save when the setting modal is open + if (postSettingEditModal.value) { + return; + } + if (isUpdateMode.value) { + handleSave({ mute: true }); + } else { + formState.value.metadata.annotations = { + ...formState.value.metadata.annotations, + [contentAnnotations.CONTENT_JSON]: JSON.stringify(content.value), + }; + // Set default title and slug + if (!formState.value.spec.title) { + formState.value.spec.title = t("core.post_editor.untitled"); + } + if (!formState.value.spec.slug) { + formState.value.spec.slug = new Date().getTime().toString(); + } + const { data: createdPost } = await apiClient.uc.post.createMyPost({ + post: formState.value, + }); + onCreatePostSuccess(createdPost); + } }); /** @@ -235,6 +280,7 @@ async function onCreatePostSuccess(data: Post) { // Update route query params name.value = data.metadata.name; await handleFetchContent(); + handleClearCache(); } // Save post @@ -276,6 +322,7 @@ const { mutateAsync: handleSave, isLoading: isSaving } = useMutation({ onSuccess(_, variables) { if (!variables.mute) Toast.success(t("core.common.toast.save_success")); handleFetchContent(); + handleClearCache(name.value); }, onError() { Toast.error(t("core.common.toast.save_failed_and_retry")); @@ -297,6 +344,7 @@ function handlePublishClick() { } function onPublishPostSuccess() { + handleClearCache(); router.push({ name: "Posts" }); } @@ -313,7 +361,7 @@ const { mutateAsync: handlePublish, isLoading: isPublishing } = useMutation({ Toast.success(t("core.common.toast.publish_success"), { duration: 2000, }); - + handleClearCache(formState.value.metadata.name); router.push({ name: "Posts" }); }, onError() { @@ -332,6 +380,7 @@ function handleOpenPostSettingEditModal() { function onUpdatePostSuccess(data: Post) { formState.value = data; handleFetchContent(); + handleClearCache(data.metadata.name); } // Upload image @@ -433,6 +482,7 @@ useSessionKeepAlive(); v-model:content="content.content" :upload-image="handleUploadImage" class="h-full" + @update="handleSetContentCache" />