mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-06 16:16:42 +08:00
feat: 更新多个组件的背景样式为透明度背景
This commit is contained in:
@@ -593,7 +593,7 @@ onBeforeUnmount(() => {
|
|||||||
|
|
||||||
.media-card-placeholder {
|
.media-card-placeholder {
|
||||||
aspect-ratio: 2 / 3;
|
aspect-ratio: 2 / 3;
|
||||||
background: rgb(var(--v-theme-surface-variant));
|
background: rgba(var(--v-theme-on-surface), 0.08);
|
||||||
block-size: 100%;
|
block-size: 100%;
|
||||||
inline-size: 100%;
|
inline-size: 100%;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ function goArtistDetail() {
|
|||||||
<div style="padding-block-end: 150%">
|
<div style="padding-block-end: 150%">
|
||||||
<div class="absolute inset-0 flex h-full w-full flex-col items-center p-2">
|
<div class="absolute inset-0 flex h-full w-full flex-col items-center p-2">
|
||||||
<div class="relative mt-2 mb-4 flex h-1/2 w-full justify-center">
|
<div class="relative mt-2 mb-4 flex h-1/2 w-full justify-center">
|
||||||
<VAvatar size="100" color="surface-variant">
|
<VAvatar size="100" class="music-artist-card-avatar">
|
||||||
<VImg v-if="showImage" :src="imageUrl" cover @error="imageLoadError = true" />
|
<VImg v-if="showImage" :src="imageUrl" cover @error="imageLoadError = true" />
|
||||||
<VIcon v-else icon="mdi-account-music" size="48" color="medium-emphasis" />
|
<VIcon v-else icon="mdi-account-music" size="48" color="medium-emphasis" />
|
||||||
</VAvatar>
|
</VAvatar>
|
||||||
@@ -60,6 +60,10 @@ function goArtistDetail() {
|
|||||||
inline-size: 100%;
|
inline-size: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.music-artist-card-avatar {
|
||||||
|
background: rgba(var(--v-theme-on-surface), 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
.music-artist-card {
|
.music-artist-card {
|
||||||
background-image: linear-gradient(45deg, rgba(var(--v-theme-background), 0.3), rgba(var(--v-theme-surface), 0.3) 60%);
|
background-image: linear-gradient(45deg, rgba(var(--v-theme-background), 0.3), rgba(var(--v-theme-surface), 0.3) 60%);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -540,9 +540,10 @@ function handleCardClick() {
|
|||||||
<template #image v-if="display.smAndUp.value">
|
<template #image v-if="display.smAndUp.value">
|
||||||
<div
|
<div
|
||||||
v-if="showPlaceholder"
|
v-if="showPlaceholder"
|
||||||
class="subscribe-card-placeholder d-flex align-center justify-center"
|
class="subscribe-card-placeholder d-flex align-center justify-center relative"
|
||||||
>
|
>
|
||||||
<VIcon :icon="placeholderIcon" size="64" color="medium-emphasis" />
|
<VIcon :icon="placeholderIcon" size="64" color="medium-emphasis" />
|
||||||
|
<div class="absolute inset-0 outline-none subscribe-card-background"></div>
|
||||||
</div>
|
</div>
|
||||||
<VImg
|
<VImg
|
||||||
v-else
|
v-else
|
||||||
@@ -568,9 +569,10 @@ function handleCardClick() {
|
|||||||
<div class="subscribe-card-mobile-media">
|
<div class="subscribe-card-mobile-media">
|
||||||
<div
|
<div
|
||||||
v-if="showPlaceholder"
|
v-if="showPlaceholder"
|
||||||
class="subscribe-card-placeholder d-flex align-center justify-center"
|
class="subscribe-card-placeholder d-flex align-center justify-center relative"
|
||||||
>
|
>
|
||||||
<VIcon :icon="placeholderIcon" size="64" color="medium-emphasis" />
|
<VIcon :icon="placeholderIcon" size="64" color="medium-emphasis" />
|
||||||
|
<div class="absolute inset-0 outline-none subscribe-card-background"></div>
|
||||||
</div>
|
</div>
|
||||||
<VImg
|
<VImg
|
||||||
v-else
|
v-else
|
||||||
@@ -697,7 +699,7 @@ function handleCardClick() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
<VCardText class="flex min-w-0 justify-space-between align-center flex-wrap px-3">
|
<VCardText class="flex min-w-0 justify-space-between align-center flex-wrap px-3 mt-auto">
|
||||||
<div class="flex min-w-0 max-w-full align-center">
|
<div class="flex min-w-0 max-w-full align-center">
|
||||||
<VIcon
|
<VIcon
|
||||||
v-if="props.media?.total_episode && props.sortable"
|
v-if="props.media?.total_episode && props.sortable"
|
||||||
@@ -976,7 +978,7 @@ function handleCardClick() {
|
|||||||
.subscribe-card-placeholder {
|
.subscribe-card-placeholder {
|
||||||
block-size: 100%;
|
block-size: 100%;
|
||||||
inline-size: 100%;
|
inline-size: 100%;
|
||||||
background: rgb(var(--v-theme-surface-variant));
|
background: rgba(var(--v-theme-on-surface), 0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { formatFileSize } from '@/@core/utils/formatters'
|
|||||||
import { VCardTitle, VChip } from 'vuetify/lib/components/index.mjs'
|
import { VCardTitle, VChip } from 'vuetify/lib/components/index.mjs'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import MediaIdSelector from '../misc/MediaIdSelector.vue'
|
import MediaIdSelector from '../misc/MediaIdSelector.vue'
|
||||||
import { numberValidator } from '@/@validators'
|
import { isValidMediaSourceId } from '@/utils/mediaId'
|
||||||
import { useGlobalSettingsStore } from '@/stores'
|
import { useGlobalSettingsStore } from '@/stores'
|
||||||
|
|
||||||
// 多语言支持
|
// 多语言支持
|
||||||
@@ -25,19 +25,25 @@ const globalSettingsStore = useGlobalSettingsStore()
|
|||||||
const globalSettings = globalSettingsStore.globalSettings
|
const globalSettings = globalSettingsStore.globalSettings
|
||||||
|
|
||||||
// 当前识别类型
|
// 当前识别类型
|
||||||
const mediaSource = ref<MediaDataSource>(
|
|
||||||
['themoviedb', 'douban', 'bangumi', 'anilist'].includes(globalSettings.RECOGNIZE_SOURCE)
|
|
||||||
? globalSettings.RECOGNIZE_SOURCE
|
|
||||||
: 'themoviedb',
|
|
||||||
)
|
|
||||||
|
|
||||||
// 输入参数
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
title: String,
|
title: String,
|
||||||
media: Object as PropType<MediaInfo>,
|
media: Object as PropType<MediaInfo>,
|
||||||
torrent: Object as PropType<TorrentInfo>,
|
torrent: Object as PropType<TorrentInfo>,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 可选的媒体数据源
|
||||||
|
const SUPPORTED_MEDIA_SOURCES: MediaDataSource[] = ['themoviedb', 'douban', 'bangumi', 'anilist', 'musicbrainz']
|
||||||
|
|
||||||
|
// 当前识别类型:优先使用媒体自身的数据源,否则使用全局识别来源
|
||||||
|
const mediaSource = computed<MediaDataSource>(() => {
|
||||||
|
const source = props.media?.source as MediaDataSource | undefined
|
||||||
|
if (source && SUPPORTED_MEDIA_SOURCES.includes(source)) return source
|
||||||
|
if (SUPPORTED_MEDIA_SOURCES.includes(globalSettings.RECOGNIZE_SOURCE as MediaDataSource)) {
|
||||||
|
return globalSettings.RECOGNIZE_SOURCE as MediaDataSource
|
||||||
|
}
|
||||||
|
return 'themoviedb'
|
||||||
|
})
|
||||||
|
|
||||||
// 定义成功和失败事件
|
// 定义成功和失败事件
|
||||||
const emit = defineEmits(['done', 'error', 'close'])
|
const emit = defineEmits(['done', 'error', 'close'])
|
||||||
|
|
||||||
@@ -65,6 +71,17 @@ const showAdvancedOptions = ref(false)
|
|||||||
// 当前数据源的原生媒体ID
|
// 当前数据源的原生媒体ID
|
||||||
const mediaId = ref<string | undefined>(undefined)
|
const mediaId = ref<string | undefined>(undefined)
|
||||||
|
|
||||||
|
// 音乐媒体自带 MusicBrainz ID,打开对话框时预填到高级选项中辅助识别
|
||||||
|
watch(
|
||||||
|
() => props.media,
|
||||||
|
media => {
|
||||||
|
if (media && media.source === 'musicbrainz' && media.media_id) {
|
||||||
|
mediaId.value = media.media_id
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
)
|
||||||
|
|
||||||
// 当前数据源对应的原生ID标签。
|
// 当前数据源对应的原生ID标签。
|
||||||
const mediaIdLabel = computed(() => {
|
const mediaIdLabel = computed(() => {
|
||||||
const labels: Record<MediaDataSource, string> = {
|
const labels: Record<MediaDataSource, string> = {
|
||||||
@@ -302,7 +319,7 @@ onMounted(() => {
|
|||||||
v-model="mediaId"
|
v-model="mediaId"
|
||||||
:label="mediaIdLabel"
|
:label="mediaIdLabel"
|
||||||
:placeholder="t('dialog.reorganize.mediaIdPlaceholder')"
|
:placeholder="t('dialog.reorganize.mediaIdPlaceholder')"
|
||||||
:rules="[numberValidator]"
|
:rules="[(value: any) => isValidMediaSourceId(value, mediaSource.value) || t('dialog.reorganize.mediaIdInvalid')]"
|
||||||
append-inner-icon="mdi-magnify"
|
append-inner-icon="mdi-magnify"
|
||||||
:hint="t('dialog.reorganize.mediaIdHint')"
|
:hint="t('dialog.reorganize.mediaIdHint')"
|
||||||
persistent-hint
|
persistent-hint
|
||||||
|
|||||||
@@ -98,18 +98,17 @@ watch(
|
|||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.vue-music-back {
|
.vue-music-back {
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
pointer-events: none;
|
|
||||||
background-image:
|
background-image:
|
||||||
linear-gradient(180deg, rgba(var(--v-theme-background), 0) 50%, rgba(var(--v-theme-background), 1) 100%),
|
linear-gradient(180deg, rgba(var(--v-theme-background), 0) 50%, rgba(var(--v-theme-background), 1) 100%),
|
||||||
linear-gradient(0deg, rgba(var(--v-theme-background), 0) 80%, rgba(var(--v-theme-background), 1) 100%),
|
linear-gradient(0deg, rgba(var(--v-theme-background), 0) 80%, rgba(var(--v-theme-background), 1) 100%),
|
||||||
linear-gradient(90deg, rgba(var(--v-theme-background), 0) 50%, rgba(var(--v-theme-background), 1) 100%),
|
linear-gradient(90deg, rgba(var(--v-theme-background), 0) 50%, rgba(var(--v-theme-background), 1) 100%),
|
||||||
linear-gradient(270deg, rgba(var(--v-theme-background), 0) 50%, rgba(var(--v-theme-background), 1) 100%);
|
linear-gradient(270deg, rgba(var(--v-theme-background), 0) 50%, rgba(var(--v-theme-background), 1) 100%);
|
||||||
margin-block-start: calc(-70px - env(safe-area-inset-top));
|
margin-block-start: calc(-70px - env(safe-area-inset-top));
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vue-music-back-image {
|
.vue-music-back-image {
|
||||||
background-image: none;
|
background-image: none;
|
||||||
filter: blur(2px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.music-detail-transparent .vue-music-back-overlay,
|
.music-detail-transparent .vue-music-back-overlay,
|
||||||
@@ -119,10 +118,10 @@ watch(
|
|||||||
|
|
||||||
.music-detail-transparent .vue-music-back-image,
|
.music-detail-transparent .vue-music-back-image,
|
||||||
.music-detail-glass .vue-music-back-image {
|
.music-detail-glass .vue-music-back-image {
|
||||||
|
mask-composite: intersect;
|
||||||
mask-image:
|
mask-image:
|
||||||
linear-gradient(to bottom, transparent 0%, #000 16%, #000 58%, transparent 100%),
|
linear-gradient(to bottom, transparent 0%, #000 16%, #000 58%, transparent 100%),
|
||||||
linear-gradient(to right, transparent 0%, #000 10%, #000 90%, transparent 100%);
|
linear-gradient(to right, transparent 0%, #000 10%, #000 90%, transparent 100%);
|
||||||
mask-composite: intersect;
|
|
||||||
opacity: 0.82;
|
opacity: 0.82;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,9 +143,9 @@ watch(
|
|||||||
|
|
||||||
.music-poster {
|
.music-poster {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
flex: 0 0 auto;
|
||||||
border-radius: var(--app-surface-radius);
|
border-radius: var(--app-surface-radius);
|
||||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 10%);
|
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 10%);
|
||||||
flex: 0 0 auto;
|
|
||||||
inline-size: 9rem;
|
inline-size: 9rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +155,7 @@ watch(
|
|||||||
|
|
||||||
.music-poster-placeholder {
|
.music-poster-placeholder {
|
||||||
aspect-ratio: 1;
|
aspect-ratio: 1;
|
||||||
background: rgb(var(--v-theme-surface-variant));
|
background: rgba(var(--v-theme-on-surface), 0.08);
|
||||||
inline-size: 100%;
|
inline-size: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,8 +163,8 @@ watch(
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex: 1 1 0%;
|
flex: 1 1 0%;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
min-inline-size: 0;
|
|
||||||
margin-block-start: 1rem;
|
margin-block-start: 1rem;
|
||||||
|
min-inline-size: 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,10 +192,10 @@ watch(
|
|||||||
|
|
||||||
.music-actions {
|
.music-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
gap: 0.5rem;
|
flex-wrap: wrap;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
gap: 0.5rem;
|
||||||
margin-block-start: 1rem;
|
margin-block-start: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -232,12 +232,12 @@ watch(() => [props.source, props.mediaid], loadMusicDetail, { immediate: true })
|
|||||||
<span class="ms-1">MusicBrainz</span>
|
<span class="ms-1">MusicBrainz</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
|
||||||
|
|
||||||
<div v-if="albumTracks.length" class="music-section">
|
<div v-if="albumTracks.length" class="music-section">
|
||||||
<h2 class="music-section-heading">{{ t('music.albumTracks') }}</h2>
|
<h2 class="music-section-heading">{{ t('music.albumTracks') }}</h2>
|
||||||
<MusicTrackList :tracks="albumTracks" :active-media-id="music.media_id" hide-artists />
|
<MusicTrackList :tracks="albumTracks" :active-media-id="music.media_id" hide-artists />
|
||||||
</div>
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
<div v-if="primaryArtistId" class="music-section">
|
<div v-if="primaryArtistId" class="music-section">
|
||||||
<MusicArtistSlideView :apipath="`music/artist/${primaryArtistId}/related`" :title="t('music.relatedArtists')" />
|
<MusicArtistSlideView :apipath="`music/artist/${primaryArtistId}/related`" :title="t('music.relatedArtists')" />
|
||||||
|
|||||||
@@ -2072,7 +2072,7 @@ onUnmounted(() => {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
inline-size: 100%;
|
inline-size: 100%;
|
||||||
block-size: 100%;
|
block-size: 100%;
|
||||||
background: rgb(var(--v-theme-surface-variant));
|
background: rgba(var(--v-theme-on-surface), 0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
.transfer-history-mobile-record__poster-type {
|
.transfer-history-mobile-record__poster-type {
|
||||||
|
|||||||
Reference in New Issue
Block a user