mirror of
https://github.com/flarum/framework.git
synced 2024-11-22 14:24:46 +08:00
feat: add option for filtering read stickied on all discussions page (#4073)
Co-authored-by: Adrian McCay <2762877+adrianmccay@users.noreply.github.com>
This commit is contained in:
parent
db17253ccd
commit
876a964e1e
|
@ -50,4 +50,8 @@ return [
|
||||||
(new Extend\SearchDriver(DatabaseSearchDriver::class))
|
(new Extend\SearchDriver(DatabaseSearchDriver::class))
|
||||||
->addFilter(DiscussionSearcher::class, StickyFilter::class)
|
->addFilter(DiscussionSearcher::class, StickyFilter::class)
|
||||||
->addMutator(DiscussionSearcher::class, PinStickiedDiscussionsToTop::class),
|
->addMutator(DiscussionSearcher::class, PinStickiedDiscussionsToTop::class),
|
||||||
|
|
||||||
|
(new Extend\Settings())
|
||||||
|
->default('flarum-sticky.only_sticky_unread_discussions', true)
|
||||||
|
->serializeToForum('onlyStickyUnreadDiscussions', 'flarum-sticky.only_sticky_unread_discussions', 'boolval'),
|
||||||
];
|
];
|
||||||
|
|
|
@ -5,13 +5,21 @@ import commonExtend from '../common/extend';
|
||||||
export default [
|
export default [
|
||||||
...commonExtend,
|
...commonExtend,
|
||||||
|
|
||||||
new Extend.Admin().permission(
|
new Extend.Admin()
|
||||||
() => ({
|
.permission(
|
||||||
icon: 'fas fa-thumbtack',
|
() => ({
|
||||||
label: app.translator.trans('flarum-sticky.admin.permissions.sticky_discussions_label'),
|
icon: 'fas fa-thumbtack',
|
||||||
permission: 'discussion.sticky',
|
label: app.translator.trans('flarum-sticky.admin.permissions.sticky_discussions_label'),
|
||||||
}),
|
permission: 'discussion.sticky',
|
||||||
'moderate',
|
}),
|
||||||
95
|
'moderate',
|
||||||
),
|
95
|
||||||
|
)
|
||||||
|
.setting(() => ({
|
||||||
|
setting: 'flarum-sticky.only_sticky_unread_discussions',
|
||||||
|
name: 'onlyStickyUnreadDiscussions',
|
||||||
|
type: 'boolean',
|
||||||
|
label: app.translator.trans('flarum-sticky.admin.settings.only_sticky_unread_discussions_label'),
|
||||||
|
help: app.translator.trans('flarum-sticky.admin.settings.only_sticky_unread_discussions_help'),
|
||||||
|
})),
|
||||||
];
|
];
|
||||||
|
|
|
@ -6,6 +6,9 @@ flarum-sticky:
|
||||||
|
|
||||||
# Translations in this namespace are used by the admin interface.
|
# Translations in this namespace are used by the admin interface.
|
||||||
admin:
|
admin:
|
||||||
|
settings:
|
||||||
|
only_sticky_unread_discussions_label: Only sticky unread discussions
|
||||||
|
only_sticky_unread_discussions_help: On the All Discussions page, unread sticky discussions pin to the top, while read sticky discussions follow the regular order.
|
||||||
|
|
||||||
# These translations are used in the Permissions page of the admin interface.
|
# These translations are used in the Permissions page of the admin interface.
|
||||||
permissions:
|
permissions:
|
||||||
|
|
|
@ -12,15 +12,30 @@ namespace Flarum\Sticky;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use Flarum\Search\Database\DatabaseSearchState;
|
use Flarum\Search\Database\DatabaseSearchState;
|
||||||
use Flarum\Search\SearchCriteria;
|
use Flarum\Search\SearchCriteria;
|
||||||
|
use Flarum\Settings\SettingsRepositoryInterface;
|
||||||
use Flarum\Tags\Search\Filter\TagFilter;
|
use Flarum\Tags\Search\Filter\TagFilter;
|
||||||
use Illuminate\Database\Query\Builder;
|
use Illuminate\Database\Query\Builder;
|
||||||
|
|
||||||
class PinStickiedDiscussionsToTop
|
class PinStickiedDiscussionsToTop
|
||||||
{
|
{
|
||||||
|
public function __construct(
|
||||||
|
protected SettingsRepositoryInterface $settings
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
public function __invoke(DatabaseSearchState $state, SearchCriteria $criteria): void
|
public function __invoke(DatabaseSearchState $state, SearchCriteria $criteria): void
|
||||||
{
|
{
|
||||||
if ($criteria->sortIsDefault && ! $state->isFulltextSearch()) {
|
if ($criteria->sortIsDefault && ! $state->isFulltextSearch()) {
|
||||||
$query = $state->getQuery()->getQuery();
|
$query = $state->getQuery()->getQuery();
|
||||||
|
$onlyStickyUnread = $this->settings->get('flarum-sticky.only_sticky_unread_discussions');
|
||||||
|
|
||||||
|
// If only sticky unread discussions is disabled, then pin all stickied
|
||||||
|
// discussions to the top whether they are read or not.
|
||||||
|
if (! $onlyStickyUnread) {
|
||||||
|
$this->pinStickiedToTop($query);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If we are viewing a specific tag, then pin all stickied
|
// If we are viewing a specific tag, then pin all stickied
|
||||||
// discussions to the top no matter what.
|
// discussions to the top no matter what.
|
||||||
|
@ -28,11 +43,7 @@ class PinStickiedDiscussionsToTop
|
||||||
|
|
||||||
if ($count = count($filters)) {
|
if ($count = count($filters)) {
|
||||||
if ($count === 1 && $filters[0] instanceof TagFilter) {
|
if ($count === 1 && $filters[0] instanceof TagFilter) {
|
||||||
if (! is_array($query->orders)) {
|
$this->pinStickiedToTop($query);
|
||||||
$query->orders = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
array_unshift($query->orders, ['column' => 'is_sticky', 'direction' => 'desc']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -76,4 +87,21 @@ class PinStickiedDiscussionsToTop
|
||||||
unset($query->offset, $sticky->offset);
|
unset($query->offset, $sticky->offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pin all stickied discussions to the top of the query.
|
||||||
|
* This is done by prepending an order clause to the query.
|
||||||
|
*
|
||||||
|
* @param $query
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function pinStickiedToTop($query): void
|
||||||
|
{
|
||||||
|
if (! is_array($query->orders)) {
|
||||||
|
$query->orders = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
array_unshift($query->orders, ['column' => 'is_sticky', 'direction' => 'desc']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,6 +104,40 @@ class ListDiscussionsTest extends TestCase
|
||||||
$this->assertEqualsCanonicalizing([2, 4, 3, 1], Arr::pluck($data['data'], 'id'));
|
$this->assertEqualsCanonicalizing([2, 4, 3, 1], Arr::pluck($data['data'], 'id'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[Test]
|
||||||
|
public function list_discussions_sticky_first_all_read_as_user_filter_read_off()
|
||||||
|
{
|
||||||
|
$this->setting('flarum-sticky.only_sticky_unread_discussions', false);
|
||||||
|
$response = $this->send(
|
||||||
|
$this->request('GET', '/api/discussions', [
|
||||||
|
'authenticatedAs' => 3
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(200, $response->getStatusCode());
|
||||||
|
|
||||||
|
$data = json_decode($response->getBody()->getContents(), true);
|
||||||
|
|
||||||
|
$this->assertEquals([3, 1, 2, 4], Arr::pluck($data['data'], 'id'));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Test]
|
||||||
|
public function list_discussions_sticky_first_all_read_as_user_filter_read_on()
|
||||||
|
{
|
||||||
|
$this->setting('flarum-sticky.only_sticky_unread_discussions', true);
|
||||||
|
$response = $this->send(
|
||||||
|
$this->request('GET', '/api/discussions', [
|
||||||
|
'authenticatedAs' => 3
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(200, $response->getStatusCode());
|
||||||
|
|
||||||
|
$data = json_decode($response->getBody()->getContents(), true);
|
||||||
|
|
||||||
|
$this->assertEquals([2, 4, 3, 1], Arr::pluck($data['data'], 'id'));
|
||||||
|
}
|
||||||
|
|
||||||
#[Test]
|
#[Test]
|
||||||
public function list_discussions_shows_stick_first_on_a_tag()
|
public function list_discussions_shows_stick_first_on_a_tag()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user