perf: only update changed data + code cleanup

This commit is contained in:
Daan Wijns 2021-04-04 11:04:32 +02:00
parent 89cf6ba32c
commit 664e4dbe2f
15 changed files with 183 additions and 77 deletions

View file

@ -0,0 +1,14 @@
import * as _ from 'lodash'
export class ArrayHelper {
static remove(array, item) {
const toRemove = Array.isArray(item) ? item : [item]
_.remove(array, item => toRemove.indexOf(item) > -1)
return array
}
static concat(a, b) {
return _.concat(a, b)
}
}

13
src/Helpers/Hostname.js Normal file
View file

@ -0,0 +1,13 @@
export class Hostname {
static get(url) {
const match = url.match(/:\/\/(www[0-9]?\.)?(.[^/:]+)/i)
if (match != null &&
match.length > 2 &&
typeof match[2] === 'string' &&
match[2].length > 0) {
return match[2]
} else {
return ''
}
}
}

6
src/Helpers/index.js Normal file
View file

@ -0,0 +1,6 @@
import { ArrayHelper } from './ArrayHelper'
import { Hostname } from './Hostname'
export {
ArrayHelper, Hostname
}

View file

@ -1,29 +1,33 @@
import { formatBytes } from '@/helpers'
import store from '../store'
export class DocumentTitle {
static setDefault() {
this.set('VueTorrent')
}
static setGlobalSpeed(speeds) {
if (!speeds || speeds.length !== 2) return
this.set(`[D: ${formatBytes(speeds[0])}/s, U: ${formatBytes(speeds[1])}/s] VueTorrent`)
static setGlobalSpeed() {
const status = store.getters.getStatus()
this.set(`[D: ${formatBytes(status.upspeed)}/s, U: ${formatBytes(status.dlspeed)}/s] VueTorrent`)
}
static setFirstTorrentStatus(torrent) {
if (!torrent) return
static setFirstTorrentStatus() {
const torrents = store.getters.getTorrents()
if (!torrents && !torrents.length) return
const torrent = torrents[0]
this.set(`[D: ${formatBytes(torrent.dlspeed)}/s, U: ${formatBytes(torrent.upspeed)}/s] ${torrent.progress}%`)
}
static updateTitle(mode, speeds, torrent) {
if (!mode || !speeds.length || !torrent) return
static update() {
const mode = store.getters.getWebuiSettings().title
switch (mode) {
case 'Default':
return this.setDefault()
case 'Global Speed':
return this.setGlobalSpeed(speeds)
return this.setGlobalSpeed()
case 'First Torrent Status':
return this.setFirstTorrentStatus(torrent)
return this.setFirstTorrentStatus()
default:
return this.setDefault()
}

11
src/actions/Graph.js Normal file
View file

@ -0,0 +1,11 @@
import store from '../store'
export class Graph {
static update() {
const state = store.state
state.download_data.shift()
state.download_data.push(state.status.dlspeedRaw || 0)
state.upload_data.shift()
state.upload_data.push(state.status.upspeedRaw || 0)
}
}

View file

@ -0,0 +1,10 @@
import store from '../store'
import Status from '@/models/Status'
export class ServerStatus {
static update(response) {
if (response.server_state) {
store.state.status = new Status(response.server_state)
}
}
}

24
src/actions/Tags.js Normal file
View file

@ -0,0 +1,24 @@
import store from '../store'
import { ArrayHelper } from '@/Helpers'
export class Tags {
static update(response) {
if (response?.full_update === true) {
store.state.tags = response.tags
return
}
if (response.tags_removed) {
store.state.tags = ArrayHelper.remove(store.state.tags, response.tags_removed)
return
}
if (response.tags) {
store.state.tags = ArrayHelper.concat(store.state.tags, response.tags)
}
}
}

17
src/actions/Torrents.js Normal file
View file

@ -0,0 +1,17 @@
import store from '../store'
import { Hostname } from '@/Helpers'
import Torrent from '@/models/Torrent'
export class Torrents {
static update(data) {
if (store.state.webuiSettings.showTrackerFilter) { // dont calculate trackers when disabled
if (store.state.sort_options.tracker !== null) {
data = data.filter(d => Hostname.get(d.tracker) === store.state.sort_options.tracker)
}
}
// update torrents
store.state.torrents = data.map(t => new Torrent(t))
}
}

13
src/actions/Trackers.js Normal file
View file

@ -0,0 +1,13 @@
import store from '../store'
import { Hostname } from '@/Helpers'
export class Trackers {
static update(data) {
if (store.state.webuiSettings.showTrackerFilter) {
store.state.trackers = data.map(t => t.tracker)
.map(url => Hostname.get(url))
.filter((domain, index, self) => index === self.indexOf(domain) && domain)
.sort()
}
}
}

View file

@ -1,5 +1,11 @@
import { DocumentTitle } from './DocumentTitle'
import { Tags } from './Tags'
import { Torrents } from './Torrents'
import { Trackers } from './Trackers'
import { Graph } from './Graph'
import { ServerStatus } from './ServerStatus'
export {
DocumentTitle
DocumentTitle, Tags, Torrents, Trackers,
Graph, ServerStatus
}

View file

@ -1,18 +1,29 @@
import store from '../store'
export default class Status {
constructor(data, tags) {
if (data) {
this.status = data.connection_status
this.downloaded = data.dl_info_data
this.uploaded = data.up_info_data
this.dlspeed = data.dl_info_speed
this.upspeed = data.up_info_speed
this.freeDiskSpace = data.free_space_on_disk
this.altSpeed = data.use_alt_speed_limits
this.dlspeedRaw = this.formatSpeed(data.dl_info_speed)
this.upspeedRaw = this.formatSpeed(data.up_info_speed)
this.tags = tags
Object.freeze(this)
}
constructor({
connection_status,
dl_info_data,
up_info_data,
dl_info_speed,
up_info_speed,
free_space_on_disk,
use_alt_speed_limits
}) {
const previous = store.state.status
this.status = connection_status || previous.status
this.downloaded = dl_info_data || previous.downloaded
this.uploaded = up_info_data || previous.uploaded
this.dlspeed = dl_info_speed || previous.dlspeed
this.upspeed = up_info_speed || previous.upspeed
this.freeDiskSpace = free_space_on_disk || previous.freeDiskSpace
this.altSpeed = use_alt_speed_limits || previous.altSpeed
this.dlspeedRaw = this.formatSpeed(dl_info_speed) || previous.dlspeedRaw
this.upspeedRaw = this.formatSpeed(up_info_speed) || previous.upspeedRaw
Object.freeze(this)
}
formatSpeed(value) {

View file

@ -12,7 +12,7 @@ class Qbit {
execute(method, action, params) {
if (method === 'post') {
const data = new URLSearchParams(params)
return this.axios.post(action, data).then(res => res.data)
}
}
@ -35,7 +35,7 @@ class Qbit {
return status === 200 || status === 403
}
})
return data
}
@ -62,6 +62,7 @@ class Qbit {
getMainData(rid) {
return this.axios.get(
'/sync/maindata', { params: { rid } })
.then(res => res.data)
}
switchToOldUi() {
@ -121,7 +122,7 @@ class Qbit {
hash,
name
}
return this.axios.get('/torrents/rename', { params })
}
@ -167,7 +168,7 @@ class Qbit {
} else {
data = new URLSearchParams(params)
}
return this.axios.post('/torrents/add', data)
}
@ -177,13 +178,13 @@ class Qbit {
id: idList.join('|'),
priority
}
return this.execute('post', '/torrents/filePrio', params)
}
deleteTorrents(hashes, deleteFiles) {
if (!hashes.length) return
return this.torrentAction('delete', hashes, { deleteFiles })
}
@ -248,16 +249,16 @@ class Qbit {
hash,
urls: trackers
}
return this.execute('post', '/torrents/addTrackers', params)
}
removeTorrentTrackers(hash, trackers) {
const params = {
hash,
urls: trackers.join('|')
urls: trackers.join('|')
}
return this.execute('post', '/torrents/removeTrackers', params)
}
@ -266,7 +267,7 @@ class Qbit {
hashes: hashes.length ? hashes.join('|') : 'all',
...extra
}
return this.execute('post', `/torrents/${action}`, params)
}
@ -276,7 +277,7 @@ class Qbit {
id,
name
}
return this.execute('post', '/torrents/renameFile', params)
}
@ -344,7 +345,7 @@ class Qbit {
category: cat.name,
savePath: cat.savePath
}
return this.execute('post', '/torrents/editCategory', params)
}
@ -359,7 +360,7 @@ class Qbit {
names: plugins.join('|'),
enable
}
return this.execute('post', '/search/enablePlugin', params)
}
@ -369,7 +370,7 @@ class Qbit {
plugins: Array.isArray(plugins) ? plugins.join('|') : 'all',
category: 'all'
}
return this.execute('post', '/search/start', params)
}

