mirror of
https://github.com/VueTorrent/VueTorrent.git
synced 2024-11-28 21:18:54 +03:00
Merge pull request #451 from WDaan/feat/rss
feat: basic rss interface (#447)
This commit is contained in:
commit
04cd58c693
15 changed files with 575 additions and 49 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -2,6 +2,9 @@
|
|||
node_modules
|
||||
/dist
|
||||
|
||||
# asdf config
|
||||
.tool-versions
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
|
95
src/components/Modals/Rss/FeedForm.vue
Normal file
95
src/components/Modals/Rss/FeedForm.vue
Normal file
|
@ -0,0 +1,95 @@
|
|||
<template>
|
||||
<v-dialog v-model="dialog" content-class="rounded-form" max-width="300px">
|
||||
<v-card>
|
||||
<v-card-title class="pa-0">
|
||||
<v-toolbar-title class="ma-4 primarytext--text">
|
||||
<h3>{{ hasInitialFeed ? $t('edit') : $t('createNew') }} {{ $t('feed') }}</h3>
|
||||
</v-toolbar-title>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-form ref="feedForm" class="px-6 mt-3">
|
||||
<v-container>
|
||||
<v-text-field
|
||||
v-model="feed.url"
|
||||
:label="$t('modals.newFeed.url')"
|
||||
required
|
||||
/>
|
||||
</v-container>
|
||||
</v-form>
|
||||
</v-card-text>
|
||||
<v-divider />
|
||||
<v-card-actions class="justify-end">
|
||||
<v-btn
|
||||
v-if="!hasInitialFeed"
|
||||
class="accent white--text elevation-0 px-4"
|
||||
@click="create"
|
||||
>
|
||||
{{ $t('create') }}
|
||||
</v-btn>
|
||||
<v-btn
|
||||
v-else
|
||||
class="accent white--text elevation-0 px-4"
|
||||
@click="edit"
|
||||
>
|
||||
{{ $t('edit') }}
|
||||
</v-btn>
|
||||
<v-btn
|
||||
class="error white--text elevation-0 px-4"
|
||||
@click="cancel"
|
||||
>
|
||||
{{ $t('cancel') }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import qbit from '@/services/qbit'
|
||||
import { Modal } from '@/mixins'
|
||||
import { mdiCancel, mdiTagPlus, mdiPencil } from '@mdi/js'
|
||||
import Vue from 'vue'
|
||||
|
||||
export default {
|
||||
name: 'FeedForm',
|
||||
mixins: [Modal],
|
||||
props: {
|
||||
initialFeed: Object
|
||||
},
|
||||
data: () => ({
|
||||
feed: { url: '' },
|
||||
mdiCancel, mdiTagPlus, mdiPencil
|
||||
}),
|
||||
computed: {
|
||||
...mapGetters(['getSelectedFeed']),
|
||||
hasInitialFeed() {
|
||||
return !!(this.initialFeed &&
|
||||
this.initialFeed.name)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$store.commit('FETCH_FEEDS')
|
||||
if (this.hasInitialFeed) {
|
||||
this.feed = this.initialFeed
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
create() {
|
||||
qbit.createFeed(this.feed)
|
||||
this.cancel()
|
||||
},
|
||||
cancel() {
|
||||
this.$store.commit('FETCH_FEEDS')
|
||||
this.dialog = false
|
||||
},
|
||||
edit() {
|
||||
qbit.editfeed(this.feed)
|
||||
Vue.$toast.success(this.$t('toast.feedSaved'))
|
||||
this.cancel()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
123
src/components/Modals/Rss/RuleForm.vue
Normal file
123
src/components/Modals/Rss/RuleForm.vue
Normal file
|
@ -0,0 +1,123 @@
|
|||
<template>
|
||||
<v-dialog v-model="dialog" max-width="300px">
|
||||
<v-card flat>
|
||||
<v-card-title class="pa-0">
|
||||
<v-toolbar-title class="ma-4 primarytext--text">
|
||||
<h3>{{ hasInitialRule ? $t('edit') : $t('createNew') }} {{ $t('rule') }}</h3>
|
||||
</v-toolbar-title>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-form ref="ruleForm" class="px-6 mt-3">
|
||||
<v-container>
|
||||
<v-text-field
|
||||
v-model="rule.name"
|
||||
:label="$t('modals.newRule.name')"
|
||||
required
|
||||
/>
|
||||
</v-container>
|
||||
<v-container>
|
||||
<v-text-field
|
||||
v-model="rule.def.mustContain"
|
||||
:label="$t('modals.newRule.def.mustContain')"
|
||||
required
|
||||
/>
|
||||
</v-container>
|
||||
<v-container>
|
||||
<v-subheader>{{ $t('modals.newRule.def.affectedFeeds') }}</v-subheader>
|
||||
<template v-for="(item, index) in availableFeeds">
|
||||
<v-checkbox
|
||||
:key="index"
|
||||
v-model="rule.def.affectedFeeds"
|
||||
:label="item.name"
|
||||
:value="item.url"
|
||||
/>
|
||||
</template>
|
||||
</v-container>
|
||||
</v-form>
|
||||
</v-card-text>
|
||||
<v-divider />
|
||||
<v-card-actions class="justify-end">
|
||||
<v-btn
|
||||
v-if="!hasInitialRule"
|
||||
class="accent white--text elevation-0 px-4"
|
||||
@click="create"
|
||||
>
|
||||
{{ $t('create') }}
|
||||
</v-btn>
|
||||
<v-btn
|
||||
v-else
|
||||
class="accent white--text elevation-0 px-4"
|
||||
@click="edit"
|
||||
>
|
||||
{{ $t('edit') }}
|
||||
</v-btn>
|
||||
<v-btn
|
||||
class="error white--text elevation-0 px-4"
|
||||
@click="cancel"
|
||||
>
|
||||
{{ $t('cancel') }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import qbit from '@/services/qbit'
|
||||
import { Modal } from '@/mixins'
|
||||
import { mdiCancel, mdiTagPlus, mdiPencil } from '@mdi/js'
|
||||
import Vue from 'vue'
|
||||
|
||||
export default {
|
||||
name: 'RuleForm',
|
||||
mixins: [Modal],
|
||||
props: {
|
||||
initialRule: Object
|
||||
},
|
||||
data: () => ({
|
||||
rule: {
|
||||
name: '',
|
||||
def: {
|
||||
mustContain: '',
|
||||
affectedFeeds: [],
|
||||
enabled: true
|
||||
}
|
||||
},
|
||||
mdiCancel, mdiTagPlus, mdiPencil
|
||||
}),
|
||||
computed: {
|
||||
...mapGetters(['getSelectedRule', 'getFeeds']),
|
||||
availableFeeds() {
|
||||
return this.getFeeds()
|
||||
},
|
||||
hasInitialRule() {
|
||||
return !!(this.initialRule &&
|
||||
this.initialRule.name)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$store.commit('FETCH_RULES')
|
||||
if (this.hasInitialRule) {
|
||||
this.rule = this.initialRule
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
create() {
|
||||
qbit.createRule(this.rule.name, this.rule.def)
|
||||
this.cancel()
|
||||
},
|
||||
cancel() {
|
||||
this.$store.commit('FETCH_RULES')
|
||||
this.dialog = false
|
||||
},
|
||||
edit() {
|
||||
qbit.editRule(this.rule)
|
||||
Vue.$toast.success(this.$t('toast.ruleSaved'))
|
||||
this.cancel()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
4
src/components/Modals/Rss/index.js
Normal file
4
src/components/Modals/Rss/index.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
import FeedForm from './FeedForm.vue'
|
||||
import RuleForm from './RuleForm.vue'
|
||||
|
||||
export { FeedForm, RuleForm }
|
44
src/components/Settings/Tabs/Rss.vue
Normal file
44
src/components/Settings/Tabs/Rss.vue
Normal file
|
@ -0,0 +1,44 @@
|
|||
<template>
|
||||
<v-card flat>
|
||||
<v-tabs v-model="tab">
|
||||
<v-tab href="#general">
|
||||
{{ $t('modals.settings.pageRss.tabName.general') }}
|
||||
</v-tab>
|
||||
<v-tab href="#feeds">
|
||||
{{ $t('modals.settings.pageRss.tabName.feeds') }}
|
||||
</v-tab>
|
||||
<v-tab href="#rules">
|
||||
{{ $t('modals.settings.pageRss.tabName.rules') }}
|
||||
</v-tab>
|
||||
</v-tabs>
|
||||
<v-tabs-items v-model="tab" touchless>
|
||||
<v-tab-item eager value="general">
|
||||
<General />
|
||||
</v-tab-item>
|
||||
<v-tab-item eager value="feeds">
|
||||
<Feeds />
|
||||
</v-tab-item>
|
||||
<v-tab-item eager value="rules">
|
||||
<Rules />
|
||||
</v-tab-item>
|
||||
</v-tabs-items>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import General from './Rss/General'
|
||||
import Feeds from './Rss/Feeds'
|
||||
import Rules from './Rss/Rules'
|
||||
import { FullScreenModal } from '@/mixins'
|
||||
|
||||
export default {
|
||||
name: 'VueTorrent',
|
||||
components: {
|
||||
General, Feeds, Rules
|
||||
},
|
||||
mixins: [FullScreenModal],
|
||||
data: () => ({
|
||||
tab: null
|
||||
})
|
||||
}
|
||||
</script>
|
69
src/components/Settings/Tabs/Rss/Feeds.vue
Normal file
69
src/components/Settings/Tabs/Rss/Feeds.vue
Normal file
|
@ -0,0 +1,69 @@
|
|||
<template>
|
||||
<v-card flat>
|
||||
<v-row dense class="ma-0 pa-0">
|
||||
<v-col cols="12" md="6">
|
||||
<v-subheader>{{ $t('modals.settings.pageRss.pageFeeds.feeds') }}</v-subheader>
|
||||
<template v-for="(item, index) in availableFeeds">
|
||||
<v-list-item :key="item.uid">
|
||||
<v-list-item-content>
|
||||
<v-list-item-title v-text="item.name" />
|
||||
</v-list-item-content>
|
||||
<v-list-item-action>
|
||||
<v-icon color="red" @click="deleteFeed(item)">
|
||||
{{ mdiDelete }}
|
||||
</v-icon>
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
<v-divider
|
||||
v-if="index < availableFeeds.length - 1"
|
||||
:key="index"
|
||||
/>
|
||||
</template>
|
||||
<v-list-item>
|
||||
<v-btn
|
||||
class="mx-auto accent white--text elevation-0 px-4"
|
||||
@click="createFeed"
|
||||
>
|
||||
{{ $t('modals.settings.pageRss.pageFeeds.btnCreateNew') }}
|
||||
</v-btn>
|
||||
</v-list-item>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card>
|
||||
</template>
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import qbit from '@/services/qbit'
|
||||
import { mdiDelete } from '@mdi/js'
|
||||
|
||||
import { Tab, General, FullScreenModal } from '@/mixins'
|
||||
|
||||
export default {
|
||||
name: 'Feeds',
|
||||
mixins: [Tab, General, FullScreenModal],
|
||||
data: () => ({
|
||||
mdiDelete
|
||||
}),
|
||||
computed: {
|
||||
...mapGetters(['getFeeds']),
|
||||
availableFeeds() {
|
||||
return this.getFeeds()
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$store.commit('FETCH_FEEDS')
|
||||
},
|
||||
methods: {
|
||||
activeMethod() {
|
||||
this.$store.commit('FETCH_FEEDS')
|
||||
},
|
||||
deleteFeed(item) {
|
||||
qbit.deleteFeed(item.name)
|
||||
this.$store.commit('FETCH_FEEDS')
|
||||
},
|
||||
createFeed() {
|
||||
this.createModal('FeedForm')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
30
src/components/Settings/Tabs/Rss/General.vue
Normal file
30
src/components/Settings/Tabs/Rss/General.vue
Normal file
|
@ -0,0 +1,30 @@
|
|||
<template>
|
||||
<v-card flat>
|
||||
<v-subheader>{{ $t('modals.settings.pageRss.pageGeneral.rssAutoProcessing') }}</v-subheader>
|
||||
<v-list-item>
|
||||
<v-checkbox
|
||||
v-model="settings.rss_processing_enabled"
|
||||
hide-details
|
||||
class="ma-0 pa-0"
|
||||
:label="$t('modals.settings.pageRss.pageGeneral.input.enableRssProcessing')"
|
||||
/>
|
||||
</v-list-item>
|
||||
<v-subheader>{{ $t('modals.settings.pageRss.pageGeneral.rssAutoDownloader') }}</v-subheader>
|
||||
<v-list-item>
|
||||
<v-checkbox
|
||||
v-model="settings.rss_auto_downloading_enabled"
|
||||
hide-details
|
||||
class="ma-0 pa-0"
|
||||
:label="$t('modals.settings.pageRss.pageGeneral.input.enableRssAutoDownload')"
|
||||
/>
|
||||
</v-list-item>
|
||||
</v-card>
|
||||
</template>
|
||||
<script>
|
||||
import { FullScreenModal, SettingsTab } from '@/mixins'
|
||||
|
||||
export default {
|
||||
name: 'Rss',
|
||||
mixins: [SettingsTab, FullScreenModal]
|
||||
}
|
||||
</script>
|
69
src/components/Settings/Tabs/Rss/Rules.vue
Normal file
69
src/components/Settings/Tabs/Rss/Rules.vue
Normal file
|
@ -0,0 +1,69 @@
|
|||
<template>
|
||||
<v-card flat>
|
||||
<v-row dense class="ma-0 pa-0">
|
||||
<v-col cols="12" md="6">
|
||||
<v-subheader>{{ $t('modals.settings.pageRss.pageRules.rules') }}</v-subheader>
|
||||
<template v-for="(item, index) in availableRules">
|
||||
<v-list-item :key="item.uid">
|
||||
<v-list-item-content>
|
||||
<v-list-item-title v-text="item.name" />
|
||||
</v-list-item-content>
|
||||
<v-list-item-action>
|
||||
<v-icon color="red" @click="deleteRule(item)">
|
||||
{{ mdiDelete }}
|
||||
</v-icon>
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
<v-divider
|
||||
v-if="index < availableRules.length - 1"
|
||||
:key="index"
|
||||
/>
|
||||
</template>
|
||||
<v-list-item>
|
||||
<v-btn
|
||||
class="mx-auto accent white--text elevation-0 px-4"
|
||||
@click="createRule"
|
||||
>
|
||||
{{ $t('modals.settings.pageRss.pageRules.btnCreateNew') }}
|
||||
</v-btn>
|
||||
</v-list-item>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card>
|
||||
</template>
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import qbit from '@/services/qbit'
|
||||
import { mdiDelete } from '@mdi/js'
|
||||
|
||||
import { Tab, General, FullScreenModal } from '@/mixins'
|
||||
|
||||
export default {
|
||||
name: 'Rules',
|
||||
mixins: [Tab, General, FullScreenModal],
|
||||
data: () => ({
|
||||
mdiDelete
|
||||
}),
|
||||
computed: {
|
||||
...mapGetters(['getRules']),
|
||||
availableRules() {
|
||||
return this.getRules()
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$store.commit('FETCH_RULES')
|
||||
},
|
||||
methods: {
|
||||
activeMethod() {
|
||||
this.$store.commit('FETCH_RULES')
|
||||
},
|
||||
deleteRule(item) {
|
||||
qbit.deleteRule(item.name)
|
||||
this.$store.commit('FETCH_RULES')
|
||||
},
|
||||
createRule() {
|
||||
this.createModal('RuleForm')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -4,5 +4,6 @@ import Downloads from './Downloads.vue'
|
|||
import VueTorrent from './VueTorrent.vue'
|
||||
import TagsAndCategories from './TagsAndCategories.vue'
|
||||
import Connection from './Connection.vue'
|
||||
import Rss from './Rss.vue'
|
||||
|
||||
export { WebUI, BitTorrent, Downloads, VueTorrent, TagsAndCategories, Connection }
|
||||
export { WebUI, BitTorrent, Downloads, VueTorrent, TagsAndCategories, Connection, Rss }
|
||||
|
|
|
@ -84,6 +84,17 @@ const locale = {
|
|||
|
||||
/** Modals */
|
||||
modals: {
|
||||
newFeed: {
|
||||
feedName: 'Name',
|
||||
url: 'URL'
|
||||
},
|
||||
newRule: {
|
||||
name: 'Name',
|
||||
def: {
|
||||
mustContain: 'Must Contain',
|
||||
affectedFeeds: 'Apply Rule to Feeds'
|
||||
}
|
||||
},
|
||||
pluginManager: {
|
||||
title: 'Plugin manager'
|
||||
},
|
||||
|
@ -106,6 +117,7 @@ const locale = {
|
|||
downloads: 'downloads',
|
||||
connection: 'connection',
|
||||
bittorrent: 'bittorrent',
|
||||
rss: 'Rss',
|
||||
webUI: 'WEB UI',
|
||||
tagsAndCategories: 'tags & categories'
|
||||
},
|
||||
|
@ -191,6 +203,29 @@ const locale = {
|
|||
whenRatioReaches: 'When ratio reaches',
|
||||
whenSeedingTimeReaches: 'When seeding time reaches'
|
||||
},
|
||||
pageRss: {
|
||||
tabName: {
|
||||
general: 'General',
|
||||
feeds: 'Feeds',
|
||||
rules: 'Rules'
|
||||
},
|
||||
pageRules: {
|
||||
rules: 'Rules',
|
||||
btnCreateNew: 'Create Rule'
|
||||
},
|
||||
pageFeeds: {
|
||||
feeds: 'Feeds',
|
||||
btnCreateNew: 'Add feed'
|
||||
},
|
||||
pageGeneral: {
|
||||
rssAutoProcessing: 'RSS Reader',
|
||||
rssAutoDownloader: 'RSS Torrent Auto Downloader',
|
||||
input: {
|
||||
enableRssAutoDownload: 'Enable auto downloading of RSS torrents',
|
||||
enableRssProcessing: 'Enable fetching RSS feeds'
|
||||
}
|
||||
}
|
||||
},
|
||||
pageWebUI: {
|
||||
useAlternativeWebUI: 'Use Alternative WebUI',
|
||||
filesLocation: 'Files location',
|
||||
|
@ -345,7 +380,9 @@ const locale = {
|
|||
loginSuccess: 'Successfully logged in! 🎉',
|
||||
loginFailed: 'Login failed 😕',
|
||||
settingsSaved: 'Settings saved successfully!',
|
||||
categorySaved: 'Category edited successfully!'
|
||||
categorySaved: 'Category edited successfully!',
|
||||
feedSaved: 'Feed saved successfully!',
|
||||
ruleSaved: 'Rule saved!'
|
||||
},
|
||||
|
||||
/** RightClick **/
|
||||
|
|
|
@ -154,6 +154,52 @@ class Qbit {
|
|||
}).then(res => res.data)
|
||||
}
|
||||
|
||||
// RSS
|
||||
|
||||
createFeed(feed) {
|
||||
return this.execute('post', '/rss/addFeed', {
|
||||
url: feed.url,
|
||||
path: feed.url
|
||||
})
|
||||
}
|
||||
|
||||
createRule(ruleName, defs) {
|
||||
return this.execute('post', '/rss/setRule', {
|
||||
ruleName: ruleName,
|
||||
ruleDef: JSON.stringify(defs)
|
||||
})
|
||||
}
|
||||
|
||||
getFeeds() {
|
||||
return this.axios.get('/rss/items')
|
||||
.then(res => res.data)
|
||||
.then(data =>
|
||||
Object.entries(data).map(feed => {
|
||||
return { name: feed[0], ...feed[1] }
|
||||
}))
|
||||
}
|
||||
|
||||
getRules() {
|
||||
return this.axios.get('/rss/rules')
|
||||
.then(res => res.data)
|
||||
.then(data =>
|
||||
Object.entries(data).map(rule => {
|
||||
return { name: rule[0], ...rule[1] }
|
||||
}))
|
||||
}
|
||||
|
||||
deleteRule(ruleName) {
|
||||
return this.execute('post', 'rss/removeRule', {
|
||||
ruleName
|
||||
})
|
||||
}
|
||||
|
||||
deleteFeed(name) {
|
||||
return this.execute('post', 'rss/removeItem', {
|
||||
path: name
|
||||
})
|
||||
}
|
||||
|
||||
// Post
|
||||
|
||||
addTorrents(params, torrents) {
|
||||
|
|
|
@ -11,6 +11,8 @@ export default {
|
|||
getWebuiSettings: state => () => state.webuiSettings,
|
||||
getAvailableTags: state => () => state.tags,
|
||||
getCategories: state => () => state.categories,
|
||||
getFeeds: state => () => state.rss.feeds,
|
||||
getRules: state => () => state.rss.rules,
|
||||
getModals: state => () => state.modals,
|
||||
getTorrents: state => () => state.torrents,
|
||||
getTrackers: state => () => state.trackers,
|
||||
|
|
|
@ -22,6 +22,10 @@ export default new Vuex.Store({
|
|||
state: {
|
||||
version: 0,
|
||||
intervals: [],
|
||||
rss: {
|
||||
feeds: [],
|
||||
rules: []
|
||||
},
|
||||
status: {
|
||||
status: '',
|
||||
downloaded: '',
|
||||
|
|
|
@ -80,6 +80,8 @@ export default {
|
|||
state.sort_options.tracker = tracker
|
||||
},
|
||||
FETCH_CATEGORIES: async state => state.categories = Object.values(await (qbit.getCategories())),
|
||||
FETCH_FEEDS: async state => state.rss.feeds = await qbit.getFeeds(),
|
||||
FETCH_RULES: async state => state.rss.rules = await qbit.getRules(),
|
||||
FETCH_SEARCH_PLUGINS: async state => state.searchPlugins = await qbit.getSearchPlugins(),
|
||||
SET_CURRENT_ITEM_COUNT: (state, count) => (state.filteredTorrentsCount = count),
|
||||
SET_LANGUAGE: async state => await loadLanguageAsync(state.webuiSettings.lang)
|
||||
|
|
|
@ -1,33 +1,17 @@
|
|||
<template>
|
||||
<div
|
||||
class="px-1 px-sm-5 background noselect"
|
||||
>
|
||||
<v-row
|
||||
no-gutters
|
||||
class="grey--text"
|
||||
align="center"
|
||||
justify="center"
|
||||
>
|
||||
<div class="px-1 px-sm-5 background noselect">
|
||||
<v-row no-gutters class="grey--text" align="center" justify="center">
|
||||
<v-col>
|
||||
<h1 style="font-size: 1.6em !important" class="subtitle-1 ml-2">
|
||||
{{ $t('settings') | titleCase }}
|
||||
{{ $t("settings") | titleCase }}
|
||||
</h1>
|
||||
</v-col>
|
||||
<v-col class="align-center justify-center">
|
||||
<v-card-actions class="justify-end">
|
||||
<v-btn
|
||||
class="accent"
|
||||
small
|
||||
elevation="0"
|
||||
@click="saveSettings"
|
||||
>
|
||||
<v-btn class="accent" small elevation="0" @click="saveSettings">
|
||||
<v-icon>{{ mdiContentSave }}</v-icon>
|
||||
</v-btn>
|
||||
<v-btn
|
||||
small
|
||||
elevation="0"
|
||||
@click="close"
|
||||
>
|
||||
<v-btn small elevation="0" @click="close">
|
||||
<v-icon>{{ mdiClose }}</v-icon>
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
|
@ -42,26 +26,28 @@
|
|||
background-color="primary"
|
||||
>
|
||||
<v-tab class="white--text" href="#vuetorrent">
|
||||
<h4>{{ $t('modals.settings.tabName.VueTorrent') }}</h4>
|
||||
<h4>{{ $t("modals.settings.tabName.VueTorrent") }}</h4>
|
||||
</v-tab>
|
||||
<v-tab class="white--text" href="#downloads">
|
||||
<h4>{{ $t('modals.settings.tabName.downloads') }}</h4>
|
||||
<h4>{{ $t("modals.settings.tabName.downloads") }}</h4>
|
||||
</v-tab>
|
||||
<v-tab class="white--text" href="#connection">
|
||||
<h4>{{ $t('modals.settings.tabName.connection') }}</h4>
|
||||
<h4>{{ $t("modals.settings.tabName.connection") }}</h4>
|
||||
</v-tab>
|
||||
<v-tab class="white--text" href="#bittorrent">
|
||||
<h4>{{ $t('modals.settings.tabName.bittorrent') }}</h4>
|
||||
<h4>{{ $t("modals.settings.tabName.bittorrent") }}</h4>
|
||||
</v-tab>
|
||||
<v-tab class="white--text" href="#rss">
|
||||
<h4>{{ $t("modals.settings.tabName.rss") }}</h4>
|
||||
</v-tab>
|
||||
<v-tab class="white--text" href="#webui">
|
||||
<h4>{{ $t('modals.settings.tabName.webUI') }}</h4>
|
||||
<h4>{{ $t("modals.settings.tabName.webUI") }}</h4>
|
||||
</v-tab>
|
||||
<v-tab class="white--text" href="#tagsAndCategories">
|
||||
<h4>{{ $t('modals.settings.tabName.tagsAndCategories') }}</h4>
|
||||
<h4>{{ $t("modals.settings.tabName.tagsAndCategories") }}</h4>
|
||||
</v-tab>
|
||||
</v-tabs>
|
||||
|
||||
|
||||
<!--<v-divider />-->
|
||||
<v-card-text class="pa-0">
|
||||
<v-tabs-items v-model="tab" touchless>
|
||||
|
@ -77,6 +63,9 @@
|
|||
<v-tab-item eager value="bittorrent">
|
||||
<BitTorrent :is-active="tab === 'bittorrent'" />
|
||||
</v-tab-item>
|
||||
<v-tab-item eager value="rss">
|
||||
<Rss :is-active="tab === 'rss'" />
|
||||
</v-tab-item>
|
||||
<v-tab-item eager value="webui">
|
||||
<WebUI :is-active="tab === 'webui'" />
|
||||
</v-tab-item>
|
||||
|
@ -90,46 +79,54 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import { mdiClose, mdiContentSave } from '@mdi/js'
|
||||
import { mapGetters } from "vuex";
|
||||
import { mdiClose, mdiContentSave } from "@mdi/js";
|
||||
import {
|
||||
WebUI,
|
||||
BitTorrent,
|
||||
Downloads,
|
||||
VueTorrent,
|
||||
TagsAndCategories,
|
||||
Connection
|
||||
} from '@/components/Settings/Tabs'
|
||||
import { SettingsTab } from '../mixins'
|
||||
Connection,
|
||||
} from "@/components/Settings/Tabs";
|
||||
import { SettingsTab } from "../mixins";
|
||||
|
||||
export default {
|
||||
name: 'Settings',
|
||||
components: { WebUI, BitTorrent, Downloads, VueTorrent, TagsAndCategories, Connection },
|
||||
name: "Settings",
|
||||
components: {
|
||||
WebUI,
|
||||
BitTorrent,
|
||||
Downloads,
|
||||
VueTorrent,
|
||||
TagsAndCategories,
|
||||
Connection,
|
||||
},
|
||||
mixins: [SettingsTab],
|
||||
data() {
|
||||
return {
|
||||
tab: null,
|
||||
items: [],
|
||||
peers: [],
|
||||
mdiClose, mdiContentSave
|
||||
}
|
||||
mdiClose,
|
||||
mdiContentSave,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['getSettings']),
|
||||
...mapGetters(["getSettings"]),
|
||||
settings() {
|
||||
return this.getSettings()
|
||||
return this.getSettings();
|
||||
},
|
||||
isPhone() {
|
||||
return this.$vuetify.breakpoint.xsOnly
|
||||
}
|
||||
return this.$vuetify.breakpoint.xsOnly;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.$store.dispatch('FETCH_SETTINGS')
|
||||
this.$store.dispatch("FETCH_SETTINGS");
|
||||
},
|
||||
methods: {
|
||||
close() {
|
||||
this.$router.back()
|
||||
}
|
||||
}
|
||||
}
|
||||
this.$router.back();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
Loading…
Reference in a new issue