REFACTOR: remove hacky search from discovery
This commit is contained in:
parent
41ceff8430
commit
2876725e1b
|
@ -16,37 +16,15 @@ const controllerOpts = {
|
||||||
expandGloballyPinned: false,
|
expandGloballyPinned: false,
|
||||||
expandAllPinned: false,
|
expandAllPinned: false,
|
||||||
|
|
||||||
isSearch: Em.computed.equal('model.filter', 'search'),
|
|
||||||
|
|
||||||
searchTerm: function(){
|
|
||||||
return this.get('model.params.q');
|
|
||||||
}.property('isSearch,model.params,model'),
|
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|
||||||
changeSort(sortBy) {
|
changeSort(sortBy) {
|
||||||
if (this.get('isSearch')) {
|
|
||||||
let term = this.get('searchTerm');
|
|
||||||
let order;
|
|
||||||
|
|
||||||
if (sortBy === 'activity') { order = 'latest'; }
|
|
||||||
if (sortBy === 'views') { order = 'views'; }
|
|
||||||
|
|
||||||
if (order && term.indexOf("order:" + order) === -1) {
|
|
||||||
term = term.replace(/order:[a-z]+/, '');
|
|
||||||
term = term.trim() + " order:" + order;
|
|
||||||
this.set('model.params.q', term);
|
|
||||||
this.get('model').refreshSort();
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (sortBy === this.get('order')) {
|
if (sortBy === this.get('order')) {
|
||||||
this.toggleProperty('ascending');
|
this.toggleProperty('ascending');
|
||||||
} else {
|
} else {
|
||||||
this.setProperties({ order: sortBy, ascending: false });
|
this.setProperties({ order: sortBy, ascending: false });
|
||||||
}
|
}
|
||||||
this.get('model').refreshSort(sortBy, this.get('ascending'));
|
this.get('model').refreshSort(sortBy, this.get('ascending'));
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Show newly inserted topics
|
// Show newly inserted topics
|
||||||
|
|
|
@ -24,7 +24,7 @@ export default DiscourseController.extend({
|
||||||
this.set('q', this.get('searchTerm'));
|
this.set('q', this.get('searchTerm'));
|
||||||
this.set('model', null);
|
this.set('model', null);
|
||||||
|
|
||||||
Discourse.ajax('/search2', {data: {q: this.get('searchTerm')}}).then(function(results) {
|
Discourse.ajax('/search', {data: {q: this.get('searchTerm')}}).then(function(results) {
|
||||||
self.set('model', translateResults(results) || {});
|
self.set('model', translateResults(results) || {});
|
||||||
self.set('model.q', self.get('q'));
|
self.set('model.q', self.get('q'));
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,18 +9,6 @@ export default DiscourseController.extend({
|
||||||
|
|
||||||
navItems: function() {
|
navItems: function() {
|
||||||
return Discourse.NavItem.buildList(null, {filterMode: this.get('filterMode')});
|
return Discourse.NavItem.buildList(null, {filterMode: this.get('filterMode')});
|
||||||
}.property('filterMode'),
|
}.property('filterMode')
|
||||||
|
|
||||||
isSearch: Em.computed.equal('filterMode', 'search'),
|
|
||||||
|
|
||||||
searchTerm: Em.computed.alias('controllers.discovery/topics.model.params.q'),
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
search: function(){
|
|
||||||
var discovery = this.get('controllers.discovery/topics');
|
|
||||||
var model = discovery.get('model');
|
|
||||||
discovery.set('q', this.get('searchTerm'));
|
|
||||||
model.refreshSort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -100,5 +100,5 @@ export default function() {
|
||||||
|
|
||||||
this.resource('queued-posts', { path: '/queued-posts' });
|
this.resource('queued-posts', { path: '/queued-posts' });
|
||||||
|
|
||||||
this.route('full-page-search', {path: '/search2'});
|
this.route('full-page-search', {path: '/search'});
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ export default Discourse.Route.extend({
|
||||||
},
|
},
|
||||||
model: function(params) {
|
model: function(params) {
|
||||||
return PreloadStore.getAndRemove("search", function() {
|
return PreloadStore.getAndRemove("search", function() {
|
||||||
return Discourse.ajax('/search2', {data: {q: params.q}});
|
return Discourse.ajax('/search', {data: {q: params.q}});
|
||||||
}).then(function(results){
|
}).then(function(results){
|
||||||
var model = translateResults(results) || {};
|
var model = translateResults(results) || {};
|
||||||
model.q = params.q;
|
model.q = params.q;
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
hideCategory=hideCategory
|
hideCategory=hideCategory
|
||||||
topics=topics
|
topics=topics
|
||||||
expandExcerpts=expandExcerpts
|
expandExcerpts=expandExcerpts
|
||||||
searchTerm=searchTerm
|
|
||||||
}}
|
}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class='alert alert-info'>
|
<div class='alert alert-info'>
|
||||||
|
|
|
@ -46,8 +46,6 @@
|
||||||
selected=selected
|
selected=selected
|
||||||
expandGloballyPinned=expandGloballyPinned
|
expandGloballyPinned=expandGloballyPinned
|
||||||
expandAllPinned=expandAllPinned
|
expandAllPinned=expandAllPinned
|
||||||
expandExcerpts=isSearch
|
|
||||||
searchTerm=searchTerm
|
|
||||||
topics=model.topics}}
|
topics=model.topics}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,9 +1,3 @@
|
||||||
{{#if isSearch}}
|
|
||||||
<div class="search row">
|
|
||||||
{{input type="text" value=searchTerm class="input-xxlarge search" action="search"}}
|
|
||||||
<button {{action "search"}} class="btn btn-primary"><i class='fa fa-search'></i></button>
|
|
||||||
</div>
|
|
||||||
{{else}}
|
|
||||||
{{bread-crumbs categories=categories}}
|
{{bread-crumbs categories=categories}}
|
||||||
|
|
||||||
{{navigation-bar navItems=navItems filterMode=filterMode}}
|
{{navigation-bar navItems=navItems filterMode=filterMode}}
|
||||||
|
@ -11,4 +5,3 @@
|
||||||
{{#if canCreateTopic}}
|
{{#if canCreateTopic}}
|
||||||
<button id="create-topic" class='btn btn-default' {{action "createTopic"}}><i class='fa fa-plus'></i>{{i18n 'topic.create'}}</button>
|
<button id="create-topic" class='btn btn-default' {{action "createTopic"}}><i class='fa fa-plus'></i>{{i18n 'topic.create'}}</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
|
||||||
|
|
|
@ -9,7 +9,8 @@ export default Ember.View.extend(ScrollTop, {
|
||||||
if(!_.isEmpty(term)) {
|
if(!_.isEmpty(term)) {
|
||||||
Em.run.next(function(){
|
Em.run.next(function(){
|
||||||
self.$('.blurb').highlight(term.split(/\s+/), {className: 'search-highlight'});
|
self.$('.blurb').highlight(term.split(/\s+/), {className: 'search-highlight'});
|
||||||
self.$('.topic-title').highlight(term.split(/\s+/), {className: 'search-highlight'} );
|
// we can highlight title, but I feel its a bit too much
|
||||||
|
// self.$('.topic-title').highlight(term.split(/\s+/), {className: 'search-highlight'} );
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}.observes('controller.model').on('didInsertElement')
|
}.observes('controller.model').on('didInsertElement')
|
||||||
|
|
|
@ -65,10 +65,6 @@ export default Discourse.View.extend(StringBuffer, {
|
||||||
},
|
},
|
||||||
|
|
||||||
expandPinned: function() {
|
expandPinned: function() {
|
||||||
if (this.get('controller.searchTerm')) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const pinned = this.get('topic.pinned');
|
const pinned = this.get('topic.pinned');
|
||||||
if (!pinned) {
|
if (!pinned) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -134,22 +130,6 @@ export default Discourse.View.extend(StringBuffer, {
|
||||||
this.set('topic.highlight', false);
|
this.set('topic.highlight', false);
|
||||||
this.highlight();
|
this.highlight();
|
||||||
}
|
}
|
||||||
|
|
||||||
var term = this.get('controller.searchTerm');
|
|
||||||
const self = this;
|
|
||||||
if (term) {
|
|
||||||
var terms = term.split(/\s+/);
|
|
||||||
// .main-link a is omitted cause a bit clowny
|
|
||||||
var excerpt = self.$('.topic-excerpt');
|
|
||||||
// some sane wrapping
|
|
||||||
excerpt.text(excerpt.text().replace(/\S{40,}/g, function(match){
|
|
||||||
return match.replace(/(\S)/g, "$1\u200B");
|
|
||||||
}));
|
|
||||||
|
|
||||||
terms.forEach(function(word) {
|
|
||||||
excerpt.highlight(word, {element: 'b', className: 'search-highlight'});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}.on('didInsertElement')
|
}.on('didInsertElement')
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -106,7 +106,6 @@ class Topic < ActiveRecord::Base
|
||||||
has_one :first_post, -> {where post_number: 1}, class_name: Post
|
has_one :first_post, -> {where post_number: 1}, class_name: Post
|
||||||
|
|
||||||
# When we want to temporarily attach some data to a forum topic (usually before serialization)
|
# When we want to temporarily attach some data to a forum topic (usually before serialization)
|
||||||
attr_accessor :search_data
|
|
||||||
attr_accessor :user_data
|
attr_accessor :user_data
|
||||||
|
|
||||||
attr_accessor :posters # TODO: can replace with posters_summary once we remove old list code
|
attr_accessor :posters # TODO: can replace with posters_summary once we remove old list code
|
||||||
|
|
|
@ -11,7 +11,6 @@ class ListableTopicSerializer < BasicTopicSerializer
|
||||||
:bumped_at,
|
:bumped_at,
|
||||||
:unseen,
|
:unseen,
|
||||||
:last_read_post_number,
|
:last_read_post_number,
|
||||||
:linked_post_number,
|
|
||||||
:unread,
|
:unread,
|
||||||
:new_posts,
|
:new_posts,
|
||||||
:pinned,
|
:pinned,
|
||||||
|
@ -79,20 +78,8 @@ class ListableTopicSerializer < BasicTopicSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def excerpt
|
def excerpt
|
||||||
if object.search_data
|
|
||||||
object.search_data[:excerpt]
|
|
||||||
else
|
|
||||||
object.excerpt
|
object.excerpt
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def include_linked_post_number?
|
|
||||||
object.search_data
|
|
||||||
end
|
|
||||||
|
|
||||||
def linked_post_number
|
|
||||||
object.search_data[:post_number]
|
|
||||||
end
|
|
||||||
|
|
||||||
alias :include_last_read_post_number? :has_user_data
|
alias :include_last_read_post_number? :has_user_data
|
||||||
|
|
||||||
|
@ -107,7 +94,7 @@ class ListableTopicSerializer < BasicTopicSerializer
|
||||||
alias :include_new_posts? :has_user_data
|
alias :include_new_posts? :has_user_data
|
||||||
|
|
||||||
def include_excerpt?
|
def include_excerpt?
|
||||||
pinned || object.search_data
|
pinned
|
||||||
end
|
end
|
||||||
|
|
||||||
def pinned
|
def pinned
|
||||||
|
|
|
@ -405,7 +405,7 @@ Discourse::Application.routes.draw do
|
||||||
|
|
||||||
get "top" => "list#top"
|
get "top" => "list#top"
|
||||||
get "search/query" => "search#query"
|
get "search/query" => "search#query"
|
||||||
get "search2" => "search#show"
|
get "search" => "search#show"
|
||||||
|
|
||||||
# Topics resource
|
# Topics resource
|
||||||
get "t/:id" => "topics#show"
|
get "t/:id" => "topics#show"
|
||||||
|
|
|
@ -61,7 +61,7 @@ module Discourse
|
||||||
class CSRF < StandardError; end
|
class CSRF < StandardError; end
|
||||||
|
|
||||||
def self.filters
|
def self.filters
|
||||||
@filters ||= [:latest, :unread, :new, :read, :posted, :bookmarks, :search]
|
@filters ||= [:latest, :unread, :new, :read, :posted, :bookmarks]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.feed_filters
|
def self.feed_filters
|
||||||
|
@ -69,7 +69,7 @@ module Discourse
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.anonymous_filters
|
def self.anonymous_filters
|
||||||
@anonymous_filters ||= [:latest, :top, :categories, :search]
|
@anonymous_filters ||= [:latest, :top, :categories]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.logged_in_filters
|
def self.logged_in_filters
|
||||||
|
|
|
@ -19,7 +19,7 @@ class Search
|
||||||
@term = term
|
@term = term
|
||||||
@search_context = search_context
|
@search_context = search_context
|
||||||
@include_blurbs = include_blurbs
|
@include_blurbs = include_blurbs
|
||||||
@blurb_length = blurb_length
|
@blurb_length = blurb_length || 200
|
||||||
@posts = []
|
@posts = []
|
||||||
@categories = []
|
@categories = []
|
||||||
@users = []
|
@users = []
|
||||||
|
@ -40,7 +40,7 @@ class Search
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def self.blurb_for(cooked, term, blurb_length)
|
def self.blurb_for(cooked, term=nil, blurb_length=200)
|
||||||
cooked = SearchObserver::HtmlScrubber.scrub(cooked).squish
|
cooked = SearchObserver::HtmlScrubber.scrub(cooked).squish
|
||||||
|
|
||||||
blurb = nil
|
blurb = nil
|
||||||
|
|
|
@ -71,53 +71,6 @@ class TopicQuery
|
||||||
create_list(:latest, {}, latest_results)
|
create_list(:latest, {}, latest_results)
|
||||||
end
|
end
|
||||||
|
|
||||||
def list_search
|
|
||||||
|
|
||||||
results = nil
|
|
||||||
if @options[:q].present?
|
|
||||||
search = Search.execute(@options[:q],
|
|
||||||
type_filter: 'topic',
|
|
||||||
guardian: Guardian.new(@user))
|
|
||||||
|
|
||||||
topic_ids = search.posts.map(&:topic_id)
|
|
||||||
|
|
||||||
if topic_ids.present?
|
|
||||||
sql = topic_ids.each_with_index.map do |id, idx|
|
|
||||||
"SELECT #{idx} pos, #{id} id"
|
|
||||||
end.join(" UNION ALL ")
|
|
||||||
|
|
||||||
results = Topic
|
|
||||||
.unscoped
|
|
||||||
.joins("JOIN (#{sql}) X on X.id = topics.id")
|
|
||||||
.order("X.pos")
|
|
||||||
|
|
||||||
posts_map = {}
|
|
||||||
search.posts.each do |p|
|
|
||||||
(posts_map[p.topic_id] ||= []) << p
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
results ||= Topic.where("1=0")
|
|
||||||
|
|
||||||
if @user
|
|
||||||
results = results.joins("LEFT OUTER JOIN topic_users AS tu ON (topics.id = tu.topic_id AND tu.user_id = #{@user.id.to_i})")
|
|
||||||
.references('tu')
|
|
||||||
end
|
|
||||||
|
|
||||||
list = create_list(:search, {unordered: true}, results)
|
|
||||||
|
|
||||||
list.topics.each do |topic|
|
|
||||||
if posts = posts_map[topic.id]
|
|
||||||
if post = posts.shift
|
|
||||||
topic.search_data = {excerpt: search.blurb(post), post_number: post.post_number}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
list
|
|
||||||
end
|
|
||||||
|
|
||||||
def list_read
|
def list_read
|
||||||
create_list(:read, unordered: true) do |topics|
|
create_list(:read, unordered: true) do |topics|
|
||||||
topics.order('COALESCE(tu.last_visited_at, topics.bumped_at) DESC')
|
topics.order('COALESCE(tu.last_visited_at, topics.bumped_at) DESC')
|
||||||
|
|
|
@ -48,28 +48,10 @@ describe TopicQuery do
|
||||||
|
|
||||||
expect(TopicQuery.new(nil).list_topics_by(user).topics.count).to eq(1)
|
expect(TopicQuery.new(nil).list_topics_by(user).topics.count).to eq(1)
|
||||||
expect(TopicQuery.new(user).list_topics_by(user).topics.count).to eq(2)
|
expect(TopicQuery.new(user).list_topics_by(user).topics.count).to eq(2)
|
||||||
|
|
||||||
# search should return nothing normally
|
|
||||||
expect(TopicQuery.new(nil).list_search.topics.count).to eq(0)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'search' do
|
|
||||||
it 'can correctly search' do
|
|
||||||
# got to enable indexing
|
|
||||||
ActiveRecord::Base.observers.enable :all
|
|
||||||
|
|
||||||
p = create_post(raw: "I am super awesome and search will find me")
|
|
||||||
create_post(topic_id: p.topic_id, raw: "I am super spectacular post of doom")
|
|
||||||
|
|
||||||
results = TopicQuery.new(nil, q: "doom").list_search
|
|
||||||
|
|
||||||
expect(results.topics.count).to eq(1)
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'bookmarks' do
|
context 'bookmarks' do
|
||||||
it "filters and returns bookmarks correctly" do
|
it "filters and returns bookmarks correctly" do
|
||||||
post = Fabricate(:post)
|
post = Fabricate(:post)
|
||||||
|
|
Loading…
Reference in New Issue