diff --git a/src/App.vue b/src/App.vue index 9af0278..a329a6f 100644 --- a/src/App.vue +++ b/src/App.vue @@ -2,7 +2,7 @@ import Toolbar from './components/Toolbar.vue'; import ProjectExplorer from './components/ProjectExplorer.vue'; import ComponentsPanel from './components/flow/ComponentsPanel.vue'; -import { onMounted, reactive, watch } from 'vue'; +import { onMounted, ref, watch } from 'vue'; import {useFilesStore} from "@/ts/useStore"; import Vue3DraggableResizable from 'vue3-draggable-resizable'; import {TabPaneName, TabsPaneContext} from "element-plus"; @@ -17,6 +17,44 @@ import { useGlobalMessage } from '@/ts/useGlobalMessage'; const filesStore = useFilesStore(); const { showMessage } = useGlobalMessage(); +const NEW_PROJECT_URL = 'https://fireschain.org/onmyoji-flow/'; +const REDIRECT_PROMPT_SESSION_KEY = 'yys-editor.new-project-redirect-prompted'; +const REDIRECT_PROMPT_DISABLED_KEY = 'yys-editor.new-project-redirect-disabled'; +const showRedirectPrompt = ref(false); +const dontShowRedirectPromptAgain = ref(false); + +const rememberRedirectPromptChoice = () => { + if (dontShowRedirectPromptAgain.value) { + window.localStorage.setItem(REDIRECT_PROMPT_DISABLED_KEY, 'true'); + } +}; + +const showNewProjectRedirectPrompt = () => { + if (typeof window === 'undefined') { + return; + } + + if (window.localStorage.getItem(REDIRECT_PROMPT_DISABLED_KEY) === 'true') { + return; + } + + if (window.sessionStorage.getItem(REDIRECT_PROMPT_SESSION_KEY) === 'true') { + return; + } + + window.sessionStorage.setItem(REDIRECT_PROMPT_SESSION_KEY, 'true'); + showRedirectPrompt.value = true; +}; + +const goToNewProject = () => { + rememberRedirectPromptChoice(); + window.location.assign(NEW_PROJECT_URL); +}; + +const stayOnLegacyProject = () => { + rememberRedirectPromptChoice(); + showRedirectPrompt.value = false; +}; const normalizeGraphData = (data: any) => { if (data && Array.isArray((data as any).nodes) && Array.isArray((data as any).edges)) { @@ -60,6 +98,7 @@ onMounted(() => { // 初始化自动保存功能 filesStore.initializeWithPrompt(); filesStore.setupAutoSave(); + showNewProjectRedirectPrompt(); }); // 1) 切换激活文件:仅当 id 变化时保存旧数据并渲染新数据 @@ -176,6 +215,26 @@ watch( + + + yys-editor 已迁移到新项目 onmyoji-flow。新版会继续维护资源与功能,是否现在前往? + + + 以后不再提示 + + + + 继续使用旧版 + 前往新版 + + + @@ -248,7 +307,11 @@ watch( min-height: 0; overflow-y: auto; } + +.redirect-prompt-text { + margin: 0 0 16px; + line-height: 1.7; + color: #303133; +} - - diff --git a/src/components/Toolbar.vue b/src/components/Toolbar.vue index ee7ef81..ef1537c 100644 --- a/src/components/Toolbar.vue +++ b/src/components/Toolbar.vue @@ -1,6 +1,15 @@ + + 前往新版 + {{ t('import') }} {{ t('export') }} 数据预览 @@ -424,6 +433,7 @@ const props = withDefaults(defineProps<{ }); const filesStore = props.piniaInstance ? useFilesStore(props.piniaInstance) : useFilesStore(); +const NEW_PROJECT_URL = 'https://fireschain.org/onmyoji-flow/'; const contactImageUrl = resolveAssetUrl('/assets/Other/Contact.png') as string; const { showMessage } = useGlobalMessage(); const { selectionEnabled, snapGridEnabled, snaplineEnabled } = useCanvasSettings(); @@ -438,6 +448,10 @@ const { t } = useSafeI18n({ feedback: '问题反馈' }); +const goToNewProject = () => { + window.location.assign(NEW_PROJECT_URL); +}; + // 定义响应式数据 const state = reactive({ previewImage: null, // 用于存储预览图像的数据URL @@ -1315,6 +1329,11 @@ const handleClose = (done) => { white-space: nowrap; } +.new-project-link { + font-weight: 700; + box-shadow: 0 0 0 2px rgba(82, 196, 26, 0.18); +} + .toolbar--embed { position: relative; top: auto;
+ yys-editor 已迁移到新项目 onmyoji-flow。新版会继续维护资源与功能,是否现在前往? +