1
0
Fork 0
mirror of https://github.com/VueTorrent/VueTorrent.git synced 2025-05-06 07:14:56 +03:00
This commit is contained in:
Daan Wijns 2020-10-28 14:44:40 +01:00 committed by GitHub
parent dde4c08f2b
commit 0b4b234b4b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 1143 additions and 734 deletions

View file

@ -10,39 +10,45 @@
<v-container>
<v-row no-gutters>
<v-col ref="fileZone">
<v-file-input
v-model="files"
color="deep-purple accent-4"
counter
label="File input"
multiple
placeholder="Select your files"
prepend-icon="mdi-paperclip"
outlined
:show-size="1000"
<div
@drop.prevent="addDropFile"
@dragover.prevent
>
<template
v-slot:selection="{ index, text }"
<v-file-input
v-if="!urls"
v-model="files"
color="deep-purple accent-4"
counter
label="File input"
multiple
placeholder="Select your files"
prepend-icon="mdi-paperclip"
:rules="fileInputRules"
outlined
:show-size="1000"
>
<v-chip
v-if="index < 2"
color="deep-purple accent-4"
dark
label
small
>{{ text }}</v-chip
<template
v-slot:selection="{ index, text }"
>
<span
v-else-if="index === 2"
class="overline grey--text text--darken-3 mx-2"
>+{{
files.length - 2
}}
File(s)</span
>
</template>
</v-file-input>
<v-chip
v-if="index < 2"
color="deep-purple accent-4"
dark
label
small
>{{ text }}</v-chip
>
<span
v-else-if="index === 2"
class="overline grey--text text--darken-3 mx-2"
>+{{
files.length - 2
}}
File(s)</span
>
</template>
</v-file-input>
</div>
<v-textarea
label="URL"
prepend-icon="mdi-link"
@ -123,12 +129,11 @@ export default {
directory: '',
autoTMM: true,
skip_checking: false,
inputRules: [
v =>
v.indexOf('magnet') > -1 ||
v.indexOf('http') > -1 ||
this.validFile ||
'Not a valid magnet link'
fileInputRules: [
v => {
const result = v.every(f => f.type === 'application/x-bittorrent' )
return result ? result : 'One or more files is not a valid torrent'
}
],
loading: false,
urls: null,
@ -136,6 +141,10 @@ export default {
}
},
methods: {
addDropFile(e)
{
this.files.push(...Array.from(e.dataTransfer.files))
},
submit() {
if (this.files.length || this.urls) {
let torrents = []

View file

@ -2,7 +2,7 @@
<v-dialog
v-model="dialog"
scrollable
:width="dialogWidth"
width="85%"
:fullscreen="phoneLayout"
>
<v-card style="min-height: 400px; overflow: hidden !important">
@ -102,9 +102,6 @@ export default {
},
computed: {
...mapGetters(['getSettings']),
dialogWidth() {
return this.phoneLayout ? '100%' : '750px'
},
dialogHeight() {
return this.phoneLayout ? '79vh' : '70vh'
}

View file

@ -1,7 +1,7 @@
<template>
<v-container>
<v-container class="pa-3 ma-2">
<v-card flat>
<v-card-text>
<v-card-text :style="{ minHeight: phoneLayout ? '' : '75vh'}">
<h3>Privacy</h3>
<div class="settings_content ml-5 mr-5">
<v-checkbox
@ -144,11 +144,11 @@
</template>
<script>
import SettingsTab from '@/mixins/SettingsTab'
import {SettingsTab, FullScreenModal} from '@/mixins'
export default {
name: 'BitTorrent',
mixins: [SettingsTab]
mixins: [SettingsTab, FullScreenModal]
}
</script>

View file

@ -1,7 +1,7 @@
<template>
<v-container>
<v-container class="pa-3 ma-2">
<v-card flat>
<v-card-text>
<v-card-text :style="{ minHeight: phoneLayout ? '' : '75vh'}">
<h3>When adding a torrent</h3>
<div class="settings_content ml-5 mr-5">
<v-checkbox
@ -69,11 +69,11 @@
</template>
<script>
import SettingsTab from '@/mixins/SettingsTab'
import {FullScreenModal, SettingsTab} from '@/mixins'
export default {
name: 'Downloads',
mixins: [SettingsTab]
mixins: [SettingsTab, FullScreenModal]
}
</script>

View file

@ -2,7 +2,8 @@
<v-card flat>
<v-card-text
class="mx-auto mt-5"
style="font-size: 1.1em; max-height: 500px; min-height: 300px"
style="font-size: 1.1em;"
:style="{ minHeight: phoneLayout ? '' : '75vh'}"
>
<v-layout class="mx-auto" row wrap>
<v-flex xs12 sm12>
@ -72,11 +73,11 @@ import { mapGetters } from 'vuex'
import qbit from '@/services/qbit'
import { Tab, General } from '@/mixins'
import { Tab, General,FullScreenModal } from '@/mixins'
export default {
name: 'TagsAndCategories',
mixins: [Tab, General],
mixins: [Tab, General, FullScreenModal],
props: {
hash: String
},

View file

@ -1,190 +1,45 @@
<template>
<v-container>
<v-card flat>
<v-card-text class="pa-0" style="font-size: 1.1em">
<div class="box">
<v-subheader
>These settings are for the custom WebUI
itself</v-subheader
>
<v-form class="px-6 mt-3">
<v-container>
<v-switch
class="v-input--reverse v-input--expand pa-0 ma-0"
inset
v-model="showCurrentSpeed"
color="green_accent"
>
<template #label> Show Current Speed </template>
</v-switch>
<v-switch
class="v-input--reverse v-input--expand pa-0 ma-0"
inset
v-model="showSpeedGraph"
color="green_accent"
>
<template #label> Show Speed Graph</template>
</v-switch>
<v-switch
class="v-input--reverse v-input--expand pa-0 ma-0"
inset
v-model="showSessionStat"
color="green_accent"
>
<template #label> Show Session Stats </template>
</v-switch>
<v-switch
class="v-input--reverse v-input--expand pa-0 ma-0"
inset
v-model="freeSpace"
color="green_accent"
>
<template #label> Show Free Space </template>
</v-switch>
<v-switch
class="v-input--reverse v-input--expand pa-0 ma-0"
inset
v-model="showGlobalRemoveResumePause"
color="green_accent"
>
<template #label>
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>
</v-col>
<v-col cols="2" sm="2" md="1">
<p class="mb-2">{{ version }}</p>
</v-col>
</v-row>
</v-container>
</v-form>
</div>
</v-card-text>
<div class="ma-1">
<v-card flat style="width: 100vh">
<v-card-text :style="{ minHeight: phoneLayout ? '' : '75vh'}">
<v-tabs v-model="tab">
<v-tab href="#general">General</v-tab>
<v-tab href="#dashboard">Dashboard</v-tab>
</v-tabs>
<v-tabs-items
v-model="tab"
:touch="updateTab(tab)"
>
<v-tab-item style="width: 100vh" value="general">
<General :is-active="tab === 'downloads'" />
</v-tab-item>
<v-tab-item style="width: 100vh" value="dashboard">
<Dashboard :is-active="tab === 'bittorrent'" />
</v-tab-item>
</v-tabs-items>
</v-card-text>
</v-card>
</v-container>
</div>
</template>
<script>
import { mapState, mapGetters } from 'vuex'
import General from './Vuetorrent/General'
import Dashboard from './Vuetorrent/Dashboard'
import {FullScreenModal} from '@/mixins'
export default {
name: 'VueTorrent',
data() {
return {
paginationSizes: [5, 15, 30, 50]
}
components: {
General, Dashboard
},
computed: {
...mapState(['webuiSettings']),
...mapGetters(['getAppVersion']),
freeSpace: {
get() {
return this.webuiSettings.showFreeSpace
},
set(val) {
this.webuiSettings.showFreeSpace = val
}
},
showCurrentSpeed: {
get() {
return this.webuiSettings.showCurrentSpeed
},
set(val) {
this.webuiSettings.showCurrentSpeed = val
}
},
showSpeedGraph: {
get() {
return this.webuiSettings.showSpeedGraph
},
set(val) {
this.webuiSettings.showSpeedGraph = val
}
},
showSessionStat: {
get() {
return this.webuiSettings.showSessionStat
},
set(val) {
this.webuiSettings.showSessionStat = val
}
},
showGlobalRemoveResumePause: {
get() {
return this.webuiSettings.showGlobalRemoveResumePause
},
set(val) {
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()
mixins: [FullScreenModal],
data : () => ({
tab: null
}),
methods: {
updateTab(tab) {
this.tab = tab
}
}
}
</script>
<style lang="scss" scoped>
@import '@/assets/styles/SettingsTab.scss';
</style>
<style lang="scss" scoped>
// Reversed input variant
::v-deep .v-input--reverse .v-input__slot {
flex-direction: row-reverse;
justify-content: flex-end;
.v-application--is-ltr & {
.v-input--selection-controls__input {
margin-right: 0;
margin-left: 8px;
}
}
.v-application--is-rtl & {
.v-input--selection-controls__input {
margin-left: 0;
margin-right: 8px;
}
}
}
</style>
</script>

View file

@ -0,0 +1,81 @@
<template>
<div class="ma-3 pa-2">
<v-card flat>
<v-card-text class="pa-0">
<v-layout row wrap align-center justify-center>
<v-flex class="box ma-1" style="width:50px !important;" xs12 md5>
<v-subheader>
Properties to display for busy torrents
</v-subheader>
<v-row dense >
<v-list flat class="ma-0 pa-0">
<draggable
:list="busyTorrentProperties"
tag="tbody"
>
<v-list-item
v-for="(item, index) in busyTorrentProperties"
:key="index"
style="width: 30vh"
>
<v-checkbox v-model="item.active" dense class="pa-0 ma-0 mt-3"/>
<v-list-item-content>
<v-list-item-title class="truncate" v-text="item.name"/>
</v-list-item-content>
</v-list-item>
</draggable>
</v-list>
</v-row>
</v-flex>
<v-flex class="box ma-1" xs12 md5>
<v-subheader>
Properties to display for completed torrents
</v-subheader>
<v-row dense>
<v-list flat class="ma-0 pa-0">
<draggable
:list="doneTorrentProperties"
tag="tbody"
>
<v-list-item
v-for="(item, index) in doneTorrentProperties"
:key="index"
style="width: 30vh"
>
<v-checkbox v-model="item.active" dense class="pa-0 ma-0 mt-3"/>
<v-list-item-content>
<v-list-item-title class="truncate" v-text="item.name"/>
</v-list-item-content>
</v-list-item>
</draggable>
</v-list>
</v-row>
</v-flex>
</v-layout>
</v-card-text>
</v-card>
</div>
</template>
<script>
import draggable from 'vuedraggable'
export default {
name: 'Dashboard',
components: {
draggable
},
computed : {
busyTorrentProperties(){
return this.$store.state.webuiSettings.busyTorrentProperties
},
doneTorrentProperties(){
return this.$store.state.webuiSettings.doneTorrentProperties
}
}
}
</script>
<style lang="scss" scoped>
@import '@/assets/styles/SettingsTab.scss';
</style>

View file

@ -0,0 +1,190 @@
<template>
<div class="ma-2">
<v-card flat style="width: 100vh">
<v-card-text class="pa-0" style="font-size: 1.1em">
<div class="box">
<v-subheader
>These settings are for the custom WebUI
itself</v-subheader
>
<v-form class="px-6 mt-3">
<v-container>
<v-switch
class="v-input--reverse v-input--expand pa-0 ma-0"
inset
v-model="showCurrentSpeed"
color="green_accent"
>
<template #label> Show Current Speed </template>
</v-switch>
<v-switch
class="v-input--reverse v-input--expand pa-0 ma-0"
inset
v-model="showSpeedGraph"
color="green_accent"
>
<template #label> Show Speed Graph</template>
</v-switch>
<v-switch
class="v-input--reverse v-input--expand pa-0 ma-0"
inset
v-model="showSessionStat"
color="green_accent"
>
<template #label> Show Session Stats </template>
</v-switch>
<v-switch
class="v-input--reverse v-input--expand pa-0 ma-0"
inset
v-model="freeSpace"
color="green_accent"
>
<template #label> Show Free Space </template>
</v-switch>
<v-switch
class="v-input--reverse v-input--expand pa-0 ma-0"
inset
v-model="showGlobalRemoveResumePause"
color="green_accent"
>
<template #label>
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>
</v-col>
<v-col cols="2" sm="2" md="1">
<p class="mb-2">{{ version }}</p>
</v-col>
</v-row>
</v-container>
</v-form>
</div>
</v-card-text>
</v-card>
</div>
</template>
<script>
import { mapState, mapGetters } from 'vuex'
export default {
name: 'General',
data() {
return {
paginationSizes: [5, 15, 30, 50]
}
},
computed: {
...mapState(['webuiSettings']),
...mapGetters(['getAppVersion']),
freeSpace: {
get() {
return this.webuiSettings.showFreeSpace
},
set(val) {
this.webuiSettings.showFreeSpace = val
}
},
showCurrentSpeed: {
get() {
return this.webuiSettings.showCurrentSpeed
},
set(val) {
this.webuiSettings.showCurrentSpeed = val
}
},
showSpeedGraph: {
get() {
return this.webuiSettings.showSpeedGraph
},
set(val) {
this.webuiSettings.showSpeedGraph = val
}
},
showSessionStat: {
get() {
return this.webuiSettings.showSessionStat
},
set(val) {
this.webuiSettings.showSessionStat = val
}
},
showGlobalRemoveResumePause: {
get() {
return this.webuiSettings.showGlobalRemoveResumePause
},
set(val) {
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()
}
}
}
</script>
<style lang="scss" scoped>
@import '@/assets/styles/SettingsTab.scss';
</style>
<style lang="scss" scoped>
// Reversed input variant
::v-deep .v-input--reverse .v-input__slot {
flex-direction: row-reverse;
justify-content: flex-end;
.v-application--is-ltr & {
.v-input--selection-controls__input {
margin-right: 0;
margin-left: 8px;
}
}
.v-application--is-rtl & {
.v-input--selection-controls__input {
margin-left: 0;
margin-right: 8px;
}
}
}
</style>

View file

@ -1,7 +1,9 @@
<template>
<v-container>
<div class="ma-3 pa-2">
<v-card flat>
<v-card-text class="pa-0" style="font-size: 1.1em">
<v-card-text class="pa-0" style="font-size: 1.1em"
:style="{ minHeight: phoneLayout ? '' : '75vh'}"
>
<div class="box">
<v-subheader>Use Alternative WebUI</v-subheader>
<div class="ml-5 mr-5">
@ -49,15 +51,15 @@
</div>
</v-card-text>
</v-card>
</v-container>
</div>
</template>
<script>
import SettingsTab from '@/mixins/SettingsTab'
import {FullScreenModal, SettingsTab} from '@/mixins'
export default {
name: 'WebUI',
mixins: [SettingsTab]
mixins: [SettingsTab, FullScreenModal]
}
</script>

View file

@ -1,77 +1,77 @@
<template>
<v-card flat>
<perfect-scrollbar>
<v-card-text style="max-height: 500px; min-height: 400px">
<v-treeview
v-model="selected"
:items="fileTree"
:open.sync="opened"
activatable
selectable
item-key="fullName"
open-all
>
<template v-slot:prepend="{ item, open }">
<v-icon v-if="!item.icon">
{{ open ? 'mdi-folder-open' : 'mdi-folder' }}
</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
>
<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>
</v-card-text>
</perfect-scrollbar>
</v-card>
<v-card flat>
<perfect-scrollbar>
<v-card-text :style="{ minHeight: phoneLayout ? '' : '75vh'}">
<v-treeview
v-model="selected"
:items="fileTree"
:open.sync="opened"
activatable
selectable
item-key="fullName"
open-all
>
<template v-slot:prepend="{ item, open }">
<v-icon v-if="!item.icon">
{{ open ? "mdi-folder-open" : "mdi-folder" }}
</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>
<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>
</v-card-text>
</perfect-scrollbar>
</v-card>
</template>
<script>
import qbit from '@/services/qbit'
import { treeify } from '@/helpers'
import { FullScreenModal } from '@/mixins'
export default {
name: 'Content',
mixins: [FullScreenModal],
props: {
hash: String,
isActive: Boolean
@ -102,16 +102,18 @@ export default {
},
async changeFilePriorities(newValue, oldValue) {
if (newValue.length == oldValue.length) return
const filesToExclude = oldValue.filter(f => !newValue.includes(f))
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))
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)
@ -122,7 +124,7 @@ export default {
togleEditing(item) {
item.editing = !item.editing
},
edit(item){
edit(item) {
item.newName = item.name
this.togleEditing(item)
},
@ -143,13 +145,16 @@ export default {
}
},
created() {
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)
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)
})
}

View file

@ -1,115 +1,113 @@
<template>
<v-card flat>
<perfect-scrollbar>
<v-card-text
style="font-size: 1.1em; min-height: 400px;"
:style="{ maxHeight: phoneLayout ? '' : '500px' }"
>
<v-simple-table>
<tbody>
<tr>
<td class="grey--text">Torrent title</td>
<td class="torrentmodaltext--text">
{{ 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">
{{ torrent.hash }}
</td>
</tr>
<tr>
<td class="grey--text">Size</td>
<td class="torrentmodaltext--text">
{{ torrent.size }}
</td>
</tr>
<tr>
<td class="grey--text">Done:</td>
<td class="torrentmodaltext--text">
{{ torrent.dloaded }}
</td>
</tr>
<tr>
<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 Speed</td>
<td class="torrentmodaltext--text">
{{ torrent.upspeed }}
</td>
</tr>
<tr>
<td class="grey--text">ETA</td>
<td class="torrentmodaltext--text">
{{ torrent.eta }}
</td>
</tr>
<tr>
<td class="grey--text">Peers</td>
<td class="torrentmodaltext--text">
{{ torrent.num_leechs
}}<span class="grey--text"
>/{{ torrent.available_peers }}</span
>
</td>
</tr>
<tr>
<td class="grey--text">Seeds</td>
<td class="torrentmodaltext--text">
{{ torrent.num_seeds
}}<span class="grey--text"
>/{{ torrent.available_seeds }}</span
>
</td>
</tr>
<tr>
<td class="grey--text">Added on</td>
<td class="torrentmodaltext--text">
{{ torrent.added_on }}
</td>
</tr>
<tr>
<td class="grey--text">Status</td>
<v-chip
small
:class="`${torrent.state.toLowerCase()} white--text my-2 caption`"
>{{ torrent.state }}</v-chip
>
</tr>
</tbody>
</v-simple-table>
</v-card-text>
</perfect-scrollbar>
</v-card>
<v-card flat>
<perfect-scrollbar>
<v-card-text
style="font-size: 1.1em"
:style="{ minHeight: phoneLayout ? '' : '75vh'}"
>
<v-simple-table>
<tbody>
<tr>
<td class="grey--text">Torrent title</td>
<td class="torrentmodaltext--text">
{{ 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">
{{ torrent.hash }}
</td>
</tr>
<tr>
<td class="grey--text">Size</td>
<td class="torrentmodaltext--text">
{{ torrent.size }}
</td>
</tr>
<tr>
<td class="grey--text">Done:</td>
<td class="torrentmodaltext--text">
{{ torrent.dloaded }}
</td>
</tr>
<tr>
<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 Speed</td>
<td class="torrentmodaltext--text">
{{ torrent.upspeed }}
</td>
</tr>
<tr>
<td class="grey--text">ETA</td>
<td class="torrentmodaltext--text">
{{ torrent.eta }}
</td>
</tr>
<tr>
<td class="grey--text">Peers</td>
<td class="torrentmodaltext--text">
{{ torrent.num_leechs
}}<span class="grey--text">/{{ torrent.available_peers }}</span>
</td>
</tr>
<tr>
<td class="grey--text">Seeds</td>
<td class="torrentmodaltext--text">
{{ torrent.num_seeds
}}<span class="grey--text">/{{ torrent.available_seeds }}</span>
</td>
</tr>
<tr>
<td class="grey--text">Added on</td>
<td class="torrentmodaltext--text">
{{ torrent.added_on }}
</td>
</tr>
<tr>
<td class="grey--text">Status</td>
<v-chip
small
:class="`${torrent.state.toLowerCase()} white--text my-2 caption`"
>{{ torrent.state }}</v-chip
>
</tr>
</tbody>
</v-simple-table>
</v-card-text>
</perfect-scrollbar>
</v-card>
</template>
<script>
import { mapGetters } from 'vuex'
import { FullScreenModal } from '@/mixins'
export default {
name: 'Info',
mixins: [FullScreenModal],
props: {
hash: String
},
@ -117,9 +115,6 @@ export default {
...mapGetters(['getTorrent']),
torrent() {
return this.getTorrent(this.hash)
},
phoneLayout() {
return this.$vuetify.breakpoint.xsOnly
}
}
}
@ -128,16 +123,16 @@ export default {
<style lang="scss" scoped>
::v-deep .v-data-table thead th,
::v-deep .v-data-table tbody td {
padding: 0 !important;
height: 3em;
padding: 0 !important;
height: 3em;
white-space: nowrap;
white-space: nowrap;
&:first-child {
padding: 0 0 0 8px !important;
}
&:last-child {
padding-right: 8px !important;
}
&:first-child {
padding: 0 0 0 8px !important;
}
&:last-child {
padding-right: 8px !important;
}
}
</style>

View file

@ -1,54 +1,55 @@
<template>
<perfect-scrollbar>
<v-data-table
v-if="peers"
:headers="headers"
:items="peers"
:items-per-page="-1"
:hide-default-footer="true"
style="max-height: 500px; min-height: 400px"
>
<template v-slot:item="row">
<tr>
<td class="ip">
<template v-if="row.item.country_code">
<img
v-if="isWindows"
class="country-flag"
:title="row.item.country"
:alt="codeToFlag(row.item.country_code).char"
:src="codeToFlag(row.item.country_code).url"
/>
<template v-else>{{
codeToFlag(row.item.country_code).char
}}</template>
</template>
{{ row.item.ip }}
<span class="grey--text">:{{ row.item.port }}</span>
</td>
<td>{{ row.item.connection }}</td>
<td :title="row.item.flags_desc">{{ row.item.flags }}</td>
<td>{{ row.item.client }}</td>
<td>{{ row.item.progress | progress }}</td>
<td>{{ row.item.dl_speed | networkSpeed }}</td>
<td>{{ row.item.downloaded | networkSize }}</td>
<td>{{ row.item.up_speed | networkSpeed }}</td>
<td>{{ row.item.uploaded | networkSize }}</td>
<td>{{ row.item.relevance | progress }}</td>
<td>{{ row.item.files }}</td>
</tr>
<perfect-scrollbar>
<v-data-table
v-if="peers"
:headers="headers"
:items="peers"
:items-per-page="-1"
:hide-default-footer="true"
:style="{ minHeight: phoneLayout ? '' : '75vh'}"
>
<template v-slot:item="row">
<tr>
<td class="ip">
<template v-if="row.item.country_code">
<img
v-if="isWindows"
class="country-flag"
:title="row.item.country"
:alt="codeToFlag(row.item.country_code).char"
:src="codeToFlag(row.item.country_code).url"
/>
<template v-else>{{
codeToFlag(row.item.country_code).char
}}</template>
</template>
</v-data-table>
</perfect-scrollbar>
{{ row.item.ip }}
<span class="grey--text">:{{ row.item.port }}</span>
</td>
<td>{{ row.item.connection }}</td>
<td :title="row.item.flags_desc">{{ row.item.flags }}</td>
<td>{{ row.item.client }}</td>
<td>{{ row.item.progress | progress }}</td>
<td>{{ row.item.dl_speed | networkSpeed }}</td>
<td>{{ row.item.downloaded | networkSize }}</td>
<td>{{ row.item.up_speed | networkSpeed }}</td>
<td>{{ row.item.uploaded | networkSize }}</td>
<td>{{ row.item.relevance | progress }}</td>
<td>{{ row.item.files }}</td>
</tr>
</template>
</v-data-table>
</perfect-scrollbar>
</template>
<script>
import { map, merge } from 'lodash'
import qbit from '@/services/qbit'
import { codeToFlag, isWindows } from '@/helpers'
import { FullScreenModal } from '@/mixins'
export default {
name: 'Peers',
mixins: [FullScreenModal],
props: { hash: String, isActive: Boolean },
data: () => ({
headers: [
@ -112,30 +113,30 @@ export default {
<style scoped>
::v-deep .ip {
display: flex;
align-items: center;
display: flex;
align-items: center;
}
::v-deep .ip .country-flag {
width: 1.5em;
margin-right: 0.5em;
width: 1.5em;
margin-right: 0.5em;
}
</style>
<style lang="scss" scoped>
@import '~@/assets/styles.scss';
@import "~@/assets/styles.scss";
::v-deep .v-data-table thead th,
::v-deep .v-data-table tbody td {
padding: 0 2px !important;
height: auto;
padding: 0 2px !important;
height: auto;
white-space: nowrap;
white-space: nowrap;
&:first-child {
padding: 0 0 0 8px !important;
}
&:last-child {
padding-right: 8px !important;
}
&:first-child {
padding: 0 0 0 8px !important;
}
&:last-child {
padding-right: 8px !important;
}
}
</style>

View file

@ -1,111 +1,110 @@
<template>
<v-card flat>
<v-card-text
class="mx-auto mt-5"
style="font-size: 1.1em; max-height: 500px; min-height: 300px"
>
<v-row>
<v-col :cols="12" :lg="6" :md="6" :sm="12">
<v-layout class="mx-auto" row wrap>
<v-flex xs12 sm12>
<h3>Available Tags:</h3>
</v-flex>
<v-flex class="mt-3 d-flex flex-wrap justify-center" xs12 sm12>
<v-chip
v-for="tag in availableTags"
:key="tag"
small
class="download white--text caption mx-2 my-1"
style="font-size: 0.95em !important"
@click="addTag(tag)"
>
{{ tag }}
</v-chip>
</v-flex>
</v-layout>
<v-layout class="mx-auto mt-12" row wrap>
<v-flex xs12 sm12>
<h3>Current Tags:</h3>
</v-flex>
<v-flex class="mt-3 d-flex flex-wrap justify-center" xs12 sm12>
<div v-if="torrent.tags">
<v-chip
v-for="tag in torrent.tags"
:key="tag"
small
close
class="download white--text caption mx-2 my-1"
style="font-size: 0.95em !important"
@click="deleteTag(tag)"
@click:close="deleteTag(tag)"
>{{ tag }}</v-chip
>
</div>
<div v-else>None</div>
</v-flex>
</v-layout>
</v-col>
<v-col :cols="12" :lg="6" :md="6" :sm="12">
<v-layout
class="mx-auto"
:class="
this.$vuetify.breakpoint.smAndDown ? 'mt-12' : ''
"
row
wrap
>
<v-flex xs12 sm12>
<h3>Available Categories:</h3>
</v-flex>
<v-flex class="mt-3 d-flex flex-wrap justify-center" xs12 sm12>
<v-chip
v-for="cat in availableCategories"
:key="cat.name"
small
class="upload white--text caption mx-2 my-1"
style="font-size: 0.95em !important"
@click="setCategory(cat.name)"
>
{{ cat.name }}
</v-chip>
</v-flex>
</v-layout>
<v-layout class="mx-auto mt-12" row wrap>
<v-flex xs12 sm12>
<h3>Current Category:</h3>
</v-flex>
<v-flex class="mt-3 d-flex justify-center" xs12 sm12>
<v-chip
v-if="torrent.category"
small
close
class="upload white--text caption mx-2"
style="font-size: 0.95em !important"
@click="deleteCategory"
@click:close="deleteCategory"
>{{ torrent.category }}</v-chip
>
<div v-else>None</div>
</v-flex>
</v-layout>
</v-col>
</v-row>
</v-card-text>
</v-card>
<v-card flat>
<v-card-text
class="mx-auto mt-4"
style="font-size: 1.1em"
:style="{ minHeight: phoneLayout ? '' : '75vh'}"
>
<v-row>
<v-col :cols="12" :lg="6" :md="6" :sm="12">
<v-layout class="mx-auto" row wrap>
<v-flex xs12 sm12>
<h3>Available Tags:</h3>
</v-flex>
<v-flex class="mt-3 d-flex flex-wrap justify-center" xs12 sm12>
<v-chip
v-for="tag in availableTags"
:key="tag"
small
class="download white--text caption mx-2 my-1"
style="font-size: 0.95em !important"
@click="addTag(tag)"
>
{{ tag }}
</v-chip>
</v-flex>
</v-layout>
<v-layout class="mx-auto mt-12" row wrap>
<v-flex xs12 sm12>
<h3>Current Tags:</h3>
</v-flex>
<v-flex class="mt-3 d-flex flex-wrap justify-center" xs12 sm12>
<div v-if="torrent.tags">
<v-chip
v-for="tag in torrent.tags"
:key="tag"
small
close
class="download white--text caption mx-2 my-1"
style="font-size: 0.95em !important"
@click="deleteTag(tag)"
@click:close="deleteTag(tag)"
>{{ tag }}</v-chip
>
</div>
<div v-else>None</div>
</v-flex>
</v-layout>
</v-col>
<v-col :cols="12" :lg="6" :md="6" :sm="12">
<v-layout
class="mx-auto"
:class="this.$vuetify.breakpoint.smAndDown ? 'mt-12' : ''"
row
wrap
>
<v-flex xs12 sm12>
<h3>Available Categories:</h3>
</v-flex>
<v-flex class="mt-3 d-flex flex-wrap justify-center" xs12 sm12>
<v-chip
v-for="cat in availableCategories"
:key="cat.name"
small
class="upload white--text caption mx-2 my-1"
style="font-size: 0.95em !important"
@click="setCategory(cat.name)"
>
{{ cat.name }}
</v-chip>
</v-flex>
</v-layout>
<v-layout class="mx-auto mt-12" row wrap>
<v-flex xs12 sm12>
<h3>Current Category:</h3>
</v-flex>
<v-flex class="mt-3 d-flex justify-center" xs12 sm12>
<v-chip
v-if="torrent.category"
small
close
class="upload white--text caption mx-2"
style="font-size: 0.95em !important"
@click="deleteCategory"
@click:close="deleteCategory"
>{{ torrent.category }}</v-chip
>
<div v-else>None</div>
</v-flex>
</v-layout>
</v-col>
</v-row>
</v-card-text>
</v-card>
</template>
<script>
import { difference } from 'lodash'
import { mapGetters } from 'vuex'
import qbit from '@/services/qbit'
import { Tab } from '@/mixins'
import { FullScreenModal } from '@/mixins'
export default {
name: 'TorrentTagsAndCategories',
props: {
hash: String
},
mixins: [Tab],
mixins: [FullScreenModal],
data: () => ({
categories: []
}),
@ -145,6 +144,6 @@ export default {
<style scoped>
h3 {
text-align: center;
text-align: center;
}
</style>

View file

@ -1,32 +1,34 @@
<template>
<perfect-scrollbar>
<v-data-table
v-if="trackers"
:headers="headers"
:items="trackers"
:hide-default-footer="true"
style="max-height: 500px; min-height: 400px"
>
<template v-slot:item="row">
<tr>
<td>{{ row.item.tier }}</td>
<td>{{ row.item.url }}</td>
<td>{{ row.item.status | formatTrackerStatus }}</td>
<td>{{ row.item.num_peers | formatTrackerNum }}</td>
<td>{{ row.item.num_seeds | formatTrackerNum }}</td>
<td>{{ row.item.num_leeches | formatTrackerNum }}</td>
<td>{{ row.item.num_downloaded | formatTrackerNum }}</td>
<td>{{ row.item.msg }}</td>
</tr>
</template>
</v-data-table>
</perfect-scrollbar>
<perfect-scrollbar>
<v-data-table
v-if="trackers"
:headers="headers"
:items="trackers"
:hide-default-footer="true"
:style="{ minHeight: phoneLayout ? '' : '75vh'}"
>
<template v-slot:item="row">
<tr>
<td>{{ row.item.tier }}</td>
<td>{{ row.item.url }}</td>
<td>{{ row.item.status | formatTrackerStatus }}</td>
<td>{{ row.item.num_peers | formatTrackerNum }}</td>
<td>{{ row.item.num_seeds | formatTrackerNum }}</td>
<td>{{ row.item.num_leeches | formatTrackerNum }}</td>
<td>{{ row.item.num_downloaded | formatTrackerNum }}</td>
<td>{{ row.item.msg }}</td>
</tr>
</template>
</v-data-table>
</perfect-scrollbar>
</template>
<script>
import qbit from '@/services/qbit'
import { FullScreenModal } from '@/mixins'
export default {
name: 'Trackers',
mixins: [FullScreenModal],
props: { hash: String, isActive: Boolean },
data: () => ({
headers: [
@ -86,20 +88,20 @@ export default {
</script>
<style lang="scss" scoped>
@import '~@/assets/styles.scss';
@import "~@/assets/styles.scss";
::v-deep .v-data-table thead th,
::v-deep .v-data-table tbody td {
padding: 0 2px !important;
height: auto;
padding: 0 2px !important;
height: auto;
white-space: nowrap;
white-space: nowrap;
&:first-child {
padding: 0 0 0 8px !important;
}
&:last-child {
padding-right: 8px !important;
}
&:first-child {
padding: 0 0 0 8px !important;
}
&:last-child {
padding-right: 8px !important;
}
}
</style>