mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-05-16 19:57:36 +08:00
torrents more
This commit is contained in:
@@ -9,6 +9,7 @@ import { useConfirm } from "vuetify-use-dialog";
|
||||
// 输入参数
|
||||
const props = defineProps({
|
||||
torrent: Object as PropType<Context>,
|
||||
more: Array as PropType<Context[]>,
|
||||
width: String,
|
||||
height: String,
|
||||
});
|
||||
@@ -19,6 +20,9 @@ const $toast = useToast();
|
||||
// 确认框
|
||||
const createConfirm = useConfirm();
|
||||
|
||||
// 更多来源界面
|
||||
const showMoreTorrents = ref(false);
|
||||
|
||||
// 种子信息
|
||||
const torrent = ref(props.torrent?.torrent_info);
|
||||
// 媒体信息
|
||||
@@ -39,10 +43,19 @@ const getSiteIcon = async () => {
|
||||
};
|
||||
|
||||
// 询问并添加下载
|
||||
const handleAddDownload = async () => {
|
||||
const handleAddDownload = async (
|
||||
_site: any = undefined,
|
||||
_media: any = undefined,
|
||||
_torrent: any = undefined
|
||||
) => {
|
||||
if (!_media || !_torrent || !_site) {
|
||||
_site = torrent.value?.site_name;
|
||||
_media = media.value;
|
||||
_torrent = torrent.value;
|
||||
}
|
||||
const isConfirmed = await createConfirm({
|
||||
title: "确认",
|
||||
content: `是否确认下载 ${torrent.value?.title} ?`,
|
||||
content: `是否确认下载【${_site}】${_torrent?.title} ?`,
|
||||
confirmationText: "确认",
|
||||
cancellationText: "取消",
|
||||
dialogProps: {
|
||||
@@ -52,25 +65,23 @@ const handleAddDownload = async () => {
|
||||
|
||||
if (!isConfirmed) return;
|
||||
|
||||
addDownload();
|
||||
addDownload(_media, _torrent);
|
||||
};
|
||||
|
||||
// 添加下载
|
||||
const addDownload = async () => {
|
||||
const addDownload = async (_media: any, _torrent: any) => {
|
||||
startNProgress();
|
||||
try {
|
||||
const result: { [key: string]: any } = await api.post("download", {
|
||||
media_in: media?.value,
|
||||
torrent_in: torrent?.value,
|
||||
media_in: _media,
|
||||
torrent_in: _torrent,
|
||||
});
|
||||
if (result.success) {
|
||||
// 添加下载成功
|
||||
$toast.success(
|
||||
`${torrent.value?.site_name} ${torrent.value?.title} 添加下载成功!`
|
||||
);
|
||||
$toast.success(`${_torrent?.site_name} ${_torrent?.title} 添加下载成功!`);
|
||||
} else {
|
||||
// 添加下载失败
|
||||
$toast.error(`${torrent.value?.site_name} ${torrent.value?.title} 添加下载失败!`);
|
||||
$toast.error(`${_torrent?.site_name} ${_torrent?.title} 添加下载失败!`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
@@ -108,12 +119,12 @@ onMounted(() => {
|
||||
</script>
|
||||
<template>
|
||||
<VCard :width="props.width" :height="props.height" @click="handleAddDownload">
|
||||
<template #image>
|
||||
<template #image v-if="!showMoreTorrents">
|
||||
<VAvatar class="absolute right-2 bottom-2" variant="flat" rounded="0">
|
||||
<VImg :src="siteIcon" />
|
||||
</VAvatar>
|
||||
</template>
|
||||
<VCardItem>
|
||||
<VCardItem class="py-1">
|
||||
<VCardTitle>
|
||||
{{ media?.title }} {{ meta?.season_episode }}
|
||||
<span class="text-green-700 ms-2 text-sm">↑{{ torrent?.seeders }}</span>
|
||||
@@ -208,5 +219,34 @@ onMounted(() => {
|
||||
{{ torrent?.volume_factor }}
|
||||
</VChip>
|
||||
</VCardItem>
|
||||
<VCardActions>
|
||||
<VBtn
|
||||
@click.stop="showMoreTorrents = !showMoreTorrents"
|
||||
v-if="props.more && props.more.length > 0"
|
||||
>
|
||||
<template #append>
|
||||
<VIcon :icon="showMoreTorrents ? 'mdi-chevron-up' : 'mdi-chevron-down'"></VIcon>
|
||||
</template>
|
||||
更多来源
|
||||
</VBtn>
|
||||
</VCardActions>
|
||||
<VExpandTransition>
|
||||
<div v-show="showMoreTorrents">
|
||||
<VDivider></VDivider>
|
||||
<VChipGroup class="p-3">
|
||||
<VChip
|
||||
v-for="item in props.more"
|
||||
@click.stop="
|
||||
handleAddDownload(
|
||||
item.torrent_info?.site_name,
|
||||
item.media_info,
|
||||
item.torrent_info
|
||||
)
|
||||
"
|
||||
>{{ item.torrent_info.site_name }}</VChip
|
||||
>
|
||||
</VChipGroup>
|
||||
</div>
|
||||
</VExpandTransition>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -12,6 +12,11 @@ const props = defineProps({
|
||||
// 数据列表
|
||||
const dataList = ref<Context[]>([]);
|
||||
|
||||
// 分组后的数据列表
|
||||
const groupedDataList = computed(() => {
|
||||
return groupByTitleAndSize(dataList.value);
|
||||
});
|
||||
|
||||
// 是否刷新过
|
||||
const isRefreshed = ref(false);
|
||||
|
||||
@@ -37,6 +42,40 @@ const fetchData = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 按标题和大小分组
|
||||
const groupByTitleAndSize = (contextArray: Context[]): Map<string, Context[]> => {
|
||||
const groupMap = new Map<string, Context[]>();
|
||||
|
||||
for (const context of contextArray) {
|
||||
const { torrent_info } = context;
|
||||
const key = `${torrent_info.title}_${torrent_info.size}`;
|
||||
|
||||
if (groupMap.has(key)) {
|
||||
// 已存在相同标题和大小的分组,将当前上下文信息添加到分组中
|
||||
const group = groupMap.get(key);
|
||||
group?.push(context);
|
||||
} else {
|
||||
// 创建新的分组,并将当前上下文信息添加到分组中
|
||||
groupMap.set(key, [context]);
|
||||
}
|
||||
}
|
||||
|
||||
return groupMap;
|
||||
};
|
||||
|
||||
// 获取每个分组的第一个数据
|
||||
const getFirstContexts = computed(() => {
|
||||
const firstContexts: Context[] = [];
|
||||
|
||||
groupedDataList.value.forEach((group) => {
|
||||
if (group.length > 0) {
|
||||
firstContexts.push(group[0]);
|
||||
}
|
||||
});
|
||||
|
||||
return firstContexts;
|
||||
});
|
||||
|
||||
// 加载时获取数据
|
||||
onBeforeMount(fetchData);
|
||||
</script>
|
||||
@@ -48,11 +87,16 @@ onBeforeMount(fetchData);
|
||||
indeterminate
|
||||
color="primary"
|
||||
></VProgressCircular>
|
||||
<div class="grid gap-3 grid-torrent-card" v-if="dataList.length > 0">
|
||||
<div class="grid gap-3 grid-torrent-card items-start" v-if="dataList.length > 0">
|
||||
<TorrentCard
|
||||
v-for="data in dataList"
|
||||
v-for="data in getFirstContexts"
|
||||
:key="data.torrent_info.title"
|
||||
:torrent="data"
|
||||
:more="
|
||||
groupedDataList
|
||||
.get(`${data.torrent_info.title}_${data.torrent_info.size}`)
|
||||
?.slice(1)
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<NoDataFound
|
||||
|
||||
Reference in New Issue
Block a user