Skip to content

Commit

Permalink
feat: add option for filtering read stickied on all discussions page (#…
Browse files Browse the repository at this point in the history
…4073)

Co-authored-by: Adrian McCay <2762877+adrianmccay@users.noreply.github.com>
  • Loading branch information
SychO9 and adrianmccay authored Oct 17, 2024
1 parent db17253 commit 876a964
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 14 deletions.
4 changes: 4 additions & 0 deletions extensions/sticky/extend.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,8 @@
(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'),
];
26 changes: 17 additions & 9 deletions extensions/sticky/js/src/admin/extend.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
})),
];
3 changes: 3 additions & 0 deletions extensions/sticky/locale/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
38 changes: 33 additions & 5 deletions extensions/sticky/src/PinStickiedDiscussionsToTop.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,38 @@
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.
$filters = $state->getActiveFilters();

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;
Expand Down Expand Up @@ -76,4 +87,21 @@ public function __invoke(DatabaseSearchState $state, SearchCriteria $criteria):
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']);
}
}
34 changes: 34 additions & 0 deletions extensions/sticky/tests/integration/api/ListDiscussionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,40 @@ public function list_discussions_shows_normal_order_when_all_read_as_user()
$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()
{
Expand Down

0 comments on commit 876a964

Please sign in to comment.