mirror of
https://github.com/VueTorrent/VueTorrent.git
synced 2025-03-29 21:11:51 +03:00
0.5.4 (#119)
This commit is contained in:
parent
8a8b7e9d62
commit
c4329ce2b9
30 changed files with 6331 additions and 782 deletions
15
.eslintrc.js
15
.eslintrc.js
|
@ -69,5 +69,16 @@ module.exports = {
|
||||||
'arrow-spacing': ['error', { before: true, after: true }],
|
'arrow-spacing': ['error', { before: true, after: true }],
|
||||||
'no-multi-spaces': ['error'],
|
'no-multi-spaces': ['error'],
|
||||||
'newline-before-return': ['error']
|
'newline-before-return': ['error']
|
||||||
}
|
},
|
||||||
}
|
overrides: [
|
||||||
|
{
|
||||||
|
files: [
|
||||||
|
'**/__tests__/*.{j,t}s?(x)',
|
||||||
|
'**/tests/unit/**/*.spec.{j,t}s?(x)'
|
||||||
|
],
|
||||||
|
env: {
|
||||||
|
jest: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
25
.github/workflows/test.yml
vendored
Normal file
25
.github/workflows/test.yml
vendored
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
name: Test Core Components
|
||||||
|
on:
|
||||||
|
push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test-core:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@master
|
||||||
|
- name: Cache node modules
|
||||||
|
uses: actions/cache@v2
|
||||||
|
env:
|
||||||
|
cache-name: cache-node-modules
|
||||||
|
with:
|
||||||
|
# npm cache files are stored in `~/.npm` on Linux/macOS
|
||||||
|
path: ~/.npm
|
||||||
|
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-build-${{ env.cache-name }}-
|
||||||
|
${{ runner.os }}-build-
|
||||||
|
${{ runner.os }}-
|
||||||
|
- name: Install & test
|
||||||
|
uses: actions/setup-node@master
|
||||||
|
- run: npm ci
|
||||||
|
- run: npm run test:unit
|
5
babel.config.js
Normal file
5
babel.config.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
module.exports = {
|
||||||
|
presets: [
|
||||||
|
'@vue/app'
|
||||||
|
]
|
||||||
|
}
|
8
jest.config.js
Normal file
8
jest.config.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
module.exports = {
|
||||||
|
preset: '@vue/cli-plugin-unit-jest',
|
||||||
|
moduleFileExtensions: ['js', 'json', 'vue'],
|
||||||
|
transform: {
|
||||||
|
'.*\\.(vue)$': 'vue-jest',
|
||||||
|
'^.+\\.js$': '<rootDir>/node_modules/babel-jest'
|
||||||
|
}
|
||||||
|
}
|
6322
package-lock.json
generated
6322
package-lock.json
generated
File diff suppressed because it is too large
Load diff
121
package.json
121
package.json
|
@ -1,61 +1,64 @@
|
||||||
{
|
{
|
||||||
"name": "vuetorrent",
|
"name": "vuetorrent",
|
||||||
"version": "0.5.3",
|
"version": "0.5.4",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "npm run serve",
|
"serve": "vue-cli-service serve",
|
||||||
"serve": "vue-cli-service serve",
|
"build": "vue-cli-service build",
|
||||||
"build": "vue-cli-service build",
|
"test:unit": "vue-cli-service test:unit --setupTestFrameworkScriptFile=./tests/setup.js",
|
||||||
"lint": "vue-cli-service lint"
|
"lint": "vue-cli-service lint",
|
||||||
},
|
"start": "npm run serve"
|
||||||
"dependencies": {
|
},
|
||||||
"@babel/polyfill": "^7.12.1",
|
"dependencies": {
|
||||||
"apexcharts": "^3.23.1",
|
"@babel/polyfill": "^7.12.1",
|
||||||
"axios": "^0.21.1",
|
"apexcharts": "^3.23.1",
|
||||||
"core-js": "^3.8.3",
|
"axios": "^0.21.1",
|
||||||
"dayjs": "^1.10.4",
|
"core-js": "^3.8.3",
|
||||||
"fuse.js": "^6.4.6",
|
"dayjs": "^1.10.4",
|
||||||
"lodash": "^4.17.20",
|
"fuse.js": "^6.4.6",
|
||||||
"register-service-worker": "^1.7.2",
|
"lodash": "^4.17.20",
|
||||||
"typeface-roboto": "^1.1.13",
|
"register-service-worker": "^1.7.2",
|
||||||
"typeface-roboto-mono": "^1.1.13",
|
"typeface-roboto": "^1.1.13",
|
||||||
"uuid": "^8.3.2",
|
"typeface-roboto-mono": "^1.1.13",
|
||||||
"vue": "^2.6.12",
|
"uuid": "^8.3.2",
|
||||||
"vue-apexcharts": "^1.6.0",
|
"vue": "^2.6.12",
|
||||||
"vue-context": "^5.2.0",
|
"vue-apexcharts": "^1.6.0",
|
||||||
"vue-observe-visibility": "^0.4.6",
|
"vue-context": "^5.2.0",
|
||||||
"vue-router": "^3.4.9",
|
"vue-router": "^3.4.9",
|
||||||
"vue-toastification": "^1.7.11",
|
"vue-toastification": "^1.7.11",
|
||||||
"vue2-perfect-scrollbar": "^1.5.0",
|
"vue2-perfect-scrollbar": "^1.5.0",
|
||||||
"vuedraggable": "^2.24.3",
|
"vuedraggable": "^2.24.3",
|
||||||
"vuetify": "^2.4.3",
|
"vuetify": "^2.4.3",
|
||||||
"vuex": "^3.6.0",
|
"vuex": "^3.6.0",
|
||||||
"vuex-persist": "^3.1.3"
|
"vuex-persist": "^3.1.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@mdi/js": "^5.9.55",
|
"@mdi/js": "^5.9.55",
|
||||||
"@vue/cli-plugin-babel": "~4.3.0",
|
"@vue/babel-preset-app": "^4.5.11",
|
||||||
"@vue/cli-plugin-eslint": "~4.3.0",
|
"@vue/cli-plugin-babel": "~4.3.0",
|
||||||
"@vue/cli-plugin-pwa": "^4.5.11",
|
"@vue/cli-plugin-eslint": "~4.3.0",
|
||||||
"@vue/cli-service": "~4.3.0",
|
"@vue/cli-plugin-pwa": "^4.5.11",
|
||||||
"@vue/eslint-config-prettier": "^6.0.0",
|
"@vue/cli-plugin-unit-jest": "^4.5.11",
|
||||||
"babel-eslint": "^10.1.0",
|
"@vue/cli-service": "~4.3.0",
|
||||||
"eslint": "^7.18.0",
|
"@vue/eslint-config-prettier": "^6.0.0",
|
||||||
"eslint-config-google": "^0.14.0",
|
"@vue/test-utils": "^1.0.3",
|
||||||
"eslint-plugin-prettier": "^3.3.1",
|
"babel-eslint": "^10.1.0",
|
||||||
"eslint-plugin-vue": "^7.5.0",
|
"eslint": "^7.18.0",
|
||||||
"fibers": "^5.0.0",
|
"eslint-config-google": "^0.14.0",
|
||||||
"node-sass": "^4.14.1",
|
"eslint-plugin-prettier": "^3.3.1",
|
||||||
"sass": "^1.32.5",
|
"eslint-plugin-vue": "^7.5.0",
|
||||||
"sass-loader": "^8.0.2",
|
"fibers": "^5.0.0",
|
||||||
"vue-cli-plugin-vuetify": "^2.0.9",
|
"node-sass": "^4.14.1",
|
||||||
"vue-template-compiler": "^2.6.12",
|
"sass": "^1.32.5",
|
||||||
"vuetify-loader": "^1.6.0"
|
"sass-loader": "^8.0.2",
|
||||||
},
|
"vue-cli-plugin-vuetify": "^2.0.9",
|
||||||
"browserslist": [
|
"vue-template-compiler": "^2.6.12",
|
||||||
"> 1%",
|
"vuetify-loader": "^1.6.0"
|
||||||
"last 2 versions",
|
},
|
||||||
"not dead",
|
"browserslist": [
|
||||||
"not ie <= 10"
|
"> 1%",
|
||||||
]
|
"last 2 versions",
|
||||||
|
"not dead",
|
||||||
|
"not ie <= 10"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ export default {
|
||||||
const res = await qbit.login()
|
const res = await qbit.login()
|
||||||
const authenticated = res === 'Ok.'
|
const authenticated = res === 'Ok.'
|
||||||
this.$store.commit('LOGIN', authenticated)
|
this.$store.commit('LOGIN', authenticated)
|
||||||
|
this.$store.commit('updateMainData')
|
||||||
if (
|
if (
|
||||||
!authenticated &&
|
!authenticated &&
|
||||||
!this.$router.currentRoute.name.includes('login')
|
!this.$router.currentRoute.name.includes('login')
|
||||||
|
|
|
@ -3,15 +3,16 @@
|
||||||
flat
|
flat
|
||||||
color="secondary"
|
color="secondary"
|
||||||
class="speedCard"
|
class="speedCard"
|
||||||
|
data-testid="SpeedCard"
|
||||||
>
|
>
|
||||||
<v-layout row :class="color + '--text'">
|
<v-layout row :class="color + '--text'">
|
||||||
<v-flex xs2>
|
<v-flex v-if="icon" xs2>
|
||||||
<v-icon :color="color" size="16px">
|
<v-icon data-testid="SpeedCard-icon" :color="color" size="16px">
|
||||||
{{ icon }}
|
{{ icon }}
|
||||||
</v-icon>
|
</v-icon>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs7 class="text-center font-weight-bold robot-mono">
|
<v-flex xs7 class="text-center font-weight-bold robot-mono">
|
||||||
<span>
|
<span data-testid="SpeedCard-value">
|
||||||
{{ value | getDataValue(2) }}
|
{{ value | getDataValue(2) }}
|
||||||
</span>
|
</span>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
|
@ -19,7 +20,7 @@
|
||||||
xs3
|
xs3
|
||||||
class="caption robot-mono text-right mt-1"
|
class="caption robot-mono text-right mt-1"
|
||||||
>
|
>
|
||||||
<span class="speedUnits">
|
<span class="speedUnits" data-testid="SpeedCard-unit">
|
||||||
{{ value | getDataUnit(1) }}/s
|
{{ value | getDataUnit(1) }}/s
|
||||||
</span>
|
</span>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
|
|
|
@ -5,14 +5,15 @@
|
||||||
<div
|
<div
|
||||||
style="margin-top: 6px"
|
style="margin-top: 6px"
|
||||||
:class="color + '--text'"
|
:class="color + '--text'"
|
||||||
|
data-testid="StorageCard-label"
|
||||||
>
|
>
|
||||||
{{ label }}
|
{{ label }}
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex md5 class="ml-4">
|
<v-flex md5 class="ml-4">
|
||||||
<span :class="color + '--text title'">
|
<span data-testid="StorageCard-Wrapper" :class="color + '--text title'">
|
||||||
{{ value | getDataValue(2) }}
|
<span data-testid="StorageCard-value"> {{ value | getDataValue(2) }} </span>
|
||||||
<span class="font-weight-light caption">
|
<span data-testid="StorageCard-unit" class="font-weight-light caption">
|
||||||
{{ value | getDataUnit }}
|
{{ value | getDataUnit }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -129,6 +129,9 @@ export default {
|
||||||
return this.getSearchPlugins().filter(p => p.enabled)
|
return this.getSearchPlugins().filter(p => p.enabled)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
this.$store.commit('FETCH_SEARCH_PLUGINS')
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async startSearch() {
|
async startSearch() {
|
||||||
if (this.searchForm.pattern.length && !this.search.interval) {
|
if (this.searchForm.pattern.length && !this.search.interval) {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<td class="grey--text">
|
<td class="grey--text">
|
||||||
Torrent title
|
Torrent title
|
||||||
</td>
|
</td>
|
||||||
<td class="torrentmodaltext--text">
|
<td>
|
||||||
{{ torrent.name }}
|
{{ torrent.name }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
<td class="grey--text">
|
<td class="grey--text">
|
||||||
Directory
|
Directory
|
||||||
</td>
|
</td>
|
||||||
<td class="torrentmodaltext--text">
|
<td>
|
||||||
{{ torrent.savePath }}
|
{{ torrent.savePath }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
<td class="grey--text">
|
<td class="grey--text">
|
||||||
hash
|
hash
|
||||||
</td>
|
</td>
|
||||||
<td class="torrentmodaltext--text">
|
<td>
|
||||||
{{ torrent.hash }}
|
{{ torrent.hash }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
<td class="grey--text">
|
<td class="grey--text">
|
||||||
Size
|
Size
|
||||||
</td>
|
</td>
|
||||||
<td class="torrentmodaltext--text">
|
<td>
|
||||||
{{ torrent.size | getDataValue }}
|
{{ torrent.size | getDataValue }}
|
||||||
{{ torrent.size | getDataUnit(1) }}
|
{{ torrent.size | getDataUnit(1) }}
|
||||||
</td>
|
</td>
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
<td class="grey--text">
|
<td class="grey--text">
|
||||||
Downloaded:
|
Downloaded:
|
||||||
</td>
|
</td>
|
||||||
<td class="torrentmodaltext--text">
|
<td>
|
||||||
{{ torrent.dloaded | getDataValue }}
|
{{ torrent.dloaded | getDataValue }}
|
||||||
{{ torrent.dloaded | getDataUnit(1) }}
|
{{ torrent.dloaded | getDataUnit(1) }}
|
||||||
</td>
|
</td>
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
<td class="grey--text">
|
<td class="grey--text">
|
||||||
Uploaded:
|
Uploaded:
|
||||||
</td>
|
</td>
|
||||||
<td class="torrentmodaltext--text">
|
<td>
|
||||||
{{ torrent.uploaded | getDataValue }}
|
{{ torrent.uploaded | getDataValue }}
|
||||||
{{ torrent.uploaded | getDataUnit(1) }}
|
{{ torrent.uploaded | getDataUnit(1) }}
|
||||||
</td>
|
</td>
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
<td class="grey--text">
|
<td class="grey--text">
|
||||||
Ratio
|
Ratio
|
||||||
</td>
|
</td>
|
||||||
<td class="torrentmodaltext--text">
|
<td>
|
||||||
{{ torrent.ratio }}
|
{{ torrent.ratio }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -70,7 +70,7 @@
|
||||||
<td class="grey--text">
|
<td class="grey--text">
|
||||||
Download Speed
|
Download Speed
|
||||||
</td>
|
</td>
|
||||||
<td class="torrentmodaltext--text">
|
<td>
|
||||||
{{ torrent.dlspeed | getDataValue }}
|
{{ torrent.dlspeed | getDataValue }}
|
||||||
{{ torrent.dlspeed | getDataUnit(1) }}
|
{{ torrent.dlspeed | getDataUnit(1) }}
|
||||||
</td>
|
</td>
|
||||||
|
@ -79,7 +79,7 @@
|
||||||
<td class="grey--text">
|
<td class="grey--text">
|
||||||
Upload Speed
|
Upload Speed
|
||||||
</td>
|
</td>
|
||||||
<td class="torrentmodaltext--text">
|
<td>
|
||||||
{{ torrent.upspeed | getDataValue }}
|
{{ torrent.upspeed | getDataValue }}
|
||||||
{{ torrent.upspeed | getDataUnit(1) }}
|
{{ torrent.upspeed | getDataUnit(1) }}
|
||||||
</td>
|
</td>
|
||||||
|
@ -88,7 +88,7 @@
|
||||||
<td class="grey--text">
|
<td class="grey--text">
|
||||||
ETA
|
ETA
|
||||||
</td>
|
</td>
|
||||||
<td class="torrentmodaltext--text">
|
<td>
|
||||||
{{ torrent.eta }}
|
{{ torrent.eta }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -96,7 +96,7 @@
|
||||||
<td class="grey--text">
|
<td class="grey--text">
|
||||||
Peers
|
Peers
|
||||||
</td>
|
</td>
|
||||||
<td class="torrentmodaltext--text">
|
<td>
|
||||||
{{ torrent.num_leechs
|
{{ torrent.num_leechs
|
||||||
}}<span class="grey--text">/{{ torrent.available_peers }}</span>
|
}}<span class="grey--text">/{{ torrent.available_peers }}</span>
|
||||||
</td>
|
</td>
|
||||||
|
@ -105,7 +105,7 @@
|
||||||
<td class="grey--text">
|
<td class="grey--text">
|
||||||
Seeds
|
Seeds
|
||||||
</td>
|
</td>
|
||||||
<td class="torrentmodaltext--text">
|
<td>
|
||||||
{{ torrent.num_seeds
|
{{ torrent.num_seeds
|
||||||
}}<span class="grey--text">/{{ torrent.available_seeds }}</span>
|
}}<span class="grey--text">/{{ torrent.available_seeds }}</span>
|
||||||
</td>
|
</td>
|
||||||
|
@ -114,26 +114,10 @@
|
||||||
<td class="grey--text">
|
<td class="grey--text">
|
||||||
Added on
|
Added on
|
||||||
</td>
|
</td>
|
||||||
<td class="torrentmodaltext--text">
|
<td>
|
||||||
{{ torrent.added_on }}
|
{{ torrent.added_on }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-if="torrent.tracker">
|
|
||||||
<td class="grey--text">
|
|
||||||
Tracker
|
|
||||||
</td>
|
|
||||||
<td class="torrentmodaltext--text">
|
|
||||||
{{ torrent.tracker }}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr v-if="torrent.comment">
|
|
||||||
<td class="grey--text">
|
|
||||||
Comment
|
|
||||||
</td>
|
|
||||||
<td class="torrentmodaltext--text">
|
|
||||||
{{ torrent.comment }}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td class="grey--text">
|
<td class="grey--text">
|
||||||
Status
|
Status
|
||||||
|
@ -145,6 +129,47 @@
|
||||||
{{ torrent.state }}
|
{{ torrent.state }}
|
||||||
</v-chip>
|
</v-chip>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr v-if="torrent.tracker">
|
||||||
|
<td class="grey--text">
|
||||||
|
Tracker
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ torrent.tracker }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr v-if="torrent.comment">
|
||||||
|
<td class="grey--text">
|
||||||
|
Comment
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ torrent.comment }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="grey--text">
|
||||||
|
First/Last Piece Priority
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ torrent.f_l_piece_prio }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="grey--text">
|
||||||
|
Sequential Download
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ torrent.seq_dl }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="grey--text">
|
||||||
|
Auto TMM
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ torrent.auto_tmm }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</v-simple-table>
|
</v-simple-table>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
|
|
|
@ -152,5 +152,10 @@ export default {
|
||||||
#app .v-select .v-text-field__details {
|
#app .v-select .v-text-field__details {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#app .v-select .v-select__selection {
|
||||||
|
padding: 16px 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
21
src/components/Torrent/DashboardItems/Downloaded.vue
Normal file
21
src/components/Torrent/DashboardItems/Downloaded.vue
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<template>
|
||||||
|
<v-flex xs6 sm1 md1>
|
||||||
|
<div class="caption grey--text">
|
||||||
|
Downloaded
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{ torrent.dloaded | getDataValue(2) }}
|
||||||
|
<span class="caption grey--text">
|
||||||
|
{{
|
||||||
|
torrent.dloaded | getDataUnit(1)
|
||||||
|
}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</v-flex>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'Downloaded',
|
||||||
|
props: ['torrent']
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -6,13 +6,14 @@
|
||||||
class="mr-4"
|
class="mr-4"
|
||||||
>
|
>
|
||||||
<div class="caption grey--text">
|
<div class="caption grey--text">
|
||||||
Done
|
Progress
|
||||||
</div>
|
</div>
|
||||||
<v-progress-linear
|
<v-progress-linear
|
||||||
:value="torrent.progress"
|
:value="torrent.progress"
|
||||||
height="20"
|
height="20"
|
||||||
:style="phoneLayout ? '' : 'width: 80%;'"
|
:style="phoneLayout ? '' : 'width: 80%;'"
|
||||||
:color="`torrent-${state}-color`"
|
:color="`torrent-${state}-color`"
|
||||||
|
rounded
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="caption white--text"
|
class="caption white--text"
|
||||||
|
|
|
@ -2,14 +2,15 @@
|
||||||
<v-flex
|
<v-flex
|
||||||
xs6
|
xs6
|
||||||
sm1
|
sm1
|
||||||
md2
|
md1
|
||||||
|
class="mr-4"
|
||||||
>
|
>
|
||||||
<div class="caption grey--text">
|
<div class="caption grey--text">
|
||||||
Status
|
Status
|
||||||
</div>
|
</div>
|
||||||
<v-chip
|
<v-chip
|
||||||
small
|
small
|
||||||
class="caption white--text"
|
class="caption white--text px-2"
|
||||||
:class="state"
|
:class="state"
|
||||||
>
|
>
|
||||||
{{ torrent.state }}
|
{{ torrent.state }}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import Size from './Size'
|
import Size from './Size'
|
||||||
import Progress from './Progress'
|
import Progress from './Progress'
|
||||||
import Download from './Download'
|
import Download from './Download'
|
||||||
|
import Downloaded from './Downloaded'
|
||||||
import Ratio from './Ratio'
|
import Ratio from './Ratio'
|
||||||
import Upload from './Upload'
|
import Upload from './Upload'
|
||||||
import ETA from './ETA'
|
import ETA from './ETA'
|
||||||
|
@ -27,5 +28,6 @@ export {
|
||||||
Tags,
|
Tags,
|
||||||
AddedOn,
|
AddedOn,
|
||||||
Uploaded,
|
Uploaded,
|
||||||
UploadedSession
|
UploadedSession,
|
||||||
|
Downloaded
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,170 +0,0 @@
|
||||||
<template>
|
|
||||||
<v-list class="py-1">
|
|
||||||
<v-list-item link @click="resume">
|
|
||||||
<v-icon>{{ mdiPlay }}</v-icon>
|
|
||||||
<v-list-item-title
|
|
||||||
class="ml-2"
|
|
||||||
style="font-size: 1em"
|
|
||||||
>
|
|
||||||
Resume
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item link @click="forceResume">
|
|
||||||
<v-icon>{{ mdiFastForward }}</v-icon>
|
|
||||||
<v-list-item-title
|
|
||||||
class="ml-2"
|
|
||||||
style="font-size: 1em"
|
|
||||||
>
|
|
||||||
Force Resume
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item link @click="pause">
|
|
||||||
<v-icon>{{ mdiPause }}</v-icon>
|
|
||||||
<v-list-item-title
|
|
||||||
class="ml-2"
|
|
||||||
style="font-size: 1em"
|
|
||||||
>
|
|
||||||
Pause
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
|
|
||||||
<v-divider />
|
|
||||||
<v-list-item link @click="deleteWithoutFiles">
|
|
||||||
<v-icon color="red">
|
|
||||||
{{ mdiDelete }}
|
|
||||||
</v-icon>
|
|
||||||
<v-list-item-title
|
|
||||||
class="ml-2"
|
|
||||||
style="font-size: 1em; color: red"
|
|
||||||
>
|
|
||||||
Delete
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item link @click="deleteWithFiles">
|
|
||||||
<v-icon color="red">
|
|
||||||
{{ mdiDeleteForever }}
|
|
||||||
</v-icon>
|
|
||||||
<v-list-item-title
|
|
||||||
class="ml-2"
|
|
||||||
style="font-size: 1em; color: red"
|
|
||||||
>
|
|
||||||
Delete with files
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-divider />
|
|
||||||
<v-list-item link @click="recheck">
|
|
||||||
<v-icon>{{ mdiPlaylistCheck }}</v-icon>
|
|
||||||
<v-list-item-title
|
|
||||||
class="ml-2"
|
|
||||||
style="font-size: 1em"
|
|
||||||
>
|
|
||||||
Force recheck
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item link @click="reannounce">
|
|
||||||
<v-icon>{{ mdiBullhorn }}</v-icon>
|
|
||||||
<v-list-item-title
|
|
||||||
class="ml-2"
|
|
||||||
style="font-size: 1em"
|
|
||||||
>
|
|
||||||
Force reannounce
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-divider />
|
|
||||||
<v-menu
|
|
||||||
open-on-hover
|
|
||||||
top
|
|
||||||
>
|
|
||||||
<template #activator="{ on }">
|
|
||||||
<v-list-item link v-on="on">
|
|
||||||
<v-icon>{{ mdiShape }}</v-icon>
|
|
||||||
<v-list-item-title
|
|
||||||
class="ml-2"
|
|
||||||
style="font-size: 1em"
|
|
||||||
>
|
|
||||||
Set Category
|
|
||||||
<v-icon>{{ mdiChevronRight }}</v-icon>
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
</template>
|
|
||||||
<v-list dense rounded>
|
|
||||||
<v-list-item
|
|
||||||
v-for="(item, index) in availableCategories"
|
|
||||||
:key="index"
|
|
||||||
link
|
|
||||||
@click="setCategory(item.value)"
|
|
||||||
>
|
|
||||||
<v-list-item-title class="ml-2" style="font-size: 12px">
|
|
||||||
{{ item.name }}
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
</v-menu>
|
|
||||||
</v-list>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import qbit from '@/services/qbit'
|
|
||||||
import { General, TorrentSelect } from '@/mixins'
|
|
||||||
import {
|
|
||||||
mdiBullhorn, mdiArrowUp, mdiArrowDown, mdiPriorityLow,
|
|
||||||
mdiDeleteForever, mdiDelete, mdiPlaylistCheck, mdiShape,
|
|
||||||
mdiPlay, mdiPause, mdiSelect, mdiPriorityHigh, mdiFastForward,
|
|
||||||
mdiChevronRight
|
|
||||||
} from '@mdi/js'
|
|
||||||
import { mapGetters, mapState } from 'vuex'
|
|
||||||
export default {
|
|
||||||
name: 'TorrentMultipleRightClickMenu',
|
|
||||||
mixins: [General, TorrentSelect],
|
|
||||||
data: () => ({
|
|
||||||
priority_options: [
|
|
||||||
{ name: 'top', icon: mdiPriorityHigh, action: 'topPrio' },
|
|
||||||
{ name: 'increase', icon: mdiArrowUp, action: 'increasePrio' },
|
|
||||||
{ name: 'decrease', icon: mdiArrowDown, action: 'decreasePrio' },
|
|
||||||
{ name: 'bottom', icon: mdiPriorityLow, action: 'bottomPrio' }
|
|
||||||
],
|
|
||||||
mdiDelete, mdiPlay, mdiPause, mdiSelect, mdiFastForward,
|
|
||||||
mdiDeleteForever, mdiBullhorn, mdiPlaylistCheck, mdiShape,
|
|
||||||
mdiChevronRight
|
|
||||||
}),
|
|
||||||
computed: {
|
|
||||||
...mapState(['selected_torrents']),
|
|
||||||
...mapGetters(['getCategories']),
|
|
||||||
availableCategories() {
|
|
||||||
const categories = [
|
|
||||||
{ name: 'None', value: '' }]
|
|
||||||
categories.push(...this.getCategories().map(c => {
|
|
||||||
return { name: c.name, value: c.name }
|
|
||||||
}))
|
|
||||||
|
|
||||||
return categories
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
resume() {
|
|
||||||
qbit.resumeTorrents(this.selected_torrents)
|
|
||||||
},
|
|
||||||
pause() {
|
|
||||||
qbit.pauseTorrents(this.selected_torrents)
|
|
||||||
},
|
|
||||||
reannounce() {
|
|
||||||
qbit.reannounceTorrents(this.selected_torrents)
|
|
||||||
},
|
|
||||||
deleteWithoutFiles() {
|
|
||||||
qbit.deleteTorrents(this.selected_torrents, false)
|
|
||||||
},
|
|
||||||
deleteWithFiles() {
|
|
||||||
qbit.deleteTorrents(this.selected_torrents, true)
|
|
||||||
},
|
|
||||||
recheck() {
|
|
||||||
qbit.recheckTorrents(this.selected_torrents)
|
|
||||||
},
|
|
||||||
forceResume() {
|
|
||||||
qbit.forceStartTorrents(this.selected_torrents)
|
|
||||||
},
|
|
||||||
setCategory(cat) {
|
|
||||||
qbit.setCategory(this.selected_torrents, cat)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -52,42 +52,88 @@
|
||||||
</v-list-item-title>
|
</v-list-item-title>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
<v-divider />
|
<v-divider />
|
||||||
<v-list-item link @click="location">
|
<v-menu
|
||||||
<v-icon>{{ mdiFolder }}</v-icon>
|
open-on-hover
|
||||||
<v-list-item-title
|
top
|
||||||
class="ml-2"
|
>
|
||||||
style="font-size: 1em"
|
<template #activator="{ on }">
|
||||||
>
|
<v-list-item link v-on="on">
|
||||||
Change location
|
<v-icon>{{ mdiHeadCog }}</v-icon>
|
||||||
</v-list-item-title>
|
<v-list-item-title
|
||||||
</v-list-item>
|
class="ml-2"
|
||||||
<v-list-item link @click="rename">
|
style="font-size: 1em"
|
||||||
<v-icon>{{ mdiRenameBox }}</v-icon>
|
>
|
||||||
<v-list-item-title
|
Advanced
|
||||||
class="ml-2"
|
<v-icon>{{ mdiChevronRight }}</v-icon>
|
||||||
style="font-size: 1em"
|
</v-list-item-title>
|
||||||
>
|
</v-list-item>
|
||||||
Rename
|
</template>
|
||||||
</v-list-item-title>
|
<v-list dense rounded>
|
||||||
</v-list-item>
|
<v-list-item v-if="!multiple" link @click="location">
|
||||||
<v-list-item link @click="recheck">
|
<v-icon>{{ mdiFolder }}</v-icon>
|
||||||
<v-icon>{{ mdiPlaylistCheck }}</v-icon>
|
<v-list-item-title
|
||||||
<v-list-item-title
|
class="ml-2"
|
||||||
class="ml-2"
|
style="font-size: 1em"
|
||||||
style="font-size: 1em"
|
>
|
||||||
>
|
Change location
|
||||||
Force recheck
|
</v-list-item-title>
|
||||||
</v-list-item-title>
|
</v-list-item>
|
||||||
</v-list-item>
|
<v-list-item v-if="!multiple" link @click="rename">
|
||||||
<v-list-item link @click="reannounce">
|
<v-icon>{{ mdiRenameBox }}</v-icon>
|
||||||
<v-icon>{{ mdiBullhorn }}</v-icon>
|
<v-list-item-title
|
||||||
<v-list-item-title
|
class="ml-2"
|
||||||
class="ml-2"
|
style="font-size: 1em"
|
||||||
style="font-size: 1em"
|
>
|
||||||
>
|
Rename
|
||||||
Force reannounce
|
</v-list-item-title>
|
||||||
</v-list-item-title>
|
</v-list-item>
|
||||||
</v-list-item>
|
<v-list-item link @click="recheck">
|
||||||
|
<v-icon>{{ mdiPlaylistCheck }}</v-icon>
|
||||||
|
<v-list-item-title
|
||||||
|
class="ml-2"
|
||||||
|
style="font-size: 1em"
|
||||||
|
>
|
||||||
|
Force recheck
|
||||||
|
</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item link @click="reannounce">
|
||||||
|
<v-icon>{{ mdiBullhorn }}</v-icon>
|
||||||
|
<v-list-item-title
|
||||||
|
class="ml-2"
|
||||||
|
style="font-size: 1em"
|
||||||
|
>
|
||||||
|
Force reannounce
|
||||||
|
</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="!multiple" link @click="toggleSeq">
|
||||||
|
<v-icon> {{ torrent.seq_dl ? mdiCheckboxMarked : mdiCheckboxBlankOutline }} </v-icon>
|
||||||
|
<v-list-item-title
|
||||||
|
class="ml-2"
|
||||||
|
style="font-size: 1em"
|
||||||
|
>
|
||||||
|
Sequential Download
|
||||||
|
</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="!multiple" link @click="toggleFL">
|
||||||
|
<v-icon> {{ torrent.f_l_piece_prio ? mdiCheckboxMarked : mdiCheckboxBlankOutline }} </v-icon>
|
||||||
|
<v-list-item-title
|
||||||
|
class="ml-2"
|
||||||
|
style="font-size: 1em"
|
||||||
|
>
|
||||||
|
First/Last priority
|
||||||
|
</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="!multiple" link @click="toggleAutoTMM">
|
||||||
|
<v-icon> {{ torrent.auto_tmm ? mdiCheckboxMarked : mdiCheckboxBlankOutline }} </v-icon>
|
||||||
|
<v-list-item-title
|
||||||
|
class="ml-2"
|
||||||
|
style="font-size: 1em"
|
||||||
|
>
|
||||||
|
Auto TMM
|
||||||
|
</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
<v-menu
|
<v-menu
|
||||||
open-on-hover
|
open-on-hover
|
||||||
top
|
top
|
||||||
|
@ -147,8 +193,8 @@
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
</v-list>
|
</v-list>
|
||||||
</v-menu>
|
</v-menu>
|
||||||
<v-divider />
|
<v-divider v-if="!multiple" />
|
||||||
<v-list-item link @click="showInfo">
|
<v-list-item v-if="!multiple" link @click="showInfo">
|
||||||
<v-icon>{{ mdiInformation }}</v-icon>
|
<v-icon>{{ mdiInformation }}</v-icon>
|
||||||
<v-list-item-title
|
<v-list-item-title
|
||||||
class="ml-2"
|
class="ml-2"
|
||||||
|
@ -157,7 +203,7 @@
|
||||||
Show Info
|
Show Info
|
||||||
</v-list-item-title>
|
</v-list-item-title>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
<v-list-item link @click="selectTorrent(hash)">
|
<v-list-item v-if="!multiple" link @click="selectTorrent(hash)">
|
||||||
<v-icon>{{ mdiSelect }}</v-icon>
|
<v-icon>{{ mdiSelect }}</v-icon>
|
||||||
<v-list-item-title
|
<v-list-item-title
|
||||||
class="ml-2"
|
class="ml-2"
|
||||||
|
@ -169,20 +215,21 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { mapGetters, mapState } from 'vuex'
|
||||||
import qbit from '@/services/qbit'
|
import qbit from '@/services/qbit'
|
||||||
import { General, TorrentSelect } from '@/mixins'
|
import { General, TorrentSelect } from '@/mixins'
|
||||||
import {
|
import {
|
||||||
mdiBullhorn, mdiPlaylistCheck, mdiArrowUp, mdiArrowDown, mdiPriorityLow,
|
mdiBullhorn, mdiPlaylistCheck, mdiArrowUp, mdiArrowDown, mdiPriorityLow,
|
||||||
mdiInformation, mdiDeleteForever, mdiRenameBox, mdiFolder, mdiDelete,
|
mdiInformation, mdiDeleteForever, mdiRenameBox, mdiFolder, mdiDelete,
|
||||||
mdiPlay, mdiPause, mdiSelect, mdiPriorityHigh, mdiChevronRight,
|
mdiPlay, mdiPause, mdiSelect, mdiPriorityHigh, mdiChevronRight,
|
||||||
mdiFastForward, mdiShape
|
mdiFastForward, mdiShape, mdiHeadCog, mdiCheckboxMarked, mdiCheckboxBlankOutline
|
||||||
} from '@mdi/js'
|
} from '@mdi/js'
|
||||||
import { mapGetters } from 'vuex'
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TorrentRightClickMenu',
|
name: 'TorrentRightClickMenu',
|
||||||
mixins: [General, TorrentSelect],
|
mixins: [General, TorrentSelect],
|
||||||
props: {
|
props: {
|
||||||
hash: String
|
torrent: Object
|
||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
priority_options: [
|
priority_options: [
|
||||||
|
@ -194,10 +241,11 @@ export default {
|
||||||
mdiDelete, mdiPlay, mdiPause, mdiSelect, mdiFastForward,
|
mdiDelete, mdiPlay, mdiPause, mdiSelect, mdiFastForward,
|
||||||
mdiFolder, mdiRenameBox, mdiDeleteForever, mdiInformation,
|
mdiFolder, mdiRenameBox, mdiDeleteForever, mdiInformation,
|
||||||
mdiPlaylistCheck, mdiPriorityHigh, mdiBullhorn, mdiChevronRight,
|
mdiPlaylistCheck, mdiPriorityHigh, mdiBullhorn, mdiChevronRight,
|
||||||
mdiShape
|
mdiShape, mdiHeadCog, mdiCheckboxMarked, mdiCheckboxBlankOutline
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['getCategories']),
|
...mapGetters(['getCategories']),
|
||||||
|
...mapState(['selected_torrents']),
|
||||||
availableCategories() {
|
availableCategories() {
|
||||||
const categories = [
|
const categories = [
|
||||||
{ name: 'None', value: '' }]
|
{ name: 'None', value: '' }]
|
||||||
|
@ -206,44 +254,61 @@ export default {
|
||||||
}))
|
}))
|
||||||
|
|
||||||
return categories
|
return categories
|
||||||
|
},
|
||||||
|
hashes() {
|
||||||
|
if (this.multiple) return this.selected_torrents
|
||||||
|
|
||||||
|
return [this.torrent.hash]
|
||||||
|
},
|
||||||
|
multiple() {
|
||||||
|
return this.selected_torrents.length
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
resume() {
|
resume() {
|
||||||
qbit.resumeTorrents([this.hash])
|
qbit.resumeTorrents(this.hashes)
|
||||||
},
|
},
|
||||||
pause() {
|
pause() {
|
||||||
qbit.pauseTorrents([this.hash])
|
qbit.pauseTorrents(this.hashes)
|
||||||
},
|
},
|
||||||
location() {
|
location() {
|
||||||
this.createModal('ChangeLocationModal', { hash: this.hash })
|
this.createModal('ChangeLocationModal', { hash: this.torrent.hash })
|
||||||
},
|
},
|
||||||
rename() {
|
rename() {
|
||||||
this.createModal('RenameModal', { hash: this.hash })
|
this.createModal('RenameModal', { hash: this.torrent.hash })
|
||||||
},
|
},
|
||||||
reannounce() {
|
reannounce() {
|
||||||
qbit.reannounceTorrents([this.hash])
|
qbit.reannounceTorrents(this.hashes)
|
||||||
},
|
},
|
||||||
deleteWithoutFiles() {
|
deleteWithoutFiles() {
|
||||||
qbit.deleteTorrents([this.hash], false)
|
qbit.deleteTorrents(this.hashes, false)
|
||||||
},
|
},
|
||||||
deleteWithFiles() {
|
deleteWithFiles() {
|
||||||
qbit.deleteTorrents([this.hash], true)
|
qbit.deleteTorrents(this.hashes, true)
|
||||||
},
|
},
|
||||||
recheck() {
|
recheck() {
|
||||||
qbit.recheckTorrents([this.hash])
|
qbit.recheckTorrents(this.hashes)
|
||||||
},
|
},
|
||||||
showInfo() {
|
showInfo() {
|
||||||
this.createModal('TorrentDetailModal', { hash: this.hash })
|
this.createModal('TorrentDetailModal', { hash: this.torrent.hash })
|
||||||
},
|
},
|
||||||
setPriority(priority) {
|
setPriority(priority) {
|
||||||
qbit.setTorrentPriority(this.hash, priority)
|
qbit.setTorrentPriority(this.hash, priority)
|
||||||
},
|
},
|
||||||
forceResume() {
|
forceResume() {
|
||||||
qbit.forceStartTorrents([this.hash])
|
qbit.forceStartTorrents(this.hashes)
|
||||||
},
|
},
|
||||||
setCategory(cat) {
|
setCategory(cat) {
|
||||||
qbit.setCategory([this.hash], cat)
|
qbit.setCategory(this.hashes, cat)
|
||||||
|
},
|
||||||
|
toggleSeq() {
|
||||||
|
qbit.toggleSequentialDownload(this.hashes)
|
||||||
|
},
|
||||||
|
toggleFL() {
|
||||||
|
qbit.toggleFirstLastPiecePriority(this.hashes)
|
||||||
|
},
|
||||||
|
toggleAutoTMM() {
|
||||||
|
qbit.setAutoTMM(this.hashes, !this.torrent.auto_tmm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import '@/registerServiceWorker'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
import '@babel/polyfill'
|
import '@babel/polyfill'
|
||||||
|
import vuetify from './plugins/vuetify'
|
||||||
import 'typeface-roboto'
|
import 'typeface-roboto'
|
||||||
import 'typeface-roboto-mono'
|
import 'typeface-roboto-mono'
|
||||||
|
|
||||||
|
@ -12,13 +13,8 @@ import filters from '@/filters'
|
||||||
import styles from '@/styles/styles.scss'
|
import styles from '@/styles/styles.scss'
|
||||||
/* eslint-enable no-unused-vars */
|
/* eslint-enable no-unused-vars */
|
||||||
|
|
||||||
import VueObserveVisibility from 'vue-observe-visibility'
|
|
||||||
|
|
||||||
Vue.use(VueObserveVisibility)
|
|
||||||
|
|
||||||
import Toast from 'vue-toastification'
|
import Toast from 'vue-toastification'
|
||||||
import 'vue-toastification/dist/index.css'
|
import 'vue-toastification/dist/index.css'
|
||||||
import vuetify from './plugins/vuetify'
|
|
||||||
Vue.use(Toast, {
|
Vue.use(Toast, {
|
||||||
maxToasts: 5,
|
maxToasts: 5,
|
||||||
timeout: 2000
|
timeout: 2000
|
||||||
|
@ -26,7 +22,6 @@ Vue.use(Toast, {
|
||||||
|
|
||||||
import PerfectScrollbar from 'vue2-perfect-scrollbar'
|
import PerfectScrollbar from 'vue2-perfect-scrollbar'
|
||||||
import 'vue2-perfect-scrollbar/dist/vue2-perfect-scrollbar.css'
|
import 'vue2-perfect-scrollbar/dist/vue2-perfect-scrollbar.css'
|
||||||
|
|
||||||
Vue.use(PerfectScrollbar)
|
Vue.use(PerfectScrollbar)
|
||||||
|
|
||||||
import './registerServiceWorker'
|
import './registerServiceWorker'
|
||||||
|
|
|
@ -23,6 +23,10 @@ export default class Torrent {
|
||||||
this.category = data.category
|
this.category = data.category
|
||||||
this.tracker = data.tracker
|
this.tracker = data.tracker
|
||||||
this.comment = data.comment
|
this.comment = data.comment
|
||||||
|
this.f_l_piece_prio = data.f_l_piece_prio
|
||||||
|
this.seq_dl = data.seq_dl
|
||||||
|
this.auto_tmm = data.auto_tmm
|
||||||
|
|
||||||
Object.freeze(this)
|
Object.freeze(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Vuetify from 'vuetify'
|
import Vuetify from 'vuetify/lib'
|
||||||
import 'vuetify/dist/vuetify.min.css'
|
|
||||||
|
|
||||||
import colors from 'vuetify/lib/util/colors'
|
import colors from 'vuetify/lib/util/colors'
|
||||||
import variables from '@/styles/colors.scss'
|
import variables from '@/styles/colors.scss'
|
||||||
|
|
|
@ -199,6 +199,18 @@ class Qbit {
|
||||||
return this.torrentAction('setForceStart', hashes, { value: true })
|
return this.torrentAction('setForceStart', hashes, { value: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleSequentialDownload(hashes) {
|
||||||
|
return this.torrentAction('toggleSequentialDownload', hashes)
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleFirstLastPiecePriority(hashes) {
|
||||||
|
return this.torrentAction('toggleFirstLastPiecePrio', hashes)
|
||||||
|
}
|
||||||
|
|
||||||
|
setAutoTMM(hashes, enable) {
|
||||||
|
return this.torrentAction('setAutoManagement', hashes, { enable })
|
||||||
|
}
|
||||||
|
|
||||||
reannounceTorrents(hashes) {
|
reannounceTorrents(hashes) {
|
||||||
return this.torrentAction('reannounce', hashes)
|
return this.torrentAction('reannounce', hashes)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,7 @@ const vuexPersist = new VuexPersist({
|
||||||
reducer: state => ({
|
reducer: state => ({
|
||||||
sort_options: state.sort_options,
|
sort_options: state.sort_options,
|
||||||
webuiSettings: state.webuiSettings,
|
webuiSettings: state.webuiSettings,
|
||||||
authenticated: state.authenticated,
|
authenticated: state.authenticated
|
||||||
torrents: state.torrents
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -64,6 +63,7 @@ export default new Vuex.Store({
|
||||||
busyTorrentProperties: [
|
busyTorrentProperties: [
|
||||||
{ name: 'Size', active: true },
|
{ name: 'Size', active: true },
|
||||||
{ name: 'Progress', active: true },
|
{ name: 'Progress', active: true },
|
||||||
|
{ name: 'Downloaded', active: true },
|
||||||
{ name: 'Download', active: true },
|
{ name: 'Download', active: true },
|
||||||
{ name: 'Upload', active: true },
|
{ name: 'Upload', active: true },
|
||||||
{ name: 'ETA', active: true },
|
{ name: 'ETA', active: true },
|
||||||
|
@ -78,6 +78,7 @@ export default new Vuex.Store({
|
||||||
doneTorrentProperties: [
|
doneTorrentProperties: [
|
||||||
{ name: 'Size', active: true },
|
{ name: 'Size', active: true },
|
||||||
{ name: 'Progress', active: true },
|
{ name: 'Progress', active: true },
|
||||||
|
{ name: 'Downloaded', active: true },
|
||||||
{ name: 'Download', active: true },
|
{ name: 'Download', active: true },
|
||||||
{ name: 'Upload', active: true },
|
{ name: 'Upload', active: true },
|
||||||
{ name: 'ETA', active: true },
|
{ name: 'ETA', active: true },
|
||||||
|
|
|
@ -92,13 +92,17 @@ export default {
|
||||||
const { data } = await qbit.getAppPreferences()
|
const { data } = await qbit.getAppPreferences()
|
||||||
state.settings = data
|
state.settings = data
|
||||||
},
|
},
|
||||||
UPDATE_SORT_OPTIONS: (state, payload) => {
|
UPDATE_SORT_OPTIONS: (state, {
|
||||||
state.sort_options.sort = payload.name ? payload.name : state.sort_options.sort
|
reverse = false,
|
||||||
state.sort_options.reverse = payload.reverse
|
hashes = [],
|
||||||
state.sort_options.hashes = payload.hashes ? payload.hashes : state.sort_options.hashes
|
filter = null, category = null,
|
||||||
state.sort_options.filter = payload.filter
|
tracker = null
|
||||||
state.sort_options.category = payload.category
|
}) => {
|
||||||
state.sort_options.tracker = payload.tracker
|
state.sort_options.reverse = reverse
|
||||||
|
state.sort_options.hashes = hashes
|
||||||
|
state.sort_options.filter = filter
|
||||||
|
state.sort_options.category = category
|
||||||
|
state.sort_options.tracker = tracker
|
||||||
},
|
},
|
||||||
FETCH_CATEGORIES: async state => state.categories = Object.values(await (qbit.getCategories())),
|
FETCH_CATEGORIES: async state => state.categories = Object.values(await (qbit.getCategories())),
|
||||||
FETCH_SEARCH_PLUGINS: async state => state.searchPlugins = await qbit.getSearchPlugins(),
|
FETCH_SEARCH_PLUGINS: async state => state.searchPlugins = await qbit.getSearchPlugins(),
|
||||||
|
|
|
@ -78,8 +78,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<vue-context ref="menu" v-slot="{ data }">
|
<vue-context ref="menu" v-slot="{ data }">
|
||||||
<TorrentRightClickMenu v-if="data && !selected_torrents.length" :hash="data.torrent.hash" />
|
<TorrentRightClickMenu v-if="data" :torrent="data.torrent" />
|
||||||
<TorrentMultipleRightClickMenu v-if="data && selected_torrents.length" />
|
|
||||||
</vue-context>
|
</vue-context>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -94,13 +93,12 @@ import 'vue-context/src/sass/vue-context.scss'
|
||||||
|
|
||||||
import Torrent from '@/components/Torrent/Torrent'
|
import Torrent from '@/components/Torrent/Torrent'
|
||||||
import TorrentRightClickMenu from '@/components/Torrent/TorrentRightClickMenu.vue'
|
import TorrentRightClickMenu from '@/components/Torrent/TorrentRightClickMenu.vue'
|
||||||
import TorrentMultipleRightClickMenu from '@/components/Torrent/TorrentMultipleRightClickMenu.vue'
|
|
||||||
|
|
||||||
import { TorrentSelect, General } from '@/mixins'
|
import { TorrentSelect, General } from '@/mixins'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Dashboard',
|
name: 'Dashboard',
|
||||||
components: { Torrent, VueContext, TorrentRightClickMenu, TorrentMultipleRightClickMenu },
|
components: { Torrent, VueContext, TorrentRightClickMenu },
|
||||||
mixins: [TorrentSelect, General],
|
mixins: [TorrentSelect, General],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
13
tests/helpers.js
Normal file
13
tests/helpers.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import { createLocalVue, mount } from '@vue/test-utils'
|
||||||
|
import Vuetify from 'vuetify'
|
||||||
|
|
||||||
|
export function setup(component, propsData) {
|
||||||
|
const localVue = createLocalVue() // because of vuetify, we should use a localVue instance
|
||||||
|
const vuetify = new Vuetify()
|
||||||
|
|
||||||
|
return mount(component, {
|
||||||
|
localVue,
|
||||||
|
vuetify,
|
||||||
|
propsData
|
||||||
|
})
|
||||||
|
}
|
7
tests/setup.js
Normal file
7
tests/setup.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import Vue from 'vue'
|
||||||
|
import Vuetify from 'vuetify'
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
import filters from '@/filters'
|
||||||
|
|
||||||
|
Vue.use(Vuetify)
|
||||||
|
Vue.config.productionTip = false
|
29
tests/unit/SpeedCard.spec.js
Normal file
29
tests/unit/SpeedCard.spec.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import { setup } from '../helpers'
|
||||||
|
import SpeedCard from '@/components/Core/SpeedCard.vue'
|
||||||
|
import { mdiChevronDown } from '@mdi/js'
|
||||||
|
|
||||||
|
describe('SpeedCard.vue', () => {
|
||||||
|
it('should render the card', () => {
|
||||||
|
const wrapper = setup(SpeedCard)
|
||||||
|
expect(wrapper.find('[data-testid="SpeedCard"]').exists()).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('shouldn\'t render the icon', () => {
|
||||||
|
const wrapper = setup(SpeedCard)
|
||||||
|
expect(wrapper.find('[data-testid="SpeedCard-icon"]').exists()).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should render the icon', () => {
|
||||||
|
const wrapper = setup(SpeedCard, { icon: mdiChevronDown })
|
||||||
|
expect(wrapper.find('[data-testid="SpeedCard-icon"]').exists()).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should render value and unit & be formatted', () => {
|
||||||
|
const wrapper = setup(SpeedCard, { value: 10000 })
|
||||||
|
expect(wrapper.find('[data-testid="SpeedCard-value"]').exists()).toBe(true)
|
||||||
|
expect(wrapper.find('[data-testid="SpeedCard-value"]').text()).toBe('9.77')
|
||||||
|
|
||||||
|
expect(wrapper.find('[data-testid="SpeedCard-unit"]').exists()).toBe(true)
|
||||||
|
expect(wrapper.find('[data-testid="SpeedCard-unit"]').text()).toBe('KB/s')
|
||||||
|
})
|
||||||
|
})
|
27
tests/unit/StorageCard.spec.js
Normal file
27
tests/unit/StorageCard.spec.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import { setup } from '../helpers'
|
||||||
|
import StorageCard from '@/components/Core/StorageCard'
|
||||||
|
|
||||||
|
describe('StorageCard.vue', () => {
|
||||||
|
|
||||||
|
it('should render the label', () => {
|
||||||
|
const label = 'Downloaded'
|
||||||
|
const wrapper = setup(StorageCard, { label })
|
||||||
|
expect(wrapper.find('[data-testid="StorageCard-label"]').text()).toEqual(label)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should render value and unit & be formatted', () => {
|
||||||
|
const wrapper = setup(StorageCard, { value: 10000 })
|
||||||
|
expect(wrapper.find('[data-testid="StorageCard-value"]').exists()).toBe(true)
|
||||||
|
expect(wrapper.find('[data-testid="StorageCard-value"]').text()).toBe('9.77')
|
||||||
|
|
||||||
|
expect(wrapper.find('[data-testid="StorageCard-unit"]').exists()).toBe(true)
|
||||||
|
expect(wrapper.find('[data-testid="StorageCard-unit"]').text()).toBe('KB')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('text should have the passed-in color', () => {
|
||||||
|
const color = 'download'
|
||||||
|
const wrapper = setup(StorageCard, { color })
|
||||||
|
expect(wrapper.find('[data-testid="StorageCard-label"]').classes()).toContain(color + '--text')
|
||||||
|
expect(wrapper.find('[data-testid="StorageCard-Wrapper"]').classes()).toContain(color + '--text')
|
||||||
|
})
|
||||||
|
})
|
|
@ -5,7 +5,7 @@ module.exports = {
|
||||||
.plugin('html')
|
.plugin('html')
|
||||||
.tap(args => {
|
.tap(args => {
|
||||||
args[0].title = 'VueTorrent'
|
args[0].title = 'VueTorrent'
|
||||||
|
|
||||||
return args
|
return args
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Reference in a new issue