feat: add discussion search source

This commit is contained in:
David Wheatley 2021-10-13 20:17:54 +01:00
parent d646c719f3
commit f4dca3d185
No known key found for this signature in database
GPG Key ID: DCC0FCE349280DFF
2 changed files with 77 additions and 55 deletions

View File

@ -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}
</>
);
}
}

View File

@ -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,
];
}
}