mirror of
https://github.com/flarum/core.git
synced 2025-08-16 13:24:11 +02:00
perf(core,mentions): limit mentionedBy
post relation results (#3780)
* perf(core,mentions): limit `mentionedBy` post relation results Signed-off-by: Sami Mazouz <sychocouldy@gmail.com> * Apply fixes from StyleCI * chore: use a static property to allow customization Signed-off-by: Sami Mazouz <sychocouldy@gmail.com> * chore: use a static property to allow customization Signed-off-by: Sami Mazouz <sychocouldy@gmail.com> * chore: include count in show post endpoint Signed-off-by: Sami Mazouz <sychocouldy@gmail.com> * chore: consistent locale key format Signed-off-by: Sami Mazouz <sychocouldy@gmail.com> * chore: forgot to delete `FilterVisiblePosts` Signed-off-by: Sami Mazouz <sychocouldy@gmail.com> * test: `mentionedByCount` must not include invisible posts to actor Signed-off-by: Sami Mazouz <sychocouldy@gmail.com> * fix: visibility scoping on `mentionedByCount` Signed-off-by: Sami Mazouz <sychocouldy@gmail.com> * fix: `loadAggregates` conflicts with visibility scopers Signed-off-by: Sami Mazouz <sychocouldy@gmail.com> * Apply fixes from StyleCI * chore: phpstan Signed-off-by: Sami Mazouz <sychocouldy@gmail.com> --------- Signed-off-by: Sami Mazouz <sychocouldy@gmail.com> Co-authored-by: StyleCI Bot <bot@styleci.io>
This commit is contained in:
8
extensions/mentions/js/src/@types/shims.d.ts
vendored
Normal file
8
extensions/mentions/js/src/@types/shims.d.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import type BasePost from 'flarum/common/models/Post';
|
||||
|
||||
declare module 'flarum/common/models/Post' {
|
||||
export default interface Post {
|
||||
mentionedBy(): BasePost[] | undefined | null;
|
||||
mentionedByCount(): number;
|
||||
}
|
||||
}
|
@@ -6,6 +6,8 @@ import PostPreview from 'flarum/forum/components/PostPreview';
|
||||
import punctuateSeries from 'flarum/common/helpers/punctuateSeries';
|
||||
import username from 'flarum/common/helpers/username';
|
||||
import icon from 'flarum/common/helpers/icon';
|
||||
import Button from 'flarum/common/components/Button';
|
||||
import MentionedByModal from './components/MentionedByModal';
|
||||
|
||||
export default function addMentionedByList() {
|
||||
function hidePreview() {
|
||||
@@ -36,14 +38,34 @@ export default function addMentionedByList() {
|
||||
// popup.
|
||||
m.render(
|
||||
$preview[0],
|
||||
replies.map((reply) => (
|
||||
<li data-number={reply.number()}>
|
||||
{PostPreview.component({
|
||||
post: reply,
|
||||
onclick: hidePreview.bind(this),
|
||||
})}
|
||||
</li>
|
||||
))
|
||||
<>
|
||||
{replies.map((reply) => (
|
||||
<li data-number={reply.number()}>
|
||||
{PostPreview.component({
|
||||
post: reply,
|
||||
onclick: hidePreview.bind(this),
|
||||
})}
|
||||
</li>
|
||||
))}
|
||||
{replies.length < post.mentionedByCount() ? (
|
||||
<li className="Post-mentionedBy-preview-more">
|
||||
<Button
|
||||
className="PostPreview Button"
|
||||
onclick={() => {
|
||||
hidePreview.call(this);
|
||||
app.modal.show(MentionedByModal, { post });
|
||||
}}
|
||||
>
|
||||
<span className="PostPreview-content">
|
||||
<span className="PostPreview-badge Avatar">{icon('fas fa-reply-all')}</span>
|
||||
<span>
|
||||
{app.translator.trans('flarum-mentions.forum.post.mentioned_by_more_text', { count: post.mentionedByCount() - replies.length })}
|
||||
</span>
|
||||
</span>
|
||||
</Button>
|
||||
</li>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
|
||||
$preview
|
||||
|
@@ -0,0 +1,73 @@
|
||||
import app from 'flarum/forum/app';
|
||||
import PostPreview from 'flarum/forum/components/PostPreview';
|
||||
import Modal, { IInternalModalAttrs } from 'flarum/common/components/Modal';
|
||||
import type Mithril from 'mithril';
|
||||
import type Post from 'flarum/common/models/Post';
|
||||
import LoadingIndicator from 'flarum/common/components/LoadingIndicator';
|
||||
import Button from 'flarum/common/components/Button';
|
||||
import MentionedByModalState from '../state/MentionedByModalState';
|
||||
|
||||
export interface IMentionedByModalAttrs extends IInternalModalAttrs {
|
||||
post: Post;
|
||||
}
|
||||
|
||||
export default class MentionedByModal<CustomAttrs extends IMentionedByModalAttrs = IMentionedByModalAttrs> extends Modal<
|
||||
CustomAttrs,
|
||||
MentionedByModalState
|
||||
> {
|
||||
oninit(vnode: Mithril.Vnode<CustomAttrs, this>) {
|
||||
super.oninit(vnode);
|
||||
|
||||
this.state = new MentionedByModalState({
|
||||
filter: {
|
||||
mentionedPost: this.attrs.post.id()!,
|
||||
},
|
||||
sort: 'number',
|
||||
});
|
||||
|
||||
this.state.refresh();
|
||||
}
|
||||
|
||||
className(): string {
|
||||
return 'MentionedByModal';
|
||||
}
|
||||
|
||||
title(): Mithril.Children {
|
||||
return app.translator.trans('flarum-mentions.forum.mentioned_by.title');
|
||||
}
|
||||
|
||||
content(): Mithril.Children {
|
||||
return (
|
||||
<>
|
||||
<div className="Modal-body">
|
||||
{this.state.isInitialLoading() ? (
|
||||
<LoadingIndicator />
|
||||
) : (
|
||||
<>
|
||||
<ul className="MentionedByModal-list Dropdown-menu Dropdown-menu--inline Post-mentionedBy-preview">
|
||||
{this.state.getPages().map((page) =>
|
||||
page.items.map((reply) => (
|
||||
<li data-number={reply.number()}>
|
||||
<PostPreview post={reply} onclick={() => app.modal.close()} />
|
||||
</li>
|
||||
))
|
||||
)}
|
||||
</ul>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
{this.state.hasNext() && (
|
||||
<div className="Modal-footer">
|
||||
<div className="Form Form--centered">
|
||||
<div className="Form-group">
|
||||
<Button className="Button Button--block" onclick={() => this.state.loadNext()} loading={this.state.isLoadingNext()}>
|
||||
{app.translator.trans('flarum-mentions.forum.mentioned_by.load_more_button')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
@@ -8,7 +8,8 @@ export default [
|
||||
.add('user.mentions', '/u/:username/mentions', MentionsUserPage),
|
||||
|
||||
new Extend.Model(Post) //
|
||||
.hasMany<Post>('mentionedBy'),
|
||||
.hasMany<Post>('mentionedBy')
|
||||
.attribute<number>('mentionedByCount'),
|
||||
|
||||
new Extend.Model(User) //
|
||||
.attribute<boolean>('canMentionGroups'),
|
||||
|
@@ -0,0 +1,27 @@
|
||||
import PaginatedListState, { PaginatedListParams } from 'flarum/common/states/PaginatedListState';
|
||||
import Post from 'flarum/common/models/Post';
|
||||
|
||||
export interface MentionedByModalParams extends PaginatedListParams {
|
||||
filter: {
|
||||
mentionedPost: string;
|
||||
};
|
||||
sort?: string;
|
||||
page?: {
|
||||
offset?: number;
|
||||
limit: number;
|
||||
};
|
||||
}
|
||||
|
||||
export default class MentionedByModalState<P extends MentionedByModalParams = MentionedByModalParams> extends PaginatedListState<Post, P> {
|
||||
constructor(params: P, page: number = 1) {
|
||||
const limit = 10;
|
||||
|
||||
params.page = { ...(params.page || {}), limit };
|
||||
|
||||
super(params, page, limit);
|
||||
}
|
||||
|
||||
get type(): string {
|
||||
return 'posts';
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user