[deploy] Remove ERB pre-processing from pure JS files and cleanup (#8030)
This commit is contained in:
parent
975ddc61c4
commit
ce28c0b5e5
10 changed files with 899 additions and 608 deletions
84
app/assets/javascripts/initializePage.js
Normal file
84
app/assets/javascripts/initializePage.js
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
global initializeLocalStorageRender, initializeStylesheetAppend, initializeBodyData,
|
||||
initializeAllChatButtons, initializeAllTagEditButtons, initializeUserFollowButts,
|
||||
initializeBaseTracking, initializeTouchDevice, initializeCommentsPage,
|
||||
initializeArticleDate, initializeArticleReactions, initNotifications,
|
||||
initializeCommentDate, initializeCommentDropdown, initializeSettings,
|
||||
initializeFooterMod, initializeCommentPreview, initializeAdditionalContentBoxes,
|
||||
initializeTimeFixer, initializeDashboardSort, initializePWAFunctionality,
|
||||
initializeEllipsisMenu, initializeArchivedPostFilter, initializeCreditsPage,
|
||||
initializeUserProfilePage, initializePodcastPlayback, initializeDrawerSliders,
|
||||
initializeHeroBannerClose, initializeOnboardingTaskCard, initScrolling,
|
||||
nextPage:writable, fetching:writable, done:writable, adClicked:writable,
|
||||
initializeSpecialNavigationFunctionality
|
||||
*/
|
||||
|
||||
function callInitializers() {
|
||||
initializeLocalStorageRender();
|
||||
initializeBodyData();
|
||||
|
||||
var waitingForDataLoad = setInterval(function wait() {
|
||||
if (document.body.getAttribute('data-loaded') === 'true') {
|
||||
clearInterval(waitingForDataLoad);
|
||||
if (document.body.getAttribute('data-user-status') === 'logged-in') {
|
||||
initializeBaseUserData();
|
||||
initializeAllChatButtons();
|
||||
initializeAllTagEditButtons();
|
||||
}
|
||||
initializeAllFollowButts();
|
||||
initializeUserFollowButts();
|
||||
initializeReadingListIcons();
|
||||
initializeSponsorshipVisibility();
|
||||
if (document.getElementById('sidebar-additional')) {
|
||||
document.getElementById('sidebar-additional').classList.add('showing');
|
||||
}
|
||||
}
|
||||
}, 1);
|
||||
|
||||
initializeSpecialNavigationFunctionality();
|
||||
initializeBaseTracking();
|
||||
initializeTouchDevice();
|
||||
initializeCommentsPage();
|
||||
initializeArticleDate();
|
||||
initializeArticleReactions();
|
||||
initNotifications();
|
||||
initializeStylesheetAppend();
|
||||
initializeCommentDate();
|
||||
initializeCommentDropdown();
|
||||
initializeSettings();
|
||||
initializeFooterMod();
|
||||
initializeCommentPreview();
|
||||
initializeAdditionalContentBoxes();
|
||||
initializeTimeFixer();
|
||||
initializeDashboardSort();
|
||||
initializePWAFunctionality();
|
||||
initializeEllipsisMenu();
|
||||
initializeArchivedPostFilter();
|
||||
initializeCreditsPage();
|
||||
initializeUserProfilePage();
|
||||
initializePodcastPlayback();
|
||||
initializeDrawerSliders();
|
||||
initializeHeroBannerClose();
|
||||
initializeOnboardingTaskCard();
|
||||
|
||||
function freezeScrolling(event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
nextPage = 0;
|
||||
fetching = false;
|
||||
done = false;
|
||||
adClicked = false;
|
||||
setTimeout(function undone() {
|
||||
done = false;
|
||||
}, 300);
|
||||
if (!initScrolling.called) {
|
||||
initScrolling();
|
||||
}
|
||||
}
|
||||
|
||||
function initializePage() {
|
||||
initializeLocalStorageRender();
|
||||
initializeStylesheetAppend();
|
||||
callInitializers();
|
||||
}
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
function initializePage(){
|
||||
initializeLocalStorageRender();
|
||||
initializeStylesheetAppend();
|
||||
callInitalizers();
|
||||
}
|
||||
|
||||
function callInitalizers(){
|
||||
initializeLocalStorageRender();
|
||||
initializeBodyData();
|
||||
var waitingForDataLoad = setInterval(function(){
|
||||
if (document.getElementsByTagName('body')[0].getAttribute('data-loaded') == "true") {
|
||||
clearInterval(waitingForDataLoad);
|
||||
if (document.getElementsByTagName('body')[0].getAttribute('data-user-status') == "logged-in") {
|
||||
initializeBaseUserData();
|
||||
initializeAllChatButtons();
|
||||
initializeAllTagEditButtons();
|
||||
}
|
||||
initializeAllFollowButts();
|
||||
initializeUserFollowButts();
|
||||
initializeReadingListIcons();
|
||||
initializeSponsorshipVisibility();
|
||||
if ( document.getElementById("sidebar-additional") ) {
|
||||
document.getElementById("sidebar-additional").classList.add("showing");
|
||||
}
|
||||
}
|
||||
},1)
|
||||
initializeSpecialNavigationFunctionality()
|
||||
initializeBaseTracking();
|
||||
initializeTouchDevice();
|
||||
initializeCommentsPage();
|
||||
initializeArticleDate();
|
||||
initializeArticleReactions();
|
||||
initNotifications();
|
||||
initializeStylesheetAppend();
|
||||
initializeCommentDate();
|
||||
initializeCommentDropdown();
|
||||
initializeSettings();
|
||||
initializeFooterMod();
|
||||
initializeCommentPreview();
|
||||
initializeAdditionalContentBoxes();
|
||||
initializeTimeFixer();
|
||||
initializeDashboardSort();
|
||||
initializePWAFunctionality();
|
||||
initializeEllipsisMenu();
|
||||
initializeArchivedPostFilter();
|
||||
initializeCreditsPage();
|
||||
initializeUserProfilePage();
|
||||
initializePodcastPlayback();
|
||||
initializeDrawerSliders();
|
||||
initializeHeroBannerClose();
|
||||
initializeOnboardingTaskCard();
|
||||
|
||||
function freezeScrolling(event){
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
nextPage = 0;
|
||||
fetching = false;
|
||||
done = false;
|
||||
adClicked = false;
|
||||
setTimeout(function(){
|
||||
done = false;
|
||||
},300);
|
||||
if(!initScrolling.called) {
|
||||
initScrolling();
|
||||
}
|
||||
}
|
||||
451
app/assets/javascripts/initializers/initScrolling.js
Normal file
451
app/assets/javascripts/initializers/initScrolling.js
Normal file
|
|
@ -0,0 +1,451 @@
|
|||
/* global insertAfter, insertArticles, buildArticleHTML, nextPage:writable, fetching:writable, done:writable, InstantClick */
|
||||
|
||||
var client;
|
||||
|
||||
function fetchNext(el, endpoint, insertCallback) {
|
||||
var indexParams = JSON.parse(el.dataset.params);
|
||||
var urlParams = Object.keys(indexParams)
|
||||
.map(function handleMap(k) {
|
||||
return encodeURIComponent(k) + '=' + encodeURIComponent(indexParams[k]);
|
||||
})
|
||||
.join('&');
|
||||
if (urlParams.indexOf('q=') > -1) {
|
||||
return;
|
||||
}
|
||||
var fetchUrl = (
|
||||
endpoint +
|
||||
'?page=' +
|
||||
nextPage +
|
||||
'&' +
|
||||
urlParams +
|
||||
'&signature=' +
|
||||
parseInt(Date.now() / 400000, 10)
|
||||
).replace('&&', '&');
|
||||
window
|
||||
.fetch(fetchUrl)
|
||||
.then(function handleResponse(response) {
|
||||
response.json().then(function insertEntries(entries) {
|
||||
nextPage += 1;
|
||||
insertCallback(entries);
|
||||
if (entries.length === 0) {
|
||||
document.getElementById('loading-articles').style.display = 'none';
|
||||
done = true;
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(function logError(err) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
|
||||
function insertNext(params, buildCallback) {
|
||||
return function insertEntries(entries) {
|
||||
var list = document.getElementById(params.listId || 'sublist');
|
||||
var newFollowersHTML = '';
|
||||
entries.forEach(function insertAnEntry(entry) {
|
||||
let existingEl = document.getElementById(
|
||||
(params.elId || 'element') + '-' + entry.id,
|
||||
);
|
||||
if (!existingEl) {
|
||||
var newHTML = buildCallback(entry);
|
||||
newFollowersHTML += newHTML;
|
||||
}
|
||||
});
|
||||
|
||||
var distanceFromBottom =
|
||||
document.documentElement.scrollHeight - document.body.scrollTop;
|
||||
var newNode = document.createElement('div');
|
||||
newNode.innerHTML = newFollowersHTML;
|
||||
var singleArticles = document.querySelectorAll(
|
||||
'.single-article, .crayons-story',
|
||||
);
|
||||
var lastElement = singleArticles[singleArticles.length - 1];
|
||||
insertAfter(newNode, lastElement);
|
||||
if (nextPage > 0) {
|
||||
fetching = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function buildFollowsHTML(follows) {
|
||||
return (
|
||||
'<div id="follows-' +
|
||||
follows.id +
|
||||
'" class="single-article">\n' +
|
||||
' <a href="' +
|
||||
follows.path +
|
||||
'" class="block-link">\n' +
|
||||
' <h2>\n' +
|
||||
' <img alt="' +
|
||||
follows.username +
|
||||
' profile image" src="' +
|
||||
follows.profile_image +
|
||||
'" />\n' +
|
||||
' ' +
|
||||
follows.name +
|
||||
'\n' +
|
||||
' <span class="dashboard-username">@' +
|
||||
follows.username +
|
||||
'</span>\n' +
|
||||
' </h2>\n' +
|
||||
' </a>\n' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
|
||||
var negativeFollow = -1;
|
||||
function buildTagsHTML(tag) {
|
||||
var tagHTML = '';
|
||||
if (tag.points < 0 && negativeFollow === -1) {
|
||||
tagHTML += '<h2>Negative Tags (anti-follows)</h2>';
|
||||
negativeFollow = 0;
|
||||
}
|
||||
return (
|
||||
tagHTML +
|
||||
'<div id="follows-' +
|
||||
tag.id +
|
||||
'" class="single-article" style="border: 1px solid ' +
|
||||
tag.color +
|
||||
';box-shadow: 3px 3px 0px ' +
|
||||
tag.color +
|
||||
'">\n' +
|
||||
' <h2>\n' +
|
||||
' <a href="/t/' +
|
||||
tag.name +
|
||||
'">\n' +
|
||||
' ' +
|
||||
tag.name +
|
||||
'\n' +
|
||||
' </a>\n' +
|
||||
' <form class="edit_follow" id="edit_follow_' +
|
||||
tag.id +
|
||||
'" action="/follows/' +
|
||||
tag.id +
|
||||
'" accept-charset="UTF-8" method="post">\n' +
|
||||
' <input name="utf8" type="hidden" value="✓">\n' +
|
||||
' <input type="hidden" name="_method" value="patch">\n' +
|
||||
' <input type="hidden" name="authenticity_token" value="' +
|
||||
tag.token +
|
||||
'">\n' +
|
||||
' <label for="follow_points">Follow Weight:</label>\n' +
|
||||
' <input step="any" required="required" type="number" value="' +
|
||||
tag.points +
|
||||
'" name="follow[points]" id="follow_points">\n' +
|
||||
' <input type="submit" name="commit" value="Submit">\n' +
|
||||
' </form>\n' +
|
||||
' </h2>\n' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
|
||||
function fetchNextFollowingPage(el) {
|
||||
var indexParams = JSON.parse(el.dataset.params);
|
||||
var action = indexParams.action;
|
||||
if (action.includes('users')) {
|
||||
fetchNext(
|
||||
el,
|
||||
'/followings/users',
|
||||
insertNext({ elId: 'follows' }, buildFollowsHTML),
|
||||
);
|
||||
} else if (action.includes('podcasts')) {
|
||||
fetchNext(
|
||||
el,
|
||||
'/followings/podcasts',
|
||||
insertNext({ elId: 'follows' }, buildFollowsHTML),
|
||||
);
|
||||
} else if (action.includes('organizations')) {
|
||||
fetchNext(
|
||||
el,
|
||||
'/followings/organizations',
|
||||
insertNext({ elId: 'follows' }, buildFollowsHTML),
|
||||
);
|
||||
} else {
|
||||
fetchNext(
|
||||
el,
|
||||
'/followings/tags',
|
||||
insertNext({ elId: 'follows' }, buildTagsHTML),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function fetchNextFollowersPage(el) {
|
||||
fetchNext(
|
||||
el,
|
||||
'/api/followers/users',
|
||||
insertNext({ elId: 'follows' }, buildFollowsHTML),
|
||||
);
|
||||
}
|
||||
|
||||
function buildVideoArticleHTML(videoArticle) {
|
||||
return (
|
||||
'<a class="single-video-article single-article" href="' +
|
||||
videoArticle.path +
|
||||
'" id="video-article-' +
|
||||
videoArticle.id +
|
||||
'">\n' +
|
||||
' <div class="video-image" style="background-image: url(' +
|
||||
videoArticle.cloudinary_video_url +
|
||||
')">\n' +
|
||||
' <span class="video-timestamp">' +
|
||||
videoArticle.video_duration_in_minutes +
|
||||
'</span>\n' +
|
||||
' </div>\n' +
|
||||
' <p><strong>' +
|
||||
videoArticle.title +
|
||||
'</strong></p>\n' +
|
||||
' <p>' +
|
||||
videoArticle.user.name +
|
||||
'</p>\n' +
|
||||
'</a>'
|
||||
);
|
||||
}
|
||||
|
||||
function insertVideos(videoArticles) {
|
||||
var list = document.getElementById('subvideos');
|
||||
var newVideosHTML = '';
|
||||
videoArticles.forEach(function insertAVideo(videoArticle) {
|
||||
var existingEl = document.getElementById(
|
||||
'video-article-' + videoArticle.id,
|
||||
);
|
||||
if (!existingEl) {
|
||||
var newHTML = buildVideoArticleHTML(videoArticle);
|
||||
newVideosHTML += newHTML;
|
||||
}
|
||||
});
|
||||
|
||||
var distanceFromBottom =
|
||||
document.documentElement.scrollHeight - document.body.scrollTop;
|
||||
var newNode = document.createElement('div');
|
||||
newNode.innerHTML = newVideosHTML;
|
||||
newNode.className += 'video-collection';
|
||||
var singleArticles = document.querySelectorAll(
|
||||
'.single-article, .crayons-story',
|
||||
);
|
||||
var lastElement = singleArticles[singleArticles.length - 1];
|
||||
insertAfter(newNode, lastElement);
|
||||
if (nextPage > 0) {
|
||||
fetching = false;
|
||||
}
|
||||
}
|
||||
|
||||
function fetchNextVideoPage(el) {
|
||||
fetchNext(el, '/api/videos', insertVideos);
|
||||
}
|
||||
|
||||
function insertArticles(articles) {
|
||||
var list = document.getElementById('substories');
|
||||
var newArticlesHTML = '';
|
||||
var el = document.getElementById('home-articles-object');
|
||||
if (el) {
|
||||
el.outerHTML = '';
|
||||
}
|
||||
articles.forEach(function insertAnArticle(article) {
|
||||
var existingEl = document.getElementById('article-link-' + article.id);
|
||||
if (
|
||||
![
|
||||
'/',
|
||||
'/top/week',
|
||||
'/top/month',
|
||||
'/top/year',
|
||||
'/top/infinity',
|
||||
'/latest',
|
||||
].includes(window.location.pathname) &&
|
||||
existingEl &&
|
||||
existingEl.parentElement &&
|
||||
existingEl.parentElement.classList.contains('crayons-story') &&
|
||||
!document.getElementById('video-player-' + article.id)
|
||||
) {
|
||||
existingEl.parentElement.outerHTML = buildArticleHTML(article);
|
||||
} else if (!existingEl) {
|
||||
var newHTML = buildArticleHTML(article);
|
||||
newArticlesHTML += newHTML;
|
||||
initializeReadingListIcons();
|
||||
}
|
||||
});
|
||||
var distanceFromBottom =
|
||||
document.documentElement.scrollHeight - document.body.scrollTop;
|
||||
var newNode = document.createElement('div');
|
||||
newNode.classList.add('paged-stories');
|
||||
newNode.innerHTML = newArticlesHTML;
|
||||
|
||||
newNode.addEventListener('click', (event) => {
|
||||
const { classList } = event.target;
|
||||
|
||||
// This looks a little messy, but it's the only
|
||||
// way to make the entire card clickable.
|
||||
if (
|
||||
classList.contains('crayons-story') ||
|
||||
classList.contains('crayons-story__top') ||
|
||||
classList.contains('crayons-story__body') ||
|
||||
classList.contains('crayons-story__indention') ||
|
||||
classList.contains('crayons-story__title') ||
|
||||
classList.contains('crayons-story__tags') ||
|
||||
classList.contains('crayons-story__bottom')
|
||||
) {
|
||||
let element = event.target;
|
||||
let { articlePath } = element.dataset;
|
||||
|
||||
while (!articlePath) {
|
||||
articlePath = element.dataset.articlePath;
|
||||
element = element.parentElement;
|
||||
}
|
||||
|
||||
InstantClick.preload(articlePath);
|
||||
InstantClick.display(articlePath);
|
||||
}
|
||||
});
|
||||
|
||||
var singleArticles = document.querySelectorAll(
|
||||
'.single-article, .crayons-story',
|
||||
);
|
||||
var lastElement = singleArticles[singleArticles.length - 1];
|
||||
insertAfter(newNode, lastElement);
|
||||
if (nextPage > 0) {
|
||||
fetching = false;
|
||||
}
|
||||
}
|
||||
|
||||
function fetchNextPodcastPage(el) {
|
||||
fetchNext(el, '/api/podcast_episodes', insertArticles);
|
||||
}
|
||||
|
||||
function paginate(tag, params, requiresApproval) {
|
||||
const searchHash = {
|
||||
...{ per_page: 15, page: nextPage },
|
||||
...JSON.parse(params),
|
||||
};
|
||||
|
||||
if (tag && tag.length > 0) {
|
||||
searchHash.tag_names = searchHash.tag_names || [];
|
||||
searchHash.tag_names.push(tag);
|
||||
}
|
||||
searchHash.approved = requiresApproval === 'true' ? 'true' : '';
|
||||
|
||||
var homeEl = document.getElementById('index-container');
|
||||
if (homeEl.dataset.feed === 'base-feed') {
|
||||
searchHash.class_name = 'Article';
|
||||
} else if (homeEl.dataset.feed === 'latest') {
|
||||
searchHash.class_name = 'Article';
|
||||
searchHash.sort_by = 'published_at';
|
||||
} else {
|
||||
searchHash.class_name = 'Article';
|
||||
searchHash['published_at[gte]'] = homeEl.dataset.articlesSince;
|
||||
searchHash.sort_by = 'public_reactions_count';
|
||||
}
|
||||
|
||||
// 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) => {
|
||||
nextPage += 1;
|
||||
insertArticles(content.result);
|
||||
const checkBlockedContentEvent = new CustomEvent('checkBlockedContent');
|
||||
window.dispatchEvent(checkBlockedContentEvent);
|
||||
initializeReadingListIcons();
|
||||
if (content.result.length === 0) {
|
||||
document.getElementById('loading-articles').style.display = 'none';
|
||||
done = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fetchNextPageIfNearBottom() {
|
||||
var indexContainer = document.getElementById('index-container');
|
||||
var elCheck = indexContainer && !document.getElementById('query-wrapper');
|
||||
if (!elCheck) {
|
||||
return;
|
||||
}
|
||||
|
||||
var indexWhich = indexContainer.dataset.which;
|
||||
|
||||
var fetchCallback;
|
||||
var scrollableElemId;
|
||||
if (indexWhich === 'podcast-episodes') {
|
||||
scrollableElemId = 'articles-list';
|
||||
fetchCallback = function fetch() {
|
||||
fetchNextPodcastPage(indexContainer);
|
||||
};
|
||||
} else if (indexWhich === 'videos') {
|
||||
scrollableElemId = 'video-collection';
|
||||
fetchCallback = function fetch() {
|
||||
fetchNextVideoPage(indexContainer);
|
||||
};
|
||||
} else if (indexWhich === 'followers') {
|
||||
scrollableElemId = 'user-dashboard';
|
||||
fetchCallback = function fetch() {
|
||||
fetchNextFollowersPage(indexContainer);
|
||||
};
|
||||
} else if (indexWhich === 'following') {
|
||||
scrollableElemId = 'user-dashboard';
|
||||
fetchCallback = function fetch() {
|
||||
fetchNextFollowingPage(indexContainer);
|
||||
};
|
||||
} else {
|
||||
scrollableElemId = 'articles-list';
|
||||
fetchCallback = function fetch() {
|
||||
paginate(
|
||||
indexContainer.dataset.tag,
|
||||
indexContainer.dataset.params,
|
||||
indexContainer.dataset.requiresApproval,
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
var scrollableElem = document.getElementById(scrollableElemId);
|
||||
|
||||
if (
|
||||
!done &&
|
||||
!fetching &&
|
||||
window.scrollY > scrollableElem.scrollHeight - 3700
|
||||
) {
|
||||
fetching = true;
|
||||
fetchCallback();
|
||||
}
|
||||
}
|
||||
|
||||
function checkIfNearBottomOfPage() {
|
||||
if (
|
||||
(document.getElementsByClassName('crayons-story').length < 2 &&
|
||||
document.getElementsByClassName('single-article').length < 2) ||
|
||||
window.location.search.indexOf('q=') > -1
|
||||
) {
|
||||
document.getElementById('loading-articles').style.display = 'none';
|
||||
done = true;
|
||||
} else {
|
||||
document.getElementById('loading-articles').style.display = 'block';
|
||||
}
|
||||
fetchNextPageIfNearBottom();
|
||||
setInterval(function handleInterval() {
|
||||
fetchNextPageIfNearBottom();
|
||||
}, 210);
|
||||
}
|
||||
|
||||
function initScrolling() {
|
||||
var elCheck = document.getElementById('index-container');
|
||||
|
||||
if (elCheck) {
|
||||
initScrolling.called = true;
|
||||
checkIfNearBottomOfPage();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,339 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
/* global insertAfter, insertArticles, buildArticleHTML, nextPage:writable, fetching:writable, done:writable */
|
||||
|
||||
var client;
|
||||
|
||||
function fetchNext(el, endpoint, insertCallback) {
|
||||
var indexParams = JSON.parse(el.dataset.params);
|
||||
var urlParams = Object.keys(indexParams).map(function handleMap(k) {
|
||||
return encodeURIComponent(k) + "=" + encodeURIComponent(indexParams[k])
|
||||
}).join('&');
|
||||
if (urlParams.indexOf("q=") > -1 ) {
|
||||
return;
|
||||
}
|
||||
var fetchUrl = (endpoint+"?page="+nextPage+"&"+urlParams+"&signature="+parseInt(Date.now()/400000, 10)).replace("&&","&");
|
||||
window.fetch(fetchUrl)
|
||||
.then(function handleResponse(response) {
|
||||
response.json().then(function insertEntries(entries) {
|
||||
nextPage += 1;
|
||||
insertCallback(entries);
|
||||
if (entries.length === 0) {
|
||||
document.getElementById("loading-articles").style.display = "none";
|
||||
done = true;
|
||||
}
|
||||
});
|
||||
}).catch(function logError(err) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
|
||||
function insertNext(params, buildCallback) {
|
||||
return function insertEntries(entries) {
|
||||
var list = document.getElementById(params.listId || "sublist");
|
||||
var newFollowersHTML = "";
|
||||
entries.forEach(function insertAnEntry(entry) {
|
||||
let existingEl = document.getElementById((params.elId || "element") + "-" + entry.id);
|
||||
if(!existingEl) {
|
||||
var newHTML = buildCallback(entry)
|
||||
newFollowersHTML += newHTML
|
||||
}
|
||||
});
|
||||
|
||||
var distanceFromBottom = document.documentElement.scrollHeight - document.body.scrollTop;
|
||||
var newNode = document.createElement("div");
|
||||
newNode.innerHTML = newFollowersHTML;
|
||||
var singleArticles = document.querySelectorAll(".single-article, .crayons-story");
|
||||
var lastElement = singleArticles[singleArticles.length - 1];
|
||||
insertAfter(newNode, lastElement);
|
||||
if (nextPage > 0) {
|
||||
fetching = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function buildFollowsHTML(follows) {
|
||||
return '<div id="follows-' + follows.id + '" class="single-article">\n' +
|
||||
' <a href="' + follows.path +'" class="block-link">\n' +
|
||||
' <h2>\n' +
|
||||
' <img alt="' + follows.username + ' profile image" src="' + follows.profile_image + '" />\n' +
|
||||
' ' + follows.name + '\n' +
|
||||
' <span class="dashboard-username">@' + follows.username + '</span>\n' +
|
||||
' </h2>\n' +
|
||||
' </a>\n' +
|
||||
'</div>';
|
||||
}
|
||||
|
||||
var negativeFollow = -1;
|
||||
function buildTagsHTML(tag) {
|
||||
var tagHTML = '';
|
||||
if (tag.points < 0 && negativeFollow === -1) {
|
||||
tagHTML += '<h2>Negative Tags (anti-follows)</h2>';
|
||||
negativeFollow = 0;
|
||||
}
|
||||
return tagHTML +
|
||||
'<div id="follows-' + tag.id + '" class="single-article" style="border: 1px solid ' + tag.color + ';box-shadow: 3px 3px 0px ' + tag.color + '">\n' +
|
||||
' <h2>\n' +
|
||||
' <a href="/t/' + tag.name + '">\n' +
|
||||
' ' + tag.name + '\n' +
|
||||
' </a>\n' +
|
||||
' <form class="edit_follow" id="edit_follow_' + tag.id + '" action="/follows/' + tag.id + '" accept-charset="UTF-8" method="post">\n' +
|
||||
' <input name="utf8" type="hidden" value="✓">\n' +
|
||||
' <input type="hidden" name="_method" value="patch">\n' +
|
||||
' <input type="hidden" name="authenticity_token" value="' + tag.token + '">\n' +
|
||||
' <label for="follow_points">Follow Weight:</label>\n' +
|
||||
' <input step="any" required="required" type="number" value="' + tag.points + '" name="follow[points]" id="follow_points">\n' +
|
||||
' <input type="submit" name="commit" value="Submit">\n' +
|
||||
' </form>\n' +
|
||||
' </h2>\n' +
|
||||
'</div>';
|
||||
}
|
||||
|
||||
function fetchNextFollowingPage(el) {
|
||||
var indexParams = JSON.parse(el.dataset.params);
|
||||
var action = indexParams.action;
|
||||
if (action.includes("users")) {
|
||||
fetchNext(el, "/followings/users", insertNext({ elId: "follows" }, buildFollowsHTML));
|
||||
} else if (action.includes("podcasts")) {
|
||||
fetchNext(el, "/followings/podcasts", insertNext({ elId: "follows" }, buildFollowsHTML));
|
||||
} else if (action.includes("organizations")) {
|
||||
fetchNext(el, "/followings/organizations", insertNext({ elId: "follows" }, buildFollowsHTML));
|
||||
} else {
|
||||
fetchNext(el, "/followings/tags", insertNext({ elId: "follows" }, buildTagsHTML));
|
||||
}
|
||||
}
|
||||
|
||||
function fetchNextFollowersPage(el) {
|
||||
fetchNext(el, "/api/followers/users", insertNext({ elId: "follows" }, buildFollowsHTML));
|
||||
}
|
||||
|
||||
function buildVideoArticleHTML(videoArticle) {
|
||||
return '<a class="single-video-article single-article" href="' + videoArticle.path + '" id="video-article-' + videoArticle.id + '">\n' +
|
||||
' <div class="video-image" style="background-image: url(' + videoArticle.cloudinary_video_url + ')">\n' +
|
||||
' <span class="video-timestamp">' + videoArticle.video_duration_in_minutes + '</span>\n' +
|
||||
' </div>\n' +
|
||||
' <p><strong>' + videoArticle.title + '</strong></p>\n' +
|
||||
' <p>' + videoArticle.user.name + '</p>\n' +
|
||||
'</a>';
|
||||
}
|
||||
|
||||
function insertVideos(videoArticles) {
|
||||
var list = document.getElementById("subvideos");
|
||||
var newVideosHTML = "";
|
||||
videoArticles.forEach(function insertAVideo(videoArticle) {
|
||||
var existingEl = document.getElementById("video-article-"+videoArticle.id);
|
||||
if(!existingEl) {
|
||||
var newHTML = buildVideoArticleHTML(videoArticle)
|
||||
newVideosHTML += newHTML
|
||||
}
|
||||
});
|
||||
|
||||
var distanceFromBottom = document.documentElement.scrollHeight - document.body.scrollTop;
|
||||
var newNode = document.createElement("div");
|
||||
newNode.innerHTML = newVideosHTML;
|
||||
newNode.className += "video-collection"
|
||||
var singleArticles = document.querySelectorAll(".single-article, .crayons-story");
|
||||
var lastElement = singleArticles[singleArticles.length - 1];
|
||||
insertAfter(newNode, lastElement);
|
||||
if (nextPage > 0) {
|
||||
fetching = false;
|
||||
}
|
||||
}
|
||||
|
||||
function fetchNextVideoPage(el) {
|
||||
fetchNext(el, "/api/videos", insertVideos)
|
||||
}
|
||||
|
||||
function insertArticles(articles) {
|
||||
var list = document.getElementById("substories");
|
||||
var newArticlesHTML = "";
|
||||
var el = document.getElementById("home-articles-object")
|
||||
if (el) {el.outerHTML = "";}
|
||||
articles.forEach(function insertAnArticle(article) {
|
||||
var existingEl = document.getElementById("article-link-"+article.id);
|
||||
if ( !['/', '/top/week', '/top/month', '/top/year', '/top/infinity', '/latest'].includes(window.location.pathname) &&
|
||||
existingEl &&
|
||||
existingEl.parentElement &&
|
||||
existingEl.parentElement.classList.contains('crayons-story') &&
|
||||
!document.getElementById("video-player-"+article.id)) {
|
||||
existingEl.parentElement.outerHTML = buildArticleHTML(article);
|
||||
} else if(!existingEl) {
|
||||
var newHTML = buildArticleHTML(article)
|
||||
newArticlesHTML += newHTML
|
||||
initializeReadingListIcons();
|
||||
}
|
||||
});
|
||||
var distanceFromBottom = document.documentElement.scrollHeight - document.body.scrollTop;
|
||||
var newNode = document.createElement("div");
|
||||
newNode.classList.add('paged-stories');
|
||||
newNode.innerHTML = newArticlesHTML;
|
||||
|
||||
newNode.addEventListener('click', (event) => {
|
||||
const { classList } = event.target;
|
||||
|
||||
// This looks a little messy, but it's the only
|
||||
// way to make the entire card clickable.
|
||||
if (
|
||||
classList.contains('crayons-story') ||
|
||||
classList.contains('crayons-story__top') ||
|
||||
classList.contains('crayons-story__body') ||
|
||||
classList.contains('crayons-story__indention') ||
|
||||
classList.contains('crayons-story__title') ||
|
||||
classList.contains('crayons-story__tags') ||
|
||||
classList.contains('crayons-story__bottom')
|
||||
) {
|
||||
let element = event.target;
|
||||
let { articlePath } = element.dataset;
|
||||
|
||||
while (!articlePath) {
|
||||
articlePath = element.dataset.articlePath;
|
||||
element = element.parentElement;
|
||||
}
|
||||
|
||||
InstantClick.preload(articlePath);
|
||||
InstantClick.display(articlePath);
|
||||
}
|
||||
})
|
||||
|
||||
var singleArticles = document.querySelectorAll(".single-article, .crayons-story");
|
||||
var lastElement = singleArticles[singleArticles.length - 1];
|
||||
insertAfter(newNode, lastElement);
|
||||
if (nextPage > 0) {
|
||||
fetching = false;
|
||||
}
|
||||
}
|
||||
|
||||
function fetchNextPodcastPage(el) {
|
||||
fetchNext(el, "/api/podcast_episodes", insertArticles)
|
||||
}
|
||||
|
||||
function paginate(tag, params, requiresApproval) {
|
||||
const searchHash = { ...{ per_page: 15, page: nextPage }, ...JSON.parse(params) };
|
||||
|
||||
if (tag && tag.length > 0) {
|
||||
searchHash.tag_names = searchHash.tag_names || [];
|
||||
searchHash.tag_names.push(tag);
|
||||
}
|
||||
searchHash.approved = (requiresApproval === 'true') ? 'true' : '';
|
||||
|
||||
var homeEl = document.getElementById("index-container");
|
||||
if (homeEl.dataset.feed === "base-feed") {
|
||||
searchHash.class_name = "Article";
|
||||
} else if (homeEl.dataset.feed === "latest") {
|
||||
searchHash.class_name = "Article";
|
||||
searchHash.sort_by = "published_at";
|
||||
} else {
|
||||
searchHash.class_name = "Article";
|
||||
searchHash["published_at[gte]"] = homeEl.dataset.articlesSince;
|
||||
searchHash.sort_by = "public_reactions_count";
|
||||
}
|
||||
|
||||
// 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) => {
|
||||
nextPage += 1;
|
||||
insertArticles(content.result);
|
||||
const checkBlockedContentEvent = new CustomEvent('checkBlockedContent')
|
||||
window.dispatchEvent(checkBlockedContentEvent);
|
||||
initializeReadingListIcons();
|
||||
if (content.result.length === 0) {
|
||||
document.getElementById("loading-articles").style.display = "none"
|
||||
done = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fetchNextPageIfNearBottom() {
|
||||
var indexContainer = document.getElementById("index-container");
|
||||
var elCheck = indexContainer && !document.getElementById("query-wrapper");
|
||||
if (!elCheck) {
|
||||
return;
|
||||
}
|
||||
|
||||
var indexWhich = indexContainer.dataset.which;
|
||||
|
||||
var fetchCallback;
|
||||
var scrollableElemId;
|
||||
if (indexWhich === "podcast-episodes") {
|
||||
scrollableElemId = "articles-list";
|
||||
fetchCallback = function fetch() {
|
||||
fetchNextPodcastPage(indexContainer);
|
||||
};
|
||||
} else if (indexWhich === "videos") {
|
||||
scrollableElemId = "video-collection";
|
||||
fetchCallback = function fetch() {
|
||||
fetchNextVideoPage(indexContainer);
|
||||
};
|
||||
} else if (indexWhich === "followers") {
|
||||
scrollableElemId = "user-dashboard";
|
||||
fetchCallback = function fetch() {
|
||||
fetchNextFollowersPage(indexContainer);
|
||||
}
|
||||
} else if (indexWhich === "following") {
|
||||
scrollableElemId = "user-dashboard";
|
||||
fetchCallback = function fetch() {
|
||||
fetchNextFollowingPage(indexContainer);
|
||||
}
|
||||
} else {
|
||||
scrollableElemId = "articles-list";
|
||||
fetchCallback = function fetch() {
|
||||
paginate(
|
||||
indexContainer.dataset.tag,
|
||||
indexContainer.dataset.params,
|
||||
indexContainer.dataset.requiresApproval
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
var scrollableElem = document.getElementById(scrollableElemId);
|
||||
|
||||
if ( !done && !fetching && (window.scrollY) > (scrollableElem.scrollHeight - 3700) ) {
|
||||
fetching = true;
|
||||
fetchCallback();
|
||||
}
|
||||
}
|
||||
|
||||
function checkIfNearBottomOfPage() {
|
||||
if ((document.getElementsByClassName("crayons-story").length < 2 && document.getElementsByClassName("single-article").length < 2)
|
||||
|| window.location.search.indexOf("q=") > -1 ) {
|
||||
document.getElementById("loading-articles").style.display = "none";
|
||||
done = true;
|
||||
} else {
|
||||
document.getElementById("loading-articles").style.display = "block";
|
||||
}
|
||||
fetchNextPageIfNearBottom();
|
||||
setInterval(function handleInterval() {
|
||||
fetchNextPageIfNearBottom();
|
||||
}, 210)
|
||||
}
|
||||
|
||||
function initScrolling() {
|
||||
var elCheck = document.getElementById("index-container");
|
||||
|
||||
if (elCheck) {
|
||||
initScrolling.called = true;
|
||||
checkIfNearBottomOfPage();
|
||||
}
|
||||
}
|
||||
|
|
@ -5,16 +5,20 @@
|
|||
*/
|
||||
|
||||
function initializeOnboardingTaskCard() {
|
||||
if (localStorage.getItem('task-card-closed') === 'yes') { return }
|
||||
if (localStorage.getItem('task-card-closed') === 'yes') {
|
||||
return;
|
||||
}
|
||||
|
||||
var taskCard = document.getElementsByClassName("onboarding-task-card")[0];
|
||||
if (taskCard == null) { return } // This guard against both null and undefined taskCard
|
||||
var taskCard = document.getElementsByClassName('onboarding-task-card')[0];
|
||||
if (taskCard == null) {
|
||||
return;
|
||||
} // This guard against both null and undefined taskCard
|
||||
|
||||
var createdAt = new Date(userData().created_at);
|
||||
var now = new Date();
|
||||
var aWeekAgo = now.setDate(now.getDate() - 7);
|
||||
|
||||
if (createdAt > aWeekAgo) {
|
||||
taskCard.style.display = "block";
|
||||
taskCard.style.display = 'block';
|
||||
}
|
||||
}
|
||||
328
app/assets/javascripts/utilities/buildArticleHTML.js
Normal file
328
app/assets/javascripts/utilities/buildArticleHTML.js
Normal file
|
|
@ -0,0 +1,328 @@
|
|||
/* global timeAgo, filterXSS */
|
||||
|
||||
/* eslint-disable no-multi-str */
|
||||
|
||||
function buildArticleHTML(article) {
|
||||
if (article && article.class_name === 'PodcastEpisode') {
|
||||
return (
|
||||
'<div class="single-article single-article-small-pic single-article-single-podcast">\
|
||||
<div class="small-pic">\
|
||||
<a href="/' +
|
||||
article.podcast.slug +
|
||||
'" class="small-pic-link-wrapper">\
|
||||
<img src="' +
|
||||
article.podcast.image_url +
|
||||
'" alt="' +
|
||||
article.podcast.title +
|
||||
' image">\
|
||||
</a>\
|
||||
</div>\
|
||||
<a href="' +
|
||||
article.path +
|
||||
'" class="small-pic-link-wrapper index-article-link" id="article-link-' +
|
||||
article.id +
|
||||
'">\
|
||||
<div class="content">\
|
||||
<h3><span class="tag-identifier">podcast</span>' +
|
||||
article.title +
|
||||
'</h3>\
|
||||
</div>\
|
||||
</a>\
|
||||
<h4><a href="/' +
|
||||
article.podcast.slug +
|
||||
'">' +
|
||||
article.podcast.title +
|
||||
'</a></h4>\
|
||||
</div>'
|
||||
);
|
||||
}
|
||||
|
||||
if (article) {
|
||||
var container = document.getElementById('index-container');
|
||||
var tagString = '';
|
||||
var tagList = article.tag_list || article.cached_tag_list_array;
|
||||
if (tagList) {
|
||||
tagList.forEach(function buildTagString(t) {
|
||||
tagString =
|
||||
tagString +
|
||||
'<a href="/t/' +
|
||||
t +
|
||||
'" class="crayons-tag"><span class="crayons-tag__prefix">#</span>' +
|
||||
t +
|
||||
'</a>\n';
|
||||
});
|
||||
}
|
||||
|
||||
var commentsDisplay = '';
|
||||
var commentsCount = '0';
|
||||
if ((article.comments_count || '0') > 0) {
|
||||
commentsCount = article.comments_count || '0';
|
||||
}
|
||||
if (article.class_name !== 'User') {
|
||||
commentsDisplay =
|
||||
'<a href="' +
|
||||
article.path +
|
||||
'#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left "><svg class="crayons-icon" width="24" height="24" xmlns="http://www.w3.org/2000/svg"><path d="M10.5 5h3a6 6 0 110 12v2.625c-3.75-1.5-9-3.75-9-8.625a6 6 0 016-6zM12 15.5h1.5a4.501 4.501 0 001.722-8.657A4.5 4.5 0 0013.5 6.5h-3A4.5 4.5 0 006 11c0 2.707 1.846 4.475 6 6.36V15.5z"/></svg>' +
|
||||
commentsCount +
|
||||
'<span class="hidden s:inline"> comments</span></a>';
|
||||
}
|
||||
|
||||
var flareTag = '';
|
||||
var currentTag = '';
|
||||
if (container) {
|
||||
currentTag = JSON.parse(container.dataset.params).tag;
|
||||
}
|
||||
if (article.flare_tag && currentTag !== article.flare_tag.name) {
|
||||
flareTag =
|
||||
"<span class='crayons-story__flare-tag' style='background:" +
|
||||
article.flare_tag.bg_color_hex +
|
||||
';color:' +
|
||||
article.flare_tag.text_color_hex +
|
||||
"'>#" +
|
||||
article.flare_tag.name +
|
||||
'</span>';
|
||||
}
|
||||
if (article.class_name === 'PodcastEpisode') {
|
||||
flareTag = "<span class='crayons-story__flare-tag'>podcast</span>";
|
||||
}
|
||||
if (article.class_name === 'Comment') {
|
||||
flareTag = "<span class='crayons-story__flare-tag'>comment</span>";
|
||||
}
|
||||
if (article.class_name === 'User') {
|
||||
flareTag =
|
||||
"<span class='crayons-story__flare-tag' style='background:#5874d9;color:white;'>person</span>";
|
||||
}
|
||||
|
||||
var rc = article.public_reactions_count;
|
||||
var reactionsCount = rc || '0';
|
||||
var reactionsDisplay = '';
|
||||
|
||||
if (article.class_name !== 'User') {
|
||||
reactionsDisplay =
|
||||
'<a href="' +
|
||||
article.path +
|
||||
'" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"><svg class="crayons-icon" width="24" height="24" xmlns="http://www.w3.org/2000/svg"><path d="M18.884 12.595l.01.011L12 19.5l-6.894-6.894.01-.01A4.875 4.875 0 0112 5.73a4.875 4.875 0 016.884 6.865zM6.431 7.037a3.375 3.375 0 000 4.773L12 17.38l5.569-5.569a3.375 3.375 0 10-4.773-4.773L9.613 10.22l-1.06-1.062 2.371-2.372a3.375 3.375 0 00-4.492.25v.001z"/></svg>' +
|
||||
reactionsCount +
|
||||
'<span class="hidden s:inline"> reactions</span></a>';
|
||||
}
|
||||
|
||||
var picUrl;
|
||||
var profileUsername;
|
||||
var userName;
|
||||
if (article.class_name === 'PodcastEpisode') {
|
||||
picUrl = article.main_image;
|
||||
profileUsername = article.slug;
|
||||
userName = article.title;
|
||||
} else {
|
||||
picUrl = article.user.profile_image_90;
|
||||
profileUsername = article.user.username;
|
||||
userName = article.user.name;
|
||||
}
|
||||
var orgHeadline = '';
|
||||
var forOrganization = '';
|
||||
var organizationLogo = '';
|
||||
var organizationClasses = 'crayons-avatar--l';
|
||||
|
||||
if (
|
||||
article.organization &&
|
||||
!document.getElementById('organization-article-index')
|
||||
) {
|
||||
organizationLogo =
|
||||
'<a href="/' +
|
||||
article.organization.slug +
|
||||
'" class="crayons-logo crayons-logo--l"><img alt="' +
|
||||
article.organization.name +
|
||||
' logo" src="' +
|
||||
article.organization.profile_image_90 +
|
||||
'" class="crayons-logo__image" loading="lazy"/></a>';
|
||||
forOrganization =
|
||||
'<span><span class="crayons-story__tertiary fw-normal"> for </span><a href="/' +
|
||||
article.organization.slug +
|
||||
'" class="crayons-story__secondary fw-medium">' +
|
||||
article.organization.name +
|
||||
'</a></span>';
|
||||
organizationClasses =
|
||||
'crayons-avatar--s absolute -right-2 -bottom-2 border-solid border-2 border-base-inverted';
|
||||
}
|
||||
|
||||
var timeAgoInWords = '';
|
||||
if (article.published_at_int) {
|
||||
timeAgoInWords = timeAgo({ oldTimeInSeconds: article.published_at_int });
|
||||
}
|
||||
|
||||
var publishDate = '';
|
||||
if (article.readable_publish_date) {
|
||||
if (article.published_timestamp) {
|
||||
publishDate =
|
||||
'<time datetime="' +
|
||||
article.published_timestamp +
|
||||
'">' +
|
||||
article.readable_publish_date +
|
||||
' ' +
|
||||
timeAgoInWords +
|
||||
'</time>';
|
||||
} else {
|
||||
publishDate =
|
||||
'<time>' +
|
||||
article.readable_publish_date +
|
||||
' ' +
|
||||
timeAgoInWords +
|
||||
'</time>';
|
||||
}
|
||||
}
|
||||
|
||||
var meta =
|
||||
'<div class="crayons-story__meta">\
|
||||
<div class="crayons-story__author-pic">\
|
||||
' +
|
||||
organizationLogo +
|
||||
'\
|
||||
<a href="/' +
|
||||
profileUsername +
|
||||
'" class="crayons-avatar ' +
|
||||
organizationClasses +
|
||||
'">\
|
||||
<img src="' +
|
||||
picUrl +
|
||||
'" alt="' +
|
||||
profileUsername +
|
||||
' profile" class="crayons-avatar__image" loading="lazy" />\
|
||||
</a>\
|
||||
</div>\
|
||||
<div>\
|
||||
<p>\
|
||||
<a href="/' +
|
||||
profileUsername +
|
||||
'" class="crayons-story__secondary fw-medium">' +
|
||||
filterXSS(article.user.name) +
|
||||
'</a>\
|
||||
' +
|
||||
forOrganization +
|
||||
'\
|
||||
</p>\
|
||||
<a href="' +
|
||||
article.path +
|
||||
'" class="crayons-story__tertiary fs-xs">\
|
||||
' +
|
||||
publishDate +
|
||||
'\
|
||||
</a>\
|
||||
</div>\
|
||||
</div>';
|
||||
|
||||
var bodyTextSnippet = '';
|
||||
var searchSnippetHTML = '';
|
||||
if (article.highlight && article.highlight.body_text.length > 0) {
|
||||
var firstSnippetChar = article.highlight.body_text[0];
|
||||
var startingEllipsis = '';
|
||||
if (firstSnippetChar.toLowerCase() !== firstSnippetChar.toUpperCase()) {
|
||||
startingEllipsis = '…';
|
||||
}
|
||||
bodyTextSnippet =
|
||||
startingEllipsis + article.highlight.body_text.join('...') + '…';
|
||||
if (bodyTextSnippet.length > 0) {
|
||||
searchSnippetHTML =
|
||||
'<div class="crayons-story__snippet mb-1">' +
|
||||
bodyTextSnippet +
|
||||
'</div>';
|
||||
}
|
||||
}
|
||||
|
||||
var readingTimeHTML = '';
|
||||
if (article.class_name === 'Article') {
|
||||
// we have ` ... || null` for the case article.reading_time is undefined
|
||||
readingTimeHTML =
|
||||
'<small class="crayons-story__tertiary fs-xs mr-2">' +
|
||||
((article.reading_time || null) < 1
|
||||
? '1 min'
|
||||
: article.reading_time + ' min') +
|
||||
' read</small>';
|
||||
}
|
||||
|
||||
var saveButton = '';
|
||||
if (article.class_name === 'Article') {
|
||||
saveButton =
|
||||
'<button type="button" class="crayons-btn crayons-btn--secondary crayons-btn--s bookmark-button" data-reactable-id="' +
|
||||
article.id +
|
||||
'">\
|
||||
<span class="bm-initial">Save</span>\
|
||||
<span class="bm-success">Saved</span>\
|
||||
</button>';
|
||||
} else if (article.class_name === 'User') {
|
||||
saveButton =
|
||||
'<button type="button" class="crayons-btn crayons-btn--secondary crayons-btn--icon-left fs-s bookmark-button article-engagement-count engage-button follow-action-button follow-user"\
|
||||
data-info=\'{"id":' +
|
||||
article.id +
|
||||
',"className":"User"}\' data-follow-action-button>\
|
||||
\
|
||||
</button>';
|
||||
}
|
||||
|
||||
var videoHTML = '';
|
||||
if (article.cloudinary_video_url) {
|
||||
videoHTML =
|
||||
'<a href="' +
|
||||
article.path +
|
||||
'" class="crayons-story__video" style="background-image:url(' +
|
||||
article.cloudinary_video_url +
|
||||
')"><div class="crayons-story__video__time">' +
|
||||
(article.video_duration_string || article.video_duration_in_minutes) +
|
||||
'</div></a>';
|
||||
}
|
||||
|
||||
return (
|
||||
'<article class="crayons-story" data-article-path="' +
|
||||
article.path +
|
||||
'" data-content-user-id="' +
|
||||
article.user_id +
|
||||
'">\
|
||||
<div role="presentation">\
|
||||
' +
|
||||
videoHTML +
|
||||
'\
|
||||
<div class="crayons-story__body">\
|
||||
<div class="crayons-story__top">\
|
||||
' +
|
||||
meta +
|
||||
'\
|
||||
</div>\
|
||||
<div class="crayons-story__indention">\
|
||||
<h2 class="crayons-story__title"><a href="' +
|
||||
article.path +
|
||||
'" id="article-link-' +
|
||||
article.id +
|
||||
'">' +
|
||||
flareTag +
|
||||
filterXSS(article.title) +
|
||||
'</a></h2>\
|
||||
<div class="crayons-story__tags">' +
|
||||
tagString +
|
||||
'</div>\
|
||||
' +
|
||||
searchSnippetHTML +
|
||||
'\
|
||||
<div class="crayons-story__bottom">\
|
||||
<div class="crayons-story__details">' +
|
||||
reactionsDisplay +
|
||||
commentsDisplay +
|
||||
'</div>\
|
||||
<div class="crayons-story__save">\
|
||||
' +
|
||||
readingTimeHTML +
|
||||
'\
|
||||
' +
|
||||
saveButton +
|
||||
'\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</article>'
|
||||
);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/* eslint-enable no-multi-str */
|
||||
|
|
@ -1,179 +0,0 @@
|
|||
function buildArticleHTML(article) {
|
||||
if (article && article.class_name == "PodcastEpisode") {
|
||||
return '<div class="single-article single-article-small-pic single-article-single-podcast">\
|
||||
<div class="small-pic">\
|
||||
<a href="/'+article.podcast.slug+'" class="small-pic-link-wrapper">\
|
||||
<img src="'+article.podcast.image_url+'" alt="'+article.podcast.title+' image">\
|
||||
</a>\
|
||||
</div>\
|
||||
<a href="'+article.path+'" class="small-pic-link-wrapper index-article-link" id="article-link-'+article.id+'">\
|
||||
<div class="content">\
|
||||
<h3><span class="tag-identifier">podcast</span>'+article.title+'</h3>\
|
||||
</div>\
|
||||
</a>\
|
||||
<h4><a href="/'+article.podcast.slug+'">'+article.podcast.title+'</a></h4>\
|
||||
</div>';
|
||||
}
|
||||
else if (article) {
|
||||
var container = document.getElementById("index-container");
|
||||
var tagString = ""
|
||||
var tagList = article.tag_list || article.cached_tag_list_array
|
||||
if(tagList) {
|
||||
tagList.forEach(function(t){
|
||||
tagString = tagString + '<a href="/t/'+t+'" class="crayons-tag"><span class="crayons-tag__prefix">#</span>'+t+'</a>\n'
|
||||
});
|
||||
}
|
||||
|
||||
var commentsDisplay = ''
|
||||
var commentsCount = '0'
|
||||
|
||||
if ((article.comments_count || '0') > 0) {
|
||||
var commentsCount = (article.comments_count || '0')
|
||||
}
|
||||
if (article.class_name != "User") {
|
||||
var commentsDisplay = '<a href="'+article.path+'#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left "><svg class="crayons-icon" width="24" height="24" xmlns="http://www.w3.org/2000/svg"><path d="M10.5 5h3a6 6 0 110 12v2.625c-3.75-1.5-9-3.75-9-8.625a6 6 0 016-6zM12 15.5h1.5a4.501 4.501 0 001.722-8.657A4.5 4.5 0 0013.5 6.5h-3A4.5 4.5 0 006 11c0 2.707 1.846 4.475 6 6.36V15.5z"/></svg>'+commentsCount+'<span class="hidden s:inline"> comments</span></a>'
|
||||
}
|
||||
|
||||
var flareTag = ""
|
||||
if (container){
|
||||
var currentTag = JSON.parse(container.dataset.params).tag
|
||||
}
|
||||
if (article.flare_tag && currentTag != article.flare_tag.name) {
|
||||
flareTag = "<span class='crayons-story__flare-tag' style='background:"+article.flare_tag.bg_color_hex+";color:"+article.flare_tag.text_color_hex+"'>#"+article.flare_tag.name+"</span>"
|
||||
}
|
||||
if (article.class_name == "PodcastEpisode"){
|
||||
flareTag = "<span class='crayons-story__flare-tag'>podcast</span>"
|
||||
}
|
||||
if (article.class_name == "Comment"){
|
||||
flareTag = "<span class='crayons-story__flare-tag'>comment</span>"
|
||||
}
|
||||
if (article.class_name == "User"){
|
||||
flareTag = "<span class='crayons-story__flare-tag' style='background:#5874d9;color:white;'>person</span>"
|
||||
}
|
||||
|
||||
var rc = article.public_reactions_count
|
||||
var reactionsCount = (rc || '0')
|
||||
var reactionsDisplay = '';
|
||||
|
||||
if (article.class_name != "User") {
|
||||
reactionsDisplay = '<a href="'+article.path+'" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"><svg class="crayons-icon" width="24" height="24" xmlns="http://www.w3.org/2000/svg"><path d="M18.884 12.595l.01.011L12 19.5l-6.894-6.894.01-.01A4.875 4.875 0 0112 5.73a4.875 4.875 0 016.884 6.865zM6.431 7.037a3.375 3.375 0 000 4.773L12 17.38l5.569-5.569a3.375 3.375 0 10-4.773-4.773L9.613 10.22l-1.06-1.062 2.371-2.372a3.375 3.375 0 00-4.492.25v.001z"/></svg>'+reactionsCount+'<span class="hidden s:inline"> reactions</span></a>'
|
||||
}
|
||||
|
||||
var picUrl;
|
||||
var profileUsername;
|
||||
var userName;
|
||||
if (article.class_name == "PodcastEpisode"){
|
||||
picUrl = article.main_image;
|
||||
profileUsername = article.slug;
|
||||
userName = article.title;
|
||||
} else {
|
||||
picUrl = article.user.profile_image_90;
|
||||
profileUsername = article.user.username;
|
||||
userName = article.user.name;
|
||||
}
|
||||
var orgHeadline = "";
|
||||
var forOrganization = "";
|
||||
var organizationLogo = "";
|
||||
var organizationClasses = "crayons-avatar--l";
|
||||
|
||||
|
||||
if (article.organization && !document.getElementById("organization-article-index")) {
|
||||
var organizationLogo = '<a href="/'+article.organization.slug+'" class="crayons-logo crayons-logo--l"><img alt="'+article.organization.name+' logo" src="'+article.organization.profile_image_90+'" class="crayons-logo__image" loading="lazy"/></a>';
|
||||
var forOrganization = '<span><span class="crayons-story__tertiary fw-normal"> for </span><a href="/'+article.organization.slug+'" class="crayons-story__secondary fw-medium">'+article.organization.name+'</a></span>';
|
||||
var organizationClasses = "crayons-avatar--s absolute -right-2 -bottom-2 border-solid border-2 border-base-inverted";
|
||||
}
|
||||
|
||||
var timeAgoInWords = '';
|
||||
if (article.published_at_int) {
|
||||
timeAgoInWords = timeAgo({ oldTimeInSeconds: article.published_at_int });
|
||||
}
|
||||
|
||||
var publishDate = '';
|
||||
if (article.readable_publish_date) {
|
||||
if (article.published_timestamp) {
|
||||
publishDate = '<time datetime="'+article.published_timestamp+'">'+article.readable_publish_date+' '+timeAgoInWords+'</time>';
|
||||
} else {
|
||||
publishDate = '<time>'+article.readable_publish_date+' '+timeAgoInWords+'</time>';
|
||||
}
|
||||
}
|
||||
|
||||
var meta = '<div class="crayons-story__meta">\
|
||||
<div class="crayons-story__author-pic">\
|
||||
'+organizationLogo+'\
|
||||
<a href="/'+profileUsername+'" class="crayons-avatar '+organizationClasses+'">\
|
||||
<img src="'+picUrl+'" alt="'+profileUsername+' profile" class="crayons-avatar__image" loading="lazy" />\
|
||||
</a>\
|
||||
</div>\
|
||||
<div>\
|
||||
<p>\
|
||||
<a href="/'+profileUsername+'" class="crayons-story__secondary fw-medium">'+filterXSS(article.user.name)+'</a>\
|
||||
'+forOrganization+'\
|
||||
</p>\
|
||||
<a href="'+article.path+'" class="crayons-story__tertiary fs-xs">\
|
||||
'+publishDate+'\
|
||||
</a>\
|
||||
</div>\
|
||||
</div>';
|
||||
|
||||
var bodyTextSnippet = "";
|
||||
var searchSnippetHTML = "";
|
||||
if (article.highlight && article.highlight.body_text.length > 0){
|
||||
var firstSnippetChar = article.highlight.body_text[0];
|
||||
var startingEllipsis = ""
|
||||
if (firstSnippetChar.toLowerCase() != firstSnippetChar.toUpperCase()){
|
||||
startingEllipsis = "…"
|
||||
}
|
||||
bodyTextSnippet = startingEllipsis + article.highlight.body_text.join("...") + "…";
|
||||
if (bodyTextSnippet.length > 0){
|
||||
searchSnippetHTML = '<div class="crayons-story__snippet mb-1">' + bodyTextSnippet + '</div>'
|
||||
}
|
||||
}
|
||||
|
||||
var readingTimeHTML = '';
|
||||
if (article.class_name === "Article") {
|
||||
// we have ` ... || null` for the case article.reading_time is undefined
|
||||
readingTimeHTML = '<small class="crayons-story__tertiary fs-xs mr-2">'+ ((article.reading_time || null) < 1 ? '1 min' : article.reading_time + ' min') +' read</small>'
|
||||
}
|
||||
|
||||
var saveButton = '';
|
||||
if (article.class_name === "Article") {
|
||||
saveButton = '<button type="button" class="crayons-btn crayons-btn--secondary crayons-btn--s bookmark-button" data-reactable-id="'+article.id+'">\
|
||||
<span class="bm-initial">Save</span>\
|
||||
<span class="bm-success">Saved</span>\
|
||||
</button>'
|
||||
} else if (article.class_name === "User") {
|
||||
saveButton = '<button type="button" class="crayons-btn crayons-btn--secondary crayons-btn--icon-left fs-s bookmark-button article-engagement-count engage-button follow-action-button follow-user"\
|
||||
data-info=\'{"id":'+article.id+',"className":"User"}\' data-follow-action-button>\
|
||||
\
|
||||
</button>'
|
||||
}
|
||||
|
||||
var videoHTML = '';
|
||||
if (article.cloudinary_video_url) {
|
||||
videoHTML = '<a href="'+article.path+'" class="crayons-story__video" style="background-image:url('+article.cloudinary_video_url+')"><div class="crayons-story__video__time">'+(article.video_duration_string || article.video_duration_in_minutes)+'</div></a>'
|
||||
}
|
||||
|
||||
return '<article class="crayons-story" data-article-path="' + article.path + '" data-content-user-id="'+article.user_id+'">\
|
||||
<div role="presentation">\
|
||||
'+videoHTML+'\
|
||||
<div class="crayons-story__body">\
|
||||
<div class="crayons-story__top">\
|
||||
'+meta+'\
|
||||
</div>\
|
||||
<div class="crayons-story__indention">\
|
||||
<h2 class="crayons-story__title"><a href="'+article.path+'" id="article-link-'+article.id+'">'+flareTag+filterXSS(article.title)+'</a></h2>\
|
||||
<div class="crayons-story__tags">'+tagString+'</div>\
|
||||
'+searchSnippetHTML+'\
|
||||
<div class="crayons-story__bottom">\
|
||||
<div class="crayons-story__details">'+reactionsDisplay+commentsDisplay+'</div>\
|
||||
<div class="crayons-story__save">\
|
||||
'+readingTimeHTML+'\
|
||||
'+saveButton+'\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</article>';
|
||||
}
|
||||
}
|
||||
28
app/assets/javascripts/utilities/getCsrfToken.js
Normal file
28
app/assets/javascripts/utilities/getCsrfToken.js
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/* global Honeybadger */
|
||||
|
||||
function getCsrfToken() {
|
||||
var promise = new Promise(function callback(resolve, reject) {
|
||||
var i = 0;
|
||||
// eslint-disable-next-line consistent-return
|
||||
var waitingOnCSRF = setInterval(function waitOnCSRF() {
|
||||
var metaTag = document.querySelector("meta[name='csrf-token']");
|
||||
i += 1;
|
||||
|
||||
if (metaTag) {
|
||||
clearInterval(waitingOnCSRF);
|
||||
var authToken = metaTag.getAttribute('content');
|
||||
return resolve(authToken);
|
||||
}
|
||||
|
||||
if (i === 1000) {
|
||||
clearInterval(waitingOnCSRF);
|
||||
Honeybadger.notify(
|
||||
'Could not locate CSRF metatag ' +
|
||||
JSON.stringify(localStorage.current_user),
|
||||
);
|
||||
return reject(new Error('Could not locate CSRF meta tag on the page.'));
|
||||
}
|
||||
}, 5);
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
function getCsrfToken() {
|
||||
var promise = new Promise(function (resolve, reject) {
|
||||
var i = 0;
|
||||
var waitingOnCSRF = setInterval(function () {
|
||||
var metaTag = document.querySelector("meta[name='csrf-token']");
|
||||
i++;
|
||||
if (metaTag) {
|
||||
clearInterval(waitingOnCSRF);
|
||||
var authToken = metaTag.getAttribute("content");
|
||||
return resolve(authToken);
|
||||
} else if (i === 1000) {
|
||||
clearInterval(waitingOnCSRF);
|
||||
Honeybadger.notify("Could not locate CSRF metatag " + JSON.stringify(localStorage.current_user));
|
||||
return reject("Could not locate CSRF meta tag on the page.");
|
||||
}
|
||||
}, 5);
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
0
app/views/users/_organizations_area.html.erb
Executable file → Normal file
0
app/views/users/_organizations_area.html.erb
Executable file → Normal file
Loading…
Add table
Reference in a new issue