mirror of
https://github.com/flarum/framework.git
synced 2024-11-25 09:41:49 +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))
|
||||
->addFilter(DiscussionSearcher::class, StickyFilter::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 [
|
||||
...commonExtend,
|
||||
|
||||
new Extend.Admin().permission(
|
||||
() => ({
|
||||
icon: 'fas fa-thumbtack',
|
||||
label: app.translator.trans('flarum-sticky.admin.permissions.sticky_discussions_label'),
|
||||
permission: 'discussion.sticky',
|
||||
}),
|
||||
'moderate',
|
||||
95
|
||||
),
|
||||
new Extend.Admin()
|
||||
.permission(
|
||||
() => ({
|
||||
icon: 'fas fa-thumbtack',
|
||||
label: app.translator.trans('flarum-sticky.admin.permissions.sticky_discussions_label'),
|
||||
permission: 'discussion.sticky',
|
||||
}),
|
||||
'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.
|
||||
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.
|
||||
permissions:
|
||||
|
|
|
@ -12,15 +12,30 @@ namespace Flarum\Sticky;
|
|||
use DateTime;
|
||||
use Flarum\Search\Database\DatabaseSearchState;
|
||||
use Flarum\Search\SearchCriteria;
|
||||
use Flarum\Settings\SettingsRepositoryInterface;
|
||||
use Flarum\Tags\Search\Filter\TagFilter;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
|
||||
class PinStickiedDiscussionsToTop
|
||||
{
|
||||
public function __construct(
|
||||
protected SettingsRepositoryInterface $settings
|
||||
) {
|
||||
}
|
||||
|
||||
public function __invoke(DatabaseSearchState $state, SearchCriteria $criteria): void
|
||||
{
|
||||
if ($criteria->sortIsDefault && ! $state->isFulltextSearch()) {
|
||||
$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
|
||||
// discussions to the top no matter what.
|
||||
|
@ -28,11 +43,7 @@ class PinStickiedDiscussionsToTop
|
|||
|
||||
if ($count = count($filters)) {
|
||||
if ($count === 1 && $filters[0] instanceof TagFilter) {
|
||||
if (! is_array($query->orders)) {
|
||||
$query->orders = [];
|
||||
}
|
||||
|
||||
array_unshift($query->orders, ['column' => 'is_sticky', 'direction' => 'desc']);
|
||||
$this->pinStickiedToTop($query);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -76,4 +87,21 @@ class PinStickiedDiscussionsToTop
|
|||
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'));
|
||||
}
|
||||
|
||||
#[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]
|
||||
public function list_discussions_shows_stick_first_on_a_tag()
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user