mirror of
https://github.com/VueTorrent/VueTorrent.git
synced 2025-03-14 12:10:18 +03:00
torrent right click menu
This commit is contained in:
parent
04975e1ce4
commit
7819abb1e7
10 changed files with 295 additions and 207 deletions
36
README.md
36
README.md
|
@ -20,28 +20,28 @@ The sleekest looking WEBUI for qBittorrent made with Vuejs!
|
|||
|
||||
## Installation
|
||||
|
||||
- Download & Unzip the latest release
|
||||
- Download & Unzip the latest release
|
||||
|
||||
- Point your Alternate WEBUI location to it
|
||||
- Point your Alternate WEBUI location to it
|
||||
|
||||
## Development
|
||||
|
||||
- clone the repo
|
||||
- clone the repo
|
||||
|
||||
- npm install
|
||||
- npm install
|
||||
|
||||
- npm run serve
|
||||
- npm run serve
|
||||
|
||||
## Features
|
||||
|
||||
- viewing sessions stats ( down / upload speed, session uploaded / downloaded )
|
||||
- adding / removing / pausing / resuming torrents
|
||||
- viewing sessions status ( down / upload speed, session uploaded / downloaded )
|
||||
- adding / removing / pausing / resuming torrents
|
||||
|
||||
- sorting by every property shown!
|
||||
- sorting by every property shown!
|
||||
|
||||
* mobile friendly! (maybe not for thousands of torrents...)
|
||||
* mobile friendly! (maybe not for thousands of torrents...)
|
||||
|
||||
- works on QBittorrent V4.2 and later
|
||||
- works on QBittorrent V4.2 and later
|
||||
|
||||
## Contributing
|
||||
|
||||
|
@ -49,23 +49,23 @@ I'll gladly accept help/pull requests & advice! (this is my first project of thi
|
|||
|
||||
## FAQ
|
||||
|
||||
- **Why build this??**
|
||||
- **Why build this??**
|
||||
|
||||
* Why not? Most WebUI's look very dated and now it's no longer necessary to search for a remote control app!
|
||||
* Why not? Most WebUI's look very dated and now it's no longer necessary to search for a remote control app!
|
||||
|
||||
## Support
|
||||
|
||||
Reach out to me at one of the following places!
|
||||
|
||||
- <a href="https://m.me/WijnsDaan" target="_blank">`Facebook Messenger`</a>
|
||||
- <a href="https://m.me/WijnsDaan" target="_blank">`Facebook Messenger`</a>
|
||||
|
||||
* Open up an issue 😛
|
||||
* Open up an issue 😛
|
||||
|
||||
[<img src="https://cdn.buymeacoffee.com/buttons/lato-blue.png" alt="drawing" width="180"/>](https://www.buymeacoffee.com/wdaan 'Buy me a coffee')
|
||||
[<img src="https://cdn.buymeacoffee.com/buttons/lato-blue.png" alt="drawing" width="180"/>](https://www.buymeacoffee.com/wdaan "Buy me a coffee")
|
||||
|
||||
## Credits
|
||||
|
||||
- Dashboard design heavily inspired by: '[Net Ninja - Vuetify](https://github.com/iamshaunjp/vuetify-playlist)'.
|
||||
Also check out The Net Ninja's Youtube Channel.
|
||||
- Dashboard design heavily inspired by: '[Net Ninja - Vuetify](https://github.com/iamshaunjp/vuetify-playlist)'.
|
||||
Also check out The Net Ninja's Youtube Channel.
|
||||
|
||||
* This repo '[CzBiX qb-web ](https://github.com/CzBiX/qb-web)'
|
||||
* This repo '[CzBiX qb-web ](https://github.com/CzBiX/qb-web)'
|
||||
|
|
20
package-lock.json
generated
20
package-lock.json
generated
|
@ -6455,8 +6455,7 @@
|
|||
"js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "3.13.1",
|
||||
|
@ -6763,7 +6762,6 @@
|
|||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||
}
|
||||
|
@ -10789,6 +10787,22 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"vue-clickaway": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/vue-clickaway/-/vue-clickaway-2.2.2.tgz",
|
||||
"integrity": "sha512-25SpjXKetL06GLYoLoC8pqAV6Cur9cQ//2g35GRFBV4FgoljbZZjTINR8g2NuVXXDMLSUXaKx5dutgO4PaDE7A==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"vue-context": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/vue-context/-/vue-context-5.1.0.tgz",
|
||||
"integrity": "sha512-PcKbc9mjiUt4fswRR/oA/IJc5oXHjpnKIcATWZcBTDk7CzTvLznkIjq6pGFI8vUtGzABxVMvPq93dpBSRfinxg==",
|
||||
"requires": {
|
||||
"vue-clickaway": "^2.2.2"
|
||||
}
|
||||
},
|
||||
"vue-eslint-parser": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.1.0.tgz",
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
"register-service-worker": "^1.7.1",
|
||||
"vue": "^2.6.11",
|
||||
"vue-apexcharts": "^1.5.3",
|
||||
"vue-context": "^5.1.0",
|
||||
"vue-observe-visibility": "^0.4.6",
|
||||
"vue-router": "^3.2.0",
|
||||
"vue-toastification": "^1.7.1",
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
<!--navigation drawer itself -->
|
||||
<v-navigation-drawer app v-model="drawer" class="primary" style="position:fixed;">
|
||||
<!--current download speeds -->
|
||||
<v-flex class="mt-3" v-if="stats">
|
||||
<v-flex class="mt-3" v-if="status">
|
||||
<div
|
||||
class="secondary_lighter--text text-uppercase caption ml-4"
|
||||
>
|
||||
|
@ -56,14 +56,14 @@
|
|||
<v-icon color="download">keyboard_arrow_down</v-icon>
|
||||
<span class="download--text title">
|
||||
{{
|
||||
stats.dlspeed.substring(
|
||||
status.dlspeed.substring(
|
||||
0,
|
||||
stats.dlspeed.indexOf(' ')
|
||||
status.dlspeed.indexOf(' ')
|
||||
)
|
||||
}}
|
||||
<span class="font-weight-light caption">{{
|
||||
stats.dlspeed.substring(
|
||||
stats.dlspeed.indexOf(' ')
|
||||
status.dlspeed.substring(
|
||||
status.dlspeed.indexOf(' ')
|
||||
)
|
||||
}}</span>
|
||||
</span>
|
||||
|
@ -72,14 +72,14 @@
|
|||
>
|
||||
<span class="upload--text title">
|
||||
{{
|
||||
stats.upspeed.substring(
|
||||
status.upspeed.substring(
|
||||
0,
|
||||
stats.upspeed.indexOf(' ')
|
||||
status.upspeed.indexOf(' ')
|
||||
)
|
||||
}}
|
||||
<span class="font-weight-light caption">{{
|
||||
stats.upspeed.substring(
|
||||
stats.upspeed.indexOf(' ')
|
||||
status.upspeed.substring(
|
||||
status.upspeed.indexOf(' ')
|
||||
)
|
||||
}}</span>
|
||||
</span>
|
||||
|
@ -98,7 +98,7 @@
|
|||
<div
|
||||
class="secondary_lighter--text text-uppercase caption ml-4"
|
||||
>
|
||||
session stats
|
||||
session status
|
||||
</div>
|
||||
<v-card flat color="secondary" class="mr-2 ml-2">
|
||||
<v-layout row wrap class="pa-3 project nav_download mx-auto">
|
||||
|
@ -108,14 +108,14 @@
|
|||
<v-flex md5 class="ml-4">
|
||||
<span class="download--text title">
|
||||
{{
|
||||
stats.downloaded.substring(
|
||||
status.downloaded.substring(
|
||||
0,
|
||||
stats.downloaded.indexOf(' ')
|
||||
status.downloaded.indexOf(' ')
|
||||
)
|
||||
}}
|
||||
<span class="font-weight-light caption">{{
|
||||
stats.downloaded.substring(
|
||||
stats.downloaded.indexOf(' ')
|
||||
status.downloaded.substring(
|
||||
status.downloaded.indexOf(' ')
|
||||
)
|
||||
}}</span>
|
||||
</span>
|
||||
|
@ -130,14 +130,14 @@
|
|||
<v-flex md5 class="ml-4">
|
||||
<span class="upload--text title">
|
||||
{{
|
||||
stats.uploaded.substring(
|
||||
status.uploaded.substring(
|
||||
0,
|
||||
stats.uploaded.indexOf(' ')
|
||||
status.uploaded.indexOf(' ')
|
||||
)
|
||||
}}
|
||||
<span class="font-weight-light caption">{{
|
||||
stats.uploaded.substring(
|
||||
stats.uploaded.indexOf(' ')
|
||||
status.uploaded.substring(
|
||||
status.uploaded.indexOf(' ')
|
||||
)
|
||||
}}</span>
|
||||
</span>
|
||||
|
@ -153,14 +153,14 @@
|
|||
<v-flex md5 class="ml-4">
|
||||
<span class="upload--text title">
|
||||
{{
|
||||
stats.freeDiskSpace.substring(
|
||||
status.freeDiskSpace.substring(
|
||||
0,
|
||||
stats.freeDiskSpace.indexOf(' ')
|
||||
status.freeDiskSpace.indexOf(' ')
|
||||
)
|
||||
}}
|
||||
<span class="font-weight-light caption">{{
|
||||
stats.freeDiskSpace.substring(
|
||||
stats.freeDiskSpace.indexOf(' ')
|
||||
status.freeDiskSpace.substring(
|
||||
status.freeDiskSpace.indexOf(' ')
|
||||
)
|
||||
}}</span>
|
||||
</span>
|
||||
|
@ -294,13 +294,13 @@ export default {
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['stats', 'selected_torrents']),
|
||||
...mapGetters(['getTheme', 'getStats']),
|
||||
...mapState(['status', 'selected_torrents']),
|
||||
...mapGetters(['getTheme', 'getStatus']),
|
||||
theme() {
|
||||
return this.getTheme() ? 'Dark' : 'Light'
|
||||
},
|
||||
altSpeed(){
|
||||
return this.getStats().altSpeed
|
||||
return this.getStatus().altSpeed
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
|
|
@ -1,172 +1,170 @@
|
|||
<template>
|
||||
<v-card ripple flat class="pointer torrent"
|
||||
<v-card
|
||||
ripple
|
||||
flat
|
||||
class="pointer torrent"
|
||||
:class="containsTorrent(torrent.hash) ? 'torrent_selected' : ''"
|
||||
@click.native="selectTorrent(torrent.hash)">
|
||||
<v-layout row wrap :class="`pa-4 ml-0 project ${torrent.state}`">
|
||||
<v-flex xs12 sm2 md3>
|
||||
<div class="caption grey--text">Torrent title</div>
|
||||
<div class="truncate">{{ torrent.name }}</div>
|
||||
</v-flex>
|
||||
<v-flex xs6 sm1 md1 class="mr-2">
|
||||
<div class="caption grey--text">Size</div>
|
||||
<div>
|
||||
{{
|
||||
torrent.size.substring(
|
||||
0,
|
||||
torrent.size.indexOf(' ')
|
||||
)
|
||||
}}
|
||||
<span class="caption grey--text">{{
|
||||
torrent.size.substring(
|
||||
torrent.size.indexOf(' ')
|
||||
)
|
||||
}}</span>
|
||||
</div>
|
||||
</v-flex>
|
||||
<v-flex xs5 sm1 md1 class="mr-2">
|
||||
<div class="caption grey--text">Done</div>
|
||||
<div>
|
||||
{{
|
||||
torrent.dloaded.substring(
|
||||
0,
|
||||
torrent.dloaded.indexOf(' ')
|
||||
)
|
||||
}}
|
||||
<span class="caption grey--text">{{
|
||||
torrent.dloaded.substring(
|
||||
torrent.dloaded.indexOf(' ')
|
||||
)
|
||||
}}</span>
|
||||
</div>
|
||||
</v-flex>
|
||||
<v-flex xs6 sm1 md1 class="mr-2">
|
||||
<div class="caption grey--text">Download</div>
|
||||
<div>
|
||||
{{
|
||||
torrent.dlspeed.substring(
|
||||
0,
|
||||
torrent.dlspeed.indexOf(' ')
|
||||
)
|
||||
}}
|
||||
<span class="caption grey--text">{{
|
||||
torrent.dlspeed.substring(
|
||||
torrent.dlspeed.indexOf(' ')
|
||||
)
|
||||
}}</span>
|
||||
</div>
|
||||
</v-flex>
|
||||
<v-flex xs5 sm1 md1 class="mr-2">
|
||||
<div class="caption grey--text">Upload</div>
|
||||
<div>
|
||||
{{
|
||||
torrent.upspeed.substring(
|
||||
0,
|
||||
torrent.upspeed.indexOf(' ')
|
||||
)
|
||||
}}
|
||||
<span class="caption grey--text">{{
|
||||
torrent.upspeed.substring(
|
||||
torrent.upspeed.indexOf(' ')
|
||||
)
|
||||
}}</span>
|
||||
</div>
|
||||
</v-flex>
|
||||
<v-flex xs6 sm1 md1 class="mr-2">
|
||||
<div class="caption grey--text">ETA</div>
|
||||
<div>{{ torrent.eta }}</div>
|
||||
</v-flex>
|
||||
<v-flex xs5 sm1 md1 class="mr-2">
|
||||
<div class="caption grey--text">Peers</div>
|
||||
<div>
|
||||
{{ torrent.num_leechs }}
|
||||
<span class="grey--text caption"
|
||||
>/{{ torrent.available_peers }}</span
|
||||
>
|
||||
</div>
|
||||
</v-flex>
|
||||
<v-flex xs5 sm1 md1 class="mr-2">
|
||||
<div class="caption grey--text">Seeds</div>
|
||||
<div>
|
||||
{{ torrent.num_seeds }}
|
||||
<span class="grey--text caption"
|
||||
>/{{ torrent.available_seeds }}</span
|
||||
>
|
||||
</div>
|
||||
</v-flex>
|
||||
<v-flex xs4 sm12 md1>
|
||||
<div class="right">
|
||||
<v-chip
|
||||
small
|
||||
:class="
|
||||
`${torrent.state} white--text my-2 caption`
|
||||
"
|
||||
>{{ torrent.state }}</v-chip
|
||||
>
|
||||
</div>
|
||||
</v-flex>
|
||||
<v-flex xs12 sm12 md12>
|
||||
<v-progress-linear
|
||||
height="3"
|
||||
color="cyan darken-1"
|
||||
background-color="cyan lighten-3"
|
||||
:value="(torrent.dloaded / torrent.size) * 100"
|
||||
></v-progress-linear>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
<v-divider></v-divider>
|
||||
</v-card>
|
||||
@click.native="selectTorrent(torrent.hash)"
|
||||
>
|
||||
<v-tooltip top>
|
||||
<template v-slot:activator="{ on }">
|
||||
<v-layout
|
||||
@contextmenu.prevent="$refs.menu.open"
|
||||
v-on="on"
|
||||
row
|
||||
wrap
|
||||
:class="`pa-4 ml-0 project ${torrent.state}`"
|
||||
>
|
||||
<v-flex xs12 sm2 md3>
|
||||
<div class="caption grey--text">Torrent title</div>
|
||||
<div class="truncate">{{ torrent.name }}</div>
|
||||
</v-flex>
|
||||
<v-flex xs6 sm1 md1 class="mr-2">
|
||||
<div class="caption grey--text">Size</div>
|
||||
<div>
|
||||
{{ torrent.size.substring(0, torrent.size.indexOf(" ")) }}
|
||||
<span class="caption grey--text">{{
|
||||
torrent.size.substring(torrent.size.indexOf(" "))
|
||||
}}</span>
|
||||
</div>
|
||||
</v-flex>
|
||||
<v-flex xs5 sm1 md1 class="mr-2">
|
||||
<div class="caption grey--text">Done</div>
|
||||
<div>
|
||||
{{ torrent.dloaded.substring(0, torrent.dloaded.indexOf(" ")) }}
|
||||
<span class="caption grey--text">{{
|
||||
torrent.dloaded.substring(torrent.dloaded.indexOf(" "))
|
||||
}}</span>
|
||||
</div>
|
||||
</v-flex>
|
||||
<v-flex xs6 sm1 md1 class="mr-2">
|
||||
<div class="caption grey--text">Download</div>
|
||||
<div>
|
||||
{{ torrent.dlspeed.substring(0, torrent.dlspeed.indexOf(" ")) }}
|
||||
<span class="caption grey--text">{{
|
||||
torrent.dlspeed.substring(torrent.dlspeed.indexOf(" "))
|
||||
}}</span>
|
||||
</div>
|
||||
</v-flex>
|
||||
<v-flex xs5 sm1 md1 class="mr-2">
|
||||
<div class="caption grey--text">Upload</div>
|
||||
<div>
|
||||
{{ torrent.upspeed.substring(0, torrent.upspeed.indexOf(" ")) }}
|
||||
<span class="caption grey--text">{{
|
||||
torrent.upspeed.substring(torrent.upspeed.indexOf(" "))
|
||||
}}</span>
|
||||
</div>
|
||||
</v-flex>
|
||||
<v-flex xs6 sm1 md1 class="mr-2">
|
||||
<div class="caption grey--text">ETA</div>
|
||||
<div>{{ torrent.eta }}</div>
|
||||
</v-flex>
|
||||
<v-flex xs5 sm1 md1 class="mr-2">
|
||||
<div class="caption grey--text">Peers</div>
|
||||
<div>
|
||||
{{ torrent.num_leechs }}
|
||||
<span class="grey--text caption"
|
||||
>/{{ torrent.available_peers }}</span
|
||||
>
|
||||
</div>
|
||||
</v-flex>
|
||||
<v-flex xs5 sm1 md1 class="mr-2">
|
||||
<div class="caption grey--text">Seeds</div>
|
||||
<div>
|
||||
{{ torrent.num_seeds }}
|
||||
<span class="grey--text caption"
|
||||
>/{{ torrent.available_seeds }}</span
|
||||
>
|
||||
</div>
|
||||
</v-flex>
|
||||
<v-flex xs4 sm12 md1>
|
||||
<div class="right">
|
||||
<v-chip
|
||||
small
|
||||
:class="`${torrent.state} white--text my-2 caption`"
|
||||
>{{ torrent.state }}</v-chip
|
||||
>
|
||||
</div>
|
||||
</v-flex>
|
||||
<v-flex xs12 sm12 md12>
|
||||
<v-progress-linear
|
||||
height="3"
|
||||
color="cyan darken-1"
|
||||
background-color="cyan lighten-3"
|
||||
:value="(torrent.dloaded / torrent.size) * 100"
|
||||
></v-progress-linear>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</template>
|
||||
<span>{{ torrent.name }}</span>
|
||||
</v-tooltip>
|
||||
<v-divider></v-divider>
|
||||
|
||||
<vue-context ref="menu">
|
||||
<torrentRightClickMenu :hash="torrent.hash" />
|
||||
</vue-context>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { VueContext } from "vue-context";
|
||||
import torrentRightClickMenu from "@/components/Torrent/torrentRightClickMenu.vue";
|
||||
|
||||
export default {
|
||||
name:'Torrent',
|
||||
props: {
|
||||
torrent: Object
|
||||
},
|
||||
methods: {selectTorrent(hash) {
|
||||
if (this.containsTorrent(hash)) {
|
||||
this.$store.commit('SET_SELECTED', {type:"remove", hash})
|
||||
name: "Torrent",
|
||||
components: {
|
||||
VueContext,
|
||||
torrentRightClickMenu,
|
||||
},
|
||||
props: {
|
||||
torrent: Object,
|
||||
},
|
||||
methods: {
|
||||
selectTorrent(hash) {
|
||||
if (this.containsTorrent(hash)) {
|
||||
this.$store.commit("SET_SELECTED", { type: "remove", hash });
|
||||
} else {
|
||||
this.$store.commit('SET_SELECTED', {type:"add", hash})
|
||||
this.$store.commit("SET_SELECTED", { type: "add", hash });
|
||||
}
|
||||
},
|
||||
containsTorrent(hash) {
|
||||
return this.$store.getters.containsTorrent(hash)
|
||||
},}
|
||||
}
|
||||
},
|
||||
containsTorrent(hash) {
|
||||
return this.$store.getters.containsTorrent(hash);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.project.done {
|
||||
border-left: 4px solid #3cd1c2;
|
||||
border-left: 4px solid #3cd1c2;
|
||||
}
|
||||
.project.busy {
|
||||
border-left: 4px solid #ffaa2c;
|
||||
border-left: 4px solid #ffaa2c;
|
||||
}
|
||||
.project.fail {
|
||||
border-left: 4px solid #f83e70;
|
||||
border-left: 4px solid #f83e70;
|
||||
}
|
||||
.project.paused {
|
||||
border-left: 4px solid #cfd8dc;
|
||||
border-left: 4px solid #cfd8dc;
|
||||
}
|
||||
.v-chip.done {
|
||||
background: #3cd1c2 !important;
|
||||
background: #3cd1c2 !important;
|
||||
}
|
||||
.v-chip.busy {
|
||||
background: #ffaa2c !important;
|
||||
background: #ffaa2c !important;
|
||||
}
|
||||
.v-chip.fail {
|
||||
background: #f83e70 !important;
|
||||
background: #f83e70 !important;
|
||||
}
|
||||
.v-chip.paused {
|
||||
background: #cfd8dc !important;
|
||||
background: #cfd8dc !important;
|
||||
}
|
||||
.pointer {
|
||||
cursor: pointer;
|
||||
cursor: pointer;
|
||||
}
|
||||
.truncate {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
.truncate {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
</style>
|
||||
|
|
69
src/components/Torrent/torrentRightClickMenu.vue
Normal file
69
src/components/Torrent/torrentRightClickMenu.vue
Normal file
|
@ -0,0 +1,69 @@
|
|||
<template>
|
||||
<v-card
|
||||
elevation="20"
|
||||
width="200"
|
||||
style="position:absolute; top: 50%; left:50% ;z-index: 10; overflow: show"
|
||||
:dark="dark"
|
||||
>
|
||||
<v-list dense rounded>
|
||||
<v-list-item @click="resume" link>
|
||||
<v-icon>play_arrow</v-icon>
|
||||
<v-list-item-title class="ml-2" style="font-size:15px;">Resume</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item @click="pause" link>
|
||||
<v-icon>pause</v-icon>
|
||||
<v-list-item-title class="ml-2" style="font-size:15px;">Pause</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-divider/>
|
||||
<v-list-item @click="reannounce" link>
|
||||
<v-icon>record_voice_over</v-icon>
|
||||
<v-list-item-title class="ml-2" style="font-size:15px;">reannounce</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-divider/>
|
||||
<v-list-item @click="deleteWithoutFiles" link>
|
||||
<v-icon color="red">delete</v-icon>
|
||||
<v-list-item-title class="ml-2" style="font-size:15px; color:red">Delete</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item @click="deleteWithFiles" link>
|
||||
<v-icon color="red">delete</v-icon>
|
||||
<v-list-item-title class="ml-2" style="font-size:15px; color:red;">Delete with files</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import qbit from '@/services/qbit'
|
||||
export default {
|
||||
name: 'torrentRightClickMenu',
|
||||
props: {
|
||||
hash: String
|
||||
},
|
||||
methods: {
|
||||
resume(){
|
||||
qbit.resumeTorrents([this.hash])
|
||||
},
|
||||
pause(){
|
||||
qbit.pauseTorrents([this.hash])
|
||||
},
|
||||
reannounce(){
|
||||
qbit.reannounceTorrents([this.hash])
|
||||
},
|
||||
deleteWithoutFiles(){
|
||||
qbit.deleteTorrents([this.hash], false)
|
||||
},
|
||||
deleteWithFiles(){
|
||||
qbit.deleteTorrents([this.hash], true)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
dark() {
|
||||
return this.$vuetify.dark
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
|
@ -1,4 +1,4 @@
|
|||
export default class Stat {
|
||||
export default class Status {
|
||||
constructor(data) {
|
||||
if (data != undefined && data != null) {
|
||||
this.status = data.connection_status
|
|
@ -2,7 +2,7 @@ import Vue from 'vue'
|
|||
import Router from 'vue-router'
|
||||
import Dashboard from '@/views/Dashboard.vue'
|
||||
import Login from '@/views/Login.vue'
|
||||
import store from '@/store'
|
||||
import {isAuthenticated} from '@/services/auth.js'
|
||||
|
||||
Vue.use(Router)
|
||||
|
||||
|
@ -28,12 +28,12 @@ const router = new Router({
|
|||
})
|
||||
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
router.beforeEach(async(to, from, next) => {
|
||||
const isPublic = to.matched.some(record => record.meta.public)
|
||||
const onlyWhenLoggedOut = to.matched.some(record => record.meta.onlyWhenLoggedOut)
|
||||
const loggedIn = store.state.authenticated
|
||||
const authenticated = await isAuthenticated();
|
||||
|
||||
if (!isPublic && !loggedIn) {
|
||||
if (!isPublic && !authenticated) {
|
||||
return next({
|
||||
path:'/login',
|
||||
query: {redirect: to.fullPath} // Store the full path to redirect the user to after login
|
||||
|
@ -41,7 +41,7 @@ router.beforeEach((to, from, next) => {
|
|||
}
|
||||
|
||||
// Do not allow user to visit login page or register page if they are logged in
|
||||
if (loggedIn && onlyWhenLoggedOut) {
|
||||
if (authenticated && onlyWhenLoggedOut) {
|
||||
return next('/')
|
||||
}
|
||||
|
||||
|
|
6
src/services/auth.js
Normal file
6
src/services/auth.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
import qbit from '@/services/qbit'
|
||||
|
||||
export async function isAuthenticated(){
|
||||
const res = await qbit.login()
|
||||
return res === 'Ok.'
|
||||
}
|
|
@ -3,7 +3,7 @@ import Vuex from 'vuex'
|
|||
import VuexPersist from 'vuex-persist'
|
||||
|
||||
import Torrent from '../models/torrent'
|
||||
import Stat from '../models/sessionStat'
|
||||
import Status from '../models/Status'
|
||||
import qbit from '../services/qbit'
|
||||
|
||||
const vuexPersist = new VuexPersist({
|
||||
|
@ -18,7 +18,7 @@ export default new Vuex.Store({
|
|||
state: {
|
||||
darkTheme: false,
|
||||
intervals: [],
|
||||
stats: null,
|
||||
status: null,
|
||||
upload_data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
download_data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
torrents: [],
|
||||
|
@ -43,7 +43,7 @@ export default new Vuex.Store({
|
|||
getTheme: state => () => state.darkTheme,
|
||||
getModalState: state => name => state.modals[name.toLowerCase()],
|
||||
getSettings: state => () => state.settings,
|
||||
getStats: state => () => state.stats
|
||||
getStatus: state => () => state.status
|
||||
},
|
||||
|
||||
mutations: {
|
||||
|
@ -88,37 +88,37 @@ export default new Vuex.Store({
|
|||
state.torrents.push(new Torrent({ hash: key, ...value }))
|
||||
}
|
||||
|
||||
// stats
|
||||
state.stats = new Stat(data.server_state)
|
||||
// status
|
||||
state.status = new Status(data.server_state)
|
||||
|
||||
// graph
|
||||
|
||||
state.download_data.splice(0, 1)
|
||||
if (state.stats.dlspeed.indexOf('KB' > -1)) {
|
||||
if (state.status.dlspeed.indexOf('KB' > -1)) {
|
||||
state.download_data.push(
|
||||
state.stats.dlspeed.substring(
|
||||
state.status.dlspeed.substring(
|
||||
0,
|
||||
state.stats.dlspeed.indexOf(' ')
|
||||
state.status.dlspeed.indexOf(' ')
|
||||
) / 1000
|
||||
)
|
||||
} else {
|
||||
state.download_data.push(
|
||||
state.stats.dlspeed(0, state.stats.dlspeed.indexOf(' '))
|
||||
state.status.dlspeed(0, state.status.dlspeed.indexOf(' '))
|
||||
)
|
||||
}
|
||||
state.upload_data.splice(0, 1)
|
||||
if (state.stats.upspeed.indexOf('KB' > -1)) {
|
||||
if (state.status.upspeed.indexOf('KB' > -1)) {
|
||||
state.upload_data.push(
|
||||
state.stats.upspeed.substring(
|
||||
state.status.upspeed.substring(
|
||||
0,
|
||||
state.stats.upspeed.indexOf(' ')
|
||||
state.status.upspeed.indexOf(' ')
|
||||
) / 1000
|
||||
)
|
||||
} else {
|
||||
state.upload_data.push(
|
||||
state.stats.upspeed.substring(
|
||||
state.status.upspeed.substring(
|
||||
0,
|
||||
state.stats.upspeed.indexOf(' ')
|
||||
state.status.upspeed.indexOf(' ')
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue