refactor: 🚚 rework how routing works
All checks were successful
repod / xml (push) Successful in 27s
repod / php (push) Successful in 1m3s
repod / nodejs (push) Successful in 1m11s
repod / release (push) Has been skipped

This commit is contained in:
Michel Roux 2024-08-27 09:42:52 +02:00
parent 4e4730efd5
commit 5ed33d1cf6
10 changed files with 30 additions and 26 deletions

View File

@ -13,6 +13,7 @@ declare(strict_types=1);
return [ return [
'routes' => [ 'routes' => [
['name' => 'page#index', 'url' => '/', 'verb' => 'GET'], ['name' => 'page#index', 'url' => '/', 'verb' => 'GET'],
['name' => 'page#feed', 'url' => '/feed/{path}', 'verb' => 'GET', 'requirements' => ['path' => '.+']],
['name' => 'episodes#action', 'url' => '/episodes/action', 'verb' => 'GET'], ['name' => 'episodes#action', 'url' => '/episodes/action', 'verb' => 'GET'],
['name' => 'episodes#list', 'url' => '/episodes/list', 'verb' => 'GET'], ['name' => 'episodes#list', 'url' => '/episodes/list', 'verb' => 'GET'],
['name' => 'opml#export', 'url' => '/opml/export', 'verb' => 'GET'], ['name' => 'opml#export', 'url' => '/opml/export', 'verb' => 'GET'],

View File

@ -44,4 +44,12 @@ class PageController extends Controller
return $response; return $response;
} }
/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function feed(): TemplateResponse {
return $this->index();
}
} }

View File

@ -2,7 +2,7 @@
<NcAppNavigationList> <NcAppNavigationList>
<NcAppNavigationNewItem <NcAppNavigationNewItem
:name="t('repod', 'Add a RSS link')" :name="t('repod', 'Add a RSS link')"
@new-item="addSubscription"> @new-item="(url) => $router.push(toFeedUrl(url))">
<template #icon> <template #icon>
<PlusIcon :size="20" /> <PlusIcon :size="20" />
</template> </template>
@ -13,7 +13,7 @@
<script> <script>
import { NcAppNavigationList, NcAppNavigationNewItem } from '@nextcloud/vue' import { NcAppNavigationList, NcAppNavigationNewItem } from '@nextcloud/vue'
import PlusIcon from 'vue-material-design-icons/Plus.vue' import PlusIcon from 'vue-material-design-icons/Plus.vue'
import { encodeUrl } from '../../utils/url.js' import { toFeedUrl } from '../../utils/url.js'
export default { export default {
name: 'AddRss', name: 'AddRss',
@ -23,9 +23,7 @@ export default {
PlusIcon, PlusIcon,
}, },
methods: { methods: {
addSubscription(feedUrl) { toFeedUrl,
this.$router.push(encodeUrl(feedUrl))
},
}, },
} }
</script> </script>

View File

