mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-08 17:26:41 +08:00
refactor: 统一组件样式,优化圆角和阴影效果,提升视觉一致性
This commit is contained in:
@@ -346,7 +346,7 @@ function stopDrag() {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
cursor: col-resize;
|
cursor: col-resize;
|
||||||
inline-size: 4px;
|
inline-size: 1px;
|
||||||
transition: background-color 0.2s ease;
|
transition: background-color 0.2s ease;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,14 @@ function submitSettings() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VDialog v-if="visible" v-model="visible" width="35rem" class="settings-dialog" scrollable :fullscreen="!display.mdAndUp.value">
|
<VDialog
|
||||||
|
v-if="visible"
|
||||||
|
v-model="visible"
|
||||||
|
width="35rem"
|
||||||
|
class="settings-dialog"
|
||||||
|
scrollable
|
||||||
|
:fullscreen="!display.mdAndUp.value"
|
||||||
|
>
|
||||||
<VCard class="settings-card">
|
<VCard class="settings-card">
|
||||||
<VCardItem class="settings-card-header">
|
<VCardItem class="settings-card-header">
|
||||||
<VCardTitle>
|
<VCardTitle>
|
||||||
@@ -195,6 +202,7 @@ function submitSettings() {
|
|||||||
.setting-item {
|
.setting-item {
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
border-radius: var(--app-surface-radius);
|
||||||
background-color: rgba(var(--v-theme-surface-variant), 0.3);
|
background-color: rgba(var(--v-theme-surface-variant), 0.3);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding-block: 10px;
|
padding-block: 10px;
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ function closeDialog() {
|
|||||||
/>
|
/>
|
||||||
</VToolbar>
|
</VToolbar>
|
||||||
<VDialogCloseBtn @click="closeDialog" />
|
<VDialogCloseBtn @click="closeDialog" />
|
||||||
<VList v-if="plugins.length > 0" lines="two">
|
<VList v-if="plugins.length > 0" class="plugin-search-list" lines="two">
|
||||||
<VVirtualScroll :items="plugins">
|
<VVirtualScroll :items="plugins">
|
||||||
<template #default="{ item }">
|
<template #default="{ item }">
|
||||||
<VListItem @click="emit('open-plugin', item)">
|
<VListItem @click="emit('open-plugin', item)">
|
||||||
@@ -130,4 +130,8 @@ function closeDialog() {
|
|||||||
</VCard>
|
</VCard>
|
||||||
</VDialog>
|
</VDialog>
|
||||||
</template>
|
</template>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.plugin-search-list {
|
||||||
|
border-radius: 0 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ const filteredSites = computed(() => {
|
|||||||
<div
|
<div
|
||||||
v-bind="props"
|
v-bind="props"
|
||||||
:class="[
|
:class="[
|
||||||
'site-checkbox-wrapper pa-2 pa-sm-3 rounded-lg d-flex align-center',
|
'site-checkbox-wrapper pa-2 pa-sm-3 d-flex align-center',
|
||||||
{
|
{
|
||||||
'site-selected': selectedSites.includes(site.id),
|
'site-selected': selectedSites.includes(site.id),
|
||||||
'site-hover': isHovering && !selectedSites.includes(site.id),
|
'site-hover': isHovering && !selectedSites.includes(site.id),
|
||||||
@@ -193,8 +193,11 @@ const filteredSites = computed(() => {
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
.site-checkbox-wrapper {
|
.site-checkbox-wrapper {
|
||||||
border: 1px solid rgba(var(--v-theme-on-surface), 0.08);
|
border: 1px solid rgba(var(--v-theme-on-surface), 0.08);
|
||||||
|
border-radius: var(--app-surface-radius);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: transform 0.2s ease, background-color 0.2s ease;
|
transition:
|
||||||
|
transform 0.2s ease,
|
||||||
|
background-color 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-checkbox-wrapper:hover {
|
.site-checkbox-wrapper:hover {
|
||||||
|
|||||||
@@ -216,11 +216,50 @@ function getMediaTypeText(type: string | undefined) {
|
|||||||
</VVirtualScroll>
|
</VVirtualScroll>
|
||||||
</VInfiniteScroll>
|
</VInfiniteScroll>
|
||||||
</VList>
|
</VList>
|
||||||
<VCardText v-if="historyList.length === 0 && isRefreshed" class="text-center">{{
|
<VCardText v-if="historyList.length === 0 && isRefreshed" class="subscribe-history-empty">
|
||||||
t('dialog.subscribeHistory.noData')
|
<VIcon class="subscribe-history-empty__icon" icon="mdi-sync" size="30" />
|
||||||
}}</VCardText>
|
|
||||||
|
<div class="subscribe-history-empty__headline">
|
||||||
|
{{ t('dialog.subscribeHistory.noData') }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="subscribe-history-empty__description">
|
||||||
|
{{ t('dialog.subscribeHistory.noDataHint') }}
|
||||||
|
</div>
|
||||||
|
</VCardText>
|
||||||
</VCard>
|
</VCard>
|
||||||
<!-- 进度框 -->
|
<!-- 进度框 -->
|
||||||
<ProgressDialog v-if="progressDialog" v-model="progressDialog" :text="progressText" />
|
<ProgressDialog v-if="progressDialog" v-model="progressDialog" :text="progressText" />
|
||||||
</VDialog>
|
</VDialog>
|
||||||
</template>
|
</template>
|
||||||
|
<style scoped>
|
||||||
|
.subscribe-history-empty {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
min-block-size: 13rem;
|
||||||
|
padding-block: 2.5rem !important;
|
||||||
|
padding-inline: 1.5rem !important;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subscribe-history-empty__icon {
|
||||||
|
color: rgba(var(--v-theme-on-surface), 0.32);
|
||||||
|
}
|
||||||
|
|
||||||
|
.subscribe-history-empty__headline {
|
||||||
|
color: rgba(var(--v-theme-on-surface), 0.9);
|
||||||
|
font-size: 1.15rem;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subscribe-history-empty__description {
|
||||||
|
color: rgba(var(--v-theme-on-surface), 0.6);
|
||||||
|
font-size: 0.92rem;
|
||||||
|
line-height: 1.65;
|
||||||
|
max-inline-size: 25rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -29,8 +29,7 @@ const display = useDisplay()
|
|||||||
const { appMode } = usePWA()
|
const { appMode } = usePWA()
|
||||||
|
|
||||||
// 计算列表可用高度
|
// 计算列表可用高度
|
||||||
// componentOffset = FileToolbar(48) + FileList操作栏(40) + VCard边距(4) = 92
|
const { availableHeight: listAvailableHeight } = useAvailableHeight(100, 300)
|
||||||
const { availableHeight: listAvailableHeight } = useAvailableHeight(89, 300)
|
|
||||||
|
|
||||||
// 输入参数
|
// 输入参数
|
||||||
const inProps = defineProps({
|
const inProps = defineProps({
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import type { FileItem } from '@/api/types'
|
|||||||
import { useDisplay } from 'vuetify'
|
import { useDisplay } from 'vuetify'
|
||||||
import type { AxiosRequestConfig, AxiosInstance } from 'axios'
|
import type { AxiosRequestConfig, AxiosInstance } from 'axios'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { usePWA } from '@/composables/usePWA'
|
|
||||||
import { useAvailableHeight } from '@/composables/useAvailableHeight'
|
import { useAvailableHeight } from '@/composables/useAvailableHeight'
|
||||||
|
|
||||||
// 国际化
|
// 国际化
|
||||||
@@ -12,16 +11,13 @@ const { t } = useI18n()
|
|||||||
|
|
||||||
const display = useDisplay()
|
const display = useDisplay()
|
||||||
|
|
||||||
const { appMode } = usePWA()
|
|
||||||
|
|
||||||
type TreeRow =
|
type TreeRow =
|
||||||
| { type: 'root'; key: string; level: number }
|
| { type: 'root'; key: string; level: number }
|
||||||
| { type: 'loading'; key: string; path: string; level: number }
|
| { type: 'loading'; key: string; path: string; level: number }
|
||||||
| { type: 'directory'; key: string; dir: FileItem; level: number }
|
| { type: 'directory'; key: string; dir: FileItem; level: number }
|
||||||
|
|
||||||
// 计算列表可用高度
|
// 计算列表可用高度
|
||||||
// componentOffset = FileToolbar(48) = 48
|
const { availableHeight } = useAvailableHeight(58, 300)
|
||||||
const { availableHeight } = useAvailableHeight(48, 300)
|
|
||||||
|
|
||||||
// 输入参数
|
// 输入参数
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -326,7 +322,6 @@ onMounted(async () => {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
background: rgb(var(--v-table-header-background));
|
|
||||||
block-size: 100%;
|
block-size: 100%;
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
inline-size: 240px;
|
inline-size: 240px;
|
||||||
|
|||||||
@@ -2790,6 +2790,7 @@ export default {
|
|||||||
resubscribeTv: 'Resubscribing {name} Season {season}...',
|
resubscribeTv: 'Resubscribing {name} Season {season}...',
|
||||||
season: 'Season {season}',
|
season: 'Season {season}',
|
||||||
noData: 'No completed subscriptions',
|
noData: 'No completed subscriptions',
|
||||||
|
noDataHint: 'Completed subscription history will be displayed here',
|
||||||
},
|
},
|
||||||
siteUserData: {
|
siteUserData: {
|
||||||
title: 'Site User Data',
|
title: 'Site User Data',
|
||||||
|
|||||||
@@ -2740,6 +2740,7 @@ export default {
|
|||||||
resubscribeTv: '正在重新订阅 {name} 第 {season} 季...',
|
resubscribeTv: '正在重新订阅 {name} 第 {season} 季...',
|
||||||
season: '第 {season} 季',
|
season: '第 {season} 季',
|
||||||
noData: '没有已完成的订阅',
|
noData: '没有已完成的订阅',
|
||||||
|
noDataHint: '完成的订阅会显示在这里',
|
||||||
},
|
},
|
||||||
siteUserData: {
|
siteUserData: {
|
||||||
title: '站点用户数据',
|
title: '站点用户数据',
|
||||||
|
|||||||
@@ -2741,6 +2741,7 @@ export default {
|
|||||||
resubscribeTv: '正在重新訂閱 {name} 第 {season} 季...',
|
resubscribeTv: '正在重新訂閱 {name} 第 {season} 季...',
|
||||||
season: '第 {season} 季',
|
season: '第 {season} 季',
|
||||||
noData: '沒有已完成的訂閱',
|
noData: '沒有已完成的訂閱',
|
||||||
|
noDataHint: '完成的訂閱會顯示在這裡',
|
||||||
},
|
},
|
||||||
siteUserData: {
|
siteUserData: {
|
||||||
title: '站點用戶數據',
|
title: '站點用戶數據',
|
||||||
|
|||||||
+50
-15
@@ -148,6 +148,15 @@ html[data-theme-shadow='high'] {
|
|||||||
transition: border-color 0.2s ease, border-radius 0.2s ease, box-shadow 0.2s ease;
|
transition: border-color 0.2s ease, border-radius 0.2s ease, box-shadow 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.app-surface-static {
|
||||||
|
border-radius: var(--app-surface-radius) !important;
|
||||||
|
box-shadow: var(--app-surface-shadow) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-surface-static:hover {
|
||||||
|
box-shadow: var(--app-surface-shadow) !important;
|
||||||
|
}
|
||||||
|
|
||||||
// 底部导航卡片原本就是胶囊形态,不参与主题圆角切换。
|
// 底部导航卡片原本就是胶囊形态,不参与主题圆角切换。
|
||||||
.footer-nav-card.v-card {
|
.footer-nav-card.v-card {
|
||||||
--app-surface-radius: 9999px;
|
--app-surface-radius: 9999px;
|
||||||
@@ -183,21 +192,52 @@ html[data-theme-shadow='high'] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 统一文本输入、下拉框、文本域等有框表单控件的圆角,显式 rounded 控件保留特殊形态。
|
// 统一文本输入、下拉框、文本域等有框表单控件的圆角,显式 rounded 控件保留特殊形态。
|
||||||
.v-field:not(.v-field--variant-plain, .v-field--variant-underlined, .v-field--rounded, [class^='rounded-'], [class*=' rounded-']) {
|
.v-field:not(
|
||||||
|
.v-field--variant-plain,
|
||||||
|
.v-field--variant-underlined,
|
||||||
|
.v-field--rounded,
|
||||||
|
[class^='rounded-'],
|
||||||
|
[class*=' rounded-']
|
||||||
|
) {
|
||||||
border-radius: var(--app-field-radius);
|
border-radius: var(--app-field-radius);
|
||||||
transition: border-radius 0.2s ease, box-shadow 0.2s ease;
|
transition: border-radius 0.2s ease, box-shadow 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-btn:not(.v-btn--variant-plain, .v-btn--variant-text) {
|
// 自定义字段圆角时,outlined 字段带左侧 inner icon 需要同步放大左侧描边弧度。
|
||||||
|
.v-field:not(
|
||||||
|
.v-field--variant-plain,
|
||||||
|
.v-field--variant-underlined,
|
||||||
|
.v-field--rounded,
|
||||||
|
[class^='rounded-'],
|
||||||
|
[class*=' rounded-']
|
||||||
|
).v-field--variant-outlined.v-field--prepended {
|
||||||
|
--app-field-outline-start-size: max(12px, calc(var(--app-field-radius) + 8px));
|
||||||
|
|
||||||
|
.v-field__outline__start {
|
||||||
|
flex-basis: var(--app-field-outline-start-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-field__outline__notch {
|
||||||
|
max-inline-size: calc(100% - var(--app-field-outline-start-size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-btn:not(.v-btn--variant-plain, .v-btn--variant-text, .v-btn--flat) {
|
||||||
box-shadow: var(--app-surface-shadow) !important;
|
box-shadow: var(--app-surface-shadow) !important;
|
||||||
transition: box-shadow 0.2s ease;
|
transition: box-shadow 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-btn:not(.v-btn--rounded, [class^='rounded-'], [class*=' rounded-']) {
|
.v-btn:not(.v-btn--rounded, .v-btn--flat, .v-btn--icon, [class^='rounded-'], [class*=' rounded-']) {
|
||||||
border-radius: var(--app-surface-radius);
|
border-radius: var(--app-surface-radius);
|
||||||
transition: border-radius 0.2s ease;
|
transition: border-radius 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.v-btn-group:not(.v-btn-group--variant-plain, .v-btn-group--variant-text) {
|
||||||
|
border-radius: var(--app-surface-radius);
|
||||||
|
box-shadow: var(--app-surface-shadow) !important;
|
||||||
|
transition: box-shadow 0.2s ease, border-radius 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
// 只给外层 surface 加边框和阴影,卡片内部的列表、表格等子组件保持平面,避免层级噪声。
|
// 只给外层 surface 加边框和阴影,卡片内部的列表、表格等子组件保持平面,避免层级噪声。
|
||||||
.v-card .v-list:not(.app-surface),
|
.v-card .v-list:not(.app-surface),
|
||||||
.v-card .v-sheet:not(.app-surface),
|
.v-card .v-sheet:not(.app-surface),
|
||||||
@@ -246,6 +286,7 @@ html[data-theme-skin='bordered'] {
|
|||||||
// 设置项强调卡片:复用通知模板入口的弱强调条、轻渐变与悬浮反馈。
|
// 设置项强调卡片:复用通知模板入口的弱强调条、轻渐变与悬浮反馈。
|
||||||
.app-card-colorful {
|
.app-card-colorful {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
border-radius: var(--app-surface-radius);
|
||||||
background:
|
background:
|
||||||
linear-gradient(
|
linear-gradient(
|
||||||
135deg,
|
135deg,
|
||||||
@@ -254,8 +295,9 @@ html[data-theme-skin='bordered'] {
|
|||||||
rgba(var(--v-theme-surface), 0) 76%
|
rgba(var(--v-theme-surface), 0) 76%
|
||||||
),
|
),
|
||||||
rgba(var(--v-theme-surface), var(--app-card-surface-opacity));
|
rgba(var(--v-theme-surface), var(--app-card-surface-opacity));
|
||||||
box-shadow: var(--app-card-rest-shadow);
|
box-shadow: var(--app-surface-shadow);
|
||||||
color: rgb(var(--v-theme-on-surface));
|
color: rgb(var(--v-theme-on-surface));
|
||||||
|
transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
|
||||||
|
|
||||||
--app-card-accent-rgb: var(--v-theme-primary);
|
--app-card-accent-rgb: var(--v-theme-primary);
|
||||||
--app-card-accent-end-rgb: var(--app-card-accent-rgb);
|
--app-card-accent-end-rgb: var(--app-card-accent-rgb);
|
||||||
@@ -268,8 +310,6 @@ html[data-theme-skin='bordered'] {
|
|||||||
--app-surface-border: 1px solid rgba(var(--app-card-accent-rgb), var(--app-card-border-opacity));
|
--app-surface-border: 1px solid rgba(var(--app-card-accent-rgb), var(--app-card-border-opacity));
|
||||||
--app-surface-hover-shadow: var(--app-card-hover-shadow);
|
--app-surface-hover-shadow: var(--app-card-hover-shadow);
|
||||||
--app-surface-shadow: var(--app-card-rest-shadow);
|
--app-surface-shadow: var(--app-card-rest-shadow);
|
||||||
|
|
||||||
transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-card-colorful::before {
|
.app-card-colorful::before {
|
||||||
@@ -459,10 +499,11 @@ html[data-theme="transparent"] .app-card-colorful,
|
|||||||
padding-block: 4.5rem;
|
padding-block: 4.5rem;
|
||||||
padding-inline: 1rem;
|
padding-inline: 1rem;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.Vue-Toastification__toast {
|
.Vue-Toastification__toast {
|
||||||
border-radius: 8px;
|
border-radius: var(--app-surface-radius);
|
||||||
}
|
box-shadow: var(--app-overlay-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 对话框样式
|
// 对话框样式
|
||||||
@@ -623,11 +664,6 @@ html[data-theme="transparent"] .app-card-colorful,
|
|||||||
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
|
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
.Vue-Toastification__toast {
|
|
||||||
border-radius: var(--app-surface-radius);
|
|
||||||
box-shadow: var(--app-overlay-shadow);
|
|
||||||
}
|
|
||||||
|
|
||||||
.backdrop-blur {
|
.backdrop-blur {
|
||||||
--tw-backdrop-blur: blur(8px)!important;
|
--tw-backdrop-blur: blur(8px)!important;
|
||||||
|
|
||||||
@@ -794,7 +830,6 @@ html[data-theme="transparent"] .app-card-colorful,
|
|||||||
|
|
||||||
// 弹出层样式
|
// 弹出层样式
|
||||||
.v-overlay__content .v-list{
|
.v-overlay__content .v-list{
|
||||||
overflow: hidden;
|
|
||||||
border-radius: var(--app-surface-radius);
|
border-radius: var(--app-surface-radius);
|
||||||
backdrop-filter: blur(6px);
|
backdrop-filter: blur(6px);
|
||||||
background-color: rgb(var(--v-theme-surface), 0.9);
|
background-color: rgb(var(--v-theme-surface), 0.9);
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ const route = useRoute()
|
|||||||
const Draggable = defineAsyncComponent(() => import('vuedraggable').then(module => module.default))
|
const Draggable = defineAsyncComponent(() => import('vuedraggable').then(module => module.default))
|
||||||
const PluginAppCard = defineAsyncComponent(() => import('@/components/cards/PluginAppCard.vue'))
|
const PluginAppCard = defineAsyncComponent(() => import('@/components/cards/PluginAppCard.vue'))
|
||||||
const PluginFolderCreateDialog = defineAsyncComponent(() => import('@/components/dialog/PluginFolderCreateDialog.vue'))
|
const PluginFolderCreateDialog = defineAsyncComponent(() => import('@/components/dialog/PluginFolderCreateDialog.vue'))
|
||||||
const PluginMarketSettingDialog = defineAsyncComponent(() => import('@/components/dialog/PluginMarketSettingDialog.vue'))
|
const PluginMarketSettingDialog = defineAsyncComponent(
|
||||||
|
() => import('@/components/dialog/PluginMarketSettingDialog.vue'),
|
||||||
|
)
|
||||||
const ProgressDialog = defineAsyncComponent(() => import('@/components/dialog/ProgressDialog.vue'))
|
const ProgressDialog = defineAsyncComponent(() => import('@/components/dialog/ProgressDialog.vue'))
|
||||||
const PluginSearchDialog = defineAsyncComponent(() => import('@/components/dialog/PluginSearchDialog.vue'))
|
const PluginSearchDialog = defineAsyncComponent(() => import('@/components/dialog/PluginSearchDialog.vue'))
|
||||||
|
|
||||||
@@ -1643,8 +1645,8 @@ function onDragStartPlugin(evt: any) {
|
|||||||
<div>
|
<div>
|
||||||
<VPageContentTitle v-if="installedFilter" :title="t('plugin.filter', { name: installedFilter })" />
|
<VPageContentTitle v-if="installedFilter" :title="t('plugin.filter', { name: installedFilter })" />
|
||||||
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
||||||
<VAlert v-if="sortMode" color="warning" variant="tonal" class="mb-4">
|
<VAlert v-if="sortMode" color="warning" variant="tonal" class="mb-4 py-0 app-surface-static">
|
||||||
<div class="d-flex flex-wrap align-center justify-space-between gap-2">
|
<div class="d-flex flex-wrap align-center justify-space-between gap-2 py-5">
|
||||||
<span>{{ t('common.sortModeHint') }}</span>
|
<span>{{ t('common.sortModeHint') }}</span>
|
||||||
<VBtn variant="tonal" color="error" @click="sortMode = false">
|
<VBtn variant="tonal" color="error" @click="sortMode = false">
|
||||||
{{ t('common.exit') }}
|
{{ t('common.exit') }}
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ onMounted(loadDownloadDirectories)
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="file-browser-view app-surface">
|
<div class="file-browser-view app-surface-static">
|
||||||
<FileBrowser
|
<FileBrowser
|
||||||
v-if="operItem"
|
v-if="operItem"
|
||||||
:storages="storages"
|
:storages="storages"
|
||||||
|
|||||||
@@ -18,7 +18,9 @@ import { useBackground } from '@/composables/useBackground'
|
|||||||
import { useGlobalSettingsStore } from '@/stores'
|
import { useGlobalSettingsStore } from '@/stores'
|
||||||
import { openSharedDialog } from '@/composables/useSharedDialog'
|
import { openSharedDialog } from '@/composables/useSharedDialog'
|
||||||
|
|
||||||
const TransferHistoryDeleteDialog = defineAsyncComponent(() => import('@/components/dialog/TransferHistoryDeleteDialog.vue'))
|
const TransferHistoryDeleteDialog = defineAsyncComponent(
|
||||||
|
() => import('@/components/dialog/TransferHistoryDeleteDialog.vue'),
|
||||||
|
)
|
||||||
|
|
||||||
// i18n
|
// i18n
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
@@ -33,8 +35,7 @@ const { appMode } = usePWA()
|
|||||||
const { useProgressSSE } = useBackground()
|
const { useProgressSSE } = useBackground()
|
||||||
|
|
||||||
// 计算列表可用高度
|
// 计算列表可用高度
|
||||||
// componentOffset = VCardItem搜索栏(68) + VDivider(1) + 分页栏(40) + VCard边距(2) = 111
|
const { availableHeight } = useAvailableHeight(135, 300)
|
||||||
const { availableHeight } = useAvailableHeight(125, 300)
|
|
||||||
|
|
||||||
// 提示框
|
// 提示框
|
||||||
const $toast = useToast()
|
const $toast = useToast()
|
||||||
@@ -1209,7 +1210,6 @@ onUnmounted(() => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Teleport>
|
</Teleport>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
@@ -410,8 +410,8 @@ useDynamicButton({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<VAlert v-if="sortMode" color="warning" variant="tonal" class="mb-4">
|
<VAlert v-if="sortMode" color="warning" variant="tonal" class="mb-4 py-0 app-surface-static">
|
||||||
<div class="d-flex flex-wrap align-center justify-space-between gap-2">
|
<div class="d-flex flex-wrap align-center justify-space-between gap-2 py-5">
|
||||||
<span>{{ t('common.sortModeHint') }}</span>
|
<span>{{ t('common.sortModeHint') }}</span>
|
||||||
<VBtn variant="tonal" color="error" @click="sortMode = false">
|
<VBtn variant="tonal" color="error" @click="sortMode = false">
|
||||||
{{ t('common.exit') }}
|
{{ t('common.exit') }}
|
||||||
|
|||||||
@@ -31,7 +31,12 @@ let progressDialogController: ReturnType<typeof openSharedDialog> | null = null
|
|||||||
// 打开订阅日历共享进度弹窗。
|
// 打开订阅日历共享进度弹窗。
|
||||||
function openProgressDialog() {
|
function openProgressDialog() {
|
||||||
progressDialogController?.close()
|
progressDialogController?.close()
|
||||||
progressDialogController = openSharedDialog(ProgressDialog, { text: `${t('common.loading')} ...` }, {}, { closeOn: false })
|
progressDialogController = openSharedDialog(
|
||||||
|
ProgressDialog,
|
||||||
|
{ text: `${t('common.loading')} ...` },
|
||||||
|
{},
|
||||||
|
{ closeOn: false },
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关闭订阅日历共享进度弹窗。
|
// 关闭订阅日历共享进度弹窗。
|
||||||
@@ -85,7 +90,10 @@ async function eventsHander(subscribe: Subscribe) {
|
|||||||
} else {
|
} else {
|
||||||
// 调用API查询集信息
|
// 调用API查询集信息
|
||||||
const params = subscribe.episode_group ? { episode_group: subscribe.episode_group } : undefined
|
const params = subscribe.episode_group ? { episode_group: subscribe.episode_group } : undefined
|
||||||
const episodes: TmdbEpisode[] = await api.get(`tmdb/${subscribe.tmdbid}/${subscribe.season}`, params ? { params } : undefined)
|
const episodes: TmdbEpisode[] = await api.get(
|
||||||
|
`tmdb/${subscribe.tmdbid}/${subscribe.season}`,
|
||||||
|
params ? { params } : undefined,
|
||||||
|
)
|
||||||
|
|
||||||
interface EpisodeInfo {
|
interface EpisodeInfo {
|
||||||
title: string
|
title: string
|
||||||
@@ -160,8 +168,8 @@ onActivated(() => {
|
|||||||
<template>
|
<template>
|
||||||
<FullCalendar :options="calendarOptions">
|
<FullCalendar :options="calendarOptions">
|
||||||
<template #eventContent="arg">
|
<template #eventContent="arg">
|
||||||
<div class="hidden md:block overflow-hidden">
|
<div class="hidden md:block">
|
||||||
<VCard>
|
<VCard class="app-surface">
|
||||||
<div class="d-flex justify-space-between flex-nowrap flex-row">
|
<div class="d-flex justify-space-between flex-nowrap flex-row">
|
||||||
<div class="ma-auto">
|
<div class="ma-auto">
|
||||||
<VImg
|
<VImg
|
||||||
@@ -434,12 +442,6 @@ onActivated(() => {
|
|||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-application .fc .fc-popover {
|
|
||||||
border-radius: 6px;
|
|
||||||
box-shadow: 0 4px 14px -4px var(--v-shadow-key-umbra-opacity), 0 4px 8px -4px var(--v-shadow-key-penumbra-opacity),
|
|
||||||
0 4px 8px -4px var(--v-shadow-key-ambient-opacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
.v-application .fc .fc-popover .fc-popover-header,
|
.v-application .fc .fc-popover .fc-popover-header,
|
||||||
.v-application .fc .fc-popover .fc-popover-body {
|
.v-application .fc .fc-popover .fc-popover-body {
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
|
|||||||
@@ -572,8 +572,8 @@ defineExpose({
|
|||||||
</VCard>
|
</VCard>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<VAlert v-if="sortMode" color="warning" variant="tonal" class="mb-4 mx-2">
|
<VAlert v-if="sortMode" color="warning" variant="tonal" class="mb-4 mx-2 py-0 app-surface-static">
|
||||||
<div class="d-flex flex-wrap align-center justify-space-between gap-2">
|
<div class="d-flex flex-wrap align-center justify-space-between gap-2 py-5">
|
||||||
<span>{{ t('common.sortModeHint') }}</span>
|
<span>{{ t('common.sortModeHint') }}</span>
|
||||||
<VBtn variant="tonal" color="error" @click="sortMode = false">
|
<VBtn variant="tonal" color="error" @click="sortMode = false">
|
||||||
{{ t('common.exit') }}
|
{{ t('common.exit') }}
|
||||||
|
|||||||
Reference in New Issue
Block a user