diff --git a/package-lock.json b/package-lock.json index 6947f45..e93a29e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,10 +16,12 @@ "axios": "^1.6.7", "html-to-image": "^1.11.13", "lucide-vue-next": "^0.322.0", + "markdown-it": "^14.1.0", "vue": "^3.4.15", "vue-i18n": "^11.2.8" }, "devDependencies": { + "@types/markdown-it": "^14.1.2", "@vitejs/plugin-vue": "^5.0.3", "autoprefixer": "^10.4.17", "postcss": "^8.4.35", @@ -956,6 +958,31 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/markdown-it": { + "version": "14.1.2", + "resolved": "https://registry.npmmirror.com/@types/markdown-it/-/markdown-it-14.1.2.tgz", + "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/linkify-it": "^5", + "@types/mdurl": "^2" + } + }, + "node_modules/@types/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/web-bluetooth": { "version": "0.0.20", "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz", @@ -1327,6 +1354,12 @@ "dev": true, "license": "MIT" }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -2161,6 +2194,15 @@ "dev": true, "license": "MIT" }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, "node_modules/lucide-vue-next": { "version": "0.322.0", "resolved": "https://registry.npmjs.org/lucide-vue-next/-/lucide-vue-next-0.322.0.tgz", @@ -2179,6 +2221,35 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmmirror.com/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -2188,6 +2259,12 @@ "node": ">= 0.4" } }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "license": "MIT" + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -2528,6 +2605,15 @@ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "license": "MIT" }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -2861,6 +2947,12 @@ "node": ">=14.17" } }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "license": "MIT" + }, "node_modules/update-browserslist-db": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", diff --git a/package.json b/package.json index 34894ca..9d13433 100644 --- a/package.json +++ b/package.json @@ -17,10 +17,12 @@ "axios": "^1.6.7", "html-to-image": "^1.11.13", "lucide-vue-next": "^0.322.0", + "markdown-it": "^14.1.0", "vue": "^3.4.15", "vue-i18n": "^11.2.8" }, "devDependencies": { + "@types/markdown-it": "^14.1.2", "@vitejs/plugin-vue": "^5.0.3", "autoprefixer": "^10.4.17", "postcss": "^8.4.35", diff --git a/src/App.vue b/src/App.vue index 6e0df4c..3d04ce9 100644 --- a/src/App.vue +++ b/src/App.vue @@ -11,8 +11,9 @@ import { useI18n } from 'vue-i18n' // 画布:VueFlow 与可选插件 import { VueFlow } from '@vue-flow/core' import { Background, BackgroundVariant } from '@vue-flow/background' -import { Controls } from '@vue-flow/controls' +import { Controls, ControlButton } from '@vue-flow/controls' import { MiniMap } from '@vue-flow/minimap' +import { Maximize, Minimize } from 'lucide-vue-next' // VueFlow 内置样式(必须引入,否则组件样式缺失) import '@vue-flow/core/dist/style.css' @@ -31,9 +32,39 @@ import WindowNode from './components/WindowNode.vue' // 业务层:统一的状态与动作入口 import { useThinkFlow } from './composables/useThinkFlow' +import { ref, onMounted, onUnmounted } from 'vue' const { t, locale } = useI18n() +/** + * 全屏控制逻辑 + */ +const isFullscreen = ref(false) + +const toggleFullscreen = () => { + if (!document.fullscreenElement) { + document.documentElement.requestFullscreen().catch((err) => { + console.error(`Error attempting to enable full-screen mode: ${err.message} (${err.name})`) + }) + } else { + if (document.exitFullscreen) { + document.exitFullscreen() + } + } +} + +const handleFullscreenChange = () => { + isFullscreen.value = !!document.fullscreenElement +} + +onMounted(() => { + document.addEventListener('fullscreenchange', handleFullscreenChange) +}) + +onUnmounted(() => { + document.removeEventListener('fullscreenchange', handleFullscreenChange) +}) + /** * 从业务层拿到全局状态与动作。 * 说明: @@ -102,7 +133,7 @@ const fitToView = () => {
{ :gap="24" :size="config.backgroundVariant === BackgroundVariant.Dots ? 1 : 0.5" /> - + + + + +