refacto: rework Settings into several components
All checks were successful
repod / xml (push) Successful in 26s
repod / php (push) Successful in 49s
repod / nodejs (push) Successful in 2m12s
repod / release (push) Has been skipped

This commit is contained in:
Michel Roux 2024-01-29 19:30:12 +01:00
parent 87315b1221
commit 99fa123640
5 changed files with 178 additions and 138 deletions

View File

@ -0,0 +1,25 @@
<template>
<NcAppNavigationItem :href="generateUrl('/apps/repod/opml/export')"
:name="t('repod', 'Export subscriptions')">
<template #icon>
<ExportIcon :size="20" />
</template>
</NcAppNavigationItem>
</template>
<script>
import ExportIcon from 'vue-material-design-icons/Export.vue'
import { NcAppNavigationItem } from '@nextcloud/vue'
import { generateUrl } from '@nextcloud/router'
export default {
name: 'Export',
components: {
ExportIcon,
NcAppNavigationItem,
},
methods: {
generateUrl,
},
}
</script>

View File

@ -0,0 +1,73 @@
<template>
<NcAppNavigationItem :name="t('repod', 'Import subscriptions')" @click="modal = true">
<template #icon>
<ImportIcon :size="20" />
</template>
<template #extra>
<NcModal v-if="modal" @close="modal = false">
<div class="modal">
<h2>{{ t('repod', 'Import OPML file') }}</h2>
<form v-if="!loading"
:action="generateUrl('/apps/repod/opml/import')"
enctype="multipart/form-data"
method="post"
@submit.prevent="importOpml">
<input accept="application/xml,.opml"
name="import"
required
type="file">
<input type="submit">
</form>
<Loading v-if="loading" />
</div>
</NcModal>
</template>
</NcAppNavigationItem>
</template>
<script>
import { NcAppNavigationItem, NcModal } from '@nextcloud/vue'
import ImportIcon from 'vue-material-design-icons/Import.vue'
import Loading from '../Atoms/Loading.vue'
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
export default {
name: 'Import',
components: {
ImportIcon,
Loading,
NcAppNavigationItem,
NcModal,
},
data() {
return {
loading: false,
modal: false,
}
},
methods: {
generateUrl,
async importOpml(event) {
try {
const formData = new FormData(event.target)
this.importLoading = true
await axios.post(event.target.action, formData)
} catch (e) {
console.error(e)
} finally {
location.reload()
}
},
},
}
</script>
<style scoped>
.modal {
align-items: center;
display: flex;
flex-direction: column;
margin: 2rem;
}
</style>

View File

@ -0,0 +1,67 @@
<template>
<NcAppNavigationItem :name="t('repod', 'Playback speed')">
<template #icon>
<SpeedometerSlow v-if="player.rate < 1" :size="20" />
<SpeedometerMedium v-if="player.rate === 1" :size="20" />
<Speedometer v-if="player.rate > 1" :size="20" />
</template>
<template #extra>
<div class="extra">
<Minus class="pointer" :size="20" @click="changeRate(-.1)" />
<NcCounterBubble class="counter">
x{{ player.rate }}
</NcCounterBubble>
<Plus class="pointer" :size="20" @click="changeRate(.1)" />
</div>
</template>
</NcAppNavigationItem>
</template>
<script>
import { NcAppNavigationItem, NcCounterBubble } from '@nextcloud/vue'
import Minus from 'vue-material-design-icons/Minus.vue'
import Plus from 'vue-material-design-icons/Plus.vue'
import Speedometer from 'vue-material-design-icons/Speedometer.vue'
import SpeedometerMedium from 'vue-material-design-icons/SpeedometerMedium.vue'
import SpeedometerSlow from 'vue-material-design-icons/SpeedometerSlow.vue'
export default {
name: 'Speed',
components: {
NcAppNavigationItem,
NcCounterBubble,
Minus,
Plus,
Speedometer,
SpeedometerMedium,
SpeedometerSlow,
},
computed: {
player() {
return this.$store.state.player
},
},
methods: {
changeRate(diff) {
const newRate = (this.player.rate + diff).toPrecision(2)
this.$store.dispatch('player/rate', newRate > 0 ? newRate : this.player.rate)
},
},
}
</script>
<style scoped>
.counter {
height: 20px;
}
.extra {
align-items: center;
display: flex;
gap: .5rem;
}
.pointer {
cursor: pointer;
}
</style>

View File

