feat: add discussion search source
This commit is contained in:
parent
d646c719f3
commit
f4dca3d185
|
|
@ -0,0 +1,77 @@
|
||||||
|
import app from 'flarum/forum/app';
|
||||||
|
import highlight from 'flarum/common/helpers/highlight';
|
||||||
|
import LinkButton from 'flarum/common/components/LinkButton';
|
||||||
|
import Link from 'flarum/common/components/Link';
|
||||||
|
import { SearchSource } from 'flarum/forum/components/Search';
|
||||||
|
import type Mithril from 'mithril';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `DiscussionsSearchSource` finds and displays discussion search results in
|
||||||
|
* the search dropdown.
|
||||||
|
*/
|
||||||
|
export default class DiscussionsSearchSource implements SearchSource {
|
||||||
|
/**
|
||||||
|
* Map of lowercase search queries to their respective model results
|
||||||
|
*/
|
||||||
|
protected results = new Map<string, any[]>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model name used for assembling API endpoint URL, and for frontend DOM.
|
||||||
|
*/
|
||||||
|
private type = 'discussions';
|
||||||
|
|
||||||
|
async search(query: string): Promise<void> {
|
||||||
|
query = query.toLowerCase();
|
||||||
|
|
||||||
|
this.results.set(query, []);
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
filter: { q: query },
|
||||||
|
page: { limit: 3 },
|
||||||
|
};
|
||||||
|
|
||||||
|
// Construct API search URI
|
||||||
|
const url = `${app.forum.attribute('apiUrl')}/blomstra/search/${this.type}`;
|
||||||
|
|
||||||
|
// Make API GET request
|
||||||
|
const results = await app.request({ params, url, method: 'GET' });
|
||||||
|
|
||||||
|
// Parse API response into models and push to store
|
||||||
|
const models = app.store.pushPayload(results);
|
||||||
|
|
||||||
|
// Add models to results map
|
||||||
|
this.results.set(query, models);
|
||||||
|
}
|
||||||
|
|
||||||
|
view(query: string): Mithril.Children {
|
||||||
|
query = query.toLowerCase();
|
||||||
|
|
||||||
|
// Get results from map
|
||||||
|
const queryResults = this.results.get(query) || [];
|
||||||
|
|
||||||
|
const results = queryResults.map((discussion: any) => {
|
||||||
|
// const mostRelevantPost = discussion.mostRelevantPost();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<li className="DiscussionSearchResult" data-index={`${this.type}${discussion.id()}`} key={`${this.type}${discussion.id()}`}>
|
||||||
|
<Link href={app.route.discussion(discussion /*, mostRelevantPost && mostRelevantPost.number()*/)}>
|
||||||
|
<div className="DiscussionSearchResult-title">{highlight(discussion.title(), query)}</div>
|
||||||
|
{/* {!!mostRelevantPost && <div className="DiscussionSearchResult-excerpt">{highlight(mostRelevantPost.contentPlain(), query, 100)}</div>} */}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
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 })}>
|
||||||
|
{app.translator.trans('core.forum.search.all_discussions_button', { query })}
|
||||||
|
</LinkButton>
|
||||||
|
</li>
|
||||||
|
{results}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
import app from 'flarum/app';
|
|
||||||
import highlight from 'flarum/common/helpers/highlight';
|
|
||||||
import LinkButton from 'flarum/common/components/LinkButton';
|
|
||||||
import Link from 'flarum/common/components/Link';
|
|
||||||
import { SearchSource } from 'flarum/forum/components/Search';
|
|
||||||
import type Mithril from 'mithril';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The `DiscussionsSearchSource` finds and displays discussion search results in
|
|
||||||
* the search dropdown.
|
|
||||||
*/
|
|
||||||
export default class Source implements SearchSource {
|
|
||||||
protected results = new Map<string, unknown[]>();
|
|
||||||
|
|
||||||
search(query: string) {
|
|
||||||
query = query.toLowerCase();
|
|
||||||
|
|
||||||
this.results.set(query, []);
|
|
||||||
|
|
||||||
const params = {
|
|
||||||
filter: { q: query },
|
|
||||||
page: { limit: 3 },
|
|
||||||
include: 'mostRelevantPost',
|
|
||||||
};
|
|
||||||
|
|
||||||
return app.request(app.forum.attribute('apiUrl') + '/blomstra/search', params).then((results) => this.results.set(query, results));
|
|
||||||
}
|
|
||||||
|
|
||||||
view(query: string): Array<Mithril.Vnode> {
|
|
||||||
query = query.toLowerCase();
|
|
||||||
|
|
||||||
const results = (this.results.get(query) || []).map((discussion: unknown) => {
|
|
||||||
const mostRelevantPost = discussion.mostRelevantPost();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<li className="DiscussionSearchResult" data-index={'discussions' + discussion.id()}>
|
|
||||||
<Link href={app.route.discussion(discussion, mostRelevantPost && mostRelevantPost.number())}>
|
|
||||||
<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>;
|
|
||||||
|
|
||||||
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 })}>
|
|
||||||
{app.translator.trans('core.forum.search.all_discussions_button', { query })}
|
|
||||||
</LinkButton>
|
|
||||||
</li>,
|
|
||||||
...results,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue