feat(ShareLimit): Add torrent share limit dialog

This commit is contained in:
Larsluph 2023-11-05 18:55:24 +01:00 committed by Daan Wijns
parent c61b957683
commit ed0991e0a5
7 changed files with 157 additions and 6 deletions

View file

@ -3,6 +3,7 @@ import RightClickMenuEntry from '@/components/Dashboard/TRC/RightClickMenuEntry.
import ConfirmDeleteDialog from '@/components/Dialogs/ConfirmDeleteDialog.vue'
import MoveTorrentDialog from '@/components/Dialogs/MoveTorrentDialog.vue'
import RenameTorrentDialog from '@/components/Dialogs/RenameTorrentDialog.vue'
import ShareLimitDialog from '@/components/Dialogs/ShareLimitDialog.vue'
import SpeedLimitDialog from '@/components/Dialogs/SpeedLimitDialog.vue'
import { useDashboardStore } from '@/stores/dashboard'
import { useDialogStore } from '@/stores/dialog'
@ -103,7 +104,7 @@ function setUploadLimit() {
}
function setShareLimit() {
//TODO: dialogStore.createDialog(ShareLimitDialog, { hash: hash.value })
dialogStore.createDialog(ShareLimitDialog, { hash: hash.value })
}
async function exportTorrents() {
@ -231,7 +232,6 @@ const menuData = computed<TRCMenuEntry[]>(() => [
{
text: t('dashboard.right_click.speed_limit.share'),
icon: 'mdi-account-group',
hidden: true,
action: setShareLimit
}
]

View file

@ -0,0 +1,133 @@
<script setup lang="ts">
import { useDialog } from '@/composables'
import { useMaindataStore } from '@/stores/maindata'
import { computed, onBeforeMount, ref } from 'vue'
type ShareType = 'global' | 'disabled' | 'enabled'
const GLOBAL = -2
const DISABLED = -1
const props = defineProps<{
guid: string
hash: string
}>()
const { isOpened } = useDialog(props.guid)
const maindataStore = useMaindataStore()
const isFormValid = ref(false)
const shareType = ref<ShareType>('global')
const ratioLimitEnabled = ref(false)
const ratioLimit = ref(0)
const seedingTimeLimitEnabled = ref(false)
const seedingTimeLimit = ref(0)
const inactiveSeedingTimeLimitEnabled = ref(false)
const inactiveSeedingTimeLimit = ref(0)
const isFieldsDisabled = computed(() => shareType.value !== 'enabled')
function close() {
isOpened.value = false
}
async function submit() {
switch (shareType.value) {
case 'global':
await maindataStore.setShareLimit([props.hash], GLOBAL, GLOBAL, GLOBAL)
break
case 'disabled':
await maindataStore.setShareLimit([props.hash], DISABLED, DISABLED, DISABLED)
break
case 'enabled':
await maindataStore.setShareLimit([props.hash],
ratioLimitEnabled.value ? ratioLimit.value : DISABLED,
seedingTimeLimitEnabled.value ? seedingTimeLimit.value : DISABLED,
inactiveSeedingTimeLimitEnabled.value ? inactiveSeedingTimeLimit.value : DISABLED)
break
}
close()
}
onBeforeMount(async () => {
const torrent = maindataStore.getTorrentByHash(props.hash)
if (!torrent) {
return close()
}
const ratio_limit = torrent.ratio_limit
const seeding_time_limit = torrent.seeding_time_limit
const inactive_seeding_time_limit = torrent.inactive_seeding_time_limit
if (ratio_limit === GLOBAL && seeding_time_limit === GLOBAL && inactive_seeding_time_limit === GLOBAL) {
shareType.value = 'global'
} else if (ratio_limit === DISABLED && seeding_time_limit === DISABLED && inactive_seeding_time_limit === DISABLED) {
shareType.value = 'disabled'
} else {
shareType.value = 'enabled'
ratioLimitEnabled.value = ratio_limit >= 0
ratioLimit.value = ratioLimitEnabled.value ? ratio_limit : 0
seedingTimeLimitEnabled.value = seeding_time_limit >= 0
seedingTimeLimit.value = seedingTimeLimitEnabled.value ? seeding_time_limit : 0
inactiveSeedingTimeLimitEnabled.value = inactive_seeding_time_limit >= 0
inactiveSeedingTimeLimit.value = inactiveSeedingTimeLimitEnabled.value ? inactive_seeding_time_limit : 0
}
})
</script>
<template>
<v-dialog v-model="isOpened" max-width="500">
<v-card :title="$t('dialogs.share_limit.title')">
<v-card-text>
<v-form v-model="isFormValid" @submit.prevent @keydown.enter.prevent="submit">
<v-radio-group v-model="shareType">
<v-radio :label="$t('dialogs.share_limit.global')" value="global" />
<v-radio :label="$t('dialogs.share_limit.disabled')" value="disabled" />
<v-radio :label="$t('dialogs.share_limit.enabled')" value="enabled" />
</v-radio-group>
<v-row>
<v-col cols="12" class="d-flex align-center">
<span><v-checkbox-btn v-model="ratioLimitEnabled" :disabled="isFieldsDisabled" /></span>
<v-text-field v-model="ratioLimit"
:disabled="isFieldsDisabled || !ratioLimitEnabled"
density="compact"
hide-details
:label="$t('dialogs.share_limit.ratio_limit')" />
</v-col>
<v-col cols="12" class="d-flex align-center">
<span><v-checkbox-btn v-model="seedingTimeLimitEnabled" :disabled="isFieldsDisabled" /></span>
<v-text-field v-model="seedingTimeLimit"
:disabled="isFieldsDisabled || !seedingTimeLimitEnabled"
density="compact"
hide-details
:label="$t('dialogs.share_limit.seeding_time_limit')" />
</v-col>
<v-col cols="12" class="d-flex align-center">
<span><v-checkbox-btn v-model="inactiveSeedingTimeLimitEnabled" :disabled="isFieldsDisabled" /></span>
<v-text-field v-model="inactiveSeedingTimeLimit"
:disabled="isFieldsDisabled || !inactiveSeedingTimeLimitEnabled"
density="compact"
hide-details
:label="$t('dialogs.share_limit.inactive_seeding_time_limit')" />
</v-col>
</v-row>
</v-form>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn color="error" @click="close">{{ $t('common.cancel') }}</v-btn>
<v-btn color="accent" :disabled="!isFormValid" @click="submit">{{ $t('common.save') }}</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<style scoped>
</style>

View file

@ -28,6 +28,7 @@ export function useTorrentBuilder() {
f_l_piece_prio: data.f_l_piece_prio,
forced: data.force_start,
hash: data.hash,
inactive_seeding_time_limit: data.inactive_seeding_time_limit,
infohash_v1: data.infohash_v1,
infohash_v2: data.infohash_v2,
last_activity: data.last_activity,
@ -38,10 +39,10 @@ export function useTorrentBuilder() {
priority: data.priority,
progress: data.progress,
ratio: Math.round(data.ratio * 100) / 100,
ratio_limit: data.max_ratio,
ratio_time_limit: data.max_seeding_time,
ratio_limit: data.ratio_limit,
savePath: data.save_path,
seeding_time: data.seeding_time,
seeding_time_limit: data.seeding_time_limit,
seen_complete: data.seen_complete,
seq_dl: data.seq_dl,
size: data.size,

View file

@ -550,6 +550,15 @@
"download": "Set Download Speed Limit",
"upload": "Set Upload Speed Limit",
"label": "Speed Limit"
},
"share_limit": {
"title": "Set Share Ratio Limit",
"global": "Use global share limit",
"disabled": "Set no share limit",
"enabled": "Set share limit to",
"ratio_limit": "Ratio",
"seeding_time_limit": "Total minutes",
"inactive_seeding_time_limit": "Inactive minutes"
}
},
"settings": {

View file

@ -311,6 +311,10 @@ export const useMaindataStore = defineStore('maindata', () => {
return await qbit.setUploadLimit(hashes, limit)
}
async function setShareLimit(hashes: string[], ratioLimit: number, seedingTimeLimit: number, inactiveSeedingTimeLimit: number) {
return await qbit.setShareLimit(hashes, ratioLimit, seedingTimeLimit, inactiveSeedingTimeLimit)
}
return {
categories,
isUpdatingMaindata,
@ -364,7 +368,8 @@ export const useMaindataStore = defineStore('maindata', () => {
setTorrentFilePriority,
exportTorrent,
setDownloadLimit,
setUploadLimit
setUploadLimit,
setShareLimit
}
}, {
persist: {

View file

@ -35,6 +35,7 @@ export default interface Torrent {
force_start: boolean
/** Torrent hash */
hash: string
inactive_seeding_time_limit: number
/** Torrent SHA1 Hash */
infohash_v1: string
/** Torrent SHA256 Hash (only in LibTorrent v2) */
@ -43,6 +44,7 @@ export default interface Torrent {
last_activity: number
/** Magnet URI corresponding to this torrent */
magnet_uri: string
max_inactive_seeding_time: number
/** Maximum share ratio until torrent is stopped from seeding/uploading */
max_ratio: number
/** Maximum seeding time (seconds) until torrent is stopped from seeding */

View file

@ -19,6 +19,7 @@ export default interface Torrent {
f_l_piece_prio: boolean
forced: boolean
hash: string
inactive_seeding_time_limit: number
infohash_v1: string
infohash_v2: string
last_activity: number
@ -30,9 +31,9 @@ export default interface Torrent {
progress: number
ratio: number
ratio_limit: number
ratio_time_limit: number
savePath: string
seeding_time: number
seeding_time_limit: number
seen_complete: number
seq_dl: boolean
size: number