mirror of
https://code.castopod.org/adaures/castopod
synced 2025-06-05 17:02:01 +00:00
feat(home): sort podcasts by recent activity + add dropdown menu to choose between sorting options
fixes #164
This commit is contained in:
parent
91128fad7a
commit
7b89da6106
@ -27,7 +27,12 @@ class HomeController extends BaseController
|
|||||||
return redirect()->to(rtrim(host_url(), '/') . $route);
|
return redirect()->to(rtrim(host_url(), '/') . $route);
|
||||||
}
|
}
|
||||||
|
|
||||||
$allPodcasts = (new PodcastModel())->findAll();
|
$sortOptions = ['activity', 'created_desc', 'created_asc'];
|
||||||
|
$sortBy = in_array($this->request->getGet('sort'), $sortOptions, true) ? $this->request->getGet(
|
||||||
|
'sort'
|
||||||
|
) : 'activity';
|
||||||
|
|
||||||
|
$allPodcasts = (new PodcastModel())->getAllPodcasts($sortBy);
|
||||||
|
|
||||||
// check if there's only one podcast to redirect user to it
|
// check if there's only one podcast to redirect user to it
|
||||||
if (count($allPodcasts) === 1) {
|
if (count($allPodcasts) === 1) {
|
||||||
@ -38,6 +43,7 @@ class HomeController extends BaseController
|
|||||||
$data = [
|
$data = [
|
||||||
'metatags' => get_home_metatags(),
|
'metatags' => get_home_metatags(),
|
||||||
'podcasts' => $allPodcasts,
|
'podcasts' => $allPodcasts,
|
||||||
|
'sortBy' => $sortBy,
|
||||||
];
|
];
|
||||||
|
|
||||||
return view('home', $data);
|
return view('home', $data);
|
||||||
|
@ -10,5 +10,11 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
'all_podcasts' => 'All podcasts',
|
'all_podcasts' => 'All podcasts',
|
||||||
|
'sort_by' => 'Sort by',
|
||||||
|
'sort_options' => [
|
||||||
|
'activity' => 'Recent activity',
|
||||||
|
'created_desc' => 'Newest first',
|
||||||
|
'created_asc' => 'Oldest first',
|
||||||
|
],
|
||||||
'no_podcast' => 'No podcast found',
|
'no_podcast' => 'No podcast found',
|
||||||
];
|
];
|
||||||
|
@ -10,5 +10,11 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
'all_podcasts' => 'Tous les podcasts',
|
'all_podcasts' => 'Tous les podcasts',
|
||||||
|
'sort_by' => 'Trier par',
|
||||||
|
'sort_options' => [
|
||||||
|
'activity' => 'Activité récente',
|
||||||
|
'created_desc' => 'Le plus récent d’abord',
|
||||||
|
'created_asc' => 'Le plus ancien d’abord',
|
||||||
|
],
|
||||||
'no_podcast' => 'Aucun podcast trouvé',
|
'no_podcast' => 'Aucun podcast trouvé',
|
||||||
];
|
];
|
||||||
|
@ -166,6 +166,42 @@ class PodcastModel extends Model
|
|||||||
return $found;
|
return $found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param 'activity'|'created_asc'|'created_desc' $orderBy
|
||||||
|
*
|
||||||
|
* @return Podcast[]
|
||||||
|
*/
|
||||||
|
public function getAllPodcasts(string $orderBy = null): array
|
||||||
|
{
|
||||||
|
if ($orderBy === 'activity') {
|
||||||
|
$prefix = $this->db->getPrefix();
|
||||||
|
|
||||||
|
$fediverseTablePrefix = config('Fediverse')
|
||||||
|
->tablesPrefix;
|
||||||
|
$this->select(
|
||||||
|
'podcasts.*, MAX(' . $prefix . $fediverseTablePrefix . 'posts.published_at' . ') as max_published_at'
|
||||||
|
)
|
||||||
|
->join(
|
||||||
|
$fediverseTablePrefix . 'posts',
|
||||||
|
$fediverseTablePrefix . 'posts.actor_id = podcasts.actor_id',
|
||||||
|
'left'
|
||||||
|
)
|
||||||
|
->where(
|
||||||
|
'`' . $prefix . $fediverseTablePrefix . 'posts`.`published_at` <= NOW()',
|
||||||
|
null,
|
||||||
|
false
|
||||||
|
)->orWhere($fediverseTablePrefix . 'posts.published_at', null)
|
||||||
|
->groupBy('cp_podcasts.actor_id')
|
||||||
|
->orderBy('max_published_at', 'DESC');
|
||||||
|
} elseif ($orderBy === 'created_desc') {
|
||||||
|
$this->orderBy('created_at', 'DESC');
|
||||||
|
} elseif ($orderBy === 'created_asc') {
|
||||||
|
$this->orderBy('created_at', 'ASC');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->findAll();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all the podcasts a given user is contributing to
|
* Gets all the podcasts a given user is contributing to
|
||||||
*
|
*
|
||||||
@ -378,6 +414,10 @@ class PodcastModel extends Model
|
|||||||
{
|
{
|
||||||
$podcast = (new self())->getPodcastById(is_array($data['id']) ? $data['id'][0] : $data['id']);
|
$podcast = (new self())->getPodcastById(is_array($data['id']) ? $data['id'][0] : $data['id']);
|
||||||
|
|
||||||
|
// delete cache for users' podcasts
|
||||||
|
cache()
|
||||||
|
->deleteMatching('user*podcasts');
|
||||||
|
|
||||||
if ($podcast !== null) {
|
if ($podcast !== null) {
|
||||||
// delete cache all podcast pages
|
// delete cache all podcast pages
|
||||||
cache()
|
cache()
|
||||||
|
6
app/Resources/icons/sort.svg
Normal file
6
app/Resources/icons/sort.svg
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||||
|
<g>
|
||||||
|
<path d="M0 0H24V24H0Z" fill="none"/>
|
||||||
|
<path d="M3 18H7V16H3ZM3 6V8H21V6Zm0 7H15V11H3Z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 178 B |
@ -47,10 +47,33 @@
|
|||||||
</h1>
|
</h1>
|
||||||
</header>
|
</header>
|
||||||
<main class="container flex-1 px-4 py-10 mx-auto">
|
<main class="container flex-1 px-4 py-10 mx-auto">
|
||||||
<Heading tagName="h2" class="inline-block mb-2"><?= lang('Home.all_podcasts') ?> (<?= count(
|
<div class="flex flex-wrap items-center justify-between py-2 border-b border-subtle gap-x-4">
|
||||||
|
<Heading tagName="h2" class="inline-block"><?= lang('Home.all_podcasts') ?> (<?= count(
|
||||||
$podcasts,
|
$podcasts,
|
||||||
) ?>)</Heading>
|
) ?>)</Heading>
|
||||||
<div class="grid gap-4 grid-cols-cards">
|
<button class="inline-flex items-center px-2 py-1 text-sm font-semibold focus:ring-accent" id="sortby-dropdown" data-dropdown="button" data-dropdown-target="sortby-dropdown-menu" aria-haspopup="true" aria-expanded="false"><?= icon('sort', 'mr-1 text-xl opacity-50') . lang('Home.sort_by') ?></button>
|
||||||
|
<DropdownMenu id="sortby-dropdown-menu" labelledby="sortby-dropdown" items="<?= esc(json_encode([
|
||||||
|
[
|
||||||
|
'type' => 'link',
|
||||||
|
'title' => ($sortBy === 'activity' ? '✓ ' : '') . lang('Home.sort_options.activity'),
|
||||||
|
'uri' => route_to('home') . '?sort=activity',
|
||||||
|
'class' => $sortBy === 'activity' ? 'font-semibold' : '',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'type' => 'link',
|
||||||
|
'title' => ($sortBy === 'created_desc' ? '✓ ' : '') . lang('Home.sort_options.created_desc'),
|
||||||
|
'uri' => route_to('home') . '?sort=created_desc',
|
||||||
|
'class' => $sortBy === 'created_desc' ? 'font-semibold' : '',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'type' => 'link',
|
||||||
|
'title' => ($sortBy === 'created_asc' ? '✓ ' : '') . lang('Home.sort_options.created_asc'),
|
||||||
|
'uri' => route_to('home') . '?sort=created_asc',
|
||||||
|
'class' => $sortBy === 'created_asc' ? 'font-semibold' : '',
|
||||||
|
],
|
||||||
|
])) ?>" />
|
||||||
|
</div>
|
||||||
|
<div class="grid gap-4 mt-4 grid-cols-cards">
|
||||||
<?php if ($podcasts): ?>
|
<?php if ($podcasts): ?>
|
||||||
<?php foreach ($podcasts as $podcast): ?>
|
<?php foreach ($podcasts as $podcast): ?>
|
||||||
<a href="<?= $podcast->link ?>" class="relative w-full h-full overflow-hidden transition shadow focus:ring-accent rounded-xl border-subtle hover:shadow-xl focus:shadow-xl group border-3">
|
<a href="<?= $podcast->link ?>" class="relative w-full h-full overflow-hidden transition shadow focus:ring-accent rounded-xl border-subtle hover:shadow-xl focus:shadow-xl group border-3">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user