1
0
Fork 0
mirror of https://github.com/VueTorrent/VueTorrent.git synced 2025-05-06 23:35:00 +03:00
This commit is contained in:
Daan Wijns 2020-11-07 13:05:31 +01:00 committed by GitHub
parent 80d1c1f6a0
commit 8b590e4e98
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
51 changed files with 760 additions and 653 deletions

View file

@ -121,6 +121,7 @@ import Modal from '@/mixins/Modal'
import qbit from '@/services/qbit'
export default {
name: 'AddModal',
props: ['initialMagnet'],
mixins: [Modal],
data() {
return {
@ -144,14 +145,13 @@ export default {
}
},
methods: {
addDropFile(e)
{
addDropFile(e) {
this.files.push(...Array.from(e.dataTransfer.files))
},
submit() {
if (this.files.length || this.urls) {
let torrents = []
let params = { urls: null, autoTMM: this.autoTMM }
const torrents = []
const params = { urls: null, autoTMM: this.autoTMM }
if (this.files.length) torrents.push(...this.files)
if (this.urls) params.urls = this.urls
if (this.category) params.category = this.category
@ -188,7 +188,7 @@ export default {
let savePath = this.getSettings().save_path
if (this.category) {
savePath += this.category
let category = this.getCategories()[this.category]
const category = this.getCategories()[this.category]
if (category && category.savePath) savePath = category.savePath
}
return savePath
@ -201,6 +201,7 @@ export default {
this.$store.commit('FETCH_SETTINGS')
this.$store.commit('FETCH_CATEGORIES')
this.directory = this.savepath
this.urls = this.initialMagnet
}
}
</script>

View file

@ -63,9 +63,9 @@ export default {
computed: {
...mapState(['selected_torrents']),
...mapGetters(['getTorrents']),
torrents(){
torrents() {
return this.getTorrents().filter(t => this.selected_torrents.includes(t.hash))
}
}
}
</script>
</script>

View file

@ -77,4 +77,4 @@ export default {
this.name = this.torrent.name
}
}
</script>
</script>

View file

@ -1,184 +0,0 @@
<template>
<v-dialog
v-model="dialog"
scrollable
:width="dialogWidth"
:fullscreen="phoneLayout"
>
<v-card :style="{ height: phoneLayout ? '100vh' : '' }">
<v-container
:style="{ height: phoneLayout ? '100vh' : '' }"
:class="`pa-0 project done`"
>
<v-card-title class="justify-center">
<h2>Search Torrent</h2>
</v-card-title>
<v-card-text>
<div>
<v-container>
<v-row no-gutters>
<v-col ref="fileZone">
<v-text-field
label="Search"
prepend-icon="search"
required
:autofocus="!phoneLayout"
v-model="searchTerm"
v-on:keydown.enter="search"
/>
<v-text-field
label="Category"
prepend-icon="category"
v-model="searchCategory"
v-on:keydown.enter="search"
/>
</v-col>
</v-row>
</v-container>
</div>
</v-card-text>
<v-spacer></v-spacer>
<div>
<v-card-actions class="justify-center">
<v-btn
text
@click="search"
:loading="status === 'Running'"
class="blue_accent white--text"
>Search</v-btn
>
</v-card-actions>
</div>
<div class="text-center mt-6">
<p
v-if="noResults"
class="red--text"
style="font-size: 1.3em"
>
No results could be found
</p>
<div v-if="results.length">
<h2>Results</h2>
<perfect-scrollbar>
<v-list
rounded
style="max-height: 500px; min-height: 400px"
>
<v-list-item>
<v-list-item-title
>FileName</v-list-item-title
>
<v-list-item-subtitle style="max-width: 20%"
>Size</v-list-item-subtitle
>
<v-list-item-subtitle style="max-width: 20%"
>Seeders</v-list-item-subtitle
>
<v-list-item-subtitle style="max-width: 20%"
>Leechers</v-list-item-subtitle
>
</v-list-item>
<v-list-item
@click="addTorrent(res.fileUrl)"
v-for="res in results"
:key="res.title"
>
<v-list-item-title>
{{ res.fileName }}
</v-list-item-title>
<v-list-item-subtitle
style="max-width: 20%"
>
{{ res.fileSize | size }}
</v-list-item-subtitle>
<v-list-item-subtitle
style="max-width: 20%"
>
{{ res.nbSeeders }}
</v-list-item-subtitle>
<v-list-item-subtitle
style="max-width: 20%"
>
{{ res.nbLeechers }}
</v-list-item-subtitle>
</v-list-item>
</v-list>
</perfect-scrollbar>
</div>
</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 { Modal, FullScreenModal } from '@/mixins'
import qbit from '@/services/qbit'
export default {
name: 'SearchModal',
mixins: [Modal, FullScreenModal],
data() {
return {
searchTerm: null,
searchCategory: null,
searchId: null,
status: null,
searchInterval: null,
results: [],
noResults: false
}
},
computed: {
dialogWidth() {
return this.phoneLayout ? '100%' : '750px'
}
},
methods: {
async search() {
this.noResults = false
if (this.searchTerm && !this.searchInterval) {
this.status = 'Running'
this.results = []
const { data } = await qbit.startSearch(
this.searchTerm,
this.searchCategory
)
this.searchId = data.id
this.searchInterval = setInterval(async () => {
let status = await this.getStatus()
if (status === 'Stopped') {
clearInterval(this.searchInterval)
this.searchInterval = null
this.getResults()
}
}, 2000)
}
},
async getStatus() {
if (this.searchId) {
const { data } = await qbit.getSearchStatus(this.searchId)
return (this.status = data[0].status)
}
},
async getResults() {
const { data } = await qbit.getSearchResults(this.searchId)
this.results = data.results
if (data.results.length === 0) this.noResults = true
},
addTorrent(torrent) {
let params = { urls: null }
params.urls = torrent
qbit.addTorrents(params)
},
close() {
this.$store.commit('DELETE_MODAL', this.guid)
}
}
}
</script>

View file

@ -0,0 +1,67 @@
<template>
<div>
<v-btn @click="opened = true">
<v-icon>mdi-cog</v-icon> Plugin manager
</v-btn>
<v-bottom-sheet
scrollable
inset
v-model="opened"
v-if="this.$vuetify.breakpoint.smAndDown"
>
<v-sheet>
<v-card>
<v-card-title> <v-icon>mdi-toy-brick</v-icon> Plugin manager </v-card-title>
<v-card-text>
<v-switch
v-for="(plugin, key) in searchPlugins"
:key="key"
:input-value="plugin.enabled"
:label="plugin.fullName"
@change="togglePlugin(plugin)"
/>
</v-card-text>
</v-card>
</v-sheet>
</v-bottom-sheet>
<v-dialog v-model="opened" width="50%" v-else>
<v-card>
<v-card-title> <v-icon>mdi-toy-brick</v-icon> Plugin manager </v-card-title>
<v-card-text>
<v-switch
v-for="(plugin, key) in searchPlugins"
:key="key"
v-model="plugin.enabled"
:label="plugin.fullName"
@change="togglePlugin(plugin)"
/>
</v-card-text>
</v-card>
</v-dialog>
</div>
</template>
<script>
import { mapState } from 'vuex'
import qbit from '@/services/qbit'
export default {
name: 'PluginsManager',
data: () =>({
opened: false
}),
computed: {
...mapState(['searchPlugins'])
},
methods: {
togglePlugin(plugin) {
qbit.enableSearchPlugin([plugin.name], plugin.enabled)
}
},
watch: {
opened() {
this.$store.commit('FETCH_SEARCH_PLUGINS')
}
}
}
</script>

View file

@ -0,0 +1,166 @@
<template>
<v-dialog
v-model="dialog"
scrollable
:width="dialogWidth"
:fullscreen="phoneLayout"
:style="{ height: phoneLayout ? '100vh' : '' }"
>
<v-card :style="{ height: phoneLayout ? '100vh' : '' }">
<v-card-title class="justify-center">
<h2>Search</h2>
</v-card-title>
<v-card-text>
<v-form
ref="form"
v-model="searchForm.valid"
>
<v-container fluid>
<v-flex row class="col-12 col-sm-6 col-md-8 mx-auto">
<v-text-field
v-model="searchForm.pattern"
prepend-inner-icon="mdi-magnify"
@keypress.enter="$refs.searchButton.click"
label="Search"
:rules="[v => !!v || 'Searchterm is required']"
clearable
style="width: 70%"
/>
<v-spacer/>
<v-btn
ref="searchButton"
:disabled="!searchForm.valid"
:color="loading ? 'warning' : 'primary'"
@click="loading ? stopSearch() : startSearch()"
>
{{ loading ? "Stop" : "Search"}}
</v-btn>
</v-flex>
</v-container>
</v-form>
<perfect-scrollbar>
<v-data-table
:headers="grid.headers"
:items="search.results"
:items-per-page="10"
:loading="loading"
:style="{ maxHeight: '60vh'}"
>
<template #[`item.fileName`]="{ item }">
<a
:href="item.descrLink"
target="_blank"
v-text="item.fileName"
/>
</template>
<template v-slot:[`item.fileSize`]="{ item }">
{{ item.fileSize | formatSize }}
</template>
<template v-slot:[`item.actions`]="{ item }">
<v-icon @click="downloadTorrent(item)">mdi-download</v-icon>
</template>
</v-data-table>
</perfect-scrollbar>
</v-card-text>
<v-card-actions>
<PluginManager/>
</v-card-actions>
<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 qbit from '@/services/qbit'
import { Modal, FullScreenModal, General } from '@/mixins'
import PluginManager from './PluginManager'
export default {
name: 'SearchModal',
components: { PluginManager },
mixins: [Modal, FullScreenModal, General],
data() {
return {
search: {
id: null,
status: null,
interval: null,
results: []
},
loading: false,
grid: {
headers: [
{ text: 'Name', value: 'fileName' },
{ text: 'Size', value: 'fileSize' },
{ text: 'Seeds', value: 'nbSeeders' },
{ text: 'Peers', value: 'nbLeechers' },
{ text: 'Search_engine', value: 'siteUrl' },
{ text: 'Action', value: 'actions', sortable: false }
]
},
searchForm: {
valid: false,
pattern: ''
}
}
},
computed: {
...mapGetters(['getSearchPlugins']),
dialogWidth() {
return this.phoneLayout ? '100%' : '60%'
},
enabledSearchPlugins() {
return this.getSearchPlugins().filter(p => p.enabled)
}
},
methods: {
async startSearch() {
if (this.searchForm.pattern.length && !this.search.interval) {
this.loading = true
this.search.status = 'Running'
this.search.results = []
const data = await qbit.startSearch(
this.searchForm.pattern,
this.enabledSearchPlugins.map(p => p.name)
)
this.search.id = data.id
await this.getStatus()
this.search.interval = setInterval(async () => {
const status = await this.getStatus()
if (status === 'Stopped') {
clearInterval(this.search.interval)
this.search.interval = null
await this.getResults()
}
}, 500)
}
},
async getStatus() {
if (this.search.id) {
const data = await qbit.getSearchStatus(this.search.id)
return (this.search.status = data[0].status)
}
},
async getResults() {
const data = await qbit.getSearchResults(this.search.id)
this.search.results = data.results
this.loading = false
},
downloadTorrent(item) {
this.createModal('addModal', { initialMagnet: item.fileUrl })
},
stopSearch() {
qbit.stopSearch(this.search.id)
},
close() {
this.$store.commit('DELETE_MODAL', this.guid)
}
}
}
</script>

View file

@ -144,7 +144,7 @@
</template>
<script>
import {SettingsTab, FullScreenModal} from '@/mixins'
import { SettingsTab, FullScreenModal } from '@/mixins'
export default {
name: 'BitTorrent',

View file

@ -69,7 +69,7 @@
</template>
<script>
import {FullScreenModal, SettingsTab} from '@/mixins'
import { FullScreenModal, SettingsTab } from '@/mixins'
export default {
name: 'Downloads',

View file

@ -77,7 +77,7 @@ import { mapGetters } from 'vuex'
import qbit from '@/services/qbit'
import { Tab, General,FullScreenModal } from '@/mixins'
import { Tab, General, FullScreenModal } from '@/mixins'
export default {
name: 'TagsAndCategories',

View file

@ -23,7 +23,7 @@
<script>
import General from './Vuetorrent/General'
import Dashboard from './Vuetorrent/Dashboard'
import {FullScreenModal} from '@/mixins'
import { FullScreenModal } from '@/mixins'
export default {
name: 'VueTorrent',
@ -31,7 +31,7 @@ export default {
General, Dashboard
},
mixins: [FullScreenModal],
data : () => ({
data: () => ({
tab: null
}),
methods: {
@ -40,4 +40,4 @@ export default {
}
}
}
</script>
</script>

View file

@ -65,11 +65,11 @@ export default {
components: {
draggable
},
computed : {
busyTorrentProperties(){
computed: {
busyTorrentProperties() {
return this.$store.state.webuiSettings.busyTorrentProperties
},
doneTorrentProperties(){
doneTorrentProperties() {
return this.$store.state.webuiSettings.doneTorrentProperties
}
}
@ -78,4 +78,4 @@ export default {
<style lang="scss" scoped>
@import '@/assets/styles/SettingsTab.scss';
</style>
</style>

View file

@ -172,8 +172,8 @@ export default {
return this.getAppVersion()
}
},
methods : {
async fetchQbitVersion(){
methods: {
async fetchQbitVersion() {
this.Qbitversion = await qbit.getAppVersion()
}
},

View file

@ -55,7 +55,7 @@
</template>
<script>
import {FullScreenModal, SettingsTab} from '@/mixins'
import { FullScreenModal, SettingsTab } from '@/mixins'
export default {
name: 'WebUI',

View file

@ -114,12 +114,15 @@ export default {
.filter(f => f.priority === 0)
.map(f => f.id)
if (filesToExclude.length)
if (filesToExclude.length) {
await qbit.setTorrentFilePriority(this.hash, filesToExclude, 0)
if (filesToInclude.length)
}
if (filesToInclude.length) {
await qbit.setTorrentFilePriority(this.hash, filesToInclude, 1)
if (filesToExclude.length || filesToInclude.length)
}
if (filesToExclude.length || filesToInclude.length) {
await this.getTorrentFiles()
}
},
togleEditing(item) {
item.editing = !item.editing

View file

@ -114,8 +114,8 @@ export default {
return this.getTorrent(this.hash)
},
availableTags() {
let availableTags = this.getAvailableTags()
let currentTags = this.getTorrent(this.hash).tags
const availableTags = this.getAvailableTags()
const currentTags = this.getTorrent(this.hash).tags
return difference(availableTags, currentTags)
},
availableCategories() {