mirror of https://github.com/halo-dev/halo
pref: adapt auto save functionality for articles in the uc (#5272)
#### 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 为个人中心的文章适配自动保存功能 ```pull/3818/head^2
parent
e8a9f063f1
commit
6ee5503643
|
@ -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";
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
Loading…
Reference in New Issue