fix layout ui

This commit is contained in:
jxxghp
2024-05-11 12:53:42 +08:00
parent f227ae89ec
commit 2c35d0f897
11 changed files with 183 additions and 66 deletions

View File

@@ -6,6 +6,7 @@ import VerticalNavLink from '@layouts/components/VerticalNavLink.vue'
// Components
import Footer from '@/layouts/components/Footer.vue'
import NavbarThemeSwitcher from '@/layouts/components/NavbarThemeSwitcher.vue'
import UserNofification from '@/layouts/components/UserNotification.vue'
import SearchBar from '@/layouts/components/SearchBar.vue'
import ShortcutBar from '@/layouts/components/ShortcutBar.vue'
import UserProfile from '@/layouts/components/UserProfile.vue'
@@ -34,7 +35,10 @@ const superUser = store.state.auth.superUser
<ShortcutBar v-if="superUser" />
<!-- 👉 Theme -->
<NavbarThemeSwitcher class="me-2" />
<NavbarThemeSwitcher />
<!-- 👉 Notification -->
<UserNofification />
<!-- 👉 UserProfile -->
<UserProfile />

View File

@@ -2,25 +2,29 @@
import type { ThemeSwitcherTheme } from '@layouts/types'
const themes: ThemeSwitcherTheme[] = [
{
name: 'auto',
title: '跟随系统',
icon: 'mdi-laptop',
},
{
name: 'light',
title: '明亮',
icon: 'mdi-weather-sunny',
},
{
name: 'dark',
title: '暗黑',
icon: 'mdi-weather-night',
},
{
name: 'purple',
title: '紫韵幽兰',
icon: 'mdi-brightness-4',
},
{
name: 'auto',
icon: 'mdi-brightness-auto',
},
]
</script>
<template>
<ThemeSwitcher :themes="themes" />
<ThemeSwitcher class="ms-2" :themes="themes" />
</template>

View File

@@ -91,7 +91,7 @@ onMounted(() => {
>
<!-- Menu Activator -->
<template #activator="{ props }">
<IconBtn class="me-2" v-bind="props">
<IconBtn class="ms-2" v-bind="props">
<VIcon icon="mdi-checkbox-multiple-blank-outline" />
</IconBtn>
</template>

View File

@@ -0,0 +1,102 @@
<script setup lang="ts">
import store from '@/store'
import { formatDateDifference } from '@core/utils/formatters'
import { SystemNotification } from '@/api/types'
// 是否有新消息
const hasNewMessage = ref(false)
// 通知列表
const notificationList = ref<SystemNotification[]>([])
// 事件源
let eventSource: EventSource | null = null
// 弹窗
const appsMenu = ref(false)
// SSE持续接收消息
function startSSEMessager() {
const token = store.state.auth.token
if (token) {
eventSource = new EventSource(`${import.meta.env.VITE_API_BASE_URL}system/message?token=${token}`)
eventSource.addEventListener('message', event => {
if (event.data) {
const noti: SystemNotification = JSON.parse(event.data)
notificationList.value.unshift(noti)
hasNewMessage.value = true
// TODO 在顶部显示消息汽泡
}
})
}
}
// 页面加载时,加载当前用户数据
onBeforeMount(async () => {
startSSEMessager()
})
// 页面卸载时,关闭事件源
onBeforeUnmount(() => {
if (eventSource) eventSource.close()
})
</script>
<template>
<VMenu v-model="appsMenu" width="400" transition="scale-transition" close-on-content-click>
<!-- Menu Activator -->
<template #activator="{ props }">
<VBadge v-if="hasNewMessage" dot color="error" :offset-x="5" :offset-y="5" v-bind="props">
<IconBtn>
<VIcon icon="mdi-bell-outline" />
</IconBtn>
</VBadge>
<IconBtn v-else v-bind="props">
<VIcon icon="mdi-bell-outline" />
</IconBtn>
</template>
<!-- Menu Content -->
<VCard>
<VCardItem class="border-b">
<VCardTitle>通知</VCardTitle>
<template #append>
<VTooltip text="设为已读">
<template #activator="{ props }">
<IconBtn
v-bind="props"
@click="
() => {
hasNewMessage = false
appsMenu = false
}
"
>
<VIcon icon="mdi-email-mark-as-unread" />
</IconBtn>
</template>
</VTooltip>
</template>
</VCardItem>
<VList lines="two" v-if="notificationList.length > 0" max-height="600">
<VListItem v-for="(item, i) in notificationList" :key="i">
<template #prepend>
<VAvatar rounded>
<VIcon v-if="item.type === 'user'" icon="mdi-account-alert" size="large"></VIcon>
<VIcon v-else-if="item.type === 'plugin'" icon="mdi-robot-happy" size="large"></VIcon>
<VIcon v-else icon="mdi-laptop" size="large"></VIcon>
</VAvatar>
</template>
<VListItemTitle class="overflow-visiable break-words whitespace-break-spaces">
{{ item.title }}
</VListItemTitle>
<VListItemSubtitle class="mt-2">{{ item.text }}</VListItemSubtitle>
<VListItemSubtitle class="mt-2">{{ formatDateDifference(item.date) }}</VListItemSubtitle>
</VListItem>
</VList>
<VList v-else>
<VListItem>
<VListItemTitle class="text-center">暂无通知</VListItemTitle>
</VListItem>
</VList>
</VCard>
</VMenu>
</template>

View File

@@ -64,7 +64,7 @@ const avatar = store.state.auth.avatar
</script>
<template>
<VAvatar class="cursor-pointer" color="primary" variant="tonal">
<VAvatar class="cursor-pointer ms-3" color="primary" variant="tonal">
<VImg :src="avatar ?? avatar1" />
<!-- SECTION Menu -->
@@ -92,10 +92,17 @@ const avatar = store.state.auth.avatar
<template #prepend>
<VIcon class="me-2" icon="mdi-account-outline" size="22" />
</template>
<VListItemTitle>设定</VListItemTitle>
</VListItem>
<!-- 👉 FAQ -->
<VListItem href="https://github.com/jxxghp/MoviePilot/blob/main/README.md" target="_blank">
<template #prepend>
<VIcon class="me-2" icon="mdi-help-circle-outline" size="22" />
</template>
<VListItemTitle>帮助</VListItemTitle>
</VListItem>
<!-- Divider -->
<VDivider class="my-2" />
@@ -104,26 +111,18 @@ const avatar = store.state.auth.avatar
<template #prepend>
<VIcon class="me-2" icon="mdi-restart" size="22" />
</template>
<VListItemTitle>重启</VListItemTitle>
</VListItem>
<!-- 👉 FAQ -->
<VListItem href="https://github.com/jxxghp/MoviePilot/blob/main/README.md" target="_blank">
<template #prepend>
<VIcon class="me-2" icon="mdi-help-circle-outline" size="22" />
</template>
<VListItemTitle>帮助</VListItemTitle>
</VListItem>
<!-- Divider -->
<VDivider class="my-2" />
<!-- 👉 Logout -->
<VListItem @click="logout">
<template #prepend>
<VIcon class="me-2" icon="mdi-logout" size="22" />
</template>
<VListItemTitle>注销</VListItemTitle>
<VBtn color="error" block>
<template #append> <VIcon size="small" icon="mdi-logout" /> </template>
退出登录
</VBtn>
</VListItem>
</VList>
</VMenu>