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/controllers/search.js.es6
2015-08-21 14:40:12 -04:00

171 lines
4.5 KiB
JavaScript

import searchForTerm from 'discourse/lib/search-for-term';
import DiscourseURL from 'discourse/lib/url';
import computed from 'ember-addons/ember-computed-decorators';
let _dontSearch = false;
export default Em.Controller.extend({
typeFilter: null,
@computed('searchContext')
contextType: {
get(searchContext) {
if (searchContext) {
return Ember.get(searchContext, 'type');
}
},
set(value, searchContext) {
// a bit hacky, consider cleaning this up, need to work through all observers though
const context = $.extend({}, searchContext);
context.type = value;
this.set('searchContext', context);
return this.get('searchContext.type');
}
},
contextChanged: function(){
if (this.get('searchContextEnabled')) {
_dontSearch = true;
this.set('searchContextEnabled', false);
_dontSearch = false;
}
}.observes('searchContext'),
fullSearchUrlRelative: function(){
if (this.get('searchContextEnabled') && this.get('searchContext.type') === 'topic') {
return null;
}
let url = '/search?q=' + encodeURIComponent(this.get('term'));
const searchContext = this.get('searchContext');
if (this.get('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;
}.property('searchContext','term','searchContextEnabled'),
fullSearchUrl: function(){
const url = this.get('fullSearchUrlRelative');
if (url) {
return Discourse.getURL(url);
}
}.property('fullSearchUrlRelative'),
searchContextDescription: function(){
const ctx = this.get('searchContext');
if (ctx) {
switch(Em.get(ctx, 'type')) {
case 'topic':
return I18n.t('search.context.topic');
case 'user':
return I18n.t('search.context.user', {username: Em.get(ctx, 'user.username')});
case 'category':
return I18n.t('search.context.category', {category: Em.get(ctx, 'category.name')});
case 'private_messages':
return I18n.t('search.context.private_messages');
}
}
}.property('searchContext'),
searchContextEnabledChanged: function(){
if (_dontSearch) { return; }
this.newSearchNeeded();
}.observes('searchContextEnabled'),
// If we need to perform another search
newSearchNeeded: function() {
this.set('noResults', false);
const term = (this.get('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);
}.observes('term', 'typeFilter'),
searchTerm(term, typeFilter) {
const self = this;
// for cancelling debounced search
if (this._cancelSearch){
this._cancelSearch = null;
return;
}
if (this._search) {
this._search.abort();
}
const searchContext = this.get('searchContextEnabled') ? this.get('searchContext') : null;
this._search = searchForTerm(term, {
typeFilter,
searchContext,
fullSearchUrl: this.get('fullSearchUrl')
});
this._search.then(function(results) {
self.setProperties({ noResults: !results, content: results });
}).finally(function() {
self.set('loading', false);
self._search = null;
});
},
showCancelFilter: function() {
if (this.get('loading')) return false;
return !Ember.isEmpty(this.get('typeFilter'));
}.property('typeFilter', 'loading'),
termChanged: function() {
this.cancelTypeFilter();
}.observes('term'),
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();
}
},
cancelTypeFilter() {
this.set('typeFilter', null);
}
});