|
|
|
|
@@ -3,13 +3,14 @@ import { useToast } from 'vue-toastification'
|
|
|
|
|
import { useDisplay } from 'vuetify'
|
|
|
|
|
import { useI18n } from 'vue-i18n'
|
|
|
|
|
import api from '@/api'
|
|
|
|
|
import type { ApiResponse, TmdbRecognitionCacheData, TmdbRecognitionCacheItem } from '@/api/types'
|
|
|
|
|
import type { ApiResponse, RecognitionCacheData, RecognitionCacheItem } from '@/api/types'
|
|
|
|
|
import { useConfirm } from '@/composables/useConfirm'
|
|
|
|
|
import { useGlobalSettingsStore } from '@/stores'
|
|
|
|
|
import { getDisplayImageUrl } from '@/utils/imageUtils'
|
|
|
|
|
|
|
|
|
|
type RecognitionStatusFilter = 'all' | 'recognized' | 'unrecognized'
|
|
|
|
|
type InfiniteScrollStatus = 'ok' | 'empty' | 'loading' | 'error'
|
|
|
|
|
type RecognitionCacheSource = 'tmdb' | 'douban'
|
|
|
|
|
|
|
|
|
|
const MOBILE_CACHE_PAGE_SIZE = 20
|
|
|
|
|
const MOBILE_CACHE_ITEM_HEIGHT = 144
|
|
|
|
|
@@ -19,14 +20,28 @@ const display = useDisplay()
|
|
|
|
|
const createConfirm = useConfirm()
|
|
|
|
|
const $toast = useToast()
|
|
|
|
|
const globalSettingsStore = useGlobalSettingsStore()
|
|
|
|
|
const globalSettings = globalSettingsStore.globalSettings
|
|
|
|
|
|
|
|
|
|
const isMobile = computed(() => display.smAndDown.value)
|
|
|
|
|
const recognitionSource = computed<RecognitionCacheSource>(() =>
|
|
|
|
|
globalSettingsStore.globalSettings.RECOGNIZE_SOURCE === 'douban' ? 'douban' : 'tmdb',
|
|
|
|
|
)
|
|
|
|
|
const recognitionSourceName = computed(() =>
|
|
|
|
|
recognitionSource.value === 'douban'
|
|
|
|
|
? t('setting.cache.recognitionSource.douban')
|
|
|
|
|
: t('setting.cache.recognitionSource.themoviedb'),
|
|
|
|
|
)
|
|
|
|
|
const recognitionIdLabel = computed(() =>
|
|
|
|
|
recognitionSource.value === 'douban' ? t('setting.cache.doubanId') : t('setting.cache.tmdbId'),
|
|
|
|
|
)
|
|
|
|
|
const recognitionCacheEndpoint = computed(() => `${recognitionSource.value}/cache`)
|
|
|
|
|
const recognitionFilterPlaceholder = computed(() =>
|
|
|
|
|
t('setting.cache.filterRecognitionCache', { source: recognitionSourceName.value }),
|
|
|
|
|
)
|
|
|
|
|
const loading = ref(false)
|
|
|
|
|
const searchFilter = ref('')
|
|
|
|
|
const statusFilter = ref<RecognitionStatusFilter>('all')
|
|
|
|
|
const selectedItems = ref<string[]>([])
|
|
|
|
|
const cacheData = ref<TmdbRecognitionCacheData>({
|
|
|
|
|
const cacheData = ref<RecognitionCacheData>({
|
|
|
|
|
count: 0,
|
|
|
|
|
recognized: 0,
|
|
|
|
|
unrecognized: 0,
|
|
|
|
|
@@ -34,6 +49,7 @@ const cacheData = ref<TmdbRecognitionCacheData>({
|
|
|
|
|
})
|
|
|
|
|
const mobileVisibleCount = ref(MOBILE_CACHE_PAGE_SIZE)
|
|
|
|
|
const mobileInfiniteKey = ref(0)
|
|
|
|
|
let cacheLoadRequestId = 0
|
|
|
|
|
|
|
|
|
|
const statusOptions = computed(() => [
|
|
|
|
|
{ title: t('setting.cache.allStatuses'), value: 'all' },
|
|
|
|
|
@@ -46,7 +62,7 @@ const tableHeaders = computed(() => [
|
|
|
|
|
{ title: t('setting.cache.poster'), key: 'poster', sortable: false, width: '76px' },
|
|
|
|
|
{ title: t('setting.cache.cacheKey'), key: 'key', sortable: true },
|
|
|
|
|
{ title: t('setting.cache.recognitionResult'), key: 'result', sortable: false, width: '220px' },
|
|
|
|
|
{ title: t('setting.cache.tmdbId'), key: 'tmdb_id', sortable: true, width: '110px' },
|
|
|
|
|
{ title: recognitionIdLabel.value, key: 'recognition_id', sortable: true, width: '120px' },
|
|
|
|
|
{ title: t('setting.cache.recognitionStatus'), key: 'status', sortable: true, width: '120px' },
|
|
|
|
|
{ title: t('setting.cache.actions'), key: 'actions', sortable: false, width: '72px' },
|
|
|
|
|
])
|
|
|
|
|
@@ -56,10 +72,10 @@ const filteredData = computed(() => {
|
|
|
|
|
return cacheData.value.data.filter(item => {
|
|
|
|
|
const matchesKeyword =
|
|
|
|
|
!keyword ||
|
|
|
|
|
[item.key, item.title, item.year, String(item.tmdb_id)].some(value => value.toLowerCase().includes(keyword))
|
|
|
|
|
[item.key, item.title, item.year, getRecognitionId(item)].some(value => value.toLowerCase().includes(keyword))
|
|
|
|
|
const matchesStatus =
|
|
|
|
|
statusFilter.value === 'all' ||
|
|
|
|
|
(statusFilter.value === 'recognized' ? item.tmdb_id > 0 : item.tmdb_id === 0)
|
|
|
|
|
(statusFilter.value === 'recognized' ? isRecognized(item) : !isRecognized(item))
|
|
|
|
|
return matchesKeyword && matchesStatus
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
@@ -89,35 +105,42 @@ function loadMoreMobileCache({ done }: { done: (status: InfiniteScrollStatus) =>
|
|
|
|
|
done(mobileHasMore.value ? 'ok' : 'empty')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 加载 TheMovieDb 识别缓存列表。 */
|
|
|
|
|
/** 加载当前识别数据源对应的缓存列表。 */
|
|
|
|
|
async function loadCacheData(showSuccess = false) {
|
|
|
|
|
const requestId = ++cacheLoadRequestId
|
|
|
|
|
try {
|
|
|
|
|
loading.value = true
|
|
|
|
|
const response = (await api.get('tmdb/cache')) as unknown as ApiResponse<TmdbRecognitionCacheData>
|
|
|
|
|
cacheData.value = response.data ?? { count: 0, recognized: 0, unrecognized: 0, data: [] }
|
|
|
|
|
const response = (await api.get(recognitionCacheEndpoint.value)) as unknown as ApiResponse<RecognitionCacheData>
|
|
|
|
|
if (requestId !== cacheLoadRequestId) return
|
|
|
|
|
const responseData = response.data ?? { count: 0, recognized: 0, unrecognized: 0, data: [] }
|
|
|
|
|
cacheData.value = {
|
|
|
|
|
...responseData,
|
|
|
|
|
data: responseData.data.map(item => ({ ...item, recognition_id: getRecognitionId(item) })),
|
|
|
|
|
}
|
|
|
|
|
selectedItems.value = selectedItems.value.filter(key => cacheData.value.data.some(item => item.key === key))
|
|
|
|
|
resetMobilePagination()
|
|
|
|
|
if (showSuccess) $toast.success(t('setting.cache.listRefreshSuccess'))
|
|
|
|
|
} catch (error) {
|
|
|
|
|
if (requestId !== cacheLoadRequestId) return
|
|
|
|
|
console.error(error)
|
|
|
|
|
$toast.error(t('setting.cache.loadFailed'))
|
|
|
|
|
} finally {
|
|
|
|
|
loading.value = false
|
|
|
|
|
if (requestId === cacheLoadRequestId) loading.value = false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 清空全部 TheMovieDb 识别缓存。 */
|
|
|
|
|
/** 清空当前识别数据源的全部识别缓存。 */
|
|
|
|
|
async function clearAllCache() {
|
|
|
|
|
const confirmed = await createConfirm({
|
|
|
|
|
type: 'warn',
|
|
|
|
|
title: t('common.confirm'),
|
|
|
|
|
content: t('setting.cache.tmdbClearConfirm'),
|
|
|
|
|
content: t('setting.cache.recognitionClearConfirm', { source: recognitionSourceName.value }),
|
|
|
|
|
})
|
|
|
|
|
if (!confirmed) return
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
loading.value = true
|
|
|
|
|
const response = (await api.delete('tmdb/cache')) as unknown as ApiResponse
|
|
|
|
|
const response = (await api.delete(recognitionCacheEndpoint.value)) as unknown as ApiResponse
|
|
|
|
|
if (!response.success) throw new Error(response.message)
|
|
|
|
|
$toast.success(response.message || t('setting.cache.clearSuccess'))
|
|
|
|
|
await loadCacheData()
|
|
|
|
|
@@ -130,13 +153,13 @@ async function clearAllCache() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 请求后端删除指定 TheMovieDb 识别缓存。 */
|
|
|
|
|
/** 请求当前识别数据源接口删除指定识别缓存。 */
|
|
|
|
|
async function deleteCacheItem(key: string) {
|
|
|
|
|
const response = (await api.delete(`tmdb/cache/${encodeURIComponent(key)}`)) as unknown as ApiResponse
|
|
|
|
|
const response = (await api.delete(`${recognitionCacheEndpoint.value}/${encodeURIComponent(key)}`)) as unknown as ApiResponse
|
|
|
|
|
if (!response.success) throw new Error(response.message)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 删除桌面端表格中选中的 TheMovieDb 识别缓存。 */
|
|
|
|
|
/** 删除桌面端表格中选中的识别缓存。 */
|
|
|
|
|
async function deleteSelectedItems() {
|
|
|
|
|
if (selectedItems.value.length === 0) {
|
|
|
|
|
$toast.warning(t('setting.cache.selectDeleteWarning'))
|
|
|
|
|
@@ -158,8 +181,8 @@ async function deleteSelectedItems() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 删除单条 TheMovieDb 识别缓存。 */
|
|
|
|
|
async function deleteSingleItem(item: TmdbRecognitionCacheItem) {
|
|
|
|
|
/** 删除单条识别缓存。 */
|
|
|
|
|
async function deleteSingleItem(item: RecognitionCacheItem) {
|
|
|
|
|
try {
|
|
|
|
|
loading.value = true
|
|
|
|
|
await deleteCacheItem(item.key)
|
|
|
|
|
@@ -173,13 +196,25 @@ async function deleteSingleItem(item: TmdbRecognitionCacheItem) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 获取 TheMovieDb 缓存海报的可展示地址。 */
|
|
|
|
|
function getPosterUrl(item: TmdbRecognitionCacheItem): string {
|
|
|
|
|
/** 获取识别缓存海报的可展示地址。 */
|
|
|
|
|
function getPosterUrl(item: RecognitionCacheItem): string {
|
|
|
|
|
if (!item.poster_path) return ''
|
|
|
|
|
const sourceUrl = item.poster_path.startsWith('/')
|
|
|
|
|
? `https://${globalSettings.TMDB_IMAGE_DOMAIN}/t/p/w300${item.poster_path}`
|
|
|
|
|
? `https://${globalSettingsStore.globalSettings.TMDB_IMAGE_DOMAIN}/t/p/w300${item.poster_path}`
|
|
|
|
|
: item.poster_path
|
|
|
|
|
return getDisplayImageUrl(sourceUrl, globalSettings.GLOBAL_IMAGE_CACHE)
|
|
|
|
|
return getDisplayImageUrl(sourceUrl, globalSettingsStore.globalSettings.GLOBAL_IMAGE_CACHE)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 获取当前识别数据源对应的媒体 ID。 */
|
|
|
|
|
function getRecognitionId(item: RecognitionCacheItem): string {
|
|
|
|
|
const recognitionId = recognitionSource.value === 'douban' ? item.douban_id : item.tmdb_id
|
|
|
|
|
return recognitionId ? String(recognitionId) : ''
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 判断识别缓存条目是否包含有效媒体 ID。 */
|
|
|
|
|
function isRecognized(item: RecognitionCacheItem): boolean {
|
|
|
|
|
const recognitionId = getRecognitionId(item)
|
|
|
|
|
return Boolean(recognitionId && recognitionId !== '0')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 获取本地化的媒体类型名称。 */
|
|
|
|
|
@@ -197,8 +232,8 @@ function getMediaTypeColor(mediaType: string): string {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 获取识别状态的本地化名称。 */
|
|
|
|
|
function getRecognitionStatusLabel(item: TmdbRecognitionCacheItem): string {
|
|
|
|
|
return item.tmdb_id > 0 ? t('setting.cache.recognized') : t('setting.cache.unrecognized')
|
|
|
|
|
function getRecognitionStatusLabel(item: RecognitionCacheItem): string {
|
|
|
|
|
return isRecognized(item) ? t('setting.cache.recognized') : t('setting.cache.unrecognized')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
@@ -208,10 +243,17 @@ onMounted(() => {
|
|
|
|
|
watch([searchFilter, statusFilter], () => {
|
|
|
|
|
resetMobilePagination()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
watch(recognitionSource, () => {
|
|
|
|
|
searchFilter.value = ''
|
|
|
|
|
statusFilter.value = 'all'
|
|
|
|
|
selectedItems.value = []
|
|
|
|
|
void loadCacheData()
|
|
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
|
<section class="tmdb-cache-panel">
|
|
|
|
|
<section class="recognition-cache-panel">
|
|
|
|
|
<div class="cache-panel-toolbar">
|
|
|
|
|
<div class="cache-panel-stats">
|
|
|
|
|
<div class="cache-panel-stat cache-panel-stat--primary">
|
|
|
|
|
@@ -266,8 +308,8 @@ watch([searchFilter, statusFilter], () => {
|
|
|
|
|
<VTextField
|
|
|
|
|
v-model="searchFilter"
|
|
|
|
|
class="cache-panel-filter"
|
|
|
|
|
:label="isMobile ? undefined : t('setting.cache.filterRecognitionCache')"
|
|
|
|
|
:placeholder="isMobile ? t('setting.cache.filterRecognitionCache') : undefined"
|
|
|
|
|
:label="isMobile ? undefined : recognitionFilterPlaceholder"
|
|
|
|
|
:placeholder="isMobile ? recognitionFilterPlaceholder : undefined"
|
|
|
|
|
prepend-inner-icon="mdi-magnify"
|
|
|
|
|
variant="outlined"
|
|
|
|
|
:density="isMobile ? 'comfortable' : 'compact'"
|
|
|
|
|
@@ -305,7 +347,7 @@ watch([searchFilter, statusFilter], () => {
|
|
|
|
|
mode="intersect"
|
|
|
|
|
side="end"
|
|
|
|
|
:items="mobileVisibleData"
|
|
|
|
|
class="tmdb-cache-mobile-scroll"
|
|
|
|
|
class="recognition-cache-mobile-scroll"
|
|
|
|
|
@load="loadMoreMobileCache"
|
|
|
|
|
>
|
|
|
|
|
<template #loading>
|
|
|
|
|
@@ -324,24 +366,24 @@ watch([searchFilter, statusFilter], () => {
|
|
|
|
|
:item-height="MOBILE_CACHE_ITEM_HEIGHT"
|
|
|
|
|
>
|
|
|
|
|
<template #default="{ item, itemRef }">
|
|
|
|
|
<article :ref="itemRef" :key="item.key" class="tmdb-cache-mobile-item">
|
|
|
|
|
<div class="tmdb-cache-poster">
|
|
|
|
|
<article :ref="itemRef" :key="item.key" class="recognition-cache-mobile-item">
|
|
|
|
|
<div class="recognition-cache-poster">
|
|
|
|
|
<VImg v-if="getPosterUrl(item)" :src="getPosterUrl(item)" :alt="item.title || item.key" cover />
|
|
|
|
|
<VIcon v-else icon="mdi-image-off-outline" size="28" />
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="tmdb-cache-mobile-item__content">
|
|
|
|
|
<div class="tmdb-cache-mobile-item__title">
|
|
|
|
|
<div class="recognition-cache-mobile-item__content">
|
|
|
|
|
<div class="recognition-cache-mobile-item__title">
|
|
|
|
|
{{ item.title || t('setting.cache.unrecognized') }}
|
|
|
|
|
</div>
|
|
|
|
|
<div class="tmdb-cache-mobile-item__meta">
|
|
|
|
|
<div class="recognition-cache-mobile-item__meta">
|
|
|
|
|
<VChip size="x-small" variant="tonal" :color="getMediaTypeColor(item.media_type)">
|
|
|
|
|
{{ getMediaTypeLabel(item.media_type) }}
|
|
|
|
|
</VChip>
|
|
|
|
|
<span v-if="item.year">{{ item.year }}</span>
|
|
|
|
|
<span v-if="item.tmdb_id">TMDB #{{ item.tmdb_id }}</span>
|
|
|
|
|
<span v-if="isRecognized(item)">{{ recognitionIdLabel }} #{{ getRecognitionId(item) }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="tmdb-cache-mobile-item__key">{{ item.key }}</div>
|
|
|
|
|
<div class="recognition-cache-mobile-item__key">{{ item.key }}</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<VBtn
|
|
|
|
|
@@ -361,7 +403,7 @@ watch([searchFilter, statusFilter], () => {
|
|
|
|
|
|
|
|
|
|
<div v-else class="cache-panel-empty">
|
|
|
|
|
<VIcon icon="mdi-database-search-outline" size="42" />
|
|
|
|
|
<strong>{{ t('setting.cache.noRecognitionCache') }}</strong>
|
|
|
|
|
<strong>{{ t('setting.cache.noRecognitionCache', { source: recognitionSourceName }) }}</strong>
|
|
|
|
|
<span>{{ t('setting.cache.noRecognitionCacheHint') }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
@@ -369,7 +411,7 @@ watch([searchFilter, statusFilter], () => {
|
|
|
|
|
<VDataTable
|
|
|
|
|
v-else
|
|
|
|
|
v-model="selectedItems"
|
|
|
|
|
class="tmdb-cache-table"
|
|
|
|
|
class="recognition-cache-table"
|
|
|
|
|
:headers="tableHeaders"
|
|
|
|
|
:items="filteredData"
|
|
|
|
|
:loading="loading"
|
|
|
|
|
@@ -382,18 +424,18 @@ watch([searchFilter, statusFilter], () => {
|
|
|
|
|
:loading-text="t('common.loadingText')"
|
|
|
|
|
>
|
|
|
|
|
<template #item.poster="{ item }">
|
|
|
|
|
<div class="tmdb-cache-table__poster">
|
|
|
|
|
<div class="recognition-cache-table__poster">
|
|
|
|
|
<VImg v-if="getPosterUrl(item)" :src="getPosterUrl(item)" :alt="item.title || item.key" cover />
|
|
|
|
|
<VIcon v-else icon="mdi-image-off-outline" />
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<template #item.key="{ item }">
|
|
|
|
|
<div class="tmdb-cache-table__key">{{ item.key }}</div>
|
|
|
|
|
<div class="recognition-cache-table__key">{{ item.key }}</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<template #item.result="{ item }">
|
|
|
|
|
<div class="tmdb-cache-result">
|
|
|
|
|
<div class="recognition-cache-result">
|
|
|
|
|
<strong>{{ item.title || t('setting.cache.unrecognized') }}</strong>
|
|
|
|
|
<span v-if="item.year">{{ item.year }}</span>
|
|
|
|
|
<VChip size="x-small" variant="tonal" :color="getMediaTypeColor(item.media_type)">
|
|
|
|
|
@@ -402,13 +444,13 @@ watch([searchFilter, statusFilter], () => {
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<template #item.tmdb_id="{ item }">
|
|
|
|
|
<span v-if="item.tmdb_id" class="font-weight-medium">#{{ item.tmdb_id }}</span>
|
|
|
|
|
<template #item.recognition_id="{ item }">
|
|
|
|
|
<span v-if="isRecognized(item)" class="font-weight-medium">#{{ getRecognitionId(item) }}</span>
|
|
|
|
|
<span v-else class="text-medium-emphasis">-</span>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<template #item.status="{ item }">
|
|
|
|
|
<VChip size="small" variant="tonal" :color="item.tmdb_id > 0 ? 'success' : 'warning'">
|
|
|
|
|
<VChip size="small" variant="tonal" :color="isRecognized(item) ? 'success' : 'warning'">
|
|
|
|
|
{{ getRecognitionStatusLabel(item) }}
|
|
|
|
|
</VChip>
|
|
|
|
|
</template>
|
|
|
|
|
@@ -423,7 +465,7 @@ watch([searchFilter, statusFilter], () => {
|
|
|
|
|
<template #no-data>
|
|
|
|
|
<div class="cache-panel-empty">
|
|
|
|
|
<VIcon icon="mdi-database-search-outline" size="42" />
|
|
|
|
|
<strong>{{ t('setting.cache.noRecognitionCache') }}</strong>
|
|
|
|
|
<strong>{{ t('setting.cache.noRecognitionCache', { source: recognitionSourceName }) }}</strong>
|
|
|
|
|
<span>{{ t('setting.cache.noRecognitionCacheHint') }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
@@ -432,7 +474,7 @@ watch([searchFilter, statusFilter], () => {
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
.tmdb-cache-panel {
|
|
|
|
|
.recognition-cache-panel {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex: 1 1 auto;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
@@ -523,7 +565,7 @@ watch([searchFilter, statusFilter], () => {
|
|
|
|
|
min-block-size: 44px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tmdb-cache-table {
|
|
|
|
|
.recognition-cache-table {
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
border: var(--app-surface-border);
|
|
|
|
|
border-radius: var(--app-surface-radius);
|
|
|
|
|
@@ -531,8 +573,8 @@ watch([searchFilter, statusFilter], () => {
|
|
|
|
|
max-block-size: calc(100dvh - 23rem);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tmdb-cache-table__poster,
|
|
|
|
|
.tmdb-cache-poster {
|
|
|
|
|
.recognition-cache-table__poster,
|
|
|
|
|
.recognition-cache-poster {
|
|
|
|
|
display: flex;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
align-items: center;
|
|
|
|
|
@@ -542,19 +584,19 @@ watch([searchFilter, statusFilter], () => {
|
|
|
|
|
color: rgba(var(--v-theme-on-surface), 0.36);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tmdb-cache-table__poster {
|
|
|
|
|
.recognition-cache-table__poster {
|
|
|
|
|
block-size: 62px;
|
|
|
|
|
inline-size: 44px;
|
|
|
|
|
margin-block: 4px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tmdb-cache-table__poster :deep(.v-img),
|
|
|
|
|
.tmdb-cache-poster :deep(.v-img) {
|
|
|
|
|
.recognition-cache-table__poster :deep(.v-img),
|
|
|
|
|
.recognition-cache-poster :deep(.v-img) {
|
|
|
|
|
block-size: 100%;
|
|
|
|
|
inline-size: 100%;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tmdb-cache-table__key {
|
|
|
|
|
.recognition-cache-table__key {
|
|
|
|
|
max-inline-size: 36rem;
|
|
|
|
|
color: rgba(var(--v-theme-on-surface), 0.68);
|
|
|
|
|
font-family: monospace;
|
|
|
|
|
@@ -562,19 +604,19 @@ watch([searchFilter, statusFilter], () => {
|
|
|
|
|
overflow-wrap: anywhere;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tmdb-cache-result {
|
|
|
|
|
.recognition-cache-result {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
gap: 6px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tmdb-cache-result strong {
|
|
|
|
|
.recognition-cache-result strong {
|
|
|
|
|
inline-size: 100%;
|
|
|
|
|
color: rgba(var(--v-theme-on-surface), 0.88);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tmdb-cache-result span {
|
|
|
|
|
.recognition-cache-result span {
|
|
|
|
|
color: rgba(var(--v-theme-on-surface), 0.56);
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
}
|
|
|
|
|
@@ -602,7 +644,7 @@ watch([searchFilter, statusFilter], () => {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media (max-width: 959.98px) {
|
|
|
|
|
.tmdb-cache-panel {
|
|
|
|
|
.recognition-cache-panel {
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
block-size: 100%;
|
|
|
|
|
padding: 14px 16px calc(18px + env(safe-area-inset-bottom));
|
|
|
|
|
@@ -656,18 +698,18 @@ watch([searchFilter, statusFilter], () => {
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tmdb-cache-mobile-scroll {
|
|
|
|
|
.recognition-cache-mobile-scroll {
|
|
|
|
|
overflow: visible !important;
|
|
|
|
|
min-block-size: 20rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tmdb-cache-mobile-scroll :deep(.v-infinite-scroll__container),
|
|
|
|
|
.tmdb-cache-mobile-scroll :deep(.v-virtual-scroll),
|
|
|
|
|
.tmdb-cache-mobile-scroll :deep(.v-virtual-scroll__container) {
|
|
|
|
|
.recognition-cache-mobile-scroll :deep(.v-infinite-scroll__container),
|
|
|
|
|
.recognition-cache-mobile-scroll :deep(.v-virtual-scroll),
|
|
|
|
|
.recognition-cache-mobile-scroll :deep(.v-virtual-scroll__container) {
|
|
|
|
|
overflow: visible !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tmdb-cache-mobile-scroll :deep(.v-infinite-scroll__side) {
|
|
|
|
|
.recognition-cache-mobile-scroll :deep(.v-infinite-scroll__side) {
|
|
|
|
|
padding-block: 14px 2px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -683,7 +725,7 @@ watch([searchFilter, statusFilter], () => {
|
|
|
|
|
gap: 8px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tmdb-cache-mobile-item {
|
|
|
|
|
.recognition-cache-mobile-item {
|
|
|
|
|
display: grid;
|
|
|
|
|
align-items: start;
|
|
|
|
|
border: var(--app-surface-border);
|
|
|
|
|
@@ -697,23 +739,23 @@ watch([searchFilter, statusFilter], () => {
|
|
|
|
|
gap: 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tmdb-cache-poster {
|
|
|
|
|
.recognition-cache-poster {
|
|
|
|
|
block-size: 78px;
|
|
|
|
|
inline-size: 54px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tmdb-cache-mobile-item__content {
|
|
|
|
|
.recognition-cache-mobile-item__content {
|
|
|
|
|
min-inline-size: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tmdb-cache-mobile-item__title {
|
|
|
|
|
.recognition-cache-mobile-item__title {
|
|
|
|
|
color: rgba(var(--v-theme-on-surface), 0.9);
|
|
|
|
|
font-size: 15px;
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
overflow-wrap: anywhere;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tmdb-cache-mobile-item__meta {
|
|
|
|
|
.recognition-cache-mobile-item__meta {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
@@ -723,7 +765,7 @@ watch([searchFilter, statusFilter], () => {
|
|
|
|
|
gap: 7px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tmdb-cache-mobile-item__key {
|
|
|
|
|
.recognition-cache-mobile-item__key {
|
|
|
|
|
margin-block-start: 8px;
|
|
|
|
|
color: rgba(var(--v-theme-on-surface), 0.48);
|
|
|
|
|
font-family: monospace;
|
|
|
|
|
@@ -734,7 +776,7 @@ watch([searchFilter, statusFilter], () => {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media (max-width: 374.98px) {
|
|
|
|
|
.tmdb-cache-panel {
|
|
|
|
|
.recognition-cache-panel {
|
|
|
|
|
padding-inline: 12px;
|
|
|
|
|
}
|
|
|
|
|
|