Add files panel

This commit is contained in:
CzBiX
2019-09-14 19:27:00 +08:00
parent 24cc2138cf
commit e212cc7652
3 changed files with 163 additions and 2 deletions

View File

@@ -159,6 +159,16 @@ class Api {
}).then(Api.handleResponse);
}
public getTorrentFiles(hash: string) {
const params = {
hash,
};
return this.axios.get('/torrents/files', {
params,
}).then(Api.handleResponse);
}
private actionTorrents(action: string, hashes: string[], extra?: any) {
const params: any = {
hashes: hashes.join('|'),

View File

@@ -23,9 +23,9 @@
<v-tab href="#peers">
Peers
</v-tab>
<!-- <v-tab>
<v-tab href="#content">
Content
</v-tab> -->
</v-tab>
</v-tabs>
<v-tabs-items :value="mTab" touchless>
<v-tab-item value="general">
@@ -67,6 +67,19 @@
/>
</panel>
</v-tab-item>
<v-tab-item value="content">
<panel
v-for="torrent in torrents"
:key="torrent.hash"
:title="torrent.name"
:single="torrents.length === 1"
>
<torrent-content
:hash="torrent.hash"
:isActive="mTab === 'content'"
/>
</panel>
</v-tab-item>
</v-tabs-items>
</v-card-text>
<v-card-actions>
@@ -81,6 +94,7 @@
import _ from 'lodash';
import Vue from 'vue';
import TorrentInfo from './TorrentInfo.vue';
import TorrentContent from './TorrentContent.vue';
import Trackers from './Trackers.vue';
import Peers from './Peers.vue';
import Panel from './Panel.vue';
@@ -88,6 +102,7 @@ import Panel from './Panel.vue';
export default Vue.extend({
components: {
TorrentInfo,
TorrentContent,
Trackers,
Peers,
Panel,

View File

@@ -0,0 +1,136 @@
<template>
<div class="torrent-content">
<v-treeview
open-on-click
:items="fileTree"
>
<template v-slot:prepend="item">
<v-icon v-text="getItemIcon(item)" />
</template>
</v-treeview>
</div>
</template>
<script lang="ts">
import _ from 'lodash';
import Vue from 'vue';
import api from '../../Api';
import Taskable from '@/mixins/taskable';
interface File {
name: string;
size: number;
progress: number;
priority: number;
is_seed: boolean;
piece_range: Array<number>;
availability: number;
};
interface TreeItem {
name: string;
item?: File;
children?: Array<TreeItem>;
}
interface Data {
files: Array<File>;
};
const FILE_KEY = '/FILE/';
export default Vue.extend({
mixins: [Taskable],
props: {
hash: String,
isActive: Boolean,
},
data(): Data {
return {
files: [],
};
},
computed: {
fileTree() {
return this.buildTree(this.files, 0);
},
},
methods: {
async getFiles() {
this.files = await api.getTorrentFiles(this.hash);
if (!this.isActive || this.destroy) {
return;
}
this.task = setTimeout(this.getFiles, 5000);
},
getItemIcon(item: any) {
if (item.item.item) {
return 'mdi-file';
}
return item.open ? 'mdi-folder-open' : 'mdi-folder';
},
getFileFolder(item: File, start: number) {
const name = item.name;
const index = name.indexOf('/', start);
if (index === -1) {
return FILE_KEY;
}
return name.substring(start, index);
},
buildTree(files: Array<File>, start: number): Array<TreeItem> {
if (!files.length) {
return [];
}
const entries = _.groupBy(files, (item) => this.getFileFolder(item, start));
const result = [];
for (const [folder, values] of _.entries(entries)) {
if (folder !== FILE_KEY) {
const subTree = this.buildTree(values, start + folder.length + 1);
result.push({
name: folder,
children: subTree,
})
continue;
}
for (const item of values) {
result.push({
name: item.name.substring(start),
item: item,
});
}
}
return result;
},
},
async created() {
if (this.isActive) {
await this.getFiles();
}
},
watch: {
async isActive(v) {
if (v) {
await this.getFiles();
} else {
this.cancelTask();
}
},
},
});
</script>
<style lang="scss" scoped>
.torrent-content {
::v-deep .v-treeview-node__root {
min-height: 0;
}
}
</style>