feat: rework Discover
All checks were successful
repod / xml (push) Successful in 20s
repod / php (push) Successful in 58s
repod / nodejs (push) Successful in 2m1s

This commit is contained in:
Michel Roux 2024-01-10 17:50:06 +01:00
parent 11865916a7
commit 70f1d3b69f
10 changed files with 174 additions and 70 deletions

View File

@ -17,6 +17,7 @@ return [
['name' => 'episodes#list', 'url' => '/episodes/list', 'verb' => 'GET'], ['name' => 'episodes#list', 'url' => '/episodes/list', 'verb' => 'GET'],
['name' => 'podcast#index', 'url' => '/podcast', 'verb' => 'GET'], ['name' => 'podcast#index', 'url' => '/podcast', 'verb' => 'GET'],
['name' => 'search#index', 'url' => '/search', 'verb' => 'GET'], ['name' => 'search#index', 'url' => '/search', 'verb' => 'GET'],
['name' => 'toplist#index', 'url' => '/toplist', 'verb' => 'GET'], ['name' => 'toplist#hot', 'url' => '/toplist/hot', 'verb' => 'GET'],
['name' => 'toplist#new', 'url' => '/toplist/new', 'verb' => 'GET'],
], ],
]; ];

View File

@ -1,9 +1,13 @@
OC.L10N.register( OC.L10N.register(
"repod", "repod",
{ {
"RePod" : "RePod",
"🔊 Browse, manage and listen to podcasts" : "🔊 Parcourir, gérer et écouter vos podcasts",
"# Features\n- 🔍 Browse and subscribe huge collection of podcasts\n- 🔊 Listen to episodes directly in Nextcloud\n- 🌐 Sync your activity with [AntennaPod](https://antennapod.org/)\n\n# Requirements\nYou need to have [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) installed to use this app!" : "# Fonctionnalités\n- 🔍 Parcourir et s'abonner à une grande collections de podcasts\n- 🔊 Écouter vos épisodes directement sur Nextcloud\n- 🌐 Synchroniser son activité avec [AntennaPod](https://antennapod.org/)\n\n# Pré-requis\nVous devez avoir [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) installé pour utiliser cette application !",
"Add a RSS link" : "Ajouter un lien RSS", "Add a RSS link" : "Ajouter un lien RSS",
"Could not fetch search results" : "Impossible de récupérer les resultats de la recherche", "Could not fetch search results" : "Impossible de récupérer les resultats de la recherche",
"Suggests by fyyd" : "Suggestions via fyyd", "Hot podcasts" : "Tendances",
"New podcasts" : "Nouveautés",
"Could not fetch tops" : "Impossible de récupérer les tops", "Could not fetch tops" : "Impossible de récupérer les tops",
"Subscribe" : "S'abonner", "Subscribe" : "S'abonner",
"Error while adding the feed" : "Erreur lors de l'ajout du flux", "Error while adding the feed" : "Erreur lors de l'ajout du flux",
@ -12,6 +16,7 @@ OC.L10N.register(
"Could not fetch episodes" : "Impossible de récuprer les épisodes", "Could not fetch episodes" : "Impossible de récuprer les épisodes",
"Download" : "Télécharger", "Download" : "Télécharger",
"Delete" : "Supprimer", "Delete" : "Supprimer",
"Are you sure you want to delete this subscription?" : "Êtes-vous sûr de vouloir supprimer ce flux ?",
"Error while removing the feed" : "Erreur lors de la suppression du flux", "Error while removing the feed" : "Erreur lors de la suppression du flux",
"Add a podcast" : "Ajouter un podcast", "Add a podcast" : "Ajouter un podcast",
"Could not fetch subscriptions" : "Impossible de récupérer les flux", "Could not fetch subscriptions" : "Impossible de récupérer les flux",

View File

@ -1,7 +1,11 @@
{ "translations": { { "translations": {
"RePod" : "RePod",
"🔊 Browse, manage and listen to podcasts" : "🔊 Parcourir, gérer et écouter vos podcasts",
"# Features\n- 🔍 Browse and subscribe huge collection of podcasts\n- 🔊 Listen to episodes directly in Nextcloud\n- 🌐 Sync your activity with [AntennaPod](https://antennapod.org/)\n\n# Requirements\nYou need to have [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) installed to use this app!" : "# Fonctionnalités\n- 🔍 Parcourir et s'abonner à une grande collections de podcasts\n- 🔊 Écouter vos épisodes directement sur Nextcloud\n- 🌐 Synchroniser son activité avec [AntennaPod](https://antennapod.org/)\n\n# Pré-requis\nVous devez avoir [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) installé pour utiliser cette application !",
"Add a RSS link" : "Ajouter un lien RSS", "Add a RSS link" : "Ajouter un lien RSS",
"Could not fetch search results" : "Impossible de récupérer les resultats de la recherche", "Could not fetch search results" : "Impossible de récupérer les resultats de la recherche",
"Suggests by fyyd" : "Suggestions via fyyd", "Hot podcasts" : "Tendances",
"New podcasts" : "Nouveautés",
"Could not fetch tops" : "Impossible de récupérer les tops", "Could not fetch tops" : "Impossible de récupérer les tops",
"Subscribe" : "S'abonner", "Subscribe" : "S'abonner",
"Error while adding the feed" : "Erreur lors de l'ajout du flux", "Error while adding the feed" : "Erreur lors de l'ajout du flux",
@ -10,6 +14,7 @@
"Could not fetch episodes" : "Impossible de récuprer les épisodes", "Could not fetch episodes" : "Impossible de récuprer les épisodes",
"Download" : "Télécharger", "Download" : "Télécharger",
"Delete" : "Supprimer", "Delete" : "Supprimer",
"Are you sure you want to delete this subscription?" : "Êtes-vous sûr de vouloir supprimer ce flux ?",
"Error while removing the feed" : "Erreur lors de la suppression du flux", "Error while removing the feed" : "Erreur lors de la suppression du flux",
"Add a podcast" : "Ajouter un podcast", "Add a podcast" : "Ajouter un podcast",
"Could not fetch subscriptions" : "Impossible de récupérer les flux", "Could not fetch subscriptions" : "Impossible de récupérer les flux",

View File

@ -23,7 +23,15 @@ class ToplistController extends Controller
* @NoAdminRequired * @NoAdminRequired
* @NoCSRFRequired * @NoCSRFRequired
*/ */
public function index(): JSONResponse { public function hot(): JSONResponse {
return new JSONResponse($this->fyydService->hot()); return new JSONResponse($this->fyydService->hot());
} }
/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function new(): JSONResponse {
return new JSONResponse($this->fyydService->latest());
}
} }

View File

@ -55,7 +55,33 @@ class FyydService implements IProvider
/** /**
* @return PodcastData[] * @return PodcastData[]
*/ */
public function hot(int $count = 10): array { public function latest(): array {
$podcasts = [];
$podcastClient = $this->clientService->newClient();
$podcastResponse = $podcastClient->get(self::BASE_URL.'podcast/latest');
$podcastJson = (array) json_decode((string) $podcastResponse->getBody(), true, flags: JSON_THROW_ON_ERROR);
if (array_key_exists('data', $podcastJson) && is_array($podcastJson['data'])) {
/** @var string[] $feed */
foreach ($podcastJson['data'] as $feed) {
$podcasts[] = new PodcastData(
$feed['title'],
$feed['author'],
$feed['xmlURL'],
$feed['description'],
$feed['imgURL'],
strtotime($feed['lastpub'])
);
}
}
return $podcasts;
}
/**
* @return PodcastData[]
*/
public function hot(): array {
$podcasts = []; $podcasts = [];
$language = 'en'; $language = 'en';
$userLang = $this->userService->getLangCode(); $userLang = $this->userService->getLangCode();
@ -75,7 +101,6 @@ class FyydService implements IProvider
$podcastResponse = $podcastClient->get(self::BASE_URL.'feature/podcast/hot', [ $podcastResponse = $podcastClient->get(self::BASE_URL.'feature/podcast/hot', [
'query' => [ 'query' => [
'count' => $count,
'language' => $language, 'language' => $language,
], ],
]); ]);

View File

@ -1,5 +1,5 @@
<template> <template>
<ul> <ul class="bar">
<NcAppNavigationNewItem :name="t('repod', 'Add a RSS link')" <NcAppNavigationNewItem :name="t('repod', 'Add a RSS link')"
@new-item="addSubscription"> @new-item="addSubscription">
<template #icon> <template #icon>
@ -26,3 +26,9 @@ export default {
}, },
} }
</script> </script>
<style scoped>
.bar {
margin-top: 1rem;
}
</style>

View File

@ -1,17 +1,29 @@
<template> <template>
<div> <div>
<Loading v-if="loading" /> <div>
<ul v-if="!loading" class="tops"> <h2>{{ t('repod', 'Hot podcasts') }}</h2>
<li v-for="top in tops" :key="top.link"> <Loading v-if="tops.hot.loading" />
<TopItem :author="top.author" <ul v-if="!tops.hot.loading">
:image-url="top.imageUrl" <li v-for="top in tops.hot.items" :key="top.link">
:link="top.link" <TopItem :author="top.author"
:title="top.title" /> :image-url="top.imageUrl"
</li> :link="top.link"
</ul> :title="top.title" />
<p v-if="!loading" class="caption"> </li>
{{ t('repod', 'Suggests by fyyd') }} </ul>
</p> </div>
<div>
<h2>{{ t('repod', 'New podcasts') }}</h2>
<Loading v-if="tops.new.loading" />
<ul v-if="!tops.new.loading">
<li v-for="top in tops.new.items" :key="top.link">
<TopItem :author="top.author"
:image-url="top.imageUrl"
:link="top.link"
:title="top.title" />
</li>
</ul>
</div>
</div> </div>
</template> </template>
@ -30,44 +42,54 @@ export default {
}, },
data() { data() {
return { return {
tops: [], tops: {
loading: true, hot: {
items: [],
loading: true,
},
new: {
items: [],
loading: true,
},
},
} }
}, },
async mounted() { async mounted() {
try { this.loadList('hot')
this.loading = true this.loadList('new')
const toplist = await axios.get(generateUrl('/apps/repod/toplist')) },
this.tops = toplist.data methods: {
} catch (e) { async loadList(type) {
console.error(e) try {
showError(t('repod', 'Could not fetch tops')) this.tops[type].loading = true
} finally { const toplist = await axios.get(generateUrl(`/apps/repod/toplist/${type}`))
this.loading = false this.tops[type].items = toplist.data
} } catch (e) {
console.error(e)
showError(t('repod', 'Could not fetch tops'))
} finally {
this.tops[type].loading = false
}
},
}, },
} }
</script> </script>
<style scoped> <style scoped>
div { h2 {
margin: 2rem 0; margin: 1rem 0;
} }
li { li {
flex-basis: 15%; flex-basis: 35%;
} flex-shrink: 0;
p {
font-size: small;
margin: .5rem;
text-align: right;
} }
ul { ul {
display: flex; display: flex;
flex-wrap: wrap; gap: 2rem;
gap: 2rem 5%; overflow-x: auto;
justify-content: center; overflow-y: hidden;
padding: .5rem;
} }
</style> </style>

View File

@ -1,7 +1,6 @@
<template> <template>
<NcAppContent class="main"> <NcAppContent class="main">
<NcTextField class="search" <NcTextField :label="t('repod', 'Find a podcast')"
:label="t('repod', 'Find a podcast')"
:value.sync="search"> :value.sync="search">
<Magnify :size="20" /> <Magnify :size="20" />
</NcTextField> </NcTextField>
@ -39,10 +38,5 @@ export default {
<style scoped> <style scoped>
.main { .main {
padding: 15px 51px; padding: 15px 51px;
overflow: hidden;
}
.search {
margin-bottom: 1rem;
} }
</style> </style>

View File

@ -8,23 +8,50 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Nextcloud 3.14159\n" "Project-Id-Version: Nextcloud 3.14159\n"
"Report-Msgid-Bugs-To: translations\\@example.com\n" "Report-Msgid-Bugs-To: translations\\@example.com\n"
"POT-Creation-Date: 2024-01-10 08:48+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n" "Language: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
msgid "RePod"
msgstr "RePod"
msgid "🔊 Browse, manage and listen to podcasts"
msgstr "🔊 Parcourir, gérer et écouter vos podcasts"
msgid ""
"# Features\n"
"- 🔍 Browse and subscribe huge collection of podcasts\n"
"- 🔊 Listen to episodes directly in Nextcloud\n"
"- 🌐 Sync your activity with [AntennaPod](https://antennapod.org/)\n"
"\n"
"# Requirements\n"
"You need to have [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) "
"installed to use this app!"
msgstr ""
"# Fonctionnalités\n"
"- 🔍 Parcourir et s'abonner à une grande collections de podcasts\n"
"- 🔊 Écouter vos épisodes directement sur Nextcloud\n"
"- 🌐 Synchroniser son activité avec [AntennaPod](https://antennapod.org/)\n"
"\n"
"# Pré-requis\n"
"Vous devez avoir [GPodderSync](https://apps.nextcloud.com/apps/gpoddersync) "
"installé pour utiliser cette application !"
msgid "Add a RSS link" msgid "Add a RSS link"
msgstr "Ajouter un lien RSS" msgstr "Ajouter un lien RSS"
msgid "Could not fetch search results" msgid "Could not fetch search results"
msgstr "Impossible de récupérer les resultats de la recherche" msgstr "Impossible de récupérer les resultats de la recherche"
msgid "Suggests by fyyd" msgid "Hot podcasts"
msgstr "Suggestions via fyyd" msgstr "Tendances"
msgid "New podcasts"
msgstr "Nouveautés"
msgid "Could not fetch tops" msgid "Could not fetch tops"
msgstr "Impossible de récupérer les tops" msgstr "Impossible de récupérer les tops"
@ -50,6 +77,9 @@ msgstr "Télécharger"
msgid "Delete" msgid "Delete"
msgstr "Supprimer" msgstr "Supprimer"
msgid "Are you sure you want to delete this subscription?"
msgstr "Êtes-vous sûr de vouloir supprimer ce flux ?"
msgid "Error while removing the feed" msgid "Error while removing the feed"
msgstr "Erreur lors de la suppression du flux" msgstr "Erreur lors de la suppression du flux"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Nextcloud 3.14159\n" "Project-Id-Version: Nextcloud 3.14159\n"
"Report-Msgid-Bugs-To: translations\\@example.com\n" "Report-Msgid-Bugs-To: translations\\@example.com\n"
"POT-Creation-Date: 2024-01-10 14:22+0000\n" "POT-Creation-Date: 2024-01-10 16:47+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -46,65 +46,73 @@ msgid "Could not fetch search results"
msgstr "" msgstr ""
#: /app/specialVueFakeDummyForL10nScript.js:3 #: /app/specialVueFakeDummyForL10nScript.js:3
msgid "Suggests by fyyd" msgid "Hot podcasts"
msgstr "" msgstr ""
#: /app/specialVueFakeDummyForL10nScript.js:4 #: /app/specialVueFakeDummyForL10nScript.js:4
msgid "Could not fetch tops" msgid "New podcasts"
msgstr "" msgstr ""
#: /app/specialVueFakeDummyForL10nScript.js:5 #: /app/specialVueFakeDummyForL10nScript.js:5
msgid "Subscribe" msgid "Could not fetch tops"
msgstr "" msgstr ""
#: /app/specialVueFakeDummyForL10nScript.js:6 #: /app/specialVueFakeDummyForL10nScript.js:6
msgid "Error while adding the feed" msgid "Subscribe"
msgstr "" msgstr ""
#: /app/specialVueFakeDummyForL10nScript.js:7 #: /app/specialVueFakeDummyForL10nScript.js:7
msgid "Play" msgid "Error while adding the feed"
msgstr "" msgstr ""
#: /app/specialVueFakeDummyForL10nScript.js:8 #: /app/specialVueFakeDummyForL10nScript.js:8
msgid "Stop" msgid "Play"
msgstr "" msgstr ""
#: /app/specialVueFakeDummyForL10nScript.js:9 #: /app/specialVueFakeDummyForL10nScript.js:9
msgid "Could not fetch episodes" msgid "Stop"
msgstr "" msgstr ""
#: /app/specialVueFakeDummyForL10nScript.js:10 #: /app/specialVueFakeDummyForL10nScript.js:10
msgid "Download" msgid "Could not fetch episodes"
msgstr "" msgstr ""
#: /app/specialVueFakeDummyForL10nScript.js:11 #: /app/specialVueFakeDummyForL10nScript.js:11
msgid "Delete" msgid "Download"
msgstr "" msgstr ""
#: /app/specialVueFakeDummyForL10nScript.js:12 #: /app/specialVueFakeDummyForL10nScript.js:12
msgid "Error while removing the feed" msgid "Delete"
msgstr "" msgstr ""
#: /app/specialVueFakeDummyForL10nScript.js:13 #: /app/specialVueFakeDummyForL10nScript.js:13
msgid "Add a podcast" msgid "Are you sure you want to delete this subscription?"
msgstr "" msgstr ""
#: /app/specialVueFakeDummyForL10nScript.js:14 #: /app/specialVueFakeDummyForL10nScript.js:14
msgid "Could not fetch subscriptions" msgid "Error while removing the feed"
msgstr "" msgstr ""
#: /app/specialVueFakeDummyForL10nScript.js:15 #: /app/specialVueFakeDummyForL10nScript.js:15
msgid "Find a podcast" msgid "Add a podcast"
msgstr "" msgstr ""
#: /app/specialVueFakeDummyForL10nScript.js:16 #: /app/specialVueFakeDummyForL10nScript.js:16
msgid "Error loading feed" msgid "Could not fetch subscriptions"
msgstr "" msgstr ""
#: /app/specialVueFakeDummyForL10nScript.js:17 #: /app/specialVueFakeDummyForL10nScript.js:17
msgid "Missing required app" msgid "Find a podcast"
msgstr "" msgstr ""
#: /app/specialVueFakeDummyForL10nScript.js:18 #: /app/specialVueFakeDummyForL10nScript.js:18
msgid "Error loading feed"
msgstr ""
#: /app/specialVueFakeDummyForL10nScript.js:19
msgid "Missing required app"
msgstr ""
#: /app/specialVueFakeDummyForL10nScript.js:20
msgid "Install GPodder Sync" msgid "Install GPodder Sync"
msgstr "" msgstr ""