mirror of
https://github.com/VueTorrent/VueTorrent.git
synced 2025-02-18 00:02:02 +03:00
perf: better share limit modal (#316)
This commit is contained in:
parent
4d1e7e069c
commit
9f2ca4230d
10 changed files with 947 additions and 838 deletions
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
|
@ -19,6 +19,8 @@ jobs:
|
|||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
release-type: node
|
||||
package-name: VueTorrent
|
||||
changelog-types: '[{"type":"feat","section":"Features","hidden":false},{"type":"fix","section":"Bug Fixes","hidden":false},{"type":"perf","section":"Improvements","hidden":false}]'
|
||||
|
||||
upload-release:
|
||||
needs: setup-release
|
||||
if: ${{ needs.setup-release.outputs.release_created }}
|
||||
|
|
1541
package-lock.json
generated
1541
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -255,19 +255,7 @@ export default {
|
|||
<style lang="scss" scoped>
|
||||
// Reversed input variant
|
||||
::v-deep .v-input--reverse .v-input__slot {
|
||||
flex-direction: row-reverse;
|
||||
justify-content: flex-end;
|
||||
.v-application--is-ltr & {
|
||||
.v-input--selection-controls__input {
|
||||
margin-right: 0;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
.v-application--is-rtl & {
|
||||
.v-input--selection-controls__input {
|
||||
margin-left: 0;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
@import "src/styles/styles.scss";
|
||||
@include reverse-switch;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
|
88
src/components/Modals/ShareLimit/ShareLimitInput.vue
Normal file
88
src/components/Modals/ShareLimit/ShareLimitInput.vue
Normal file
|
@ -0,0 +1,88 @@
|
|||
<template>
|
||||
<div style="min-width: 300px;">
|
||||
<h3>{{ title }}</h3>
|
||||
<v-list-item>
|
||||
<v-row dense>
|
||||
<v-col>
|
||||
<v-switch
|
||||
v-model="global"
|
||||
class="v-input--reverse pa-0 ma-0"
|
||||
hide-details
|
||||
inset
|
||||
label="Use global limit"
|
||||
@change="disableUnlimited"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<v-row dense>
|
||||
<v-col>
|
||||
<v-switch
|
||||
v-model="unlimited"
|
||||
class="v-input--reverse pa-0 ma-0"
|
||||
hide-details
|
||||
inset
|
||||
label="Unlimited"
|
||||
@change="disabledGlobal"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-list-item>
|
||||
<v-list-item class="mx-2">
|
||||
<v-text-field
|
||||
v-model="limit"
|
||||
type="number"
|
||||
autofocus
|
||||
clearable
|
||||
dense
|
||||
:label="`${title} Limit`"
|
||||
:prepend-inner-icon="title === 'Ratio' ? mdiPercent : mdiClockTimeEight"
|
||||
/>
|
||||
</v-list-item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mdiPercent, mdiClose, mdiClockTimeEight } from '@mdi/js'
|
||||
export default {
|
||||
name: 'ShareLimitInput',
|
||||
props: ['title', 'initialLimit'],
|
||||
data() {
|
||||
return {
|
||||
mdiPercent, mdiClose, mdiClockTimeEight,
|
||||
global: false,
|
||||
unlimited: false,
|
||||
limit: ''
|
||||
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (this.initialLimit === -2) {
|
||||
this.global = true
|
||||
|
||||
return
|
||||
}
|
||||
if (this.initialLimit === -1) {
|
||||
this.unlimited = true
|
||||
|
||||
return
|
||||
}
|
||||
this.limit = this.initialLimit
|
||||
},
|
||||
methods: {
|
||||
disableUnlimited() {
|
||||
this.unlimited = false
|
||||
},
|
||||
disabledGlobal() {
|
||||
this.global = false
|
||||
},
|
||||
export() {
|
||||
if (this.global) return -2
|
||||
if (this.unlimited) return -1
|
||||
|
||||
return this.limit
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -6,41 +6,27 @@
|
|||
max-width="500px"
|
||||
:fullscreen="isPhone"
|
||||
>
|
||||
<v-card>
|
||||
<v-card class="px-2">
|
||||
<v-card-title class="pa-0">
|
||||
<v-toolbar-title class="ma-4 primarytext--text">
|
||||
<h3>Limit ratio</h3>
|
||||
<h3>Limit Ratio</h3>
|
||||
</v-toolbar-title>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-text-field
|
||||
v-model="limit"
|
||||
autofocus
|
||||
clearable
|
||||
label="Ratio Limit"
|
||||
:prepend-inner-icon="mdiSpeedometer"
|
||||
@focus="$event.target.select()"
|
||||
@keydown.enter="setLimit"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
<v-card-text class="px-4 py-2">
|
||||
<ShareLimitInput ref="ratio" title="Ratio" :initial-limit="torrent.ratio_limit" />
|
||||
<ShareLimitInput
|
||||
ref="time"
|
||||
title="Duration"
|
||||
:initial-limit="torrent.ratio_time_limit"
|
||||
class="mt-2"
|
||||
/>
|
||||
</v-card-text>
|
||||
<v-divider />
|
||||
<v-card-actions class="justify-end">
|
||||
<v-btn
|
||||
class="accent white--text elevation-0 px-4"
|
||||
@click="setLimit"
|
||||
>
|
||||
<v-btn class="accent white--text elevation-0 px-4" @click="save">
|
||||
Save
|
||||
</v-btn>
|
||||
<v-btn
|
||||
class="error white--text elevation-0 px-4"
|
||||
@click="close"
|
||||
>
|
||||
<v-btn class="error white--text elevation-0 px-4" @click="close">
|
||||
Cancel
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
|
@ -50,22 +36,17 @@
|
|||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import { mdiSpeedometer, mdiClose } from '@mdi/js'
|
||||
import ShareLimitInput from './ShareLimitInput.vue'
|
||||
import { Modal, FullScreenModal } from '@/mixins'
|
||||
import qbit from '@/services/qbit'
|
||||
export default {
|
||||
name: 'ShareLimitModal',
|
||||
components: { ShareLimitInput },
|
||||
mixins: [Modal, FullScreenModal],
|
||||
props: {
|
||||
mode: String,
|
||||
hash: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
limit: '',
|
||||
mdiSpeedometer, mdiClose
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['getTorrent']),
|
||||
torrent() {
|
||||
|
@ -76,9 +57,11 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
setLimit() {
|
||||
console.log(this.limit || -2)
|
||||
qbit.setShareLimit([this.hash], this.limit || -2, -2)
|
||||
save() {
|
||||
qbit.setShareLimit([this.hash],
|
||||
this.$refs.ratio.export(),
|
||||
this.$refs.time.export()
|
||||
)
|
||||
this.close()
|
||||
},
|
||||
close() {
|
||||
|
@ -87,3 +70,11 @@ export default {
|
|||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// Reversed input variant
|
||||
::v-deep .v-input--reverse .v-input__slot {
|
||||
@import "../../../styles/styles";
|
||||
@include reverse-switch;
|
||||
}
|
||||
</style>
|
|
@ -91,19 +91,7 @@ export default {
|
|||
}
|
||||
// Reversed input variant
|
||||
::v-deep .v-input--reverse .v-input__slot {
|
||||
flex-direction: row-reverse;
|
||||
justify-content: flex-end;
|
||||
.v-application--is-ltr & {
|
||||
.v-input--selection-controls__input {
|
||||
margin-right: 0;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
.v-application--is-rtl & {
|
||||
.v-input--selection-controls__input {
|
||||
margin-left: 0;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
@import "src/styles/styles.scss";
|
||||
@include reverse-switch;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -177,10 +177,18 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td :class="commonStyle">
|
||||
Share Limit
|
||||
Share Ratio Limit
|
||||
</td>
|
||||
<td>
|
||||
{{ torrent.ratio_limit }}
|
||||
{{ torrent.ratio_limit | limitToValue }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td :class="commonStyle">
|
||||
Share Time Limit (minutes)
|
||||
</td>
|
||||
<td>
|
||||
{{ torrent.ratio_time_limit | limitToValue }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
|
@ -27,7 +27,7 @@ export function formatSize(value) {
|
|||
if (index < 0) {
|
||||
return `${value} ${unit}`
|
||||
}
|
||||
|
||||
|
||||
return `${toPrecision(value, 3)} ${unit}`
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ export function formatTimestamp(timestamp) {
|
|||
}
|
||||
|
||||
const m = dayjs.unix(timestamp)
|
||||
|
||||
|
||||
return m.format('YYYY-MM-DD HH:mm:ss')
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ Vue.filter('formatTimestamp', formatTimestamp)
|
|||
|
||||
export function formatProgress(progress) {
|
||||
progress *= 100
|
||||
|
||||
|
||||
return `${toPrecision(progress, 3)}%`
|
||||
}
|
||||
|
||||
|
@ -102,8 +102,22 @@ export function getDataValue(a, b) {
|
|||
const c = 1024
|
||||
const d = b || 2
|
||||
const f = Math.floor(Math.log(a) / Math.log(c))
|
||||
|
||||
|
||||
return `${parseFloat((a / Math.pow(c, f)).toFixed(d))}`
|
||||
}
|
||||
|
||||
Vue.filter('getDataValue', getDataValue)
|
||||
|
||||
|
||||
export function limitToValue(value) {
|
||||
if (value === -2) {
|
||||
return 'global'
|
||||
}
|
||||
if (value === -1) {
|
||||
return 'unlimited'
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
Vue.filter('limitToValue', limitToValue)
|
||||
|
|
|
@ -27,7 +27,8 @@ export default class Torrent {
|
|||
this.auto_tmm = data.auto_tmm
|
||||
this.dl_limit = data.dl_limit
|
||||
this.up_limit = data.up_limit
|
||||
this.ratio_limit = data.ratio_limit
|
||||
this.ratio_limit = data.max_ratio
|
||||
this.ratio_time_limit = data.max_seeding_time
|
||||
this.availability = Math.round(data.availability * 100) / 100
|
||||
this.forced = data.state.includes('forced')
|
||||
this.magnet = data.magnet_uri
|
||||
|
|
|
@ -145,4 +145,22 @@ body {
|
|||
background: gray;
|
||||
border-radius: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reversed switch input variant
|
||||
@mixin reverse-switch {
|
||||
flex-direction: row-reverse;
|
||||
justify-content: flex-end;
|
||||
.v-application--is-ltr & {
|
||||
.v-input--selection-controls__input {
|
||||
margin-right: 0;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
.v-application--is-rtl & {
|
||||
.v-input--selection-controls__input {
|
||||
margin-left: 0;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue