312 lines
6.1 KiB
Vue
312 lines
6.1 KiB
Vue
<script setup lang="ts">
|
|
import { onMounted, onUnmounted, computed } from 'vue'
|
|
import { useData } from 'vitepress'
|
|
import { useSettingsStore } from './stores/settings'
|
|
import { isMobileDevice } from './utils'
|
|
import VideoBackground from './components/VideoBackground.vue'
|
|
import Dock from './components/Dock.vue'
|
|
import DraggableWidget from './components/DraggableWidget.vue'
|
|
import Window from './components/Window.vue'
|
|
import Calendar from './components/Calendar.vue'
|
|
import TaoXin from './components/TaoXin.vue'
|
|
import Cafe from './components/Cafe.vue'
|
|
import Settings from './components/Settings.vue'
|
|
import DocSidebar from './components/DocSidebar.vue'
|
|
import sidebarData from './data/sidebar.json'
|
|
|
|
const { frontmatter } = useData()
|
|
const settingsStore = useSettingsStore()
|
|
|
|
settingsStore.initWidgets(['calendar', 'taoxin', 'cafe'])
|
|
|
|
const isHome = computed(() => frontmatter.value.home === true)
|
|
|
|
const blurAmount = computed(() => settingsStore.theme.blurAmount ?? 20)
|
|
const backgroundColor = computed(() => settingsStore.theme.backgroundColor ?? 'rgba(30, 30, 30, 0.7)')
|
|
|
|
const navItems = computed(() => {
|
|
return sidebarData.map(group => ({
|
|
text: group.title,
|
|
link: group.path
|
|
}))
|
|
})
|
|
|
|
const handleResize = () => {
|
|
settingsStore.setMobile(isMobileDevice())
|
|
}
|
|
|
|
onMounted(() => {
|
|
handleResize()
|
|
window.addEventListener('resize', handleResize)
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
window.removeEventListener('resize', handleResize)
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div class="app-container">
|
|
<VideoBackground />
|
|
|
|
<template v-if="isHome">
|
|
<div class="home-container" :class="{ 'home-mobile': settingsStore.isMobile }">
|
|
<DraggableWidget id="calendar" :width="320" :height="400">
|
|
<Calendar />
|
|
</DraggableWidget>
|
|
|
|
<DraggableWidget id="taoxin" :width="300" :height="280">
|
|
<TaoXin />
|
|
</DraggableWidget>
|
|
|
|
<DraggableWidget id="cafe" :width="300" :height="300">
|
|
<Cafe />
|
|
</DraggableWidget>
|
|
</div>
|
|
|
|
<Dock />
|
|
|
|
<Window id="settings" title="设置中心" :default-width="800" :default-height="600">
|
|
<Settings />
|
|
</Window>
|
|
</template>
|
|
|
|
<template v-else>
|
|
<div class="doc-page">
|
|
<header class="doc-header">
|
|
<a href="/" class="logo">乌仿镇</a>
|
|
<nav class="doc-nav">
|
|
<a href="/" class="nav-link">首页</a>
|
|
<a
|
|
v-for="item in navItems"
|
|
:key="item.link"
|
|
:href="item.link"
|
|
class="nav-link"
|
|
>
|
|
{{ item.text }}
|
|
</a>
|
|
</nav>
|
|
</header>
|
|
|
|
<div class="doc-layout" :style="{
|
|
background: backgroundColor,
|
|
backdropFilter: 'blur(' + blurAmount + 'px)',
|
|
WebkitBackdropFilter: 'blur(' + blurAmount + 'px)'
|
|
}">
|
|
<aside class="doc-sidebar">
|
|
<DocSidebar />
|
|
</aside>
|
|
|
|
<main class="doc-main">
|
|
<Content />
|
|
</main>
|
|
</div>
|
|
</div>
|
|
|
|
<Dock />
|
|
<Window id="settings" title="设置中心" :default-width="800" :default-height="600">
|
|
<Settings />
|
|
</Window>
|
|
</template>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.app-container {
|
|
min-height: 100vh;
|
|
position: relative;
|
|
}
|
|
|
|
.home-container {
|
|
position: relative;
|
|
min-height: 100vh;
|
|
padding-bottom: 100px;
|
|
}
|
|
|
|
.home-mobile {
|
|
display: flex;
|
|
flex-direction: column;
|
|
padding: 10px;
|
|
padding-bottom: 120px;
|
|
}
|
|
|
|
.doc-page {
|
|
min-height: 100vh;
|
|
}
|
|
|
|
.doc-header {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: 60px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 0 24px;
|
|
background: rgba(30, 30, 30, 0.9);
|
|
backdrop-filter: blur(20px);
|
|
-webkit-backdrop-filter: blur(20px);
|
|
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
|
z-index: 50;
|
|
}
|
|
|
|
.logo {
|
|
font-size: 20px;
|
|
font-weight: 700;
|
|
color: white;
|
|
text-decoration: none;
|
|
}
|
|
|
|
.doc-nav {
|
|
display: flex;
|
|
gap: 24px;
|
|
}
|
|
|
|
.nav-link {
|
|
color: rgba(255, 255, 255, 0.8);
|
|
text-decoration: none;
|
|
font-size: 14px;
|
|
transition: color 0.2s ease;
|
|
}
|
|
|
|
.nav-link:hover {
|
|
color: white;
|
|
}
|
|
|
|
.doc-layout {
|
|
position: fixed;
|
|
top: 60px;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
display: flex;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.doc-sidebar {
|
|
width: 280px;
|
|
padding: 20px;
|
|
height: 100%;
|
|
overflow-y: auto;
|
|
border-right: 1px solid rgba(255, 255, 255, 0.1);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.doc-main {
|
|
flex: 1;
|
|
padding: 20px 40px;
|
|
padding-bottom: 120px;
|
|
overflow-y: auto;
|
|
height: 100%;
|
|
}
|
|
|
|
.doc-main :deep(*) {
|
|
color: white;
|
|
}
|
|
|
|
.doc-main :deep(a) {
|
|
color: #007AFF;
|
|
}
|
|
|
|
.doc-main :deep(h1),
|
|
.doc-main :deep(h2),
|
|
.doc-main :deep(h3) {
|
|
color: white;
|
|
border-bottom-color: rgba(255, 255, 255, 0.1);
|
|
padding-bottom: 8px;
|
|
margin-top: 24px;
|
|
}
|
|
|
|
.doc-main :deep(h1) {
|
|
font-size: 28px;
|
|
}
|
|
|
|
.doc-main :deep(h2) {
|
|
font-size: 22px;
|
|
}
|
|
|
|
.doc-main :deep(h3) {
|
|
font-size: 18px;
|
|
}
|
|
|
|
.doc-main :deep(p) {
|
|
line-height: 1.8;
|
|
margin: 16px 0;
|
|
}
|
|
|
|
.doc-main :deep(code) {
|
|
background: rgba(255, 255, 255, 0.1);
|
|
padding: 2px 6px;
|
|
border-radius: 4px;
|
|
font-family: 'Fira Code', monospace;
|
|
}
|
|
|
|
.doc-main :deep(pre) {
|
|
background: rgba(0, 0, 0, 0.4);
|
|
border-radius: 8px;
|
|
padding: 16px;
|
|
overflow-x: auto;
|
|
margin: 16px 0;
|
|
}
|
|
|
|
.doc-main :deep(pre code) {
|
|
background: transparent;
|
|
padding: 0;
|
|
}
|
|
|
|
.doc-main :deep(blockquote) {
|
|
border-left: 4px solid #007AFF;
|
|
background: rgba(255, 255, 255, 0.05);
|
|
padding: 12px 16px;
|
|
margin: 16px 0;
|
|
border-radius: 0 8px 8px 0;
|
|
}
|
|
|
|
.doc-main :deep(table) {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
margin: 16px 0;
|
|
}
|
|
|
|
.doc-main :deep(th),
|
|
.doc-main :deep(td) {
|
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
padding: 12px;
|
|
text-align: left;
|
|
}
|
|
|
|
.doc-main :deep(th) {
|
|
background: rgba(255, 255, 255, 0.1);
|
|
}
|
|
|
|
.doc-main :deep(ul),
|
|
.doc-main :deep(ol) {
|
|
padding-left: 24px;
|
|
margin: 16px 0;
|
|
}
|
|
|
|
.doc-main :deep(li) {
|
|
margin: 8px 0;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.doc-sidebar {
|
|
display: none;
|
|
}
|
|
|
|
.doc-main {
|
|
padding: 16px;
|
|
padding-bottom: 120px;
|
|
}
|
|
|
|
.doc-header {
|
|
padding: 0 16px;
|
|
}
|
|
|
|
.doc-nav {
|
|
gap: 16px;
|
|
}
|
|
}
|
|
</style>
|