mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-05-28 03:39:46 +08:00
优化多个组件的样式,调整卡片布局和间距,更新网格列数以适应不同屏幕尺寸
This commit is contained in:
@@ -167,31 +167,35 @@ const dropdownItems = ref([
|
||||
}"
|
||||
>
|
||||
<div
|
||||
class="relative flex flex-row items-start pa-3 justify-between grow"
|
||||
:style="`background: linear-gradient(rgba(0, 0, 0, 0.6) 0%, rgba(0, 0, 0, 0.5) 100%), linear-gradient(${backgroundColor} 0%, ${backgroundColor} 100%)`"
|
||||
>
|
||||
<div class="relative flex-1 min-w-0">
|
||||
<VCardText class="pa-2 pb-1">
|
||||
<VCardTitle
|
||||
class="text-white text-lg px-2 text-shadow whitespace-nowrap overflow-hidden text-ellipsis ..."
|
||||
class="text-white px-2 pb-0 text-lg text-shadow whitespace-nowrap overflow-hidden text-ellipsis"
|
||||
>
|
||||
<VBadge v-if="props.plugin?.state" dot inline color="success" />
|
||||
{{ props.plugin?.plugin_name }}
|
||||
<span class="text-sm text-gray-200">v{{ props.plugin?.plugin_version }}</span>
|
||||
<span class="text-sm mt-1 text-gray-200"> v{{ props.plugin?.plugin_version }} </span>
|
||||
</VCardTitle>
|
||||
<VCardText class="text-white text-sm px-2 py-0 text-shadow overflow-hidden line-clamp-3 ...">
|
||||
{{ props.plugin?.plugin_desc }}
|
||||
</VCardText>
|
||||
</div>
|
||||
<div class="relative flex-shrink-0 self-center">
|
||||
<VAvatar size="64">
|
||||
<VImg
|
||||
ref="imageRef"
|
||||
:src="iconPath"
|
||||
aspect-ratio="4/3"
|
||||
cover
|
||||
@load="imageLoaded"
|
||||
@error="imageLoadError = true"
|
||||
/>
|
||||
</VAvatar>
|
||||
</VCardText>
|
||||
<div class="relative flex flex-row items-start px-2 justify-between grow">
|
||||
<div class="relative flex-1 min-w-0">
|
||||
<VCardText class="text-white text-sm px-2 py-0 text-shadow overflow-hidden line-clamp-3 ...">
|
||||
{{ props.plugin?.plugin_desc }}
|
||||
</VCardText>
|
||||
</div>
|
||||
<div class="relative flex-shrink-0 self-center pb-3">
|
||||
<VAvatar size="48">
|
||||
<VImg
|
||||
ref="imageRef"
|
||||
:src="iconPath"
|
||||
aspect-ratio="4/3"
|
||||
cover
|
||||
@load="imageLoaded"
|
||||
@error="imageLoadError = true"
|
||||
/>
|
||||
</VAvatar>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<VCardText class="flex flex-none align-self-baseline py-3 w-full align-end">
|
||||
|
||||
@@ -344,30 +344,35 @@ watch(
|
||||
}"
|
||||
>
|
||||
<div
|
||||
class="relative flex flex-row items-start pa-3 justify-between grow"
|
||||
:style="`background: linear-gradient(rgba(0, 0, 0, 0.6) 0%, rgba(0, 0, 0, 0.5) 100%), linear-gradient(${backgroundColor} 0%, ${backgroundColor} 100%)`"
|
||||
>
|
||||
<div class="relative flex-1 min-w-0">
|
||||
<VCardTitle class="text-white text-lg px-2 text-shadow whitespace-nowrap overflow-hidden text-ellipsis">
|
||||
<VCardText class="pa-2 pb-1">
|
||||
<VCardTitle
|
||||
class="text-white px-2 pb-0 text-lg text-shadow whitespace-nowrap overflow-hidden text-ellipsis"
|
||||
>
|
||||
<VBadge v-if="props.plugin?.state" dot inline color="success" />
|
||||
{{ props.plugin?.plugin_name }}
|
||||
<span class="text-sm mt-1 text-gray-200"> v{{ props.plugin?.plugin_version }} </span>
|
||||
</VCardTitle>
|
||||
<VCardText class="px-2 py-0 text-white text-sm text-shadow overflow-hidden line-clamp-3 ...">
|
||||
{{ props.plugin?.plugin_desc }}
|
||||
</VCardText>
|
||||
</div>
|
||||
<div class="relative flex-shrink-0 self-center cursor-move">
|
||||
<VAvatar size="64">
|
||||
<VImg
|
||||
ref="imageRef"
|
||||
:src="iconPath"
|
||||
aspect-ratio="4/3"
|
||||
cover
|
||||
@load="imageLoaded"
|
||||
@error="imageLoadError = true"
|
||||
/>
|
||||
</VAvatar>
|
||||
</VCardText>
|
||||
<div class="relative flex flex-row items-start px-2 justify-between grow">
|
||||
<div class="relative flex-1 min-w-0">
|
||||
<VCardText class="px-2 py-0 text-white text-sm text-shadow overflow-hidden line-clamp-3 ...">
|
||||
{{ props.plugin?.plugin_desc }}
|
||||
</VCardText>
|
||||
</div>
|
||||
<div class="relative flex-shrink-0 self-center cursor-move pb-3">
|
||||
<VAvatar size="48">
|
||||
<VImg
|
||||
ref="imageRef"
|
||||
:src="iconPath"
|
||||
aspect-ratio="4/3"
|
||||
cover
|
||||
@load="imageLoaded"
|
||||
@error="imageLoadError = true"
|
||||
/>
|
||||
</VAvatar>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<VCardText class="flex flex-none align-self-baseline py-3 w-full align-end">
|
||||
|
||||
@@ -311,7 +311,7 @@ function onSubscribeEditRemove() {
|
||||
'opacity-70': subscribeState === 'S',
|
||||
}"
|
||||
rounded="0"
|
||||
min-height="170"
|
||||
min-height="150"
|
||||
@click="editSubscribeDialog"
|
||||
:ripple="false"
|
||||
>
|
||||
@@ -347,7 +347,7 @@ function onSubscribeEditRemove() {
|
||||
/>
|
||||
</template>
|
||||
<div>
|
||||
<VCardText class="flex items-center py-3">
|
||||
<VCardText class="flex items-center pt-3 pb-1">
|
||||
<div class="h-auto w-16 flex-shrink-0 overflow-hidden rounded-md cursor-move" v-if="imageLoaded">
|
||||
<VImg :src="posterUrl" aspect-ratio="2/3" cover>
|
||||
<template #placeholder>
|
||||
@@ -365,7 +365,7 @@ function onSubscribeEditRemove() {
|
||||
</div>
|
||||
</div>
|
||||
</VCardText>
|
||||
<VCardText class="flex justify-space-between align-center flex-wrap py-3">
|
||||
<VCardText class="flex justify-space-between align-center flex-wrap">
|
||||
<div class="flex align-center">
|
||||
<IconBtn
|
||||
v-if="props.media?.total_episode"
|
||||
@@ -384,7 +384,10 @@ function onSubscribeEditRemove() {
|
||||
</span>
|
||||
</div>
|
||||
</VCardText>
|
||||
<VCardText v-if="lastUpdateText" class="absolute right-0 bottom-0 d-flex align-center p-2 text-gray-300">
|
||||
<VCardText
|
||||
v-if="lastUpdateText"
|
||||
class="absolute right-0 bottom-0 d-flex align-center p-2 text-gray-300 text-xs"
|
||||
>
|
||||
<VIcon icon="mdi-download" class="me-1" />
|
||||
{{ lastUpdateText }}
|
||||
</VCardText>
|
||||
|
||||
@@ -108,7 +108,7 @@ function doDelete() {
|
||||
:key="props.media?.id"
|
||||
class="flex flex-col h-full"
|
||||
rounded="0"
|
||||
min-height="170"
|
||||
min-height="150"
|
||||
@click="showForkSubscribe"
|
||||
>
|
||||
<template #image>
|
||||
@@ -122,8 +122,8 @@ function doDelete() {
|
||||
</VImg>
|
||||
</template>
|
||||
<div class="h-full flex flex-col">
|
||||
<VCardText class="flex items-center pb-1 grow">
|
||||
<div class="h-auto w-12 flex-shrink-0 overflow-hidden rounded-md" v-if="imageLoaded">
|
||||
<VCardText class="flex items-center pa-3 pb-1 grow">
|
||||
<div class="h-auto w-16 flex-shrink-0 overflow-hidden rounded-md" v-if="imageLoaded">
|
||||
<VImg :src="posterUrl" aspect-ratio="2/3" cover @click.stop="viewMediaDetail">
|
||||
<template #placeholder>
|
||||
<div class="w-full h-full">
|
||||
@@ -141,7 +141,7 @@ function doDelete() {
|
||||
</div>
|
||||
</div>
|
||||
</VCardText>
|
||||
<VCardText class="flex justify-space-between align-center flex-wrap">
|
||||
<VCardText class="flex justify-space-between align-center flex-wrap py-2">
|
||||
<div class="flex align-center">
|
||||
<IconBtn v-bind="props" icon="mdi-account" color="white" class="me-1" />
|
||||
<div class="text-subtitle-2 me-4 text-white">
|
||||
|
||||
@@ -172,88 +172,56 @@ html.v-overlay-scroll-blocked {
|
||||
}
|
||||
|
||||
.grid-site-card {
|
||||
grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
|
||||
grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
|
||||
padding-block-end: 1rem;
|
||||
}
|
||||
|
||||
.grid-media-card {
|
||||
grid-template-columns: repeat(auto-fill, minmax(9.375rem, 1fr));
|
||||
grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
|
||||
}
|
||||
|
||||
.grid-backdrop-card {
|
||||
grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
|
||||
padding-block-end: 1rem;
|
||||
}
|
||||
|
||||
.grid-torrent-card {
|
||||
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
|
||||
padding-block-end: 1rem;
|
||||
}
|
||||
|
||||
.grid-plugin-card {
|
||||
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
|
||||
padding-block-end: 1rem;
|
||||
grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
|
||||
}
|
||||
|
||||
.grid-downloading-card {
|
||||
grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
|
||||
padding-block-end: 1rem;
|
||||
}
|
||||
|
||||
.grid-directory-card {
|
||||
grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
|
||||
padding-block-end: 1rem;
|
||||
}
|
||||
|
||||
|
||||
.grid-filterrule-card {
|
||||
grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
|
||||
padding-block-end: 1rem;
|
||||
}
|
||||
|
||||
.grid-customrule-card {
|
||||
grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
|
||||
padding-block-end: 1rem;
|
||||
}
|
||||
|
||||
.grid-subscribe-card {
|
||||
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
|
||||
padding-block-end: 1rem;
|
||||
grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
|
||||
}
|
||||
|
||||
.grid-user-card {
|
||||
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
|
||||
padding-block-end: 1rem;
|
||||
}
|
||||
|
||||
@media (width <= 600px) {
|
||||
.user-list-container {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.grid-user-card {
|
||||
gap: 1rem;
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 601px) and (width <= 960px) {
|
||||
.grid-user-card{
|
||||
gap: 1rem;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 961px) {
|
||||
.grid-user-card {
|
||||
gap: 1.5rem;
|
||||
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
.grid-app-card {
|
||||
grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
|
||||
padding-block-end: 1rem;
|
||||
grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
|
||||
}
|
||||
|
||||
.grid-workflow-card {
|
||||
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
|
||||
}
|
||||
|
||||
.v-tabs:not(.v-tabs-pill).v-tabs--horizontal {
|
||||
|
||||
@@ -112,7 +112,7 @@ async function fetchData({ done }: { done: any }) {
|
||||
|
||||
<template>
|
||||
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
||||
<VInfiniteScroll mode="intersect" side="end" :items="dataList" class="overflow-visible pt-3" @load="fetchData">
|
||||
<VInfiniteScroll mode="intersect" side="end" :items="dataList" class="overflow-visible pt-3 px-2" @load="fetchData">
|
||||
<template #loading />
|
||||
<template #empty />
|
||||
<div v-if="dataList.length > 0" class="grid gap-4 grid-media-card" tabindex="0">
|
||||
|
||||
@@ -609,7 +609,7 @@ useDynamicButton({
|
||||
</template>
|
||||
</VHeaderTab>
|
||||
|
||||
<VWindow v-model="activeTab" class="mt-5 disable-tab-transition" :touch="false">
|
||||
<VWindow v-model="activeTab" class="mt-5 disable-tab-transition px-2" :touch="false">
|
||||
<!-- 我的插件 -->
|
||||
<VWindowItem value="installed">
|
||||
<transition name="fade-slide" appear>
|
||||
|
||||
@@ -111,7 +111,7 @@ useDynamicButton({
|
||||
handle=".cursor-move"
|
||||
item-key="id"
|
||||
tag="div"
|
||||
:component-data="{ 'class': 'grid gap-4 grid-site-card' }"
|
||||
:component-data="{ 'class': 'grid gap-4 grid-site-card px-2' }"
|
||||
>
|
||||
<template #item="{ element }">
|
||||
<SiteCard :site="element" :data="getUserData(element.domain)" @remove="fetchData" @update="fetchData" />
|
||||
|
||||
@@ -173,7 +173,7 @@ useDynamicButton({
|
||||
handle=".cursor-move"
|
||||
item-key="id"
|
||||
tag="div"
|
||||
:component-data="{ class: 'grid gap-4 grid-subscribe-card' }"
|
||||
:component-data="{ class: 'grid gap-4 grid-subscribe-card px-2' }"
|
||||
>
|
||||
<template #item="{ element }">
|
||||
<SubscribeCard :key="element.id" :media="element" @remove="fetchData" @save="fetchData" />
|
||||
|
||||
@@ -111,7 +111,7 @@ async function fetchData({ done }: { done: any }) {
|
||||
|
||||
<template>
|
||||
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
||||
<VInfiniteScroll mode="intersect" side="end" :items="dataList" class="overflow-visible" @load="fetchData">
|
||||
<VInfiniteScroll mode="intersect" side="end" :items="dataList" class="overflow-visible px-2" @load="fetchData">
|
||||
<template #loading />
|
||||
<template #empty />
|
||||
<div v-if="dataList.length > 0" class="grid gap-4 grid-media-card" tabindex="0">
|
||||
|
||||
@@ -121,7 +121,7 @@ function removeData(id: number) {
|
||||
<template>
|
||||
<VPageContentTitle v-if="keyword" :title="`${t('common.search')}:${keyword}`" />
|
||||
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
||||
<VInfiniteScroll mode="intersect" side="end" :items="dataList" class="overflow-visible" @load="fetchData">
|
||||
<VInfiniteScroll mode="intersect" side="end" :items="dataList" class="overflow-visible px-2" @load="fetchData">
|
||||
<template #loading />
|
||||
<template #empty />
|
||||
<div v-if="dataList.length > 0" class="grid gap-4 grid-subscribe-card" tabindex="0">
|
||||
|
||||
@@ -78,7 +78,7 @@ useDynamicButton({
|
||||
<!-- 加载中提示 -->
|
||||
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
||||
<!-- 用户卡片网格 -->
|
||||
<div v-if="allUsers.length > 0 && isRefreshed" class="grid gap- grid-user-card">
|
||||
<div v-if="allUsers.length > 0 && isRefreshed" class="grid gap-4 grid-user-card px-2">
|
||||
<!-- 普通用户卡片 -->
|
||||
<UserCard
|
||||
v-for="user in allUsers"
|
||||
|
||||
@@ -60,11 +60,9 @@ useDynamicButton({
|
||||
<div>
|
||||
<VPageContentTitle :title="t('workflow.title')" />
|
||||
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
||||
<VRow v-if="workflowList.length > 0" class="match-height">
|
||||
<VCol cols="12" md="6" lg="4" v-for="item in workflowList" :key="item.id">
|
||||
<WorkflowTaskCard :workflow="item" @refresh="fetchData" />
|
||||
</VCol>
|
||||
</VRow>
|
||||
<div v-if="workflowList.length > 0 && isRefreshed" class="grid gap-4 grid-workflow-card px-2">
|
||||
<WorkflowTaskCard v-for="item in workflowList" :key="item.id" :workflow="item" @refresh="fetchData" />
|
||||
</div>
|
||||
<NoDataFound
|
||||
v-if="workflowList.length === 0 && isRefreshed"
|
||||
error-code="404"
|
||||
|
||||
Reference in New Issue
Block a user