1
0
Fork 0
mirror of https://github.com/VueTorrent/VueTorrent.git synced 2025-05-04 14:24:40 +03:00
This commit is contained in:
Daan Wijns 2020-10-18 12:12:16 +02:00 committed by GitHub
parent 403c7d5aea
commit af923e6648
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 915 additions and 406 deletions

View file

@ -11,6 +11,7 @@
<v-row no-gutters>
<v-col ref="fileZone">
<v-file-input
v-if="!url"
v-model="files"
color="deep-purple accent-4"
counter
@ -44,6 +45,7 @@
</template>
</v-file-input>
<v-text-field
v-if="files.length == 0"
label="URL"
prepend-icon="mdi-link"
:rows="
@ -62,19 +64,29 @@
clearable
label="Category"
prepend-icon="tag"
@input="categoryChanged"
></v-combobox>
<v-text-field
:disabled="autoTMM"
v-model="directory"
:placeholder="savepath"
label="Download Directory"
prepend-icon="folder"
></v-text-field>
<v-checkbox
v-model="skip_checking"
label="Skip hash check"
></v-checkbox>
<v-row no-gutters>
<v-flex xs12 sm6>
<v-checkbox
v-model="autoTMM"
label="Automatic Torrent Management"
></v-checkbox>
</v-flex>
<v-flex xs12 sm6>
<v-checkbox
v-model="skip_checking"
label="Skip hash check"
></v-checkbox>
</v-flex>
</v-row>
</v-container>
</v-form>
</v-card-text>
@ -108,6 +120,7 @@ export default {
files: [],
category: null,
directory: '',
autoTMM: true,
skip_checking: false,
inputRules: [
v =>
@ -125,14 +138,11 @@ export default {
submit() {
if (this.files.length || this.url) {
let torrents = []
let params = { urls: null, autoTMM: true }
let params = { urls: null, autoTMM: this.autoTMM }
if (this.files.length) torrents.push(...this.files)
if (this.url) params.urls = this.url
if (this.category) params.category = this.category
if (this.directory) {
params.savepath = this.directory
params.autoTMM = false
}
if (!this.autoTMM) params.savepath = this.directory
if (this.skip_checking) params.skip_checking = this.skip_checking
qbit.addTorrents(params, torrents)
@ -142,6 +152,9 @@ export default {
this.$store.commit('DELETE_MODAL', this.guid)
}
},
categoryChanged() {
if (this.autoTMM) this.directory = this.savepath
},
resetForm() {
this.url = null
this.files = []
@ -162,8 +175,8 @@ export default {
let savePath = this.getSettings().save_path
if (this.category) {
savePath += this.category
let category_path = this.getCategories()[this.category].savePath
if (category_path) savePath = category_path
let category = this.getCategories()[this.category]
if (category && category.savePath) savePath = category.savePath
}
return savePath
},
@ -174,6 +187,7 @@ export default {
created() {
this.$store.commit('FETCH_SETTINGS')
this.$store.commit('FETCH_CATEGORIES')
this.directory = this.savepath
}
}
</script>

View file

@ -0,0 +1,88 @@
<template>
<v-dialog
v-model="dialog"
scrollable
:width="dialogWidth"
:fullscreen="phoneLayout"
>
<v-card style="overflow: hidden !important">
<v-container :style="{ height: phoneLayout ? '100vh' : '' }">
<v-card-title class="pb-0 justify-center">
<h2>Change Torrent Location</h2>
</v-card-title>
<v-card-text>
<div>
<v-container>
<v-row>
<v-col>
<v-text-field
label="Torrent Name"
prepend-icon="insert_drive_file"
readonly
v-model="torrent.name"
/>
<v-text-field
label="Directory"
prepend-icon="folder"
v-model="newPath"
v-on:keydown.enter="setLocation"
/>
</v-col>
</v-row>
</v-container>
</div>
</v-card-text>
<div>
<v-card-actions class="justify-center">
<v-btn color="success" @click="setLocation">Save</v-btn>
</v-card-actions>
</div>
</v-container>
<v-fab-transition v-if="phoneLayout">
<v-btn @click="close" color="red" dark absolute bottom right>
<v-icon>close</v-icon>
</v-btn>
</v-fab-transition>
</v-card>
</v-dialog>
</template>
<script>
import { mapGetters } from 'vuex'
import { Modal, FullScreenModal } from '@/mixins'
import qbit from '@/services/qbit'
export default {
name: 'ChangeLocationModal',
mixins: [Modal, FullScreenModal],
props: {
hash: String
},
data() {
return {
newPath: ''
}
},
computed: {
...mapGetters(['getTorrent']),
dialogWidth() {
return this.phoneLayout ? '100%' : '750px'
},
torrent() {
return this.getTorrent(this.hash)
}
},
methods: {
setLocation() {
qbit.setTorrentLocation([this.hash], this.newPath)
this.close()
},
close() {
this.$store.commit('DELETE_MODAL', this.guid)
}
},
created() {
this.newPath = this.torrent.savePath
}
}
</script>

View file

@ -10,7 +10,7 @@
<v-card-title class="pb-0 justify-center primary">
<h2 class="white--text">Settings</h2>
</v-card-title>
<v-tabs v-model="tab" background-color="primary" center-active>
<v-tabs v-model="tab" background-color="primary" dark fixed-tabs>
<v-tab href="#downloads">Downloads</v-tab>
<v-tab href="#bittorrent">BitTorrent</v-tab>
<v-tab href="#webui">WebUI</v-tab>

View file

@ -51,6 +51,29 @@
Global Remove/Resume/Pause Buttons</template
>
</v-switch>
<v-switch
class="v-input--reverse v-input--expand pa-0 ma-0"
inset
v-model="denseDashboard"
color="green_accent"
>
<template #label>
Dense version of the dasbhoard</template
>
</v-switch>
<v-row dense>
<v-col cols="10" sm="10" md="10">
<p class="subtitle-1">Pagination size:</p>
</v-col>
<v-col cols="2" sm="2" md="2">
<v-select
class="pa-0 ma-0"
color="green_accent"
:items="paginationSizes"
v-model="paginationSize"
></v-select>
</v-col>
</v-row>
<v-row dense>
<v-col cols="10" sm="10" md="11">
<p class="subtitle-1">Current Version:</p>
@ -71,6 +94,11 @@
import { mapState, mapGetters } from 'vuex'
export default {
name: 'VueTorrent',
data() {
return {
paginationSizes: [5, 15, 30, 50]
}
},
computed: {
...mapState(['webuiSettings']),
...mapGetters(['getAppVersion']),
@ -114,6 +142,22 @@ export default {
this.webuiSettings.showGlobalRemoveResumePause = val
}
},
denseDashboard: {
get() {
return this.webuiSettings.denseDashboard
},
set(val) {
this.webuiSettings.denseDashboard = val
}
},
paginationSize: {
get() {
return this.webuiSettings.paginationSize
},
set(val) {
this.webuiSettings.paginationSize = val
}
},
version() {
return this.getAppVersion()
}

View file

@ -46,10 +46,10 @@ export default {
mixins: [Modal],
data() {
return {
sortProperty: { value: '', name: 'Default' },
reverse: false,
sortProperty: { value: 'added_on', name: 'Default' },
reverse: true,
options: [
{ value: 'default', name: 'Default' },
{ value: 'added_on', name: 'Default' },
{ value: 'availability', name: 'Availability' },
{ value: 'category', name: 'Category' },
{ value: 'completed', name: 'Completed' },

View file

@ -3,7 +3,7 @@
<v-card>
<v-container style="min-height: 200px" :class="`pa-0 project done`">
<v-card-title class="justify-center">
<h2>Create New Category</h2>
<h2>{{ hasInitialCategory ? 'Edit' : 'Create New' }} Category</h2>
</v-card-title>
<v-form ref="categoryForm" class="px-6 mt-3">
@ -69,8 +69,7 @@ export default {
hasInitialCategory() {
return (
this.initialCategory &&
this.initialCategory.name &&
this.initialCategory.savePath
this.initialCategory.name
)
}
},

View file

@ -3,11 +3,13 @@
<perfect-scrollbar>
<v-card-text style="max-height: 500px; min-height: 400px">
<v-treeview
v-model="tree"
v-model="selected"
:items="fileTree"
:open.sync="opened"
activatable
item-key="name"
open-on-click
selectable
item-key="fullName"
open-all
>
<template v-slot:prepend="{ item, open }">
<v-icon v-if="!item.icon">
@ -15,6 +17,14 @@
</v-icon>
<v-icon v-else>{{ item.icon }}</v-icon>
</template>
<template v-slot:label="{ item }">
<span v-if="!item.editing">{{item.name}}</span>
<v-text-field
autofocus
v-if="item.editing"
v-model="item.newName"
/>
</template>
<template v-slot:append="{ item }">
<span v-if="!item.icon"
>{{ item.children.length }} Files</span
@ -22,6 +32,33 @@
<div v-else>
<span>[{{ item.size }}]</span>
<span class="ml-4">{{ item.progress }}%</span>
<v-btn
v-if="!item.editing"
class="mb-2 ml-4"
x-small
fab
@click="edit(item)"
>
<v-icon>mdi-pencil</v-icon>
</v-btn>
<v-btn
v-if="item.editing"
class="mb-2 ml-4"
x-small
fab
@click="renameFile(item)"
>
<v-icon>save</v-icon>
</v-btn>
<v-btn
v-if="item.editing"
class="mb-2 ml-2"
x-small
fab
@click="togleEditing(item)"
>
<v-icon>close</v-icon>
</v-btn>
</div>
</template>
</v-treeview>
@ -41,7 +78,8 @@ export default {
},
data() {
return {
tree: [],
opened: null,
selected: [],
treeData: null
}
},
@ -56,7 +94,42 @@ export default {
methods: {
async getTorrentFiles() {
const { data } = await qbit.getTorrentFiles(this.hash)
data.forEach((d, i) => {
d.id = i
d.name = d.name.replace('.unwanted/', '')
})
this.treeData = data
},
async changeFilePriorities(newValue, oldValue) {
if (newValue.length == oldValue.length) return
const filesToExclude = oldValue.filter(f => !newValue.includes(f))
.map(name => this.treeData.find(f => f.name === name))
.filter(f => f.priority !== 0)
.map(f => f.id)
const filesToInclude = newValue.filter(f => !oldValue.includes(f))
.map(name => this.treeData.find(f => f.name === name))
.filter(f => f.priority === 0)
.map(f => f.id)
if (filesToExclude.length)
await qbit.setTorrentFilePriority(this.hash, filesToExclude, 0)
if (filesToInclude.length)
await qbit.setTorrentFilePriority(this.hash, filesToInclude, 1)
if (filesToExclude.length || filesToInclude.length)
await this.getTorrentFiles()
},
togleEditing(item) {
item.editing = !item.editing
},
edit(item){
item.newName = item.name
this.togleEditing(item)
},
renameFile(item) {
qbit.renameFile(this.hash, item.id, item.newName)
item.name = item.newName
this.togleEditing(item)
}
},
watch: {
@ -64,10 +137,21 @@ export default {
if (active) {
this.getTorrentFiles()
}
},
selected(newValue, oldValue) {
this.changeFilePriorities(newValue, oldValue)
}
},
created() {
this.getTorrentFiles()
this.getTorrentFiles().then(() => {
this.opened = [].concat(
...this.treeData.map(file => file.name.split('/'))
.filter(f => f.splice(-1, 1)))
.filter((f, index, self) => index === self.indexOf(f)
)
this.selected = this.treeData.filter(file => file.priority !== 0)
.map(file => file.name)
})
}
}
</script>

View file

@ -2,8 +2,8 @@
<v-card flat>
<perfect-scrollbar>
<v-card-text
class="pa-0"
style="font-size: 1.1em; max-height: 500px; min-height: 400px"
style="font-size: 1.1em; min-height: 400px;"
:style="{ maxHeight: phoneLayout ? '' : '500px' }"
>
<v-simple-table>
<tbody>
@ -13,6 +13,12 @@
{{ torrent.name }}
</td>
</tr>
<tr>
<td class="grey--text">Directory</td>
<td class="torrentmodaltext--text">
{{ torrent.savePath }}
</td>
</tr>
<tr style="margin-top: 10px !important">
<td class="grey--text">hash</td>
<td class="torrentmodaltext--text">
@ -32,13 +38,25 @@
</td>
</tr>
<tr>
<td class="grey--text">Download</td>
<td class="grey--text">Uploaded:</td>
<td class="torrentmodaltext--text">
{{ torrent.uploaded }}
</td>
</tr>
<tr>
<td class="grey--text">Ratio</td>
<td class="torrentmodaltext--text">
{{ torrent.ratio }}
</td>
</tr>
<tr>
<td class="grey--text">Download Speed</td>
<td class="torrentmodaltext--text">
{{ torrent.dlspeed }}
</td>
</tr>
<tr>
<td class="grey--text">Upload</td>
<td class="grey--text">Upload Speed</td>
<td class="torrentmodaltext--text">
{{ torrent.upspeed }}
</td>
@ -68,39 +86,21 @@
</td>
</tr>
<tr>
<td class="grey--text">Ratio</td>
<td class="grey--text">Added on</td>
<td class="torrentmodaltext--text">
{{ torrent.ratio }}%
{{ torrent.added_on }}
</td>
</tr>
<tr>
<td class="grey--text">Tags</td>
<td v-if="torrent.tags">
{{ torrent.tags.join(',') }}
</td>
<td v-else>None</td>
</tr>
<tr>
<td class="grey--text">Status</td>
<v-chip
small
:class="`${torrent.state} white--text my-2 caption`"
:class="`${torrent.state.toLowerCase()} white--text my-2 caption`"
>{{ torrent.state }}</v-chip
>
</tr>
</tbody>
</v-simple-table>
<v-flex class="pt-3 pb-4">
<v-progress-linear
height="5"
stream
rounded
color="cyan darken-1"
background-color="cyan lighten-3"
:buffer-value="torrent.progress"
></v-progress-linear>
</v-flex>
</v-card-text>
</perfect-scrollbar>
</v-card>
@ -117,6 +117,9 @@ export default {
...mapGetters(['getTorrent']),
torrent() {
return this.getTorrent(this.hash)
},
phoneLayout() {
return this.$vuetify.breakpoint.xsOnly
}
}
}

View file

@ -16,7 +16,7 @@
<v-card-title class="pb-0 justify-center primary">
<h2 class="white--text">Torrent Detail</h2>
</v-card-title>
<v-tabs v-model="tab" background-color="primary" center-active>
<v-tabs v-model="tab" background-color="primary" dark fixed-tabs>
<v-tab href="#info">Info</v-tab>
<v-tab href="#trackers">Trackers</v-tab>
<v-tab href="#peers">Peers</v-tab>