@ -7,7 +7,7 @@
:key="feed.link" :key="feed.link"
:details="formatLocaleDate(new Date(feed.fetchedAtUnix * 1000))" :details="formatLocaleDate(new Date(feed.fetchedAtUnix * 1000))"
:name="feed.title" :name="feed.title"
:to="toUrl(feed.link)"> :to="toFeedUrl(feed.link)">
<template #icon> <template #icon>
<NcAvatar <NcAvatar
:display-name="feed.author" :display-name="feed.author"
@ -44,7 +44,7 @@ import { debounce } from '../../utils/debounce.js'
import { formatLocaleDate } from '../../utils/time.js' import { formatLocaleDate } from '../../utils/time.js'
import { generateUrl } from '@nextcloud/router' import { generateUrl } from '@nextcloud/router'
import { showError } from '../../utils/toast.js' import { showError } from '../../utils/toast.js'
import { toUrl } from '../../utils/url.js' import { toFeedUrl } from '../../utils/url.js'
import { useSubscriptions } from '../../store/subscriptions.js' import { useSubscriptions } from '../../store/subscriptions.js'
export default { export default {
@ -77,7 +77,7 @@ export default {
methods: { methods: {
...mapActions(useSubscriptions, ['fetch']), ...mapActions(useSubscriptions, ['fetch']),
formatLocaleDate, formatLocaleDate,
toUrl, toFeedUrl,
async addSubscription(url) { async addSubscription(url) {
try { try {
await axios.post( await axios.post(

View File

@ -4,7 +4,7 @@
<Loading v-if="loading" /> <Loading v-if="loading" />
<ul v-if="!loading"> <ul v-if="!loading">
<li v-for="top in tops" :key="top.link"> <li v-for="top in tops" :key="top.link">
<router-link :to="toUrl(top.link)"> <router-link :to="toFeedUrl(top.link)">
<img :src="top.imageUrl" :title="top.author" /> <img :src="top.imageUrl" :title="top.author" />
</router-link> </router-link>
</li> </li>
@ -17,7 +17,7 @@ import Loading from '../Atoms/Loading.vue'
import axios from '@nextcloud/axios' import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router' import { generateUrl } from '@nextcloud/router'
import { showError } from '../../utils/toast.js' import { showError } from '../../utils/toast.js'
import { toUrl } from '../../utils/url.js' import { toFeedUrl } from '../../utils/url.js'
export default { export default {
name: 'Toplist', name: 'Toplist',
@ -61,7 +61,7 @@ export default {
} }
}, },
methods: { methods: {
toUrl, toFeedUrl,
}, },
} }
</script> </script>

View File

@ -8,7 +8,6 @@
:active="isCurrentEpisode(episode)" :active="isCurrentEpisode(episode)"
:details="formatLocaleDate(new Date(episode.pubDate?.date))" :details="formatLocaleDate(new Date(episode.pubDate?.date))"
:force-display-actions="true" :force-display-actions="true"
:href="$route.href"
:name="episode.name" :name="episode.name"
:style="{ opacity: hasEnded(episode) ? 0.4 : 1 }" :style="{ opacity: hasEnded(episode) ? 0.4 : 1 }"
target="_self" target="_self"

View File

@ -3,7 +3,7 @@
<strong class="pointer" @click="modal = true"> <strong class="pointer" @click="modal = true">
{{ episode.name }} {{ episode.name }}
</strong> </strong>
<router-link :to="hash"> <router-link :to="toFeedUrl(podcastUrl)">
<i>{{ episode.title }}</i> <i>{{ episode.title }}</i>
</router-link> </router-link>
<NcModal v-if="modal" @close="modal = false"> <NcModal v-if="modal" @close="modal = false">
@ -23,7 +23,7 @@
import Modal from '../Atoms/Modal.vue' import Modal from '../Atoms/Modal.vue'
import { NcModal } from '@nextcloud/vue' import { NcModal } from '@nextcloud/vue'
import { mapState } from 'pinia' import { mapState } from 'pinia'
import { toUrl } from '../../utils/url.js' import { toFeedUrl } from '../../utils/url.js'
import { usePlayer } from '../../store/player.js' import { usePlayer } from '../../store/player.js'
export default { export default {
@ -37,9 +37,9 @@ export default {
}), }),
computed: { computed: {
...mapState(usePlayer, ['episode', 'podcastUrl']), ...mapState(usePlayer, ['episode', 'podcastUrl']),
hash() { },
return toUrl(this.podcastUrl) methods: {
}, toFeedUrl,
}, },
} }
</script> </script>

View File

@ -2,7 +2,7 @@
<NcAppNavigationItem <NcAppNavigationItem
:loading="loading" :loading="loading"
:name="feed ? feed.title : url" :name="feed ? feed.title : url"
:to="hash"> :to="toFeedUrl(url)">
<template #actions> <template #actions>
<NcActionButton <NcActionButton
:aria-label="t('repod', 'Favorite')" :aria-label="t('repod', 'Favorite')"
@ -48,7 +48,7 @@ import StarRemoveIcon from 'vue-material-design-icons/StarRemove.vue'
import axios from '@nextcloud/axios' import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router' import { generateUrl } from '@nextcloud/router'
import { showError } from '../../utils/toast.js' import { showError } from '../../utils/toast.js'
import { toUrl } from '../../utils/url.js' import { toFeedUrl } from '../../utils/url.js'
import { useSubscriptions } from '../../store/subscriptions.js' import { useSubscriptions } from '../../store/subscriptions.js'
export default { export default {
@ -76,9 +76,6 @@ export default {
}), }),
computed: { computed: {
...mapState(useSubscriptions, ['favs']), ...mapState(useSubscriptions, ['favs']),
hash() {
return toUrl(this.url)
},
isFavorite() { isFavorite() {
return this.favs.map((fav) => fav.url).includes(this.url) return this.favs.map((fav) => fav.url).includes(this.url)
}, },
@ -109,6 +106,7 @@ export default {
'editFavoriteData', 'editFavoriteData',
'removeFavorite', 'removeFavorite',
]), ]),
toFeedUrl,
async deleteSubscription() { async deleteSubscription() {
if ( if (
confirm( confirm(

View File

@ -1,11 +1,11 @@
import { createRouter, createWebHashHistory } from 'vue-router' import { createRouter, createWebHistory } from 'vue-router'
import Discover from './views/Discover.vue' import Discover from './views/Discover.vue'
import Feed from './views/Feed.vue' import Feed from './views/Feed.vue'
import Home from './views/Home.vue' import Home from './views/Home.vue'
import { generateUrl } from '@nextcloud/router' import { generateUrl } from '@nextcloud/router'
const router = createRouter({ const router = createRouter({
history: createWebHashHistory(generateUrl('apps/repod')), history: createWebHistory(generateUrl('apps/repod')),
routes: [ routes: [
{ {
path: '/', path: '/',
@ -16,7 +16,7 @@ const router = createRouter({
component: Discover, component: Discover,
}, },
{ {
path: '/:url', path: '/feed/:url',
component: Feed, component: Feed,
}, },
], ],

View File

@ -1,6 +1,6 @@
export const encodeUrl = (url) => encodeURIComponent(btoa(url)) export const encodeUrl = (url) => encodeURIComponent(btoa(url))
export const decodeUrl = (url) => atob(decodeURIComponent(url)) export const decodeUrl = (url) => atob(decodeURIComponent(url))
export const toUrl = (url) => `/${encodeUrl(url)}` export const toFeedUrl = (url) => `/feed/${encodeUrl(url)}`
export const filenameFromUrl = (str) => { export const filenameFromUrl = (str) => {
const url = new URL(str) const url = new URL(str)
return url.pathname.split('/').pop() return url.pathname.split('/').pop()