From 47d837952b48f80bd0817e8bbf253a8243d1218d Mon Sep 17 00:00:00 2001 From: Ryan Wang Date: Tue, 19 Mar 2024 14:58:22 +0800 Subject: [PATCH] fix: refactor the theme and post preview feature to solve the session expiration issue (#5518) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /area ui /kind bug /milestone 2.14.x #### What this PR does / why we need it: 重构文章预览和主题预览的页面加载方式,尝试解决在某些情况下打开预览导致登录 session 失效的问题。 #### Which issue(s) this PR fixes: Fixes https://github.com/halo-dev/halo/issues/4047 #### Special notes for your reviewer: 需要测试: 1. 主题预览中的各个功能是否正常。 2. 文章预览功能是否正常。 #### Does this PR introduce a user-facing change? ```release-note 修复在某些情况下,打开文章预览或主题预览之后导致登录失效的问题。 ``` --- .../contents/pages/SinglePageEditor.vue | 4 +- .../modules/contents/posts/PostEditor.vue | 4 +- .../dashboard/widgets/QuickLinkWidget.vue | 3 +- .../components/list-tabs/InstalledThemes.vue | 3 +- .../components/preview/ThemePreviewModal.vue | 75 +++++++++---------- .../interface/themes/layouts/ThemeLayout.vue | 6 +- ui/src/components/preview/UrlPreviewModal.vue | 42 +++++++---- ui/src/utils/api-client.ts | 2 +- 8 files changed, 75 insertions(+), 64 deletions(-) diff --git a/ui/console-src/modules/contents/pages/SinglePageEditor.vue b/ui/console-src/modules/contents/pages/SinglePageEditor.vue index c98cd0e53..5f94f7f91 100644 --- a/ui/console-src/modules/contents/pages/SinglePageEditor.vue +++ b/ui/console-src/modules/contents/pages/SinglePageEditor.vue @@ -433,10 +433,10 @@ async function handleUploadImage(file: File, options?: AxiosRequestConfig) { /> diff --git a/ui/console-src/modules/contents/posts/PostEditor.vue b/ui/console-src/modules/contents/posts/PostEditor.vue index 898af701b..029213a13 100644 --- a/ui/console-src/modules/contents/posts/PostEditor.vue +++ b/ui/console-src/modules/contents/posts/PostEditor.vue @@ -461,10 +461,10 @@ async function handleUploadImage(file: File, options?: AxiosRequestConfig) { /> diff --git a/ui/console-src/modules/dashboard/widgets/QuickLinkWidget.vue b/ui/console-src/modules/dashboard/widgets/QuickLinkWidget.vue index bf6f1106b..bda3bbe6d 100644 --- a/ui/console-src/modules/dashboard/widgets/QuickLinkWidget.vue +++ b/ui/console-src/modules/dashboard/widgets/QuickLinkWidget.vue @@ -229,9 +229,10 @@ const actions: Action[] = [ diff --git a/ui/console-src/modules/interface/themes/components/list-tabs/InstalledThemes.vue b/ui/console-src/modules/interface/themes/components/list-tabs/InstalledThemes.vue index c8e91682a..84c9fbdc3 100644 --- a/ui/console-src/modules/interface/themes/components/list-tabs/InstalledThemes.vue +++ b/ui/console-src/modules/interface/themes/components/list-tabs/InstalledThemes.vue @@ -106,8 +106,9 @@ const handleOpenPreview = (theme: Theme) => { diff --git a/ui/console-src/modules/interface/themes/components/preview/ThemePreviewModal.vue b/ui/console-src/modules/interface/themes/components/preview/ThemePreviewModal.vue index 70883e3e0..faa8fade7 100644 --- a/ui/console-src/modules/interface/themes/components/preview/ThemePreviewModal.vue +++ b/ui/console-src/modules/interface/themes/components/preview/ThemePreviewModal.vue @@ -2,7 +2,7 @@ import ThemePreviewListItem from "./ThemePreviewListItem.vue"; import { useSettingFormConvert } from "@console/composables/use-setting-form"; import { useThemeStore } from "@console/stores/theme"; -import { apiClient } from "@/utils/api-client"; +import { apiClient, axiosInstance } from "@/utils/api-client"; import type { ConfigMap, Setting, @@ -22,28 +22,27 @@ import { IconTablet, IconRefreshLine, Toast, + VLoading, } from "@halo-dev/components"; import { storeToRefs } from "pinia"; -import { computed, markRaw, ref, toRaw, watch } from "vue"; +import { computed, markRaw, ref, toRaw } from "vue"; import { useI18n } from "vue-i18n"; import { OverlayScrollbarsComponent } from "overlayscrollbars-vue"; import { useQuery } from "@tanstack/vue-query"; +import { onMounted } from "vue"; const props = withDefaults( defineProps<{ - visible: boolean; title?: string; theme?: Theme; }>(), { - visible: false, title: undefined, theme: undefined, } ); const emit = defineEmits<{ - (event: "update:visible", visible: boolean): void; (event: "close"): void; }>(); @@ -56,7 +55,6 @@ interface SettingTab { const { activatedTheme } = storeToRefs(useThemeStore()); -const previewFrame = ref(null); const themesVisible = ref(false); const switching = ref(false); const selectedTheme = ref(); @@ -71,29 +69,11 @@ const { data: themes } = useQuery({ }); return data.items; }, - enabled: computed(() => props.visible), }); -watch( - () => props.visible, - (visible) => { - if (visible) { - selectedTheme.value = props.theme || activatedTheme?.value; - } else { - setTimeout(() => { - themesVisible.value = false; - settingsVisible.value = false; - }, 200); - } - } -); - -const onVisibleChange = (visible: boolean) => { - emit("update:visible", visible); - if (!visible) { - emit("close"); - } -}; +onMounted(() => { + selectedTheme.value = toRaw(props.theme) || toRaw(activatedTheme?.value); +}); const handleOpenThemes = () => { settingsVisible.value = false; @@ -122,6 +102,26 @@ const modalTitle = computed(() => { }); }); +const { + data: previewHTML, + isLoading, + refetch: refetchPreviewHTML, +} = useQuery({ + queryKey: ["site-preview", previewUrl], + queryFn: async () => { + const { data } = await axiosInstance.get(previewUrl.value, { + headers: { + Accept: "text/html", + "Cache-Control": "no-cache", + Pragma: "no-cache", + Expires: "0", + }, + }); + return data; + }, + enabled: computed(() => !!previewUrl.value), +}); + // theme settings const saving = ref(false); const settingTabs = ref([] as SettingTab[]); @@ -150,9 +150,7 @@ const { data: setting } = useQuery({ activeSettingTab.value = settingTabs.value[0].id; }, - enabled: computed( - () => props.visible && !!selectedTheme.value?.spec.settingName - ), + enabled: computed(() => !!selectedTheme.value?.spec.settingName), }); const { data: configMap, refetch: handleFetchConfigMap } = useQuery({ @@ -195,7 +193,7 @@ const handleSaveConfigMap = async () => { saving.value = false; - handleRefresh(); + refetchPreviewHTML(); }; const handleOpenSettings = (theme?: Theme) => { @@ -206,10 +204,6 @@ const handleOpenSettings = (theme?: Theme) => { settingsVisible.value = !settingsVisible.value; }; -const handleRefresh = () => { - previewFrame.value?.contentWindow?.location.reload(); -}; - // mock devices const mockDevices = [ { @@ -241,11 +235,10 @@ const iframeClasses = computed(() => {