* spelling: access Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: additional Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: administrative Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: aggregate Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: assigns Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: attributes Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: autocomplete Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: because Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: between Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: bootstrap Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: calculating Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: captcha Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: character Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: chosen Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: commenter Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: competitor Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: componentize Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: contrast Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: corresponding Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: description Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: destroyed Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: destroys Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: discussion Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: episode Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: escaped Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: evaluates Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: expired Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: explicitly Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: facebook Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: fragment Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: functionality Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: improper Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: incentive Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: interfere Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: latest Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: message Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: minimum Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: moderator Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: mouseover Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: mutual Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: nonexistent Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: notification Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: occasionally Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: occurrence Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: occurs Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: octokit Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: offset Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: omitted Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: opacity Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: organization Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: organizations Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: overridden Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: override Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: overriding Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: prefill Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: previous Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: profile Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: recycling Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: registered Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: repositories Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: rescuing Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: response Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: returns Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: second Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: separator Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: services Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: subscriber Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: subscription Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: success Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: successful Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: successfully Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: suppress Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: test Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: thought Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: uniqueness Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: unknown Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: unproductive Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: unreachable Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: unsuccessful Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: utilities Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: utility Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: valid Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: voluntarily Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: vomited Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: website Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: withholding Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
218 lines
6.5 KiB
JavaScript
218 lines
6.5 KiB
JavaScript
/* global checkUserLoggedIn, showLoginModal, userData, buildArticleHTML, initializeReadingListIcons */
|
|
/* eslint no-undef: "error" */
|
|
|
|
function getQueryParams(qs) {
|
|
qs = qs.split('+').join(' ');
|
|
|
|
const params = {},
|
|
re = /[?&]?([^=]+)=([^&]*)/g;
|
|
let tokens;
|
|
|
|
while ((tokens = re.exec(qs))) {
|
|
params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
|
|
}
|
|
|
|
return params;
|
|
}
|
|
|
|
const params = getQueryParams(document.location.search);
|
|
|
|
function searchMain(substories) {
|
|
const query = filterXSS(params.q);
|
|
const filters = filterXSS(params.filters || 'class_name:Article');
|
|
const sortBy = filterXSS(params.sort_by || '');
|
|
const sortDirection = filterXSS(params.sort_direction || '');
|
|
|
|
substories.innerHTML =
|
|
'<div class="p-9 align-center crayons-card"><br></div>';
|
|
if (document.getElementById('query-wrapper')) {
|
|
search(query, filters, sortBy, sortDirection);
|
|
initializeFilters(query, filters);
|
|
initializeSortingTabs(query);
|
|
}
|
|
}
|
|
|
|
function initializeSortingTabs(query) {
|
|
const sortingTabs = document.querySelectorAll(
|
|
'#sorting-option-tabs .crayons-navigation__item',
|
|
);
|
|
|
|
for (let i = 0; i < sortingTabs.length; i++) {
|
|
const tab = sortingTabs[i];
|
|
|
|
tab.addEventListener('click', (e) => {
|
|
const currentParams = getQueryParams(document.location.search);
|
|
const filters = filterXSS(currentParams.filters);
|
|
|
|
const { sortBy, sortDirection } = e.target.dataset;
|
|
const sortString = buildSortString(sortBy, sortDirection);
|
|
|
|
if (filters) {
|
|
window.history.pushState(
|
|
null,
|
|
null,
|
|
`/search?q=${query}&filters=${filters}${sortString}`,
|
|
);
|
|
search(query, filters, sortBy, sortDirection);
|
|
} else {
|
|
window.history.pushState(null, null, `/search?q=${query}${sortString}`);
|
|
search(query, '', sortBy, sortDirection);
|
|
}
|
|
|
|
for (let j = 0; j < sortingTabs.length; j++) {
|
|
if (sortingTabs[j] !== e.target) {
|
|
sortingTabs[j].classList.remove('crayons-navigation__item--current');
|
|
sortingTabs[j].setAttribute('aria-current', '');
|
|
}
|
|
}
|
|
|
|
e.target.classList.add('crayons-navigation__item--current');
|
|
e.target.setAttribute('aria-current', 'page');
|
|
});
|
|
}
|
|
}
|
|
|
|
function initializeFilters(query, filters) {
|
|
const filterButts = document.getElementsByClassName('query-filter-button');
|
|
for (let i = 0; i < filterButts.length; i++) {
|
|
if (filters === filterButts[i].dataset.filter) {
|
|
filterButts[i].classList.add('crayons-navigation__item--current');
|
|
}
|
|
filterButts[i].onclick = function (e) {
|
|
const currentParams = getQueryParams(document.location.search);
|
|
const sortBy = filterXSS(currentParams.sort_by);
|
|
const sortDirection = filterXSS(currentParams.sort_direction);
|
|
const sortString = buildSortString(sortBy, sortDirection);
|
|
|
|
if (
|
|
e.target.classList.contains('my-posts-query-button') &&
|
|
!checkUserLoggedIn()
|
|
) {
|
|
showLoginModal();
|
|
return;
|
|
}
|
|
const filters = e.target.dataset.filter;
|
|
window.history.pushState(
|
|
null,
|
|
null,
|
|
`/search?q=${query}&filters=${filters}${sortString}`,
|
|
);
|
|
const { className } = e.target;
|
|
for (let i = 0; i < filterButts.length; i++) {
|
|
filterButts[i].classList.remove('crayons-navigation__item--current');
|
|
}
|
|
if (className.indexOf('crayons-navigation__item--current') === -1) {
|
|
e.target.classList.add('crayons-navigation__item--current');
|
|
window.history.replaceState(
|
|
null,
|
|
null,
|
|
`/search?q=${query}&filters=${filters}${sortString}`,
|
|
);
|
|
search(query, filters, sortBy, sortDirection);
|
|
} else {
|
|
window.history.replaceState(
|
|
null,
|
|
null,
|
|
`/search?q=${query}${sortString}`,
|
|
);
|
|
search(query, '', sortBy, sortDirection);
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
function buildSortString(sortBy, sortDirection) {
|
|
return sortBy && sortDirection
|
|
? `&sort_by=${sortBy}&sort_direction=${sortDirection}`
|
|
: '';
|
|
}
|
|
|
|
function search(query, filters, sortBy, sortDirection) {
|
|
const hashtags = query.match(/#\w+/g);
|
|
const searchTerm = query.replace(/#/g, '').trim();
|
|
const searchHash = { per_page: 60, page: 0 };
|
|
|
|
if (sortBy && sortDirection) {
|
|
searchHash.sort_by = sortBy;
|
|
searchHash.sort_direction = sortDirection;
|
|
}
|
|
|
|
if (filters === 'MY_POSTS' && userData()) {
|
|
searchHash.user_id = userData()['id'];
|
|
searchHash.class_name = 'Article';
|
|
}
|
|
|
|
if (hashtags && hashtags.length > 0) {
|
|
for (let i = 0; i < hashtags.length; i++) {
|
|
hashtags[i] = hashtags[i].replace(/#/, '');
|
|
}
|
|
searchHash.tag_names = hashtags;
|
|
}
|
|
|
|
if (filters) {
|
|
filters.split('&').forEach((filter) => {
|
|
const [key, value] = filter.split(':');
|
|
searchHash[key] = value;
|
|
});
|
|
}
|
|
|
|
if (searchTerm) {
|
|
searchHash.search_fields = searchTerm;
|
|
}
|
|
|
|
// Brute force copying code from a utility for quick fix
|
|
const searchParams = new URLSearchParams();
|
|
Object.keys(searchHash).forEach((key) => {
|
|
const value = searchHash[key];
|
|
if (Array.isArray(value)) {
|
|
value.forEach((arrayValue) => {
|
|
searchParams.append(`${key}[]`, arrayValue);
|
|
});
|
|
} else {
|
|
searchParams.append(key, value);
|
|
}
|
|
});
|
|
|
|
fetch(`/search/feed_content?${searchParams.toString()}`, {
|
|
method: 'GET',
|
|
headers: {
|
|
Accept: 'application/json',
|
|
'X-CSRF-Token': window.csrfToken,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
credentials: 'same-origin',
|
|
})
|
|
.then((response) => response.json())
|
|
.then((content) => {
|
|
const resultDivs = [];
|
|
content.result.forEach((story) => {
|
|
resultDivs.push(buildArticleHTML(story));
|
|
});
|
|
document.getElementById('substories').innerHTML = resultDivs.join('');
|
|
initializeReadingListIcons();
|
|
document
|
|
.getElementById('substories')
|
|
.classList.add('search-results-loaded');
|
|
if (content.result.length === 0) {
|
|
document.getElementById('substories').innerHTML =
|
|
'<div class="p-9 align-center crayons-card">No results match that query</div>';
|
|
}
|
|
});
|
|
}
|
|
|
|
const waitingOnSearch = setInterval(() => {
|
|
if (
|
|
typeof search === 'function' &&
|
|
typeof filterXSS === 'function' &&
|
|
typeof buildArticleHTML === 'function'
|
|
) {
|
|
clearInterval(waitingOnSearch);
|
|
const substories = document.getElementById('substories');
|
|
if (
|
|
substories &&
|
|
document.getElementsByClassName('search-results-loaded').length === 0
|
|
) {
|
|
searchMain(substories);
|
|
}
|
|
}
|
|
}, 1);
|