refactor: 🚚 rework how routing works
This commit is contained in:
parent
4e4730efd5
commit
5ed33d1cf6
@ -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'],
|
||||||
|
@ -44,4 +44,12 @@ class PageController extends Controller
|
|||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @NoCSRFRequired
|
||||||
|
*/
|
||||||
|
public function feed(): TemplateResponse {
|
||||||
|
return $this->index();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
@ -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(
|
||||||
|
@ -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>
|
||||||
|
@ -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"
|
||||||
|
@ -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>
|
||||||
|
@ -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(
|
||||||
|
@ -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,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -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()
|
||||||
|
Loading…
Reference in New Issue
Block a user