This repository has been archived on 2023-03-18. You can view files and clone it, but cannot push or open issues or pull requests.
osr-discourse-src/app/assets/javascripts/discourse/components/search-menu.js.es6
Sam e13ed24122 FEATURE: on mobile take users to full page search
UX: improve styling on full page search page
FEATURE: allow search context in full page search
FEATURE: visited color link for full page search
FIX: broken search help on fulls page search page
FEATURE: allow preload store to return a null
FEATURE: "mobileAction" for the header buttons
2015-09-08 11:04:03 +10:00

164 lines
4.5 KiB
JavaScript

import {searchForTerm, searchContextDescription} from 'discourse/lib/search';
import DiscourseURL from 'discourse/lib/url';
import { default as computed, observes } from 'ember-addons/ember-computed-decorators';
import showModal from 'discourse/lib/show-modal';
let _dontSearch = false;
export default Ember.Component.extend({
searchService: Ember.inject.service('search'),
classNames: ['search-menu'],
typeFilter: null,
@observes('searchService.searchContext')
contextChanged: function() {
if (this.get('searchService.searchContextEnabled')) {
_dontSearch = true;
this.set('searchService.searchContextEnabled', false);
_dontSearch = false;
}
},
@computed('searchService.searchContext', 'searchService.term', 'searchService.searchContextEnabled')
fullSearchUrlRelative(searchContext, term, searchContextEnabled) {
if (searchContextEnabled && Ember.get(searchContext, 'type') === 'topic') {
return null;
}
let url = '/search?q=' + encodeURIComponent(this.get('searchService.term'));
if (searchContextEnabled) {
if (searchContext.id.toString().toLowerCase() === this.get('currentUser.username_lower') &&
searchContext.type === "private_messages"
) {
url += ' in:private';
} else {
url += encodeURIComponent(" " + searchContext.type + ":" + searchContext.id);
}
}
return url;
},
@computed('fullSearchUrlRelative')
fullSearchUrl(fullSearchUrlRelative) {
if (fullSearchUrlRelative) {
return Discourse.getURL(fullSearchUrlRelative);
}
},
@computed('searchService.searchContext')
searchContextDescription(ctx) {
return searchContextDescription(Em.get(ctx, 'type'), Em.get(ctx, 'user.username') || Em.get(ctx, 'category.name'));
},
@observes('searchService.searchContextEnabled')
searchContextEnabledChanged() {
if (_dontSearch) { return; }
this.newSearchNeeded();
},
// If we need to perform another search
@observes('searchService.term', 'typeFilter')
newSearchNeeded() {
this.set('noResults', false);
const term = (this.get('searchService.term') || '').trim();
if (term.length >= Discourse.SiteSettings.min_search_term_length) {
this.set('loading', true);
Ember.run.debounce(this, 'searchTerm', term, this.get('typeFilter'), 400);
} else {
this.setProperties({ content: null });
}
this.set('selectedIndex', 0);
},
searchTerm(term, typeFilter) {
// for cancelling debounced search
if (this._cancelSearch){
this._cancelSearch = null;
return;
}
if (this._search) {
this._search.abort();
}
const searchContext = this.get('searchService.searchContextEnabled') ? this.get('searchService.searchContext') : null;
this._search = searchForTerm(term, { typeFilter, searchContext, fullSearchUrl: this.get('fullSearchUrl') });
this._search.then((content) => {
this.setProperties({ noResults: !content, content });
}).finally(() => {
this.set('loading', false);
this._search = null;
});
},
@computed('typeFilter', 'loading')
showCancelFilter(typeFilter, loading) {
if (loading) { return false; }
return !Ember.isEmpty(typeFilter);
},
@observes('searchService.term')
termChanged() {
this.cancelTypeFilter();
},
actions: {
fullSearch() {
const self = this;
if (this._search) {
this._search.abort();
}
// maybe we are debounced and delayed
// stop that as well
this._cancelSearch = true;
Em.run.later(function() {
self._cancelSearch = false;
}, 400);
const url = this.get('fullSearchUrlRelative');
if (url) {
DiscourseURL.routeTo(url);
}
},
moreOfType(type) {
this.set('typeFilter', type);
},
cancelType() {
this.cancelTypeFilter();
},
showedSearch() {
$('#search-term').focus();
},
showSearchHelp() {
// TODO: @EvitTrout how do we get a loading indicator here?
Discourse.ajax("/static/search_help.html", { dataType: 'html' }).then((model) => {
showModal('searchHelp', { model });
});
},
cancelHighlight() {
this.set('searchService.highlightTerm', null);
}
},
cancelTypeFilter() {
this.set('typeFilter', null);
},
keyDown(e) {
const term = this.get('searchService.term');
if (e.which === 13 && term && term.length >= this.siteSettings.min_search_term_length) {
this.set('visible', false);
this.send('fullSearch');
}
}
});