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:
@@ -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,
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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(' ');
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user