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);
|
||||
}
|
||||
|
||||
$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
|
||||
if (count($allPodcasts) === 1) {
|
||||
|
@ -38,6 +43,7 @@ class HomeController extends BaseController
|
|||
$data = [
|
||||
'metatags' => get_home_metatags(),
|
||||
'podcasts' => $allPodcasts,
|
||||
'sortBy' => $sortBy,
|
||||
];
|
||||
|
||||
return view('home', $data);
|
||||
|
|
|
@ -10,5 +10,11 @@ declare(strict_types=1);
|
|||
|
||||
return [
|
||||
'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',
|
||||
];
|
||||
|
|
|
@ -10,5 +10,11 @@ declare(strict_types=1);
|
|||
|
||||
return [
|
||||
'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é',
|
||||
];
|
||||
|
|
|
@ -166,6 +166,42 @@ class PodcastModel extends Model
|
|||
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
|
||||
*
|
||||
|
@ -378,6 +414,10 @@ class PodcastModel extends Model
|
|||
{
|
||||
$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) {
|
||||
// delete cache all podcast pages
|
||||
cache()
|
||||
|
|
|
@ -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>
|
||||
</header>
|
||||
<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,
|
||||
) ?>)</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 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">
|
||||
|
|
Loading…
Reference in New Issue