1
0
mirror of https://github.com/flarum/core.git synced 2025-08-07 00:47:00 +02:00

feat: [1.x] [extensibility] feat: allow to be extended (#4025)

This commit is contained in:
IanM
2024-09-28 07:36:58 +01:00
committed by GitHub
parent 46cdaf5d1a
commit c79d2892de
3 changed files with 88 additions and 16 deletions

View File

@@ -77,6 +77,7 @@ import routes from './routes';
import ForumApplication from './ForumApplication';
import isSafariMobile from './utils/isSafariMobile';
import AccessTokensList from './components/AccessTokensList';
import DiscussionsSearchItem from './components/DiscussionsSearchItem';
export default Object.assign(compat, {
'utils/PostControls': PostControls,
@@ -116,6 +117,7 @@ export default Object.assign(compat, {
'components/IndexPage': IndexPage,
'components/DiscussionRenamedNotification': DiscussionRenamedNotification,
'components/DiscussionsSearchSource': DiscussionsSearchSource,
'components/DiscussionsSearchItem': DiscussionsSearchItem,
'components/HeaderSecondary': HeaderSecondary,
'components/ComposerButton': ComposerButton,
'components/DiscussionList': DiscussionList,

View File

@@ -0,0 +1,61 @@
import app from '../../forum/app';
import Component, { ComponentAttrs } from '../../common/Component';
import Link from '../../common/components/Link';
import highlight from '../../common/helpers/highlight';
import Discussion from '../../common/models/Discussion';
import Post from '../../common/models/Post';
import type Mithril from 'mithril';
import ItemList from '../../common/utils/ItemList';
export interface DiscussionsSearchItemAttrs extends ComponentAttrs {
query: string;
discussion: Discussion;
mostRelevantPost: Post;
}
export default class DiscussionsSearchItem extends Component<DiscussionsSearchItemAttrs> {
query!: string;
discussion!: Discussion;
mostRelevantPost!: Post | null | undefined;
oninit(vnode: Mithril.Vnode<DiscussionsSearchItemAttrs, this>) {
super.oninit(vnode);
this.query = this.attrs.query;
this.discussion = this.attrs.discussion;
this.mostRelevantPost = this.attrs.mostRelevantPost;
}
view() {
return (
<li className="DiscussionSearchResult" data-index={'discussions' + this.discussion.id()}>
<Link href={app.route.discussion(this.discussion, (this.mostRelevantPost && this.mostRelevantPost.number()) || 0)}>
{this.viewItems().toArray()}
</Link>
</li>
);
}
discussionTitle() {
return this.discussion.title();
}
mostRelevantPostContent() {
return this.mostRelevantPost?.contentPlain();
}
viewItems(): ItemList<Mithril.Children> {
const items = new ItemList<Mithril.Children>();
items.add('discussion-title', <div className="DiscussionSearchResult-title">{highlight(this.discussionTitle(), this.query)}</div>, 90);
!!this.mostRelevantPost &&
items.add(
'most-relevant',
<div className="DiscussionSearchResult-excerpt">{highlight(this.mostRelevantPostContent() ?? '', this.query, 100)}</div>,
80
);
return items;
}
}

View File

@@ -1,10 +1,9 @@
import app from '../../forum/app';
import highlight from '../../common/helpers/highlight';
import LinkButton from '../../common/components/LinkButton';
import Link from '../../common/components/Link';
import { SearchSource } from './Search';
import type Mithril from 'mithril';
import Discussion from '../../common/models/Discussion';
import DiscussionsSearchItem from './DiscussionsSearchItem';
/**
* The `DiscussionsSearchSource` finds and displays discussion search results in
@@ -12,16 +11,19 @@ import Discussion from '../../common/models/Discussion';
*/
export default class DiscussionsSearchSource implements SearchSource {
protected results = new Map<string, Discussion[]>();
queryString: string | null = null;
async search(query: string): Promise<void> {
query = query.toLowerCase();
this.results.set(query, []);
this.setQueryString(query);
const params = {
filter: { q: query },
page: { limit: 3 },
include: 'mostRelevantPost',
filter: { q: this.queryString || query },
page: { limit: this.limit() },
include: this.includes().join(','),
};
return app.store.find<Discussion[]>('discussions', params).then((results) => {
@@ -36,26 +38,33 @@ export default class DiscussionsSearchSource implements SearchSource {
const results = (this.results.get(query) || []).map((discussion) => {
const mostRelevantPost = discussion.mostRelevantPost();
return (
<li className="DiscussionSearchResult" data-index={'discussions' + discussion.id()}>
<Link href={app.route.discussion(discussion, (mostRelevantPost && mostRelevantPost.number()) || 0)}>
<div className="DiscussionSearchResult-title">{highlight(discussion.title(), query)}</div>
{!!mostRelevantPost && (
<div className="DiscussionSearchResult-excerpt">{highlight(mostRelevantPost.contentPlain() ?? '', query, 100)}</div>
)}
</Link>
</li>
);
return <DiscussionsSearchItem query={query} discussion={discussion} mostRelevantPost={mostRelevantPost} />;
}) as Array<Mithril.Vnode>;
return [
<li className="Dropdown-header">{app.translator.trans('core.forum.search.discussions_heading')}</li>,
<li>
<LinkButton icon="fas fa-search" href={app.route('index', { q: query })}>
<LinkButton icon="fas fa-search" href={app.route('index', { q: this.queryString })}>
{app.translator.trans('core.forum.search.all_discussions_button', { query })}
</LinkButton>
</li>,
...results,
];
}
includes(): string[] {
return ['mostRelevantPost'];
}
limit(): number {
return 3;
}
queryMutators(): string[] {
return [];
}
setQueryString(query: string): void {
this.queryString = query + ' ' + this.queryMutators().join(' ');
}
}