This commit is contained in:
CzBiX
2019-09-16 00:09:45 +08:00
parent 53e404a685
commit cf1d48ea7a
12 changed files with 90 additions and 76 deletions

View File

@@ -15,6 +15,7 @@ module.exports = {
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-restricted-syntax': 'off',
'no-await-in-loop': 'off',
'no-plusplus': 'off',
'no-continue': 'off',
'func-names': ['warn', 'as-needed'],

View File

@@ -1,20 +1,18 @@
language: node_js
node_js: lts/*
branches:
only:
- master
before_install:
- export TZ=Asia/Shanghai COMMIT_ID=${TRAVIS_COMMIT::6}
script: npm run build; [ -d dist/public ]
script:
- npm run lint
- npm run build; [ -d dist/public ]
before_deploy:
# Add tag if missing
- if [ -z "$TRAVIS_TAG" ]; then
export TRAVIS_TAG=nightly-$COMMIT_ID RELEASE_TITLE=$(date +'%Y%m%d')-$COMMIT_ID;
git tag $TRAVIS_TAG;
export TRAVIS_TAG=nightly-$COMMIT_ID RELEASE_TITLE=$(date +'%Y%m%d')-$COMMIT_ID &&
git tag $TRAVIS_TAG &&
echo tagged as $TRAVIS_TAG;
fi
# Pack for release
@@ -31,3 +29,5 @@ deploy:
overwrite: true
prerelease: true
name: $RELEASE_TITLE
on:
branch: master

View File

@@ -136,7 +136,7 @@ class Api {
params,
}).then(Api.handleResponse);
}
public editTracker(hash: string, origUrl: string, newUrl: string) {
const params = {
hash,

View File

@@ -161,7 +161,7 @@ export default Vue.extend({
...mapState({
prefs: 'preferences',
categories(state, getters) {
return getters.allCategories.map(c => ({text: c.name, value: c.key}));
return getters.allCategories.map(c => ({ text: c.name, value: c.key }));
},
}),
params() {

View File

@@ -264,4 +264,4 @@ export default {
.drawer .v-list-item__icon {
margin-left: 8px;
}
</style>
</style>

View File

@@ -10,23 +10,25 @@
height="40px"
class="elevation-2"
>
<v-btn icon @click="confirmDelete" title="Delete" :disabled="selectedRows.length == 0">
<v-btn icon @click="confirmDelete" title="Delete" :disabled="!hasSelected">
<v-icon>mdi-delete</v-icon>
</v-btn>
<v-divider vertical inset />
<v-btn icon @click="resumeTorrents" title="Resume" :disabled="selectedRows.length == 0">
<v-btn icon @click="resumeTorrents" title="Resume" :disabled="!hasSelected">
<v-icon>mdi-play</v-icon>
</v-btn>
<v-btn icon @click="pauseTorrents" title="Pause" :disabled="selectedRows.length == 0">
<v-btn icon @click="pauseTorrents" title="Pause" :disabled="!hasSelected">
<v-icon>mdi-pause</v-icon>
</v-btn>
<v-divider vertical inset />
<v-btn icon @click="showInfo()" title="Info" :disabled="selectedRows.length == 0 || selectedRows.length > 5">
<v-btn icon @click="showInfo()" title="Info"
:disabled="!hasSelected || selectedRows.length > 5"
>
<v-icon>mdi-alert-circle</v-icon>
</v-btn>
<v-menu offset-y>
<template v-slot:activator="{ on }">
<v-btn icon v-on="on" title="Category" :disabled="selectedRows.length == 0">
<v-btn icon v-on="on" title="Category" :disabled="!hasSelected">
<v-icon>mdi-folder</v-icon>
</v-btn>
</template>
@@ -141,7 +143,9 @@
</v-data-table>
<confirm-delete-dialog v-if="toDelete.length" v-model="toDelete" />
<confirm-set-category-dialog v-if="toSetCategory.length" :category="categoryToSet" v-model="toSetCategory" />
<confirm-set-category-dialog v-if="toSetCategory.length"
:category="categoryToSet" v-model="toSetCategory"
/>
<edit-tracker-dialog v-if="toEditTracker.length" v-model="toEditTracker" />
<info-dialog
v-if="toShowInfo.length"
@@ -304,7 +308,7 @@ export default Vue.extend({
return !this.isDataReady;
},
hasSelected() {
return this.selectedRows.length;
return !!this.selectedRows.length;
},
selectedHashes() {
return this.selectedRows.map(_.property('hash'));
@@ -375,7 +379,7 @@ export default Vue.extend({
await api.pauseTorrents(this.selectedHashes);
},
async reannounceTorrents() {
if (this.selectedRows.length == 0) {
if (!this.hasSelected) {
this.selectedRows = this.allTorrents;
}
await api.reannounceTorrents(this.selectedHashes);
@@ -388,11 +392,11 @@ export default Vue.extend({
this.toSetCategory = this.selectedRows;
},
editTracker() {
if (this.selectedRows.length == 0) {
if (this.hasSelected) {
this.selectedRows = this.allTorrents;
}
this.toEditTracker = this.selectedRows;
}
},
},
watch: {

View File

@@ -47,8 +47,8 @@
<script lang="ts">
import _ from 'lodash';
import Vue from 'vue';
import api from '@/Api';
import { mapGetters } from 'vuex';
import api from '@/Api';
import { getSameNamedTorrents } from '@/utils';
export default Vue.extend({

View File

@@ -47,8 +47,8 @@
<script lang="ts">
import _ from 'lodash';
import Vue from 'vue';
import api from '@/Api';
import { mapGetters } from 'vuex';
import api from '@/Api';
import { getSameNamedTorrents } from '@/utils';
export default Vue.extend({

View File

@@ -85,8 +85,9 @@
<script lang="ts">
import _ from 'lodash';
import Vue from 'vue';
import api from '@/Api';
import { mapGetters } from 'vuex';
import api from '@/Api';
export default Vue.extend({
props: {
@@ -113,15 +114,16 @@ export default Vue.extend({
return this.$vuetify.breakpoint.xsOnly;
},
canNext() {
if (this.step == 1 && this.valid) {
if (this.step === 1 && this.valid) {
return true;
} else if (this.step == 2 && this.toEdit.length > 0) {
return true;
} else if (this.step == 3 && !this.submitting) {
return true;
} else {
return false;
}
if (this.step === 2 && this.toEdit.length > 0) {
return true;
}
if (this.step === 3 && !this.submitting) {
return true;
}
return false;
},
},
methods: {
@@ -132,9 +134,9 @@ export default Vue.extend({
const regex = new RegExp(this.search);
return _.chain(this.torrents)
.map(({tracker, hash, name}) => {
.map(({ tracker, hash, name }) => {
const newUrl = tracker.replace(regex, this.replace);
return newUrl == tracker ? null : {
return newUrl === tracker ? null : {
hash,
name,
origUrl: tracker,
@@ -143,19 +145,19 @@ export default Vue.extend({
}).compact().value();
},
back() {
if (this.step == 1) {
if (this.step === 1) {
this.closeDialog();
return;
}
this.step--;
},
async foward() {
if (this.step == 1) {
if (this.step === 1) {
this.toEdit = this.calcResults();
this.step++;
return;
}
if (this.step == 3) {
if (this.step === 3) {
this.closeDialog();
return;
}

View File

@@ -22,6 +22,7 @@ import Vue from 'vue';
import api from '../../Api';
import Taskable from '@/mixins/taskable';
/* eslint-disable camelcase */
interface File {
name: string;
size: number;
@@ -30,7 +31,8 @@ interface File {
is_seed: boolean;
piece_range: Array<number>;
availability: number;
};
}
/* eslint-disable camelcase */
interface TreeItem {
name: string;
@@ -40,7 +42,7 @@ interface TreeItem {
interface Data {
files: Array<File>;
};
}
const FILE_KEY = '/FILE/';
@@ -79,9 +81,9 @@ export default Vue.extend({
},
getTotalSize(item: TreeItem) {
if (item.item) {
return item.item.size
return item.item.size;
}
let size = 0;
for (const child of item.children!) {
size += this.getTotalSize(child);
@@ -90,7 +92,7 @@ export default Vue.extend({
return size;
},
getFileFolder(item: File, start: number) {
const name = item.name;
const { name } = item;
const index = name.indexOf('/', start);
if (index === -1) {
return FILE_KEY;
@@ -103,7 +105,7 @@ export default Vue.extend({
return [];
}
const entries = _.groupBy(files, (item) => this.getFileFolder(item, start));
const entries = _.groupBy(files, item => this.getFileFolder(item, start));
const result = [];
for (const [folder, values] of _.entries(entries)) {
@@ -112,14 +114,14 @@ export default Vue.extend({
result.push({
name: folder,
children: subTree,
})
});
continue;
}
for (const item of values) {
result.push({
name: item.name.substring(start),
item: item,
item,
});
}
}
@@ -150,4 +152,4 @@ export default Vue.extend({
min-height: 0;
}
}
</style>
</style>

View File

@@ -41,8 +41,11 @@
import Vue from 'vue';
import api from '../../Api';
import Taskable from '@/mixins/taskable';
import { formatDuration, formatSize, formatTimestamp, toPrecision } from '@/filters';
import {
formatDuration, formatSize, formatTimestamp, toPrecision,
} from '@/filters';
/* eslint-disable camelcase */
interface Properties {
addition_date: number;
comment: string;
@@ -77,18 +80,19 @@ interface Properties {
up_limit: number;
up_speed: number;
up_speed_avg: number;
};
}
/* eslint-enable camelcase */
interface Item {
label: string;
value: (prop: Properties) => string;
};
}
interface Data {
properties?: Properties;
transfer: Array<Item>;
information: Array<Item>;
};
}
export default Vue.extend({
mixins: [Taskable],
@@ -101,32 +105,33 @@ export default Vue.extend({
return {
properties: undefined,
transfer: [
{ label: 'Time active', value: (prop) => {
return formatDuration(prop.time_elapsed) + (prop.seeding_time ? ` (seeded ${formatDuration(prop.seeding_time)})` : '')
}},
{ label: 'ETA', value: (prop) => formatDuration(prop.eta, {dayLimit: 100}) },
{ label: 'Connections', value: (prop) => `${prop.nb_connections} (${prop.nb_connections_limit} max)` },
{ label: 'Downloaded', value: (prop) => `${formatSize(prop.total_downloaded_session)}/${formatSize(prop.total_downloaded)}` },
{ label: 'Uploaded', value: (prop) => `${formatSize(prop.total_uploaded_session)}/${formatSize(prop.total_uploaded)}` },
{ label: 'Seeds', value: (prop) => `${prop.seeds} (${prop.seeds_total} total)` },
{ label: 'DL speed', value: (prop) => `${formatSize(prop.dl_speed)}/s` },
{ label: 'UP speed', value: (prop) => `${formatSize(prop.up_speed)}/s` },
{ label: 'Peers', value: (prop) => `${prop.peers} (${prop.peers_total} total)` },
{ label: 'Wasted', value: (prop) => formatSize(prop.total_wasted) },
{ label: 'Share ratio', value: (prop) => toPrecision(prop.share_ratio, 2) },
{ label: 'Reannounce', value: (prop) => formatDuration(prop.reannounce) },
{ label: 'Last seen', value: (prop) => formatTimestamp(prop.last_seen) },
{
label: 'Time active',
value: prop => formatDuration(prop.time_elapsed) + (prop.seeding_time ? ` (seeded ${formatDuration(prop.seeding_time)})` : ''),
},
{ label: 'ETA', value: prop => formatDuration(prop.eta, { dayLimit: 100 }) },
{ label: 'Connections', value: prop => `${prop.nb_connections} (${prop.nb_connections_limit} max)` },
{ label: 'Downloaded', value: prop => `${formatSize(prop.total_downloaded_session)}/${formatSize(prop.total_downloaded)}` },
{ label: 'Uploaded', value: prop => `${formatSize(prop.total_uploaded_session)}/${formatSize(prop.total_uploaded)}` },
{ label: 'Seeds', value: prop => `${prop.seeds} (${prop.seeds_total} total)` },
{ label: 'DL speed', value: prop => `${formatSize(prop.dl_speed)}/s` },
{ label: 'UP speed', value: prop => `${formatSize(prop.up_speed)}/s` },
{ label: 'Peers', value: prop => `${prop.peers} (${prop.peers_total} total)` },
{ label: 'Wasted', value: prop => formatSize(prop.total_wasted) },
{ label: 'Share ratio', value: prop => toPrecision(prop.share_ratio, 2) },
{ label: 'Reannounce', value: prop => formatDuration(prop.reannounce) },
{ label: 'Last seen', value: prop => formatTimestamp(prop.last_seen) },
],
information: [
{ label: 'Total size', value: (prop) => formatSize(prop.total_size) },
{ label: 'Pieces', value: (prop) => `${prop.pieces_num} x ${formatSize(prop.piece_size)} (have ${prop.pieces_have})` },
{ label: 'Created by', value: (prop) => prop.created_by },
{ label: 'Created on', value: (prop) => formatTimestamp(prop.creation_date) },
{ label: 'Added on', value: (prop) => formatTimestamp(prop.addition_date) },
{ label: 'Completed on', value: (prop) => formatTimestamp(prop.completion_date) },
{ label: 'Torrent hash', value: (prop) => this.torrent.hash },
{ label: 'Save path', value: (prop) => prop.save_path },
{ label: 'Comment', value: (prop) => prop.comment },
{ label: 'Total size', value: prop => formatSize(prop.total_size) },
{ label: 'Pieces', value: prop => `${prop.pieces_num} x ${formatSize(prop.piece_size)} (have ${prop.pieces_have})` },
{ label: 'Created by', value: prop => prop.created_by },
{ label: 'Created on', value: prop => formatTimestamp(prop.creation_date) },
{ label: 'Added on', value: prop => formatTimestamp(prop.addition_date) },
{ label: 'Completed on', value: prop => formatTimestamp(prop.completion_date) },
{ label: 'Torrent hash', value: prop => this.torrent.hash },
{ label: 'Save path', value: prop => prop.save_path },
{ label: 'Comment', value: prop => prop.comment },
],
};
},
@@ -173,4 +178,4 @@ export default Vue.extend({
white-space: nowrap;
}
}
</style>
</style>

View File

@@ -68,7 +68,7 @@ export function codeToFlag(code: string) {
export const isWindows = navigator.userAgent.includes('Windows');
export function getSameNamedTorrents(allTorrents: Array<any>, torrents: Array<any>) {
const hashes = _.map(torrents, (t) => t.hash);
const hashes = _.map(torrents, t => t.hash);
const result = [];
for (const t1 of torrents) {
for (const t2 of allTorrents) {
@@ -76,7 +76,7 @@ export function getSameNamedTorrents(allTorrents: Array<any>, torrents: Array<an
continue;
}
if (t1.name != t2.name) {
if (t1.name !== t2.name) {
continue;
}
@@ -86,4 +86,4 @@ export function getSameNamedTorrents(allTorrents: Array<any>, torrents: Array<an
}
return result;
};
}