|
1 | 1 | <template> |
2 | 2 | <a-table |
| 3 | + v-if="mdAndLarger" |
3 | 4 | :columns="columns" |
4 | 5 | :data="data?.data" |
| 6 | + column-resizable |
5 | 7 | :loading="!loading && !data" |
6 | | - :virtual-list-props="{ height: 350, threshold: 10 }" |
| 8 | + :virtual-list-props="useVirtualList" |
7 | 9 | :pagination="false" |
8 | 10 | > |
9 | 11 | <template #name="{ record }"> |
10 | | - <a-typography-text bold style="margin-bottom: 0" :ellipsis="{ showTooltip: true }"> |
| 12 | + <a-typography-text |
| 13 | + :ellipsis="{ |
| 14 | + showTooltip: true |
| 15 | + }" |
| 16 | + style="margin-bottom: 0em" |
| 17 | + > |
11 | 18 | {{ record.name }} |
12 | 19 | </a-typography-text> |
13 | 20 | </template> |
| 21 | + <template #speed="{ record }"> |
| 22 | + <a-space fill style="justify-content: space-between"> |
| 23 | + <a-space fill direction="vertical"> |
| 24 | + <a-typography-text style="white-space: nowrap"> |
| 25 | + <icon-arrow-up class="green" /> |
| 26 | + {{ formatFileSize(record.rtUploadSpeed) }}/s |
| 27 | + </a-typography-text> |
| 28 | + <a-typography-text style="white-space: nowrap"> |
| 29 | + <icon-arrow-down class="red" /> |
| 30 | + {{ formatFileSize(record.rtDownloadSpeed) }}/s |
| 31 | + </a-typography-text> |
| 32 | + </a-space> |
| 33 | + </a-space> |
| 34 | + </template> |
14 | 35 | <template #size="{ record }"> |
15 | | - <a-typography-text>{{ formatFileSize(record.size) }}</a-typography-text> |
| 36 | + <a-typography-text style="white-space: nowrap"> |
| 37 | + {{ formatFileSize(record.size) }} |
| 38 | + </a-typography-text> |
16 | 39 | </template> |
17 | 40 | <template #hash="{ record }"> |
18 | | - <a-button @click="handleCopy(record.hash)">{{ |
19 | | - t('page.rule_management.ruleSubscribe.column.clickToCopy') |
20 | | - }}</a-button> |
| 41 | + <a-button @click="handleCopy(record.hash)"> |
| 42 | + {{ t('page.rule_management.ruleSubscribe.column.clickToCopy') }} |
| 43 | + </a-button> |
21 | 44 | </template> |
22 | 45 | <template #progress="{ record }"> |
23 | 46 | <a-space> |
24 | 47 | <a-progress :percent="record.progress" size="mini" /> |
25 | | - <a-typography-text> |
| 48 | + <a-typography-text style="white-space: nowrap"> |
26 | 49 | {{ (record.progress * 100).toFixed(2) + '%' }} |
27 | 50 | </a-typography-text> |
28 | 51 | </a-space> |
29 | 52 | </template> |
30 | | - <template #speed="{ record }"> |
31 | | - <a-space fill style="justify-content: space-between"> |
32 | | - <a-space fill direction="vertical"> |
33 | | - <a-typography-text |
34 | | - ><icon-arrow-up class="green" /> |
35 | | - {{ formatFileSize(record.rtUploadSpeed) }}/s</a-typography-text |
36 | | - > |
37 | | - <a-typography-text |
38 | | - ><icon-arrow-down class="red" /> |
39 | | - {{ formatFileSize(record.rtDownloadSpeed) }}/s</a-typography-text |
40 | | - > |
41 | | - </a-space> |
42 | | - </a-space> |
43 | | - </template> |
44 | 53 | <template #peer="{ record }"> |
45 | 54 | <a-button @click="() => peerList?.showModal(downloader, record.id, record.name)"> |
46 | 55 | {{ t('page.dashboard.torrentList.column.view') }} |
47 | 56 | </a-button> |
48 | 57 | </template> |
49 | 58 | </a-table> |
| 59 | + |
| 60 | + <a-list |
| 61 | + v-else |
| 62 | + :loading="!loading && !data" |
| 63 | + :bordered="true" |
| 64 | + hoverable |
| 65 | + :virtual-list-props="useVirtualList" |
| 66 | + > |
| 67 | + <a-list-item v-for="record in data?.data" :key="record.id" action-layout="vertical"> |
| 68 | + <a-list-item-meta style="width: 100%"> |
| 69 | + <template #title> |
| 70 | + <div style="margin-bottom: 8px">{{ record.name }}</div> |
| 71 | + </template> |
| 72 | + <template #description> |
| 73 | + <a-space direction="vertical" fill> |
| 74 | + <a-space> |
| 75 | + {{ getColumnTitle('speed') }}: |
| 76 | + <span class="green" |
| 77 | + ><icon-arrow-up /> {{ formatFileSize(record.rtUploadSpeed) }}/s</span |
| 78 | + > |
| 79 | + <span class="red" |
| 80 | + ><icon-arrow-down /> {{ formatFileSize(record.rtDownloadSpeed) }}/s</span |
| 81 | + > |
| 82 | + </a-space> |
| 83 | + <a-space> {{ getColumnTitle('size') }}: {{ formatFileSize(record.size) }}</a-space> |
| 84 | + <a-space> |
| 85 | + {{ getColumnTitle('progress') }}: |
| 86 | + <a-progress :percent="record.progress" size="mini" /> |
| 87 | + <a-typography-text>{{ (record.progress * 100).toFixed(2) }}%</a-typography-text> |
| 88 | + </a-space> |
| 89 | + </a-space> |
| 90 | + </template> |
| 91 | + </a-list-item-meta> |
| 92 | + |
| 93 | + <template #actions> |
| 94 | + <a-button size="small" @click="handleCopy(record.hash)"> |
| 95 | + {{ getColumnTitle('hash') }} ({{ |
| 96 | + t('page.rule_management.ruleSubscribe.column.clickToCopy') |
| 97 | + }}) |
| 98 | + </a-button> |
| 99 | + <a-button |
| 100 | + size="small" |
| 101 | + @click="() => peerList?.showModal(downloader, record.id, record.name)" |
| 102 | + > |
| 103 | + {{ getColumnTitle('peer') }} ({{ t('page.dashboard.torrentList.column.view') }}) |
| 104 | + </a-button> |
| 105 | + </template> |
| 106 | + </a-list-item> |
| 107 | + </a-list> |
| 108 | + |
50 | 109 | <peerListModal ref="peerList" /> |
51 | 110 | </template> |
52 | 111 | <script setup lang="ts"> |
53 | | -import { Message } from '@arco-design/web-vue' |
54 | 112 | import { getTorrents } from '@/service/downloaders' |
55 | | -import { defineAsyncComponent, ref } from 'vue' |
56 | | -import { useRequest } from 'vue-request' |
57 | | -import { formatFileSize } from '@/utils/file' |
58 | | -import { useI18n } from 'vue-i18n' |
59 | 113 | import { useAutoUpdatePlugin } from '@/stores/autoUpdate' |
| 114 | +import { formatFileSize } from '@/utils/file' |
| 115 | +import { Message } from '@arco-design/web-vue' |
| 116 | +import { breakpointsTailwind, useBreakpoints } from '@vueuse/core' |
60 | 117 | import copy from 'copy-to-clipboard' |
| 118 | +import { computed, defineAsyncComponent, ref } from 'vue' |
| 119 | +import { useI18n } from 'vue-i18n' |
| 120 | +import { useRequest } from 'vue-request' |
61 | 121 | const peerListModal = defineAsyncComponent(() => import('./peerListModal.vue')) |
62 | 122 | const { t } = useI18n() |
63 | 123 | const { downloader } = defineProps<{ |
@@ -108,6 +168,19 @@ const columns = [ |
108 | 168 | slotName: 'peer' |
109 | 169 | } |
110 | 170 | ] |
| 171 | +
|
| 172 | +const breakpoints = useBreakpoints(breakpointsTailwind) |
| 173 | +const mdAndLarger = breakpoints.greaterOrEqual('md') |
| 174 | +
|
| 175 | +const getColumnTitle = (slotName: string) => { |
| 176 | + const column = columns.find((c) => c.slotName === slotName) |
| 177 | + if (!column?.title) return '' |
| 178 | + return typeof column.title === 'function' ? column.title() : column.title |
| 179 | +} |
| 180 | +
|
| 181 | +const useVirtualList = computed(() => { |
| 182 | + return (data.value?.data?.length ?? 0) > 10 ? { height: 350, threshold: 10 } : {} |
| 183 | +}) |
111 | 184 | </script> |
112 | 185 |
|
113 | 186 | <style scoped> |
|
0 commit comments