Skip to content

Commit

Permalink
add pagination to flags list
Browse files Browse the repository at this point in the history
  • Loading branch information
OrdinaryJellyfish committed Nov 21, 2023
1 parent 6cbdfb6 commit 6b7ee14
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 55 deletions.
69 changes: 37 additions & 32 deletions extensions/flags/js/src/forum/components/FlagList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,49 +16,54 @@ export interface IFlagListAttrs extends ComponentAttrs {
export default class FlagList<CustomAttrs extends IFlagListAttrs = IFlagListAttrs> extends Component<CustomAttrs, FlagListState> {
oninit(vnode: Mithril.Vnode<CustomAttrs, this>) {
super.oninit(vnode);
this.state = this.attrs.state;
}

view() {
const flags = this.state.cache || [];
const state = this.attrs.state;

return (
<HeaderList
className="FlagList"
title={app.translator.trans('flarum-flags.forum.flagged_posts.title')}
hasItems={flags.length}
loading={this.state.loading}
hasItems={state.hasItems()}
loading={state.isLoading()}
emptyText={app.translator.trans('flarum-flags.forum.flagged_posts.empty_text')}
loadMore={() => state.hasNext() && !state.isLoadingNext() && state.loadNext()}
>
<ul className="HeaderListGroup-content">
{!this.state.loading &&
flags.map((flag) => {
const post = flag.post() as Post;

return (
<li>
<HeaderListItem
className="Flag"
avatar={<Avatar user={post.user() || null} />}
icon="fas fa-flag"
content={app.translator.trans('flarum-flags.forum.flagged_posts.item_text', {
username: username(post.user()),
em: <em />,
discussion: post.discussion().title(),
})}
excerpt={post.contentPlain()}
datetime={flag.createdAt()}
href={app.route.post(post)}
onclick={(e: MouseEvent) => {
app.flags.index = post;
e.redraw = false;
}}
/>
</li>
);
})}
</ul>
{this.content(state)}
</HeaderList>
);
}

content(state) {
if (!state.isLoading() && state.hasItems()) {
return state.getPages().map((page) => {
return page.items.map((flag) => {
const post = flag.post() as Post;

return (
<HeaderListItem
className="Flag"
avatar={<Avatar user={post.user() || null} />}
icon="fas fa-flag"
content={app.translator.trans('flarum-flags.forum.flagged_posts.item_text', {
username: username(post.user()),
em: <em />,
discussion: post.discussion().title(),
})}
excerpt={post.contentPlain()}
datetime={flag.createdAt()}
href={app.route.post(post)}
onclick={(e: MouseEvent) => {
app.flags.index = post;
e.redraw = false;
}}
/>
);
});
});
}

return null;
}
}
32 changes: 15 additions & 17 deletions extensions/flags/js/src/forum/states/FlagListState.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,37 @@
import type ForumApplication from 'flarum/forum/ForumApplication';
import type Flag from '../models/Flag';
import type Post from 'flarum/common/models/Post';
import PaginatedListState from 'flarum/common/states/PaginatedListState';

export default class FlagListState {
export default class FlagListState extends PaginatedListState<Flag> {
public app: ForumApplication;
public loading = false;
public cache: Flag[] | null = null;
public index: Post | false | null = null;

constructor(app: ForumApplication) {
super({}, 1, null);
this.app = app;
}

get type(): string {
return 'flags';
}

/**
* Load flags into the application's cache if they haven't already
* been loaded.
*/
load() {
if (this.cache && !this.app.session.user!.attribute<number>('newFlagCount')) {
return;
load(): Promise<void> {
if (this.app.session.user?.attribute<number>('newFlagCount')) {
this.pages = [];
this.location = { page: 1 };
}

this.loading = true;
m.redraw();
if (this.pages.length > 0) {
return Promise.resolve();
}

this.app.store
.find<Flag[]>('flags')
.then((flags) => {
this.app.session.user!.pushAttributes({ newFlagCount: 0 });
this.cache = flags.sort((a, b) => b.createdAt()!.getTime() - a.createdAt()!.getTime());
})
.catch(() => {})
.then(() => {
this.loading = false;
m.redraw();
});
return super.loadNext();
}
}
43 changes: 37 additions & 6 deletions extensions/flags/src/Api/Controller/ListFlagsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Flarum\Http\RequestUtil;
use Psr\Http\Message\ServerRequestInterface;
use Tobscure\JsonApi\Document;
use Flarum\Http\UrlGenerator;

class ListFlagsController extends AbstractListController
{
Expand All @@ -28,26 +29,56 @@ class ListFlagsController extends AbstractListController
'post.discussion'
];

public function __construct(
protected UrlGenerator $url
) {
}

protected function data(ServerRequestInterface $request, Document $document): iterable
{
$actor = RequestUtil::getActor($request);
$include = $this->extractInclude($request);

$actor->assertRegistered();

$actor->read_flags_at = Carbon::now();
$actor->save();

$flags = Flag::whereVisibleTo($actor)
->latest('flags.created_at')
->groupBy('post_id')
->get();
$limit = $this->extractLimit($request);
$offset = $this->extractOffset($request);
$include = $this->extractInclude($request);

if (in_array('post.user', $include)) {
$include[] = 'post.user.groups';
}

$this->loadRelations($flags, $include);
$primaries = Flag::whereVisibleTo($actor)
->groupBy('post_id')
->orderBy('created_at', 'DESC')
->skip($offset)
->take($limit + 1);

$flags = Flag::whereVisibleTo($actor)
->joinSub($primaries, 'p', 'flags.id', '=', 'p.id')
->latest()
->get();

$this->loadRelations($flags, $include, $request);

$flags = $flags->all();

$areMoreResults = false;

if (count($flags) > $limit) {
array_pop($flags);
$areMoreResults = true;
}

$this->addPaginationData(
$document,
$request,
$this->url->to('api')->route('flags.index'),
$areMoreResults ? null : 0
);

return $flags;
}
Expand Down

0 comments on commit 6b7ee14

Please sign in to comment.