@ -1,134 +0,0 @@
<template>
<NcAppNavigationSettings>
<NcAppNavigationItem :name="t('repod', 'Playback speed')">
<template #icon>
<SpeedometerSlow v-if="player.rate < 1" :size="20" />
<SpeedometerMedium v-if="player.rate === 1" :size="20" />
<Speedometer v-if="player.rate > 1" :size="20" />
</template>
<template #extra>
<div class="extra">
<Minus class="pointer" :size="20" @click="changeRate(-.1)" />
<NcCounterBubble class="counter">
x{{ player.rate }}
</NcCounterBubble>
<Plus class="pointer" :size="20" @click="changeRate(.1)" />
</div>
</template>
</NcAppNavigationItem>
<NcAppNavigationItem :name="t('repod', 'Import subscriptions')" @click="importModal = true">
<template #icon>
<Import :size="20" />
</template>
<template #extra>
<NcModal v-if="importModal" @close="importModal = false">
<div class="importModal">
<h2>{{ t('repod', 'Import OPML file') }}</h2>
<form v-if="!importLoading"
:action="generateUrl('/apps/repod/opml/import')"
enctype="multipart/form-data"
method="post"
@submit.prevent="importOpml">
<input accept="application/xml,.opml"
name="import"
required
type="file">
<input type="submit">
</form>
<Loading v-if="importLoading" />
</div>
</NcModal>
</template>
</NcAppNavigationItem>
<NcAppNavigationItem :href="generateUrl('/apps/repod/opml/export')"
:name="t('repod', 'Export subscriptions')">
<template #icon>
<Export :size="20" />
</template>
</NcAppNavigationItem>
</NcAppNavigationSettings>
</template>
<script>
import { NcAppNavigationItem, NcAppNavigationSettings, NcCounterBubble, NcModal } from '@nextcloud/vue'
import Export from 'vue-material-design-icons/Export.vue'
import Import from 'vue-material-design-icons/Import.vue'
import Loading from '../Atoms/Loading.vue'
import Minus from 'vue-material-design-icons/Minus.vue'
import Plus from 'vue-material-design-icons/Plus.vue'
import Speedometer from 'vue-material-design-icons/Speedometer.vue'
import SpeedometerMedium from 'vue-material-design-icons/SpeedometerMedium.vue'
import SpeedometerSlow from 'vue-material-design-icons/SpeedometerSlow.vue'
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
export default {
name: 'Settings',
components: {
Export,
Import,
Loading,
Minus,
NcAppNavigationItem,
NcAppNavigationSettings,
NcCounterBubble,
NcModal,
Plus,
Speedometer,
SpeedometerMedium,
SpeedometerSlow,
},
data() {
return {
importModal: false,
importLoading: false,
}
},
computed: {
player() {
return this.$store.state.player
},
},
methods: {
generateUrl,
changeRate(diff) {
const newRate = (this.player.rate + diff).toPrecision(2)
this.$store.dispatch('player/rate', newRate > 0 ? newRate : this.player.rate)
},
async importOpml(event) {
try {
const formData = new FormData(event.target)
this.importLoading = true
await axios.post(event.target.action, formData)
} catch (e) {
console.error(e)
} finally {
location.reload()
}
},
},
}
</script>
<style scoped>
.counter {
height: 20px;
}
.extra {
align-items: center;
display: flex;
gap: .5rem;
}
.importModal {
align-items: center;
display: flex;
flex-direction: column;
margin: 2rem;
}
.pointer {
cursor: pointer;
}
</style>

View File

@ -18,30 +18,39 @@
</NcAppContentList>
</template>
<template #footer>
<Settings />
<NcAppNavigationSettings>
<Speed />
<Import />
<Export />
</NcAppNavigationSettings>
</template>
</AppNavigation>
</template>
<script>
import { NcAppContentList, NcAppNavigationNew } from '@nextcloud/vue'
import { NcAppContentList, NcAppNavigationNew, NcAppNavigationSettings } from '@nextcloud/vue'
import AppNavigation from '../Atoms/AppNavigation.vue'
import Export from '../Settings/Export.vue'
import Import from '../Settings/Import.vue'
import Item from './Item.vue'
import Loading from '../Atoms/Loading.vue'
import Plus from 'vue-material-design-icons/Plus.vue'
import Settings from './Settings.vue'
import Speed from '../Settings/Speed.vue'
import { showError } from '@nextcloud/dialogs'
export default {
name: 'Subscriptions',
components: {
AppNavigation,
Export,
Import,
Item,
Loading,
NcAppContentList,
NcAppNavigationNew,
NcAppNavigationSettings,
Plus,
Settings,
Speed,
},
data() {
return {