diff --git a/packages/frontend/index.html b/packages/frontend/index.html index 7806d3c..57fdc9d 100644 --- a/packages/frontend/index.html +++ b/packages/frontend/index.html @@ -5,6 +5,12 @@ Nexus Terminal + + + + + +
diff --git a/packages/frontend/public/icons/icon-144x144.png b/packages/frontend/public/icons/icon-144x144.png new file mode 100644 index 0000000..fdf2d16 Binary files /dev/null and b/packages/frontend/public/icons/icon-144x144.png differ diff --git a/packages/frontend/public/icons/icon-192x192.png b/packages/frontend/public/icons/icon-192x192.png new file mode 100644 index 0000000..b590e7f Binary files /dev/null and b/packages/frontend/public/icons/icon-192x192.png differ diff --git a/packages/frontend/public/icons/icon-512x512.png b/packages/frontend/public/icons/icon-512x512.png new file mode 100644 index 0000000..2d5ac19 Binary files /dev/null and b/packages/frontend/public/icons/icon-512x512.png differ diff --git a/packages/frontend/public/manifest.json b/packages/frontend/public/manifest.json new file mode 100644 index 0000000..eb9e11b --- /dev/null +++ b/packages/frontend/public/manifest.json @@ -0,0 +1,31 @@ +{ + "name": "Nexus Terminal", + "short_name": "NexusTerm", + "description": "A modern, web-based terminal.", + "icons": [ + { + "src": "/icons/icon-144x144.png", + "sizes": "144x144", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/icons/icon-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/icons/icon-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "any" + } + ], + "start_url": "/", + "display": "standalone", + "background_color": "#333333", + "theme_color": "#9370DB", + "scope": "/", + "orientation": "portrait-primary" +} \ No newline at end of file diff --git a/packages/frontend/public/sw.js b/packages/frontend/public/sw.js new file mode 100644 index 0000000..b4780bb --- /dev/null +++ b/packages/frontend/public/sw.js @@ -0,0 +1,52 @@ +const CACHE_NAME = 'nexus-terminal-cache-v1'; +const urlsToCache = [ + '/', + '/index.html', + '/manifest.json', + '/icons/icon-72x72.png', + '/icons/icon-96x96.png', + '/icons/icon-128x128.png', + '/icons/icon-144x144.png', + '/icons/icon-152x152.png', + '/icons/icon-192x192.png', + '/icons/icon-384x384.png', + '/icons/icon-512x512.png' +]; + +self.addEventListener('install', (event) => { + event.waitUntil( + caches.open(CACHE_NAME) + .then((cache) => { + console.log('Opened cache'); + return cache.addAll(urlsToCache); + }) + ); +}); + +self.addEventListener('fetch', (event) => { + event.respondWith( + caches.match(event.request) + .then((response) => { + if (response) { + return response; + } + return fetch(event.request); + } + ) + ); +}); + +self.addEventListener('activate', (event) => { + const cacheWhitelist = [CACHE_NAME]; + event.waitUntil( + caches.keys().then((cacheNames) => { + return Promise.all( + cacheNames.map((cacheName) => { + if (cacheWhitelist.indexOf(cacheName) === -1) { + return caches.delete(cacheName); + } + }) + ); + }) + ); +}); \ No newline at end of file diff --git a/packages/frontend/src/App.vue b/packages/frontend/src/App.vue index 9e539b5..03bc57e 100644 --- a/packages/frontend/src/App.vue +++ b/packages/frontend/src/App.vue @@ -7,8 +7,8 @@ import { useDeviceDetection } from './composables/useDeviceDetection'; import { useSettingsStore } from './stores/settings.store'; import { useAppearanceStore } from './stores/appearance.store'; import { useLayoutStore } from './stores/layout.store'; -import { useFocusSwitcherStore } from './stores/focusSwitcher.store'; // +++ 导入焦点切换 Store +++ -import { useSessionStore } from './stores/session.store'; // +++ 导入 Session Store +++ +import { useFocusSwitcherStore } from './stores/focusSwitcher.store'; +import { useSessionStore } from './stores/session.store'; import { storeToRefs } from 'pinia'; // 导入通知显示组件 import UINotificationDisplay from './components/UINotificationDisplay.vue'; @@ -72,7 +72,16 @@ onMounted(() => { // +++ 添加全局 Alt 键监听器 +++ window.addEventListener('keydown', handleAltKeyDown); // +++ 监听 keydown 设置状态 +++ window.addEventListener('keyup', handleGlobalKeyUp); // +++ 监听 keyup 执行切换 +++ + + // PWA Install Prompt + window.addEventListener('beforeinstallprompt', (e) => { + console.log('[App.vue] beforeinstallprompt event fired. Browser will handle install prompt.'); + }); + window.addEventListener('appinstalled', () => { + console.log('[App.vue] PWA was installed'); + }); + // +++ 加载 Header 可见性状态 +++ layoutStore.loadHeaderVisibility(); }); @@ -250,6 +259,8 @@ const isElementVisibleAndFocusable = (element: HTMLElement): boolean => { return rect.width > 0 && rect.height > 0; }; + + @@ -336,14 +349,12 @@ const isElementVisibleAndFocusable = (element: HTMLElement): boolean => { flex-direction: column; min-height: 100vh; font-family: var(--font-family-sans-serif); /* 使用字体变量 */ - /* background-color: var(--app-bg-color); */ /* 移除容器背景色,让 body 背景透出来 */ } -/* Removed header, nav, nav-left, nav-right, nav a, nav a:hover, nav a.router-link-exact-active, .nav-underline, and specific icon/login/logout link styles as they are now handled by Tailwind classes */ main { flex-grow: 1; - /* padding: var(--base-padding); */ /* Keep padding removed from main */ + } diff --git a/packages/frontend/src/main.ts b/packages/frontend/src/main.ts index ffe834a..e2dccb8 100644 --- a/packages/frontend/src/main.ts +++ b/packages/frontend/src/main.ts @@ -83,4 +83,14 @@ app.use(i18n); // 使用 i18n } app.mount('#app'); } +// --- PWA Service Worker Registration --- + if ('serviceWorker' in navigator) { + window.addEventListener('load', () => { + navigator.serviceWorker.register('/sw.js').then(registration => { + console.log('SW registered: ', registration); + }).catch(registrationError => { + console.log('SW registration failed: ', registrationError); + }); + }); + } })();