View file

@ -9,7 +9,7 @@ export default {
getTorrent: state => hash =>
state.torrents.filter(el => el.hash === hash)[0],
getWebuiSettings: state => () => state.webuiSettings,
getAvailableTags: state => () => state.status.tags,
getAvailableTags: state => () => state.tags,
getCategories: state => () => state.categories,
getModals: state => () => state.modals,
getTorrents: state => () => state.torrents,

View file

@ -97,6 +97,7 @@ export default new Vuex.Store({
},
categories: [],
trackers: [],
tags: [],
filteredTorrentsCount: 0,
latestSelectedTorrent: null,
selectMode: false,

View file

@ -1,8 +1,5 @@
import Torrent from '../models/Torrent'
import Status from '../models/Status'
import qbit from '../services/qbit'
import { getHostName } from '@/helpers'
import { DocumentTitle } from '@/actions'
import { DocumentTitle, Tags, Trackers, Torrents, Graph, ServerStatus } from '@/actions'
export default {
SET_APP_VERSION(state, version) {
@ -45,49 +42,27 @@ export default {
TOGGLE_THEME(state) {
state.webuiSettings.darkTheme = !state.webuiSettings.darkTheme
},
LOGOUT: state => {
qbit.logout()
LOGOUT: async state => {
await qbit.logout()
state.authenticated = false
},
LOGIN: async (state, payload) => {
state.authenticated = payload
},
updateMainData: async state => {
const res = await qbit.getMainData(undefined)
const response = await qbit.getMainData(state.rid || undefined)
state.rid = response.rid || undefined
// status
state.status = new Status(res.data.server_state, res.data.tags)
ServerStatus.update(response)
Tags.update(response)
Graph.update()
// graph
state.download_data.splice(0, 1)
state.download_data.push(state.status.dlspeedRaw)
state.upload_data.splice(0, 1)
state.upload_data.push(state.status.upspeedRaw)
// fetch torrent data
const { data } = await qbit.getTorrents(state.sort_options)
// torrents
let { data } = await qbit.getTorrents(state.sort_options)
// trackers
if (state.webuiSettings.showTrackerFilter) { // dont calculate trackers when disabled
state.trackers = data.map(t => t.tracker)
.map(url => getHostName(url))
.filter((domain, index, self) => index === self.indexOf(domain) && domain)
.sort()
if (state.sort_options.tracker !== null) {
data = data.filter(d => getHostName(d.tracker) === state.sort_options.tracker)
}
}
// torrents
state.torrents = data.map(t => new Torrent(t))
// update document title
DocumentTitle.updateTitle(
state.webuiSettings.title,
[state.status.dlspeed, state.status.upspeed],
state.torrents ? state.torrents[0] : null
)
Trackers.update(data)
Torrents.update(data)
DocumentTitle.update()
},
FETCH_SETTINGS: async state => {
const { data } = await qbit.getAppPreferences()