diff --git a/app/javascript/packs/searchParams.js b/app/javascript/packs/searchParams.js
new file mode 100644
index 000000000..ac495f948
--- /dev/null
+++ b/app/javascript/packs/searchParams.js
@@ -0,0 +1,220 @@
+/* global checkUserLoggedIn, showLoginModal, userData, buildArticleHTML, initializeReadingListIcons, initializeAllFollowButts, initializeUserFollowButts */
+/* 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 =
+ '
';
+ 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-tabs__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-tabs__item--current');
+ sortingTabs[j].setAttribute('aria-current', '');
+ }
+ }
+
+ e.target.classList.add('crayons-tabs__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-link--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-link--current');
+ }
+ if (className.indexOf('crayons-link--current') === -1) {
+ e.target.classList.add('crayons-link--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 utlity 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();
+ initializeAllFollowButts();
+ initializeUserFollowButts();
+ document
+ .getElementById('substories')
+ .classList.add('search-results-loaded');
+ if (content.result.length === 0) {
+ document.getElementById('substories').innerHTML =
+ 'No results match that query
';
+ }
+ });
+}
+
+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);
diff --git a/app/views/articles/_search.html.erb b/app/views/articles/_search.html.erb
deleted file mode 100644
index 080282540..000000000
--- a/app/views/articles/_search.html.erb
+++ /dev/null
@@ -1,197 +0,0 @@
-
diff --git a/app/views/articles/search.html.erb b/app/views/articles/search.html.erb
index 770fa4de0..dfa50305e 100644
--- a/app/views/articles/search.html.erb
+++ b/app/views/articles/search.html.erb
@@ -54,6 +54,5 @@
-<%= render "articles/search" %>
-<%= javascript_packs_with_chunks_tag "storiesList", defer: true %>
+<%= javascript_packs_with_chunks_tag "searchParams", "storiesList", defer: true %>