mirror of
https://github.com/VueTorrent/VueTorrent.git
synced 2025-05-04 14:24:40 +03:00
0.4.0 (#47)
This commit is contained in:
parent
403c7d5aea
commit
af923e6648
38 changed files with 915 additions and 406 deletions
src/components/Modals
|
@ -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>
|
||||
|
|
88
src/components/Modals/ChangeLocationModal.vue
Normal file
88
src/components/Modals/ChangeLocationModal.vue
Normal 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>
|
|
@ -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>
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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' },
|
||||
|
|
|
@ -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
|
||||
)
|
||||
}
|
||||
},
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue