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