mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-15 18:26:15 +01:00
refactor: use search api for topic search
This commit is contained in:
@@ -531,7 +531,8 @@ app.cacheBuster = null;
|
|||||||
}
|
}
|
||||||
data.posts.forEach(function (p) {
|
data.posts.forEach(function (p) {
|
||||||
const text = $('<div>' + p.content + '</div>').text();
|
const text = $('<div>' + p.content + '</div>').text();
|
||||||
const start = Math.max(0, text.toLowerCase().indexOf(inputEl.val().toLowerCase()) - 40);
|
const query = inputEl.val().toLowerCase().replace(/^in:topic-\d+/, '');
|
||||||
|
const start = Math.max(0, text.toLowerCase().indexOf(query) - 40);
|
||||||
p.snippet = utils.escapeHTML((start > 0 ? '...' : '') +
|
p.snippet = utils.escapeHTML((start > 0 ? '...' : '') +
|
||||||
text.slice(start, start + 80) +
|
text.slice(start, start + 80) +
|
||||||
(text.length - start > 80 ? '...' : ''));
|
(text.length - start > 80 ? '...' : ''));
|
||||||
@@ -598,8 +599,9 @@ app.cacheBuster = null;
|
|||||||
});
|
});
|
||||||
inputEl.on('focus', function () {
|
inputEl.on('focus', function () {
|
||||||
mousedownOnResults = false;
|
mousedownOnResults = false;
|
||||||
oldValue = inputEl.val();
|
const query = inputEl.val();
|
||||||
if (inputEl.val() && quickSearchResults.find('#quick-search-results').children().length) {
|
oldValue = query;
|
||||||
|
if (query && quickSearchResults.find('#quick-search-results').children().length) {
|
||||||
updateCategoryFilterName();
|
updateCategoryFilterName();
|
||||||
if (ajaxified) {
|
if (ajaxified) {
|
||||||
doSearch();
|
doSearch();
|
||||||
@@ -607,7 +609,10 @@ app.cacheBuster = null;
|
|||||||
} else {
|
} else {
|
||||||
quickSearchResults.removeClass('hidden');
|
quickSearchResults.removeClass('hidden');
|
||||||
}
|
}
|
||||||
inputEl[0].setSelectionRange(0, inputEl.val().length);
|
inputEl[0].setSelectionRange(
|
||||||
|
query.startsWith('in:topic') ? query.indexOf(' ') + 1 : 0,
|
||||||
|
query.length
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -95,12 +95,9 @@ define('forum/topic', [
|
|||||||
if (config.topicSearchEnabled) {
|
if (config.topicSearchEnabled) {
|
||||||
require(['mousetrap'], function (mousetrap) {
|
require(['mousetrap'], function (mousetrap) {
|
||||||
mousetrap.bind(['command+f', 'ctrl+f'], function (e) {
|
mousetrap.bind(['command+f', 'ctrl+f'], function (e) {
|
||||||
const match = ajaxify.currentPage.match(/^topic\/([\d]+)/);
|
if (ajaxify.data.template.topic) {
|
||||||
let tid;
|
|
||||||
if (match) {
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
tid = match[1];
|
$('#search-fields input').val('in:topic-' + ajaxify.data.tid + ' ');
|
||||||
$('#search-fields input').val('in:topic-' + tid + ' ');
|
|
||||||
app.prepareSearch();
|
app.prepareSearch();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,20 +7,9 @@ define('search', ['navigator', 'translator', 'storage', 'hooks'], function (nav,
|
|||||||
};
|
};
|
||||||
|
|
||||||
Search.query = function (data, callback) {
|
Search.query = function (data, callback) {
|
||||||
// Detect if a tid was specified
|
|
||||||
const topicSearch = data.term.match(/^in:topic-([\d]+) /);
|
|
||||||
callback = callback || function () {};
|
callback = callback || function () {};
|
||||||
if (!topicSearch) {
|
ajaxify.go('search?' + createQueryString(data));
|
||||||
ajaxify.go('search?' + createQueryString(data));
|
callback();
|
||||||
callback();
|
|
||||||
} else {
|
|
||||||
const cleanedTerm = data.term.replace(topicSearch[0], '');
|
|
||||||
const tid = topicSearch[1];
|
|
||||||
|
|
||||||
if (cleanedTerm.length > 0) {
|
|
||||||
Search.queryTopic(tid, cleanedTerm, callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Search.api = function (data, callback) {
|
Search.api = function (data, callback) {
|
||||||
@@ -139,102 +128,5 @@ define('search', ['navigator', 'translator', 'storage', 'hooks'], function (nav,
|
|||||||
$('.search-result-text').find('img:not(.not-responsive)').addClass('img-responsive');
|
$('.search-result-text').find('img:not(.not-responsive)').addClass('img-responsive');
|
||||||
};
|
};
|
||||||
|
|
||||||
Search.queryTopic = function (tid, term) {
|
|
||||||
socket.emit('topics.search', {
|
|
||||||
tid: tid,
|
|
||||||
term: term,
|
|
||||||
}, function (err, pids) {
|
|
||||||
if (err) {
|
|
||||||
return app.alertError(err.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(pids)) {
|
|
||||||
// Sort pids numerically & store
|
|
||||||
Search.current = {
|
|
||||||
results: pids.sort(function (a, b) {
|
|
||||||
return a - b;
|
|
||||||
}),
|
|
||||||
tid: tid,
|
|
||||||
term: term,
|
|
||||||
};
|
|
||||||
|
|
||||||
Search.checkPagePresence(tid, function () {
|
|
||||||
Search.topicDOM.update(0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Search.checkPagePresence = function (tid, callback) {
|
|
||||||
if (parseInt(ajaxify.data.tid, 10) !== parseInt(tid, 10)) {
|
|
||||||
ajaxify.go('topic/' + tid, callback);
|
|
||||||
} else {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Search.topicDOM = {
|
|
||||||
active: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
Search.topicDOM.prev = function () {
|
|
||||||
Search.topicDOM.update((Search.current.index === 0) ? Search.current.results.length - 1 : Search.current.index - 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
Search.topicDOM.next = function () {
|
|
||||||
Search.topicDOM.update((Search.current.index === Search.current.results.length - 1) ? 0 : Search.current.index + 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
Search.topicDOM.update = function (index) {
|
|
||||||
const topicSearchEl = $('.topic-search');
|
|
||||||
Search.current.index = index;
|
|
||||||
|
|
||||||
Search.topicDOM.start();
|
|
||||||
|
|
||||||
if (Search.current.results.length > 0) {
|
|
||||||
topicSearchEl.find('.count').html((index + 1) + ' / ' + Search.current.results.length);
|
|
||||||
topicSearchEl.find('.prev, .next').removeAttr('disabled');
|
|
||||||
const data = {
|
|
||||||
pid: Search.current.results[index],
|
|
||||||
tid: Search.current.tid,
|
|
||||||
topicPostSort: config.topicPostSort,
|
|
||||||
};
|
|
||||||
socket.emit('posts.getPidIndex', data, function (err, postIndex) {
|
|
||||||
if (err) {
|
|
||||||
return app.alertError(err.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
nav.scrollToIndex(postIndex, true);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
translator.translate('[[search:no-matches]]', function (text) {
|
|
||||||
topicSearchEl.find('.count').html(text);
|
|
||||||
});
|
|
||||||
topicSearchEl.removeClass('hidden').find('.prev, .next').attr('disabled', 'disabled');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Search.topicDOM.start = function () {
|
|
||||||
$('.topic-search').removeClass('hidden');
|
|
||||||
if (!Search.topicDOM.active) {
|
|
||||||
Search.topicDOM.active = true;
|
|
||||||
|
|
||||||
// Bind to esc
|
|
||||||
require(['mousetrap'], function (mousetrap) {
|
|
||||||
mousetrap.bind('esc', Search.topicDOM.end);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Search.topicDOM.end = function () {
|
|
||||||
$('.topic-search').addClass('hidden').find('.prev, .next').attr('disabled', 'disabled');
|
|
||||||
Search.topicDOM.active = false;
|
|
||||||
|
|
||||||
// Unbind esc
|
|
||||||
require(['mousetrap'], function (mousetrap) {
|
|
||||||
mousetrap.unbind('esc', Search.topicDOM.end);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return Search;
|
return Search;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -56,10 +56,19 @@ async function searchInContent(data) {
|
|||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const [pids, tids] = await Promise.all([
|
let pids = [];
|
||||||
doSearch('post', ['posts', 'titlesposts']),
|
let tids = [];
|
||||||
doSearch('topic', ['titles', 'titlesposts']),
|
const inTopic = data.query.match(/^in:topic-([\d]+) /);
|
||||||
]);
|
if (inTopic) {
|
||||||
|
const tid = inTopic[1];
|
||||||
|
const cleanedTerm = data.query.replace(inTopic[0], '');
|
||||||
|
pids = await topics.search(tid, cleanedTerm);
|
||||||
|
} else {
|
||||||
|
[pids, tids] = await Promise.all([
|
||||||
|
doSearch('post', ['posts', 'titlesposts']),
|
||||||
|
doSearch('topic', ['titles', 'titlesposts']),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
if (data.returnIds) {
|
if (data.returnIds) {
|
||||||
return { pids: pids, tids: tids };
|
return { pids: pids, tids: tids };
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ SocketTopics.isFollowed = async function (socket, tid) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
SocketTopics.search = async function (socket, data) {
|
SocketTopics.search = async function (socket, data) {
|
||||||
|
sockets.warnDeprecated(socket, 'GET /api/search');
|
||||||
if (!data) {
|
if (!data) {
|
||||||
throw new Error('[[error:invalid-data]]');
|
throw new Error('[[error:invalid-data]]');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user