mirror of
https://github.com/flarum/core.git
synced 2025-08-08 01:16:52 +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 ForumApplication from './ForumApplication';
|
||||||
import isSafariMobile from './utils/isSafariMobile';
|
import isSafariMobile from './utils/isSafariMobile';
|
||||||
import AccessTokensList from './components/AccessTokensList';
|
import AccessTokensList from './components/AccessTokensList';
|
||||||
|
import DiscussionsSearchItem from './components/DiscussionsSearchItem';
|
||||||
|
|
||||||
export default Object.assign(compat, {
|
export default Object.assign(compat, {
|
||||||
'utils/PostControls': PostControls,
|
'utils/PostControls': PostControls,
|
||||||
@@ -116,6 +117,7 @@ export default Object.assign(compat, {
|
|||||||
'components/IndexPage': IndexPage,
|
'components/IndexPage': IndexPage,
|
||||||
'components/DiscussionRenamedNotification': DiscussionRenamedNotification,
|
'components/DiscussionRenamedNotification': DiscussionRenamedNotification,
|
||||||
'components/DiscussionsSearchSource': DiscussionsSearchSource,
|
'components/DiscussionsSearchSource': DiscussionsSearchSource,
|
||||||
|
'components/DiscussionsSearchItem': DiscussionsSearchItem,
|
||||||
'components/HeaderSecondary': HeaderSecondary,
|
'components/HeaderSecondary': HeaderSecondary,
|
||||||
'components/ComposerButton': ComposerButton,
|
'components/ComposerButton': ComposerButton,
|
||||||
'components/DiscussionList': DiscussionList,
|
'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 app from '../../forum/app';
|
||||||
import highlight from '../../common/helpers/highlight';
|
|
||||||
import LinkButton from '../../common/components/LinkButton';
|
import LinkButton from '../../common/components/LinkButton';
|
||||||
import Link from '../../common/components/Link';
|
|
||||||
import { SearchSource } from './Search';
|
import { SearchSource } from './Search';
|
||||||
import type Mithril from 'mithril';
|
import type Mithril from 'mithril';
|
||||||
import Discussion from '../../common/models/Discussion';
|
import Discussion from '../../common/models/Discussion';
|
||||||
|
import DiscussionsSearchItem from './DiscussionsSearchItem';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `DiscussionsSearchSource` finds and displays discussion search results in
|
* 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 {
|
export default class DiscussionsSearchSource implements SearchSource {
|
||||||
protected results = new Map<string, Discussion[]>();
|
protected results = new Map<string, Discussion[]>();
|
||||||
|
queryString: string | null = null;
|
||||||
|
|
||||||
async search(query: string): Promise<void> {
|
async search(query: string): Promise<void> {
|
||||||
query = query.toLowerCase();
|
query = query.toLowerCase();
|
||||||
|
|
||||||
this.results.set(query, []);
|
this.results.set(query, []);
|
||||||
|
|
||||||
|
this.setQueryString(query);
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
filter: { q: query },
|
filter: { q: this.queryString || query },
|
||||||
page: { limit: 3 },
|
page: { limit: this.limit() },
|
||||||
include: 'mostRelevantPost',
|
include: this.includes().join(','),
|
||||||
};
|
};
|
||||||
|
|
||||||
return app.store.find<Discussion[]>('discussions', params).then((results) => {
|
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 results = (this.results.get(query) || []).map((discussion) => {
|
||||||
const mostRelevantPost = discussion.mostRelevantPost();
|
const mostRelevantPost = discussion.mostRelevantPost();
|
||||||
|
|
||||||
return (
|
return <DiscussionsSearchItem query={query} discussion={discussion} mostRelevantPost={mostRelevantPost} />;
|
||||||
<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>
|
|
||||||
);
|
|
||||||
}) as Array<Mithril.Vnode>;
|
}) as Array<Mithril.Vnode>;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
<li className="Dropdown-header">{app.translator.trans('core.forum.search.discussions_heading')}</li>,
|
<li className="Dropdown-header">{app.translator.trans('core.forum.search.discussions_heading')}</li>,
|
||||||
<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 })}
|
{app.translator.trans('core.forum.search.all_discussions_button', { query })}
|
||||||
</LinkButton>
|
</LinkButton>
|
||||||
</li>,
|
</li>,
|
||||||
...results,
|
...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