Add Algolia to comments, modify button styles, add comments tab to reading list area (#32)
* Add Algolia to search and add Only My Posts filter * Actually fix Algolia index possible issue * Fix search issue * Make minor adjustments to sponsorship sidebar * Make submission rules headsup html allowed and remove devise trackable * Remove devise_trackable from application_controller * Adjust login CTA for /new * Adjust string in test to reflect changes * Quick fix for internal navigatioon draft caching issue * Add ID to internal/articles * Fix auth with Twitter in two places * Added comments to algolia and modified design * Update sidebar styles and make other small adjustments * Clean up tag styling and other small improvements * Finalize design adjustments * Add indexing condition for comments * Fix Algolia typo * Fix Algolia indexing on comment
This commit is contained in:
parent
a27852cbc3
commit
2771a2e866
47 changed files with 1134 additions and 713 deletions
3
Gemfile
3
Gemfile
|
|
@ -40,6 +40,7 @@ gem "fog", "~> 1.41"
|
|||
gem "front_matter_parser", "~> 0.1"
|
||||
gem "gibbon", "~> 2.2"
|
||||
gem "google-api-client", "~> 0.19"
|
||||
gem "html_truncator", "~>0.2"
|
||||
gem "httparty", "~> 0.16"
|
||||
gem "inline_svg", "~> 0.12"
|
||||
gem "jbuilder", "~> 2.7"
|
||||
|
|
@ -87,6 +88,7 @@ gem "uglifier", "~> 3.2"
|
|||
gem "validate_url", "~> 1.0"
|
||||
gem "webpacker", "~> 3.2"
|
||||
|
||||
|
||||
group :development do
|
||||
gem "brakeman", "~> 3.7", require: false
|
||||
gem "bullet", "~> 5.7"
|
||||
|
|
@ -106,7 +108,6 @@ group :development, :test do
|
|||
gem "faker", "~> 1.8"
|
||||
gem "memory_profiler", "~> 0.9"
|
||||
gem "parallel_tests", "~> 2.21"
|
||||
gem "rack-mini-profiler", "~> 0.10"
|
||||
gem "rspec-rails", "~> 3.7"
|
||||
gem "rspec-retry", "~> 0.5"
|
||||
gem "rubocop", "~> 0.52", require: false
|
||||
|
|
|
|||
|
|
@ -465,6 +465,8 @@ GEM
|
|||
hashdiff (0.3.7)
|
||||
hashie (3.5.7)
|
||||
heapy (0.1.3)
|
||||
html_truncator (0.4.2)
|
||||
nokogiri (~> 1.5)
|
||||
http (3.0.0)
|
||||
addressable (~> 2.3)
|
||||
http-cookie (~> 1.0)
|
||||
|
|
@ -605,8 +607,6 @@ GEM
|
|||
rack (2.0.4)
|
||||
rack-host-redirect (1.3.0)
|
||||
rack
|
||||
rack-mini-profiler (0.10.7)
|
||||
rack (>= 1.2.0)
|
||||
rack-protection (2.0.1)
|
||||
rack
|
||||
rack-proxy (0.6.3)
|
||||
|
|
@ -925,6 +925,7 @@ DEPENDENCIES
|
|||
guard (~> 2.14)
|
||||
guard-livereload (~> 2.5)
|
||||
guard-rspec (~> 4.7)
|
||||
html_truncator (~> 0.2)
|
||||
httparty (~> 0.16)
|
||||
inline_svg (~> 0.12)
|
||||
jbuilder (~> 2.7)
|
||||
|
|
@ -947,7 +948,6 @@ DEPENDENCIES
|
|||
puma_worker_killer (~> 0.1)
|
||||
pundit (~> 1.1)
|
||||
rack-host-redirect (~> 1.3)
|
||||
rack-mini-profiler (~> 0.10)
|
||||
rack-timeout (~> 0.4)
|
||||
rack_session_access (~> 0.1)
|
||||
rails (~> 5.1)
|
||||
|
|
|
|||
1
app/assets/images/comments-bubble.svg
Normal file
1
app/assets/images/comments-bubble.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 7.5 KiB |
1
app/assets/images/reactions-stack.svg
Normal file
1
app/assets/images/reactions-stack.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 22 KiB |
1
app/assets/images/readinglist-button.svg
Normal file
1
app/assets/images/readinglist-button.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 9.1 KiB |
|
|
@ -1,10 +1,14 @@
|
|||
function initializeBaseTracking() {
|
||||
var wait = 0;
|
||||
var addedGA = false;
|
||||
var waitingOnGA = setInterval(function(){
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
if (!addedGA) {
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
}
|
||||
addedGA = true;
|
||||
wait++;
|
||||
if(window.ga && ga.create){
|
||||
ga('create', '<%= ENV["GA_TRACKING_ID"] %>', 'auto');
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ function initializeUserSidebar(user) {
|
|||
renderedTagsCount++
|
||||
tagHTML = tagHTML + '<div class="sidebar-nav-element" id="sidebar-element-'+t.name+'">\
|
||||
<a class="sidebar-nav-link" href="/t/'+t.name+'">\
|
||||
<span class="sidebar-nav-tag-text" style="color:'+t.text_color_hex+';background:'+t.bg_color_hex+';">#'+t.name+'</span>\
|
||||
<span class="sidebar-nav-tag-text">#'+t.name+'</span>\
|
||||
</a>\
|
||||
</div>';
|
||||
if (document.getElementById("default-sidebar-element-"+t.name)){
|
||||
|
|
|
|||
|
|
@ -102,14 +102,14 @@ function initializeCommentsPage() {
|
|||
showModal('reply-to-comment');
|
||||
return;
|
||||
}
|
||||
var actionNode = this.parentNode;
|
||||
var actionNode = event.target.parentNode;
|
||||
var parentId = actionNode.dataset.commentId;
|
||||
document.getElementById("button-for-comment-"+actionNode.dataset.commentId).style.zIndex = "5";
|
||||
var waitingOnCSRF = setInterval(function () {
|
||||
var metaTag = document.querySelector("meta[name='csrf-token']");
|
||||
if (metaTag) {
|
||||
clearInterval(waitingOnCSRF);
|
||||
actionNode.innerHTML = formHTML(commentableId, commentableType, parentId);
|
||||
actionNode.innerHTML = buildCommentFormHTML(commentableId, commentableType, parentId);
|
||||
setTimeout(function () {
|
||||
actionNode.getElementsByTagName('textarea')[0].focus();
|
||||
}, 30);
|
||||
|
|
@ -147,12 +147,6 @@ function toggleCodeOfConduct() {
|
|||
}
|
||||
}
|
||||
|
||||
function cancel(event, el) {
|
||||
event.preventDefault();
|
||||
replaceActionButts(el.parentNode.parentNode.parentNode.parentNode);
|
||||
initializeCommentsPage();
|
||||
}
|
||||
|
||||
function replaceActionButts(el) {
|
||||
var loggedInActionButts = "";
|
||||
var wrapper = el.getElementsByClassName("actions")[0]
|
||||
|
|
@ -172,42 +166,6 @@ function addRelevantButtonsToArticle(responseObj) {
|
|||
}
|
||||
}
|
||||
|
||||
function formHTML(commentableId, commentableType, parentId) {
|
||||
var authToken = document.querySelector("meta[name='csrf-token']").getAttribute('content');
|
||||
var user = userData();
|
||||
var codeOfConductHTML = ""
|
||||
if (user && !user.codeOfConduct && user.commentCount < 1){
|
||||
codeOfConductHTML = '<div class="code-of-conduct sub-comment-code-of-conduct" style="display:block" id="toggle-code-of-conduct-checkbox">\
|
||||
<input class="checkbox" type="checkbox" name="checked_code_of_conduct" required />\
|
||||
<label for="checked_code_of_conduct">I\'ve read the <a href="https://dev.to/code-of-conduct">code of conduct</a></label>\
|
||||
</div>'
|
||||
}
|
||||
var randomIdNumber = Math.floor(Math.random() * 1991)
|
||||
return '<form class="new_comment" onsubmit="handleCommentSubmit.bind(this)(event)" id="new-comment-' + parentId + '" action="/comments" accept-charset="UTF-8" method="post" data-comment-id="'+parentId+'">\
|
||||
<input name="utf8" type="hidden" value="✓" />\
|
||||
<input type="hidden" name="authenticity_token" value="' + authToken + '">\
|
||||
<input value="' + commentableId + '" type="hidden" name="comment[commentable_id]" id="comment_commentable_id" />\
|
||||
<input value="' + commentableType + '" type="hidden" name="comment[commentable_type]" id="comment_commentable_type" />\
|
||||
<input value="' + parentId + '" type="hidden" name="comment[parent_id]" id="comment_parent_id" />\
|
||||
<textarea id="textarea-for-' + parentId + '" class="embiggened" name="comment[body_markdown]" id="comment_body_markdown" required></textarea>\
|
||||
'+codeOfConductHTML+'\
|
||||
<a href="/p/editor_guide" class="markdown-guide" target="_blank" title="Markdown Guide">\
|
||||
<img class="icon-image" src="<%= asset_path('info.svg') %>" />\
|
||||
</a>\
|
||||
<div class="editor-image-upload">\
|
||||
<input type="file" id="image-upload-' + randomIdNumber + '" name="file" accept="image/*" style="display:none">\
|
||||
<button title="Upload Image" class="image-upload-button" id="image-upload-button-' + randomIdNumber + '" onclick="handleImageUpload(event,'+ randomIdNumber + ')">\
|
||||
<img class="icon-image" src="<%= asset_path("image-upload.svg") %>" />\
|
||||
</button>\
|
||||
<label class="image-upload-file-label" id="image-upload-file-label-' + randomIdNumber + '"></label>\
|
||||
<input type="submit" id="image-upload-submit-' + randomIdNumber + '" value="Upload" style="display:none">\
|
||||
<input class="uploaded-image" id="uploaded-image-' + randomIdNumber + '" />\
|
||||
</div>\
|
||||
<a href="#" class="cancel" onclick="cancel(event,this)">CANCEL</a>\
|
||||
<input type="submit" name="commit" value="SUBMIT" />\
|
||||
</form>';
|
||||
}
|
||||
|
||||
function handleCommentSubmit(event) {
|
||||
event.preventDefault();
|
||||
var form = event.target;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,14 @@
|
|||
function initializeReadingListPage(){
|
||||
if ( getCurrentPage("reading_list_items-index") && checkUserLoggedIn() ) {
|
||||
client = algoliasearch('<%= ENV["ALGOLIASEARCH_APPLICATION_ID"] %>', '<%= ENV["ALGOLIASEARCH_SEARCH_ONLY_KEY"] %>');
|
||||
articlesIndex = client.initIndex('ordered_articles_<%= Rails.env %>');
|
||||
commentsIndex = client.initIndex('ordered_comments_<%= Rails.env %>');
|
||||
var params = getQueryParams(document.location.search);
|
||||
var tag = filterXSS(params.t || "");
|
||||
getArticles(tag);
|
||||
document.getElementById('substories').dataset.tabs = '{"v": "'+(params.v || '')+'", "t": "'+(params.t || '')+'" }'
|
||||
postCommentFilter();
|
||||
if (params.v === "comments") {
|
||||
getArticles("***onlytags***");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -11,12 +17,10 @@ function initializeReadingListPage(){
|
|||
function getArticles(tag){
|
||||
var user = userData();
|
||||
var substoriesDiv = document.getElementById("substories");
|
||||
var client = algoliasearch('<%= ENV["ALGOLIASEARCH_APPLICATION_ID"] %>', '<%= ENV["ALGOLIASEARCH_SEARCH_ONLY_KEY"] %>');
|
||||
var index = client.initIndex('ordered_articles_<%= Rails.env %>');
|
||||
var algoliaIndexes = user.reading_list_ids.map(function(id){return "articles-"+id});
|
||||
var algoliaIds = user.reading_list_ids.map(function(id){return "articles-"+id});
|
||||
var resultDivs = []
|
||||
var tags = {}
|
||||
index.getObjects(algoliaIndexes, function(err, content) {
|
||||
articlesIndex.getObjects(algoliaIds, function(err, content) {
|
||||
content.results.forEach(function(story){
|
||||
if (story) {
|
||||
if (tag == "" || story.tag_list.indexOf(tag) > -1){
|
||||
|
|
@ -31,16 +35,44 @@ function getArticles(tag){
|
|||
})
|
||||
}
|
||||
})
|
||||
substoriesDiv.innerHTML = resultDivs.join("");
|
||||
renderTags(tags)
|
||||
if ( resultDivs.length == 0) {
|
||||
var message = "<div style='text-align:left;margin-top:20px;'>This is where to find your bookmarked posts, but it looks like you have not bookmarked anything.</div>"
|
||||
substoriesDiv.innerHTML = message;
|
||||
if (tag != "***onlytags***") {
|
||||
substoriesDiv.innerHTML = resultDivs.join("");
|
||||
if ( resultDivs.length == 0) {
|
||||
var message = "<div style='text-align:left;margin-top:20px;'>This is where to find your bookmarked posts, but it looks like you have not bookmarked anything.</div>"
|
||||
substoriesDiv.innerHTML = message;
|
||||
}
|
||||
}
|
||||
renderTags(tags)
|
||||
initializeReadingListIcons();
|
||||
});
|
||||
}
|
||||
|
||||
function getComments(){
|
||||
var user = userData();
|
||||
var algoliaIds = user.reading_list_ids.map(function(id){return "commentable_Article_"+id});
|
||||
var substories = document.getElementById("substories");
|
||||
var tabsObj = JSON.parse(substories.dataset.tabs);
|
||||
commentsIndex.search("*", {
|
||||
hitsPerPage: 100,
|
||||
attributesToHighlight: [],
|
||||
tagFilters: [algoliaIds,tabsObj["t"]],
|
||||
})
|
||||
.then(function searchDone(content) {
|
||||
var substoriesDiv = document.getElementById("substories");
|
||||
var resultDivs = []
|
||||
content.hits.forEach(function(comment){
|
||||
var aboveDiv = ""
|
||||
aboveDiv = aboveDiv + '<div class="comment-view-parent comment-view-commentable"><a href="'+comment.commentable.path+'">Re: '+comment.commentable.title+'</a></div>'
|
||||
if (comment.parent_path) {
|
||||
aboveDiv = aboveDiv + '<div class="comment-view-parent"><a href="'+comment.root_path+'">VIEW COMMENT TREE</a></div>'
|
||||
}
|
||||
resultDivs.push(aboveDiv+buildCommentHTML(comment));
|
||||
});
|
||||
substoriesDiv.innerHTML = '<div class="comment-trees"><h2>Recent Comment Activity</h2>'+resultDivs.join("<br/>")+'</div>';
|
||||
initializeCommentDropdown();
|
||||
});
|
||||
}
|
||||
|
||||
function renderTags(tags){
|
||||
var sortedTags = [];
|
||||
for (var tag in tags) {
|
||||
|
|
@ -51,7 +83,7 @@ function renderTags(tags){
|
|||
});
|
||||
var tagDivs = []
|
||||
sortedTags.forEach(function(tag){
|
||||
var html = '<button class="query-filter-button" data-tag="'+tag[0]+'">#'+tag[0]+' ('+tag[1]+')</button>'
|
||||
var html = '<button class="query-filter-button query-tag-filter-button" data-tag="'+tag[0]+'">#'+tag[0]+' ('+tag[1]+')</button>'
|
||||
tagDivs.push(html)
|
||||
})
|
||||
document.getElementById("tag-filters").innerHTML = tagDivs.join("");
|
||||
|
|
@ -74,10 +106,9 @@ function getQueryParams(qs) {
|
|||
return params;
|
||||
}
|
||||
|
||||
|
||||
function tagFilters(tag){
|
||||
var filterButts = document.getElementsByClassName("query-filter-button");
|
||||
|
||||
var substories = document.getElementById('substories');
|
||||
var filterButts = document.getElementsByClassName("query-tag-filter-button");
|
||||
for(var i = 0; i < filterButts.length; i++) {
|
||||
filterButts[i].classList.remove("selected");
|
||||
if (tag == filterButts[i].dataset.tag){
|
||||
|
|
@ -86,19 +117,70 @@ function tagFilters(tag){
|
|||
filterButts[i].onclick = function(e){
|
||||
var tag = e.target.dataset.tag;
|
||||
window.scrollTo(0, 0);
|
||||
window.history.replaceState(null, null, "/readinglist?t="+tag);
|
||||
var className = e.target.className;
|
||||
var tabsObj = JSON.parse(substories.dataset.tabs);
|
||||
for(var i = 0; i < filterButts.length; i++) {
|
||||
filterButts[i].classList.remove("selected");
|
||||
}
|
||||
if (className.indexOf("selected") == -1 ) {
|
||||
e.target.classList.add("selected");
|
||||
window.history.replaceState(null, null, "/readinglist?t="+tag);
|
||||
getArticles(tag);
|
||||
assignTab(tabsObj, "t", tag)
|
||||
getStories();
|
||||
} else{
|
||||
window.history.replaceState(null, null, "/readinglist");
|
||||
getArticles("");
|
||||
assignTab(tabsObj, "t", "")
|
||||
getStories();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function postCommentFilter(){
|
||||
var substories = document.getElementById('substories');
|
||||
var tabsObj = JSON.parse(substories.dataset.tabs);
|
||||
getStories()
|
||||
var filterButts = document.getElementsByClassName("query-type-filter-button");
|
||||
for(var i = 0; i < filterButts.length; i++) {
|
||||
filterButts[i].classList.remove("selected");
|
||||
if ((tabsObj["v"] || "posts") === filterButts[i].dataset.type){
|
||||
filterButts[i].classList.add("selected");
|
||||
}
|
||||
filterButts[i].onclick = function(e){
|
||||
for(var i = 0; i < filterButts.length; i++) {
|
||||
filterButts[i].classList.remove("selected");
|
||||
}
|
||||
var tabsObj = JSON.parse(substories.dataset.tabs);
|
||||
assignTab(tabsObj, "v", e.target.dataset.type);
|
||||
e.target.classList.add("selected");
|
||||
getStories()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getStories(){
|
||||
var substories = document.getElementById('substories');
|
||||
var tabsObj = JSON.parse(substories.dataset.tabs);
|
||||
if (tabsObj["v"] == "comments") {
|
||||
getComments(tabsObj["t"] || "");
|
||||
} else {
|
||||
getArticles(tabsObj["t"] || "");
|
||||
}
|
||||
}
|
||||
|
||||
function assignTab(obj, tab, value) {
|
||||
obj[tab] = value
|
||||
substories.dataset.tabs = JSON.stringify(obj);
|
||||
window.history.replaceState(null, null, "/readinglist"+urlParams(obj));
|
||||
return obj
|
||||
}
|
||||
|
||||
function urlParams(obj){
|
||||
if (obj["v"].length > 0 && obj["t"].length > 0) {
|
||||
return "?v="+obj["v"]+"&t="+obj["t"]
|
||||
} else if (obj["v"].length > 0) {
|
||||
return "?v="+obj["v"]
|
||||
} else if (obj["t"].length > 0) {
|
||||
return "?t="+obj["t"]
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
var CACHE_VERSION = 'v2.4.4';
|
||||
var CACHE_VERSION = 'v2.4.5';
|
||||
var CACHE_NAME = CACHE_VERSION + ':sw-cache::';
|
||||
var REQUESTS_LIMIT = 70;
|
||||
|
||||
|
|
@ -11,6 +11,12 @@ function onInstall(event) {
|
|||
'/offline.html',
|
||||
'<%= asset_path "devword.png" %>',
|
||||
'<%= asset_path "wires.png" %>',
|
||||
'<%= asset_path "comments-bubble.svg" %>',
|
||||
'<%= asset_path "reactions-stack.svg" %>',
|
||||
'<%= asset_path "readinglist-button.svg" %>',
|
||||
'<%= asset_path "emoji/emoji-one-heart.png" %>',
|
||||
'<%= asset_path "emoji/emoji-one-unicorn.png" %>',
|
||||
'<%= asset_path "emoji/emoji-one-bookmark.png" %>',
|
||||
]).then(function () {
|
||||
console.log("WORKER: Install completed");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ function buildArticleHTML(article) {
|
|||
}
|
||||
var commentsCountHTML = ""
|
||||
if ((article.comments_count || '0') > 0 && article.class_name != "User") {
|
||||
commentsCountHTML = '<div class="article-engagement-count comments-count"><a href="'+article.path+'"><img src="<%= asset_path("chat.svg") %>" alt="chat" /><span class="engagement-count-number">'+(article.comments_count || '0')+'</span></a></div>'
|
||||
commentsCountHTML = '<div class="article-engagement-count comments-count"><a href="'+article.path+'"><img src="<%= asset_path("comments-bubble.svg") %>" alt="chat" /><span class="engagement-count-number">'+(article.comments_count || '0')+'</span></a></div>'
|
||||
}
|
||||
var flareTag = ""
|
||||
if (container){
|
||||
|
|
@ -42,7 +42,7 @@ function buildArticleHTML(article) {
|
|||
var rc = article.positive_reactions_count || article.reactions_count
|
||||
var reactionsCountHTML = ''
|
||||
if ((rc || '0') > 0 && article.class_name != "User") {
|
||||
var reactionsCountHTML = '<div class="article-engagement-count reactions-count"><a href="'+article.path+'"><img src="<%= asset_path("favorite-heart-outline-button.svg") %>" alt="heart" /><span id="engagement-count-number-'+article.id+'" class="engagement-count-number">'+(rc || '0')+'</span></a></div>'
|
||||
var reactionsCountHTML = '<div class="article-engagement-count reactions-count"><a href="'+article.path+'"><img src="<%= asset_path("reactions-stack.svg") %>" alt="heart" /><span id="engagement-count-number-'+article.id+'" class="engagement-count-number">'+(rc || '0')+'</span></a></div>'
|
||||
}
|
||||
if ( article.organization && article.tag_list.indexOf("hiring") > -1 && !document.getElementById("organization-index-page") ){
|
||||
var picUrl = article.organization.profile_image_90
|
||||
|
|
@ -96,8 +96,8 @@ function buildArticleHTML(article) {
|
|||
<div class="tags">'+tagString+'</div>\
|
||||
'+commentsCountHTML+reactionsCountHTML+'\
|
||||
<button class="article-engagement-count bookmark-engage" data-reactable-id="'+article.id+'">\
|
||||
<img src="<%= asset_path("bookmark.svg") %>" alt="bookmark" class="bm-initial" />\
|
||||
<img src="<%= asset_path("emoji/emoji-one-bookmark.png") %>" alt="bookmark" class="bm-success" />\
|
||||
<span class="bm-success"><img src="<%= asset_path("readinglist-button.svg") %>" alt="bookmark" /> SAVED</span>\
|
||||
<span class="bm-initial">SAVE</span>\
|
||||
</button></div>';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
41
app/assets/javascripts/utilities/buildCommentFormHTML.js.erb
Normal file
41
app/assets/javascripts/utilities/buildCommentFormHTML.js.erb
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
function buildCommentFormHTML(commentableId, commentableType, parentId) {
|
||||
var authToken = document.querySelector("meta[name='csrf-token']").getAttribute('content');
|
||||
var user = userData();
|
||||
var codeOfConductHTML = ""
|
||||
if (user && !user.codeOfConduct && user.commentCount < 1){
|
||||
codeOfConductHTML = '<div class="code-of-conduct sub-comment-code-of-conduct" style="display:block" id="toggle-code-of-conduct-checkbox">\
|
||||
<input class="checkbox" type="checkbox" name="checked_code_of_conduct" required />\
|
||||
<label for="checked_code_of_conduct">I\'ve read the <a href="https://dev.to/code-of-conduct">code of conduct</a></label>\
|
||||
</div>'
|
||||
}
|
||||
var randomIdNumber = Math.floor(Math.random() * 1991)
|
||||
return '<form class="new_comment" onsubmit="handleCommentSubmit.bind(this)(event)" id="new-comment-' + parentId + '" action="/comments" accept-charset="UTF-8" method="post" data-comment-id="'+parentId+'">\
|
||||
<input name="utf8" type="hidden" value="✓" />\
|
||||
<input type="hidden" name="authenticity_token" value="' + authToken + '">\
|
||||
<input value="' + commentableId + '" type="hidden" name="comment[commentable_id]" id="comment_commentable_id" />\
|
||||
<input value="' + commentableType + '" type="hidden" name="comment[commentable_type]" id="comment_commentable_type" />\
|
||||
<input value="' + parentId + '" type="hidden" name="comment[parent_id]" id="comment_parent_id" />\
|
||||
<textarea id="textarea-for-' + parentId + '" class="embiggened" name="comment[body_markdown]" id="comment_body_markdown" required></textarea>\
|
||||
'+codeOfConductHTML+'\
|
||||
<a href="/p/editor_guide" class="markdown-guide" target="_blank" title="Markdown Guide">\
|
||||
<img class="icon-image" src="<%= asset_path('info.svg') %>" />\
|
||||
</a>\
|
||||
<div class="editor-image-upload">\
|
||||
<input type="file" id="image-upload-' + randomIdNumber + '" name="file" accept="image/*" style="display:none">\
|
||||
<button title="Upload Image" class="image-upload-button" id="image-upload-button-' + randomIdNumber + '" onclick="handleImageUpload(event,'+ randomIdNumber + ')">\
|
||||
<img class="icon-image" src="<%= asset_path("image-upload.svg") %>" />\
|
||||
</button>\
|
||||
<label class="image-upload-file-label" id="image-upload-file-label-' + randomIdNumber + '"></label>\
|
||||
<input type="submit" id="image-upload-submit-' + randomIdNumber + '" value="Upload" style="display:none">\
|
||||
<input class="uploaded-image" id="uploaded-image-' + randomIdNumber + '" />\
|
||||
</div>\
|
||||
<a href="#" class="cancel" onclick="cancel(event,this)">CANCEL</a>\
|
||||
<input type="submit" name="commit" value="SUBMIT" />\
|
||||
</form>';
|
||||
}
|
||||
|
||||
function cancel(event, el) {
|
||||
event.preventDefault();
|
||||
replaceActionButts(el.parentNode.parentNode.parentNode.parentNode);
|
||||
initializeCommentsPage();
|
||||
}
|
||||
|
|
@ -2,10 +2,12 @@ function buildCommentHTML(comment) {
|
|||
var depthClass = ""
|
||||
var githubIcon = ""
|
||||
var twitterIcon = ""
|
||||
if (comment.depth == 0 ){
|
||||
var customClass = ""
|
||||
if (!comment.newly_created) {
|
||||
depthClass="child flat-node"
|
||||
} else if (comment.depth == 0 ){
|
||||
depthClass = "root";
|
||||
}
|
||||
else if (comment.depth < 3) {
|
||||
} else if (comment.depth < 3) {
|
||||
depthClass="child"
|
||||
} else {
|
||||
depthClass="child flat-node"
|
||||
|
|
@ -16,12 +18,15 @@ function buildCommentHTML(comment) {
|
|||
if (comment.user.github_username && comment.user.github_username.length > 0) {
|
||||
githubIcon = '<a href="http://github.com/'+comment.user.github_username+'"><%= image_tag("github-logo.svg", class:"icon-img") %></a>'
|
||||
}
|
||||
if (comment.newly_created) {
|
||||
customClass = "comment-created-via-fetch"
|
||||
}
|
||||
|
||||
return '<style>'+comment.css+'</style>\
|
||||
<div class="comment-hash-marker" id="'+comment.id_code+'"></div>\
|
||||
<div id="comment-node-'+comment.id+'" class="single-comment-node '+depthClass+' comment-deep-'+comment.depth+'" "\
|
||||
data-comment-id="'+comment.id+'" data-comment-author-id="'+comment.user.id+'" data-current-user-comment="true">\
|
||||
<div class="inner-comment comment-created-via-fetch">\
|
||||
data-comment-id="'+comment.id+'" data-comment-author-id="'+comment.user.id+'" data-current-user-comment="'+comment.newly_created+'">\
|
||||
<div class="inner-comment '+customClass+'">\
|
||||
<div class="details">\
|
||||
<a href="/'+comment.user.username+'">\
|
||||
<img class="profile-pic" src="'+comment.user.profile_pic+'">\
|
||||
|
|
@ -46,18 +51,44 @@ function buildCommentHTML(comment) {
|
|||
</div>\
|
||||
<div class="body">\
|
||||
'+comment.body_html+'\
|
||||
<button class="reaction-button reacted" id="button-for-comment-'+comment.id+'" data-comment-id="'+comment.id+'">\
|
||||
<img src="<%= asset_path("emoji/emoji-one-heart.png") %>" alt="Favorite heart outline button">\
|
||||
<img class="voted-heart" src="<%= asset_path("emoji/emoji-one-heart.png") %>">\
|
||||
<span class="reactions-count" id="reactions-count-'+comment.id+'">1</span></button>\
|
||||
'+reactions(comment)+'\
|
||||
</div>\
|
||||
<div class="actions" data-comment-id="'+comment.id+'" data-path="'+comment.url+'">\
|
||||
<span class="current-user-actions" style="display: inline-block;">\
|
||||
'+actions(comment)+'\
|
||||
</div>\
|
||||
</div>'
|
||||
}
|
||||
|
||||
function actions(comment) {
|
||||
if (comment.newly_created) {
|
||||
return '<div class="actions" data-comment-id="'+comment.id+'" data-path="'+comment.url+'">\
|
||||
<span class="current-user-actions" style="display: '+ (comment.newly_created ? 'inline-block' : 'none') +';">\
|
||||
<a data-no-instant="" href="'+comment.url+'/delete_confirm" class="edit-butt" rel="nofollow">DELETE</a>\
|
||||
<a href="'+comment.url+'/edit" class="edit-butt" rel="nofollow">EDIT</a>\
|
||||
</span>\
|
||||
<a href="#" class="toggle-reply-form" rel="nofollow">REPLY</a>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>'
|
||||
</div>';
|
||||
} else {
|
||||
return '<div class="actions" data-comment-id="'+comment.id+'" data-path="'+comment.url+'" data-commentable-id="'+comment.commentable.id+'">\
|
||||
<a href="'+comment.url+'" class="toggle-reply-form" rel="nofollow">VIEW/REPLY</a>\
|
||||
</div>';
|
||||
}
|
||||
}
|
||||
|
||||
function reactions(comment) {
|
||||
if (comment.newly_created) {
|
||||
return '<button class="reaction-button reacted" id="button-for-comment-'+comment.id+'" data-comment-id="'+comment.id+'">\
|
||||
<img src="<%= asset_path("favorite-heart-outline-button.svg") %>" alt="Favorite heart outline button">\
|
||||
<img class="voted-heart" src="<%= asset_path("emoji/emoji-one-heart.png") %>">\
|
||||
<span class="reactions-count" id="reactions-count-'+comment.id+'">1</span></button>';
|
||||
} else {
|
||||
if (comment.heart_ids.indexOf(userData().id) > -1) {
|
||||
var reactedClass = "reacted";
|
||||
} else {
|
||||
var reactedClass = ""
|
||||
}
|
||||
return '<button style="background:white" class="reaction-button '+ reactedClass +'" id="button-for-comment-'+comment.id+'" data-comment-id="'+comment.id+'">\
|
||||
<img src="<%= asset_path("favorite-heart-outline-button.svg") %>" alt="Favorite heart outline button">\
|
||||
<img class="voted-heart" src="<%= asset_path("emoji/emoji-one-heart.png") %>">\
|
||||
<span class="reactions-count" id="reactions-count-'+comment.id+'">'+comment.positive_reactions_count+'</span></button>';
|
||||
}
|
||||
}
|
||||
|
|
@ -180,7 +180,7 @@
|
|||
float:left;
|
||||
width:calc(100% - 75px);
|
||||
padding:calc(1vw + 7px) 9px;
|
||||
padding-bottom:94px;
|
||||
padding-bottom:110px;
|
||||
h3{
|
||||
margin:0px;
|
||||
font-size:21px;
|
||||
|
|
@ -206,7 +206,7 @@
|
|||
@media screen and ( min-width: 430px ){
|
||||
width:calc(100% - 88px);
|
||||
padding-right:0px;
|
||||
padding-bottom:104px;
|
||||
padding-bottom:124px;
|
||||
h3{
|
||||
margin:0px;
|
||||
font-size:27px;
|
||||
|
|
@ -236,12 +236,12 @@
|
|||
display:inline-block;
|
||||
left:62px;
|
||||
position:absolute;
|
||||
bottom:65px;
|
||||
bottom:80px;
|
||||
a{
|
||||
color: #666666;
|
||||
}
|
||||
@media screen and ( min-width: 430px ){
|
||||
bottom:74px;
|
||||
bottom:90px;
|
||||
left:72px;
|
||||
font-size:17px;
|
||||
}
|
||||
|
|
@ -262,7 +262,7 @@
|
|||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
bottom:48px;
|
||||
bottom:63px;
|
||||
color: $black;
|
||||
a{
|
||||
display:inline-block;
|
||||
|
|
@ -275,7 +275,7 @@
|
|||
}
|
||||
@media screen and ( min-width: 430px ){
|
||||
left:72px;
|
||||
bottom:58px;
|
||||
bottom:72px;
|
||||
font-size:16px;
|
||||
}
|
||||
|
||||
|
|
@ -334,7 +334,7 @@
|
|||
z-index:5;
|
||||
border-top:1px solid darken($lightest-gray,4%);
|
||||
border-bottom:1px solid darken($lightest-gray,4%);
|
||||
padding-bottom:90px;
|
||||
padding-bottom:105px;
|
||||
border-radius:3px;
|
||||
h3{
|
||||
font-size:calc(1.7vw + 22px);
|
||||
|
|
@ -352,7 +352,7 @@
|
|||
display:inline-block;
|
||||
}
|
||||
@media screen and ( min-width: 430px ){
|
||||
padding-bottom:106px;
|
||||
padding-bottom:120px;
|
||||
}
|
||||
}
|
||||
&:hover{
|
||||
|
|
@ -364,12 +364,12 @@
|
|||
}
|
||||
.featured-profile-button{
|
||||
float:left;
|
||||
margin-top:-88px;
|
||||
margin-top:-104px;
|
||||
z-index:10;
|
||||
left:12px;
|
||||
position:absolute;
|
||||
@media screen and ( min-width: 430px ){
|
||||
margin-top:-108px;
|
||||
margin-top:-124px;
|
||||
}
|
||||
}
|
||||
img.featured-profile-pic{
|
||||
|
|
@ -386,7 +386,7 @@
|
|||
}
|
||||
.featured-user-name{
|
||||
font-weight:bold;
|
||||
margin-top:-87px;
|
||||
margin-top:-101px;
|
||||
position:absolute;
|
||||
z-index:10;
|
||||
left:62px;
|
||||
|
|
@ -401,12 +401,12 @@
|
|||
@media screen and ( min-width: 430px ){
|
||||
left:72px;
|
||||
font-size:18px;
|
||||
margin-top:-106px;
|
||||
margin-top:-120px;
|
||||
}
|
||||
}
|
||||
.featured-tags{
|
||||
font-size:15px;
|
||||
margin-top:-66px !important;
|
||||
margin-top:-78px !important;
|
||||
bottom:auto !important;
|
||||
position:absolute;
|
||||
max-width:76%;
|
||||
|
|
@ -426,63 +426,78 @@
|
|||
font-size:16px !important;
|
||||
left:72px;
|
||||
bottom:auto;
|
||||
margin-top:-82px !important;
|
||||
margin-top:-94px !important;
|
||||
}
|
||||
}
|
||||
.article-engagement-count{
|
||||
font-size:13px;
|
||||
font-weight:bold;
|
||||
position:absolute;
|
||||
bottom:10px;
|
||||
bottom:12px;
|
||||
font-weight:400;
|
||||
padding:3px 6px;
|
||||
background: transparent;
|
||||
border:0;
|
||||
-webkit-appearance:none;
|
||||
font-family: $helvetica-condensed;
|
||||
color: $medium-gray;
|
||||
a{
|
||||
&:hover{
|
||||
opacity:1;
|
||||
}
|
||||
color: $medium-gray;
|
||||
}
|
||||
img{
|
||||
width:16px;
|
||||
height:18px;
|
||||
border:0px;
|
||||
vertical-align:-4px;
|
||||
margin-right:7px;
|
||||
}
|
||||
&.comments-count {
|
||||
left:73px;
|
||||
left:93px;
|
||||
}
|
||||
&.reactions-count {
|
||||
left:10px;
|
||||
img{
|
||||
margin-bottom:1px;
|
||||
opacity:0.8;
|
||||
}
|
||||
left:20px;
|
||||
}
|
||||
&.bookmark-engage {
|
||||
right: 7px;
|
||||
right: 12px;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 3px;
|
||||
text-align:center;
|
||||
bottom:8px;
|
||||
img{
|
||||
width:28px;
|
||||
margin-right: auto;
|
||||
&.bm-success{
|
||||
display:none;
|
||||
}
|
||||
bottom:12px;
|
||||
// border: 2px solid darken($purple, 30%);
|
||||
background: darken($purple, 26%);
|
||||
color: white;
|
||||
letter-spacing: 1px;
|
||||
&:hover{
|
||||
background: darken($purple, 30%);
|
||||
}
|
||||
img{
|
||||
height:18px;
|
||||
margin-right: 0px;
|
||||
vertical-align:-3px;
|
||||
}
|
||||
.bm-success{
|
||||
display:none;
|
||||
}
|
||||
&.selected{
|
||||
img.bm-initial{
|
||||
color: darken($purple, 33%);
|
||||
background: transparent;
|
||||
padding-right: 0px;
|
||||
.bm-initial{
|
||||
display:none;
|
||||
}
|
||||
img.bm-success{
|
||||
.bm-success{
|
||||
display:block;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.featured-engagement-count{
|
||||
margin-top:-35px;
|
||||
margin-top:-38px;
|
||||
bottom: auto;
|
||||
z-index:10;
|
||||
&.bookmark-engage {
|
||||
margin-top:-46px;
|
||||
margin-top:-39px;
|
||||
}
|
||||
}
|
||||
.engagement-count-number{
|
||||
|
|
@ -493,7 +508,8 @@
|
|||
@media screen and ( min-width: 430px ){
|
||||
font-size:15px;
|
||||
img{
|
||||
width:18px;
|
||||
height:20px;
|
||||
min-width:26px;
|
||||
vertical-align:-5px;
|
||||
}
|
||||
&.featured-engagement{
|
||||
|
|
@ -628,13 +644,16 @@
|
|||
}
|
||||
.sidebar-profile-pic{
|
||||
display:inline-block;
|
||||
width:66px;
|
||||
height:66px;
|
||||
width:50px;
|
||||
height:50px;
|
||||
vertical-align:top;
|
||||
overflow:hidden;
|
||||
background: $tan;
|
||||
border-radius: 100%;
|
||||
margin: 8px 5px 8px 12px;
|
||||
img{
|
||||
width:100%;
|
||||
border-radius: 100%;
|
||||
}
|
||||
}
|
||||
.sidebar-profile-content{
|
||||
|
|
@ -666,7 +685,7 @@
|
|||
}
|
||||
.sidebar-nav-header{
|
||||
padding:15px 10px;
|
||||
font-size: 1.1em;
|
||||
font-size: 1.3em;
|
||||
font-family: $helvetica-condensed;
|
||||
font-stretch:condensed;
|
||||
font-weight: 800;
|
||||
|
|
@ -682,6 +701,7 @@
|
|||
padding:10px;
|
||||
font-weight:500;
|
||||
font-size:0.9em;
|
||||
background: darken($light-gray, 4%);
|
||||
a{
|
||||
color:$black;
|
||||
}
|
||||
|
|
@ -695,31 +715,39 @@
|
|||
.sidebar-nav-element{
|
||||
color:$black;
|
||||
display:block;
|
||||
font-family: "Lucida Console", Monaco, monospace, sans-serif;
|
||||
// font-family: "Lucida Console", Monaco, monospace, sans-serif;
|
||||
position:relative;
|
||||
&.sidebar-nav-readinglist{
|
||||
background: $purple;
|
||||
font-family: $helvetica-condensed;
|
||||
font-stretch:condensed;
|
||||
&:hover{
|
||||
background:darken($purple, 3%);
|
||||
}
|
||||
font-size:1.1em;
|
||||
}
|
||||
&:hover{
|
||||
background:$light-gray;
|
||||
}
|
||||
@media screen and ( min-width: 950px ){
|
||||
.sidebar-nav-link-follow{
|
||||
display: none;
|
||||
}
|
||||
&:hover{
|
||||
.sidebar-nav-link-follow{
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
img {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border: 0px;
|
||||
vertical-align: -7px;
|
||||
vertical-align: -8px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
a.sidebar-nav-link{
|
||||
color:$black;
|
||||
padding:10px;
|
||||
padding:5px;
|
||||
display:inline-block;
|
||||
width:100%;
|
||||
width:calc(100% - 10px);
|
||||
font-weight: 500;
|
||||
.sidebar-nav-tag-text{
|
||||
border-radius: 3px;
|
||||
padding: 3px 8px;
|
||||
|
|
@ -728,15 +756,13 @@
|
|||
a.sidebar-nav-link-follow{
|
||||
position:absolute;
|
||||
color:$black;
|
||||
right:9px;
|
||||
top:5px;
|
||||
width:31px;
|
||||
height:31px;
|
||||
right:5px;
|
||||
top:2px;
|
||||
text-align:center;
|
||||
border-radius:100px;
|
||||
border-radius:3px;
|
||||
font-weight:900;
|
||||
line-height:28px;
|
||||
font-size:1.3em;
|
||||
font-size:0.8em;
|
||||
padding: 2px 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -761,6 +787,9 @@
|
|||
&.sponsorship-widget{
|
||||
display: none;
|
||||
text-align:center;
|
||||
header{
|
||||
font-size:1.1em;
|
||||
}
|
||||
}
|
||||
&.showing{
|
||||
display: block;
|
||||
|
|
@ -808,12 +837,15 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
hr{
|
||||
opacity:0.2;
|
||||
}
|
||||
header{
|
||||
width:100%;
|
||||
margin:auto;
|
||||
padding-bottom:5px;
|
||||
font-weight:800;
|
||||
font-size: 1.1em;
|
||||
font-size: 1.3em;
|
||||
padding-bottom:10px;
|
||||
font-family: $helvetica-condensed;
|
||||
font-stretch:condensed;
|
||||
|
|
@ -832,8 +864,8 @@
|
|||
.widget-body{
|
||||
margin-top:9px;
|
||||
&.body-scrollable{
|
||||
height: calc(100vh - 500px);
|
||||
max-height: 385px;
|
||||
height: calc(100vh - 300px);
|
||||
max-height: 500px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
&.signup-cta-widget-body{
|
||||
|
|
@ -877,7 +909,7 @@
|
|||
}
|
||||
.sponsor-footer{
|
||||
font-size:0.77em;
|
||||
margin-top:110px;
|
||||
margin-top:106px;
|
||||
margin:auto;
|
||||
margin-bottom:18px;
|
||||
width:96%;
|
||||
|
|
@ -931,14 +963,22 @@
|
|||
border: 0px;
|
||||
display:block;
|
||||
padding: 6px 8px;
|
||||
width: calc(100% - 16px);
|
||||
width: 100%;
|
||||
text-align:left;
|
||||
border-radius: 0px;
|
||||
&:hover{
|
||||
background: lighten($purple, 7%);
|
||||
background: lighten($yellow, 15%);
|
||||
}
|
||||
&.selected{
|
||||
background: $purple;
|
||||
background: lighten($yellow, 2%);
|
||||
}
|
||||
&.query-type-filter-button{
|
||||
&:hover{
|
||||
background: $light-green;
|
||||
}
|
||||
&.selected{
|
||||
background: darken($light-green,10%);
|
||||
}
|
||||
}
|
||||
}
|
||||
p{
|
||||
|
|
@ -1018,16 +1058,18 @@
|
|||
// background:red;
|
||||
}
|
||||
.discuss-list-comment-count{
|
||||
background:$bold-blue;
|
||||
color:white;
|
||||
font-size:0.7em;
|
||||
padding:2px 6px;
|
||||
vertical-align:1px;
|
||||
border-radius:5px;
|
||||
opacity:0.95;
|
||||
font-size: 0.7em;
|
||||
color: $medium-gray;
|
||||
margin-top: 2px;
|
||||
img {
|
||||
width: 20px;
|
||||
vertical-align: -3px;
|
||||
border: 0px;
|
||||
}
|
||||
&.discuss-list-comment-count-brand-new {
|
||||
background:$yellow;
|
||||
color:$black;
|
||||
font-size:1.1em;
|
||||
}
|
||||
}
|
||||
&::before {
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ a.header-link{
|
|||
padding-top:10px;
|
||||
margin:auto;
|
||||
margin-bottom:100px;
|
||||
text-align: left;
|
||||
&.comments-dedicated-page-container{
|
||||
min-height:calc(97vh - 200px);
|
||||
}
|
||||
|
|
@ -301,7 +302,7 @@ a.header-link{
|
|||
.comment-hash-marker{
|
||||
margin-top:-45px;
|
||||
margin-bottom:45px;
|
||||
border:1px solid white;
|
||||
border:1px solid transparent;
|
||||
z-index:-10;
|
||||
position:relative;
|
||||
&:target + .single-comment-node{
|
||||
|
|
@ -313,426 +314,462 @@ a.header-link{
|
|||
.root-comment{
|
||||
margin-top:-80px;
|
||||
}
|
||||
.single-comment-node{
|
||||
padding:2px 0px 2px $indent-distance;
|
||||
&.root{
|
||||
padding:10px 0px 2px 0;
|
||||
}
|
||||
margin-top:42px;
|
||||
font-size:17px;
|
||||
}
|
||||
.comment-view-parent{
|
||||
margin-bottom: 7px;
|
||||
text-align:left;
|
||||
font-family: $helvetica-condensed;
|
||||
font-size:0.8em;
|
||||
background: $purple;
|
||||
display: inline-block;
|
||||
padding: 2px 4px;
|
||||
border-radius: 3px;
|
||||
margin-right: 5px;
|
||||
vertical-align:top;
|
||||
&.comment-view-commentable{
|
||||
background: transparent;
|
||||
max-width: calc(100% - 100px);
|
||||
white-space: nowrap;
|
||||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.single-comment-node{
|
||||
padding:2px 0px 2px $indent-distance;
|
||||
text-align: left;
|
||||
&.root{
|
||||
padding:10px 0px 2px 0;
|
||||
}
|
||||
margin-top:42px;
|
||||
font-size:17px;
|
||||
position:relative;
|
||||
@media screen and ( min-width: 390px ){
|
||||
font-size:20px;
|
||||
}
|
||||
&.flat-node{
|
||||
padding:0px;
|
||||
margin-top:-3px;
|
||||
margin-bottom:-3px;
|
||||
&.root{
|
||||
padding:2px 0px;
|
||||
margin-top:0px;
|
||||
}
|
||||
.inner-comment{
|
||||
border-top-left-radius:0px;
|
||||
border-top-right-radius:0px;
|
||||
}
|
||||
button{
|
||||
margin-bottom:3px;
|
||||
z-index:7;
|
||||
position:relative;
|
||||
@media screen and ( min-width: 390px ){
|
||||
font-size:20px;
|
||||
}
|
||||
}
|
||||
.comment-deep-3{
|
||||
padding:2px 0px 2px calc(0.9vw + 7px);
|
||||
button{
|
||||
margin-bottom:3px;
|
||||
z-index:8;
|
||||
position:relative;
|
||||
}
|
||||
}
|
||||
.permalink{
|
||||
width:40px;
|
||||
position:absolute;
|
||||
right:2px;
|
||||
margin-top:calc(0.4vw + 12px);
|
||||
text-align:center;
|
||||
opacity:0.9;
|
||||
img{
|
||||
width:14px;
|
||||
}
|
||||
&:hover{
|
||||
opacity:1;
|
||||
}
|
||||
}
|
||||
.body{
|
||||
padding:1px;
|
||||
padding-left:1.5%;
|
||||
padding-right:1.5%;
|
||||
padding-bottom:5px;
|
||||
margin:0;
|
||||
width:96%;
|
||||
color:$black;
|
||||
font-size:0.95em;
|
||||
line-height:1.35em;
|
||||
overflow:hidden;
|
||||
margin-bottom:-30px;
|
||||
word-wrap: break-word;
|
||||
font-family: $helvetica;
|
||||
position:relative;
|
||||
h1,h2,h3,h4,h5,h6{
|
||||
padding:0px;
|
||||
margin:4px 0px calc(1.1vw + 10px);
|
||||
font-size:1em;
|
||||
font-weight:600;
|
||||
}
|
||||
h1{
|
||||
font-size:1.3em;
|
||||
}
|
||||
p{
|
||||
padding:0px;
|
||||
margin:4px 0px calc(1.1vw + 10px);
|
||||
}
|
||||
ul,ol{
|
||||
padding-left:6px;
|
||||
margin:0.8em 0.7em 0.8em 1em;
|
||||
}
|
||||
ul{
|
||||
list-style-type: square;
|
||||
}
|
||||
li{
|
||||
margin:3px 0px calc(0.5vw + 5px);
|
||||
}
|
||||
blockquote{
|
||||
border-left:calc(0.2vw + 2px) solid $dark-gray;
|
||||
padding:0.1% 3% 0.1% 2%;
|
||||
margin:1.6em 1vw;
|
||||
font-size:0.92em;
|
||||
line-height:1.4em;
|
||||
p{
|
||||
padding:0;
|
||||
margin:0.95em 0 0.95em;
|
||||
}
|
||||
&.flat-node{
|
||||
padding:0px;
|
||||
margin-top:-3px;
|
||||
margin-bottom:-3px;
|
||||
&.root{
|
||||
padding:2px 0px;
|
||||
margin-top:0px;
|
||||
}
|
||||
.inner-comment{
|
||||
border-top-left-radius:0px;
|
||||
border-top-right-radius:0px;
|
||||
}
|
||||
button{
|
||||
margin-bottom:3px;
|
||||
z-index:7;
|
||||
position:relative;
|
||||
&.twitter-tweet{
|
||||
background:white;
|
||||
max-width:480px;
|
||||
min-height:135px;
|
||||
border:1px solid #e9eef2;
|
||||
font-size:17px;
|
||||
line-height:20px;
|
||||
border-radius:5px;
|
||||
margin-top:10px;
|
||||
padding:10px;
|
||||
}
|
||||
}
|
||||
.edited-notification{
|
||||
color:lighten($medium-gray,20%);
|
||||
font-size:0.7em;
|
||||
padding:3px 0px 0px;
|
||||
position:relative;
|
||||
z-index:1;
|
||||
}
|
||||
code{
|
||||
margin:auto;
|
||||
white-space: nowrap;
|
||||
background:$lightest-gray;
|
||||
padding:1px 5px 0px;
|
||||
border-radius:2px;
|
||||
color:#333842;
|
||||
font-size:0.8em;
|
||||
display:inline-block;
|
||||
vertical-align:0.1em;
|
||||
max-width:100%;
|
||||
line-height:1.4em;
|
||||
}
|
||||
pre{
|
||||
width:88%;
|
||||
margin-left:-3%;
|
||||
margin-left:0px;
|
||||
padding-left:4%;
|
||||
padding-right:7%;
|
||||
padding-top:6%;
|
||||
padding-bottom:6%;
|
||||
overflow-wrap: normal;
|
||||
code{
|
||||
background:#29292e;
|
||||
color:#eff0f9;
|
||||
white-space: pre;
|
||||
font-size:1em;
|
||||
}
|
||||
}
|
||||
img{
|
||||
max-width:100%;
|
||||
}
|
||||
.table-wrapper-paragraph{
|
||||
width:100%;
|
||||
margin-left:0%;
|
||||
overflow-x:auto;
|
||||
}
|
||||
}
|
||||
.icon-img{
|
||||
height:16px;
|
||||
width:16px;
|
||||
margin-right:0px;
|
||||
opacity:0.7;
|
||||
}
|
||||
.details{
|
||||
padding:0px;
|
||||
border-top-left-radius:3px;
|
||||
border-top-left-radius:3px;
|
||||
color:$dark-gray;
|
||||
position:relative;
|
||||
// background:$light-gray;
|
||||
.comment-date{
|
||||
border: none;
|
||||
position: absolute;
|
||||
top: calc(16px - 0.25vw);
|
||||
right: calc(35px + 0.2vw);
|
||||
font-size:12px;
|
||||
text-align:right;
|
||||
a{
|
||||
color:$medium-gray;
|
||||
}
|
||||
}
|
||||
.dropbtn {
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: calc(0.3vw + 11px);
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
right: 10px;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
|
||||
.dropdown-content {
|
||||
display: none;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
border: 1px solid $light-medium-gray;
|
||||
border-radius: 3px;
|
||||
background: white;
|
||||
z-index:20;
|
||||
box-shadow: $shadow;
|
||||
&.showing{
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.comment-deep-3{
|
||||
padding:2px 0px 2px calc(0.9vw + 7px);
|
||||
button{
|
||||
margin-bottom:3px;
|
||||
z-index:8;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.dropdown-content a {
|
||||
color: black;
|
||||
padding: 12px 16px;
|
||||
width: 93px;
|
||||
height: 14px;
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
}
|
||||
.permalink{
|
||||
width:40px;
|
||||
position:absolute;
|
||||
right:2px;
|
||||
margin-top:calc(0.4vw + 12px);
|
||||
text-align:center;
|
||||
opacity:0.9;
|
||||
img{
|
||||
width:14px;
|
||||
}
|
||||
&:hover{
|
||||
opacity:1;
|
||||
}
|
||||
|
||||
.dropdown-content a:hover { background-color: #f1f1f1 }
|
||||
|
||||
.dropdown-icon {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 7px;
|
||||
padding: 4px;
|
||||
max-width: 15px;
|
||||
max-height: 15px;
|
||||
}
|
||||
.body{
|
||||
padding:1px;
|
||||
padding-left:1.5%;
|
||||
padding-right:1.5%;
|
||||
padding-bottom:5px;
|
||||
margin:0;
|
||||
width:96%;
|
||||
}
|
||||
|
||||
img.profile-pic{
|
||||
height:33px;
|
||||
width:33px;
|
||||
border-radius:50px;
|
||||
margin:1.5% 0.2% 1.5% 1.5%;
|
||||
}
|
||||
.comment-username{
|
||||
vertical-align:calc(0.62vw + 13px);
|
||||
}
|
||||
.comment-username-inner{
|
||||
vertical-align:middle;
|
||||
display:inline-block;
|
||||
white-space: nowrap;
|
||||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width:calc( 60% - 20px);
|
||||
}
|
||||
.icon-img{
|
||||
vertical-align:calc(0.7vw + 9px);
|
||||
margin-left:2px;
|
||||
}
|
||||
.op-marker{
|
||||
display:none;
|
||||
@media screen and ( min-width: 580px ){
|
||||
display:inline-block;
|
||||
vertical-align:calc(0.7vw + 12px);
|
||||
background:$purple;
|
||||
color:$black;
|
||||
font-size:0.95em;
|
||||
line-height:1.35em;
|
||||
overflow:hidden;
|
||||
margin-bottom:-30px;
|
||||
word-wrap: break-word;
|
||||
font-family: $helvetica;
|
||||
position:relative;
|
||||
h1,h2,h3,h4,h5,h6{
|
||||
padding:0px;
|
||||
margin:4px 0px calc(1.1vw + 10px);
|
||||
font-size:1em;
|
||||
font-weight:600;
|
||||
}
|
||||
h1{
|
||||
font-size:1.3em;
|
||||
}
|
||||
p{
|
||||
padding:0px;
|
||||
margin:4px 0px calc(1.1vw + 10px);
|
||||
}
|
||||
ul,ol{
|
||||
padding-left:6px;
|
||||
margin:0.8em 0.7em 0.8em 1em;
|
||||
}
|
||||
ul{
|
||||
list-style-type: square;
|
||||
}
|
||||
li{
|
||||
margin:3px 0px calc(0.5vw + 5px);
|
||||
}
|
||||
blockquote{
|
||||
border-left:calc(0.2vw + 2px) solid $dark-gray;
|
||||
padding:0.1% 3% 0.1% 2%;
|
||||
margin:1.6em 1vw;
|
||||
font-size:0.92em;
|
||||
line-height:1.4em;
|
||||
p{
|
||||
padding:0;
|
||||
margin:0.95em 0 0.95em;
|
||||
}
|
||||
&.twitter-tweet{
|
||||
background:white;
|
||||
max-width:480px;
|
||||
min-height:135px;
|
||||
border:1px solid #e9eef2;
|
||||
font-size:17px;
|
||||
line-height:20px;
|
||||
border-radius:5px;
|
||||
margin-top:10px;
|
||||
padding:10px;
|
||||
}
|
||||
}
|
||||
.edited-notification{
|
||||
color:lighten($medium-gray,20%);
|
||||
font-size:0.7em;
|
||||
padding:3px 0px 0px;
|
||||
position:relative;
|
||||
z-index:1;
|
||||
}
|
||||
code{
|
||||
margin:auto;
|
||||
white-space: nowrap;
|
||||
background:$lightest-gray;
|
||||
padding:1px 5px 0px;
|
||||
border-radius:2px;
|
||||
color:#333842;
|
||||
font-size:0.8em;
|
||||
display:inline-block;
|
||||
vertical-align:0.1em;
|
||||
max-width:100%;
|
||||
line-height:1.4em;
|
||||
}
|
||||
pre{
|
||||
width:88%;
|
||||
margin-left:-3%;
|
||||
margin-left:0px;
|
||||
padding-left:4%;
|
||||
padding-right:7%;
|
||||
padding-top:6%;
|
||||
padding-bottom:6%;
|
||||
overflow-wrap: normal;
|
||||
code{
|
||||
background:#29292e;
|
||||
color:#eff0f9;
|
||||
white-space: pre;
|
||||
font-size:1em;
|
||||
}
|
||||
}
|
||||
img{
|
||||
max-width:100%;
|
||||
}
|
||||
.table-wrapper-paragraph{
|
||||
width:100%;
|
||||
margin-left:0%;
|
||||
overflow-x:auto;
|
||||
}
|
||||
}
|
||||
.icon-img{
|
||||
height:16px;
|
||||
width:16px;
|
||||
margin-right:0px;
|
||||
opacity:0.7;
|
||||
}
|
||||
.details{
|
||||
padding:0px;
|
||||
border-top-left-radius:3px;
|
||||
border-top-left-radius:3px;
|
||||
color:$dark-gray;
|
||||
position:relative;
|
||||
// background:$light-gray;
|
||||
.comment-date{
|
||||
border: none;
|
||||
position: absolute;
|
||||
top: calc(16px - 0.25vw);
|
||||
right: calc(35px + 0.2vw);
|
||||
font-size:12px;
|
||||
text-align:right;
|
||||
a{
|
||||
color:$medium-gray;
|
||||
}
|
||||
}
|
||||
.dropbtn {
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: calc(0.3vw + 11px);
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
right: 10px;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
|
||||
.dropdown-content {
|
||||
display: none;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
border: 1px solid $light-medium-gray;
|
||||
border-radius: 3px;
|
||||
background: white;
|
||||
z-index:20;
|
||||
box-shadow: $shadow;
|
||||
&.showing{
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-content a {
|
||||
color: black;
|
||||
padding: 12px 16px;
|
||||
width: 93px;
|
||||
height: 14px;
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.dropdown-content a:hover { background-color: #f1f1f1 }
|
||||
|
||||
.dropdown-icon {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 7px;
|
||||
padding: 4px;
|
||||
max-width: 15px;
|
||||
max-height: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
img.profile-pic{
|
||||
height:33px;
|
||||
width:33px;
|
||||
border-radius:50px;
|
||||
margin:1.5% 0.2% 1.5% 1.5%;
|
||||
}
|
||||
.comment-username{
|
||||
vertical-align:calc(0.62vw + 13px);
|
||||
}
|
||||
.comment-username-inner{
|
||||
vertical-align:middle;
|
||||
display:inline-block;
|
||||
white-space: nowrap;
|
||||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width:calc( 60% - 20px);
|
||||
}
|
||||
.icon-img{
|
||||
vertical-align:calc(0.7vw + 9px);
|
||||
margin-left:2px;
|
||||
}
|
||||
.op-marker{
|
||||
display:none;
|
||||
@media screen and ( min-width: 580px ){
|
||||
display:inline-block;
|
||||
vertical-align:calc(0.7vw + 12px);
|
||||
background:$purple;
|
||||
color:$black;
|
||||
padding:2px 6px 2px;
|
||||
margin-left:0.3vw;
|
||||
font-family: $helvetica-condensed;
|
||||
font-stretch:condensed;
|
||||
font-size: 0.78em;
|
||||
}
|
||||
}
|
||||
a{
|
||||
color:lighten($dark-gray,3%);
|
||||
}
|
||||
}
|
||||
.reaction-button,.dropbtn{
|
||||
border:0px;
|
||||
background:transparent;
|
||||
vertical-align:2px;
|
||||
cursor:pointer;
|
||||
border-radius:3px;
|
||||
height:32px;
|
||||
display:block;
|
||||
padding:0px;
|
||||
margin-left:2px;
|
||||
position:relative;
|
||||
margin-top:calc(-0.6vw - 4px);
|
||||
z-index:8;
|
||||
position:relative;
|
||||
.reactions-count {
|
||||
font-size:calc(0.9em + 0.1vw);
|
||||
background: $light-gray;
|
||||
padding:1px 5px;
|
||||
border-radius:3px;
|
||||
border: 1px solid darken($light-gray, 10%);
|
||||
margin-left:1px;
|
||||
position:absolute;
|
||||
top:8px;
|
||||
left: 24px;
|
||||
}
|
||||
img{
|
||||
height:20px;
|
||||
width:20px;
|
||||
opacity:0.62;
|
||||
left:0px;
|
||||
}
|
||||
&:hover{
|
||||
img{
|
||||
opacity:1;
|
||||
}
|
||||
}
|
||||
.voted-heart{
|
||||
display:none;
|
||||
vertical-align:0px;
|
||||
margin-left:0px;
|
||||
height: 25px;
|
||||
width: 22px;
|
||||
opacity:0.9;
|
||||
animation: fadein 0.22s ease ;
|
||||
&:hover{
|
||||
opacity:1;
|
||||
}
|
||||
}
|
||||
@media screen and ( min-width: 390px ){
|
||||
vertical-align:-7px;
|
||||
}
|
||||
&.reacted{
|
||||
color:$green;
|
||||
img{
|
||||
display:none;
|
||||
}
|
||||
.voted-heart{
|
||||
display:inline-block;
|
||||
}
|
||||
.reactions-count {
|
||||
color:$black;
|
||||
font-weight:500;
|
||||
}
|
||||
}
|
||||
}
|
||||
img.icon-image{
|
||||
height:20px;
|
||||
}
|
||||
.editor-image-upload{
|
||||
width:calc(100% - 150px);
|
||||
text-align:left;
|
||||
.uploaded-image {
|
||||
width: calc( 93% - 54px);
|
||||
}
|
||||
.image-upload-button {
|
||||
padding: 5px 2px 0px;
|
||||
margin-left:3px;
|
||||
}
|
||||
@media screen and ( min-width: 500px ){
|
||||
.uploaded-image {
|
||||
width: calc( 94% - 62px);
|
||||
}
|
||||
}
|
||||
}
|
||||
.actions{
|
||||
font-size:0.8em;
|
||||
padding:0.3em 0.6em 0.3em 0.4em;
|
||||
text-align:right;
|
||||
position:relative;
|
||||
min-height:1.2em;
|
||||
z-index:5;
|
||||
padding:2px 6px 2px;
|
||||
margin-left:0.3vw;
|
||||
font-family: $helvetica-condensed;
|
||||
font-stretch:condensed;
|
||||
width: calc(100% - 74px);
|
||||
margin-left: 58px;
|
||||
.current-user-actions{
|
||||
.hidden{
|
||||
display:none;
|
||||
}
|
||||
a{
|
||||
margin-right:10px;
|
||||
display:inline-block;
|
||||
color:$medium-gray;
|
||||
}
|
||||
font-size: 0.78em;
|
||||
}
|
||||
}
|
||||
a{
|
||||
color:lighten($dark-gray,3%);
|
||||
}
|
||||
}
|
||||
.reaction-button,.dropbtn{
|
||||
border:0px;
|
||||
background:transparent;
|
||||
vertical-align:2px;
|
||||
cursor:pointer;
|
||||
border-radius:3px;
|
||||
height:32px;
|
||||
display:block;
|
||||
padding:0px;
|
||||
margin-left:2px;
|
||||
position:relative;
|
||||
margin-top:calc(-0.6vw - 4px);
|
||||
z-index:8;
|
||||
position:relative;
|
||||
.reactions-count {
|
||||
font-size:calc(0.9em + 0.1vw);
|
||||
background: $light-gray;
|
||||
padding:1px 5px;
|
||||
border-radius:3px;
|
||||
border: 1px solid darken($light-gray, 10%);
|
||||
margin-left:1px;
|
||||
position:absolute;
|
||||
top:8px;
|
||||
left: 24px;
|
||||
}
|
||||
img{
|
||||
height:20px;
|
||||
width:20px;
|
||||
opacity:0.62;
|
||||
left:0px;
|
||||
}
|
||||
&:hover{
|
||||
img{
|
||||
opacity:1;
|
||||
}
|
||||
}
|
||||
.voted-heart{
|
||||
display:none;
|
||||
vertical-align:0px;
|
||||
margin-left:0px;
|
||||
height: 25px;
|
||||
width: 22px;
|
||||
opacity:0.9;
|
||||
animation: fadein 0.22s ease ;
|
||||
&:hover{
|
||||
opacity:1;
|
||||
}
|
||||
}
|
||||
@media screen and ( min-width: 390px ){
|
||||
vertical-align:-7px;
|
||||
}
|
||||
&.reacted{
|
||||
color:$green;
|
||||
img{
|
||||
display:none;
|
||||
}
|
||||
.voted-heart{
|
||||
display:inline-block;
|
||||
}
|
||||
.reactions-count {
|
||||
color:$black;
|
||||
font-weight:500;
|
||||
}
|
||||
}
|
||||
}
|
||||
img.icon-image{
|
||||
height:20px;
|
||||
}
|
||||
.editor-image-upload{
|
||||
width:calc(100% - 150px);
|
||||
text-align:left;
|
||||
.uploaded-image {
|
||||
width: calc( 93% - 54px);
|
||||
}
|
||||
.image-upload-button {
|
||||
padding: 5px 2px 0px;
|
||||
margin-left:3px;
|
||||
}
|
||||
@media screen and ( min-width: 500px ){
|
||||
.uploaded-image {
|
||||
width: calc( 94% - 62px);
|
||||
}
|
||||
}
|
||||
}
|
||||
.actions{
|
||||
font-size:0.8em;
|
||||
padding:0.3em 0.6em 0.3em 0.4em;
|
||||
text-align:right;
|
||||
position:relative;
|
||||
min-height:1.2em;
|
||||
z-index:5;
|
||||
font-family: $helvetica-condensed;
|
||||
font-stretch:condensed;
|
||||
width: calc(100% - 74px);
|
||||
margin-left: 58px;
|
||||
.current-user-actions{
|
||||
.hidden{
|
||||
display:none;
|
||||
}
|
||||
a{
|
||||
margin-right:10px;
|
||||
display:inline-block;
|
||||
color:$medium-gray;
|
||||
}
|
||||
}
|
||||
form{
|
||||
margin-bottom:-5px;
|
||||
margin-top:-7px;
|
||||
z-index:29;
|
||||
position:relative;
|
||||
width: calc(100% + 60px);
|
||||
margin-left: -58px;
|
||||
&.submitting{
|
||||
input[type="submit"]{
|
||||
background:$bold-blue;
|
||||
}
|
||||
form{
|
||||
margin-bottom:-5px;
|
||||
margin-top:-7px;
|
||||
z-index:29;
|
||||
position:relative;
|
||||
width: calc(100% + 60px);
|
||||
margin-left: -58px;
|
||||
&.submitting{
|
||||
input[type="submit"]{
|
||||
background:$bold-blue;
|
||||
}
|
||||
textarea{
|
||||
color:lighten($dark-gray,25%);
|
||||
}
|
||||
}
|
||||
input[type="submit"]{
|
||||
padding:5px 8px;
|
||||
margin-bottom:5px;
|
||||
}
|
||||
textarea{
|
||||
color:lighten($dark-gray,25%);
|
||||
}
|
||||
}
|
||||
input[type="submit"]{
|
||||
padding:5px 8px;
|
||||
margin-bottom:5px;
|
||||
}
|
||||
|
||||
.cancel{
|
||||
margin-right:5px;
|
||||
color:$red;
|
||||
opacity:0.5;
|
||||
vertical-align:-1px;
|
||||
font-size:0.9em;
|
||||
&:hover{
|
||||
opacity:0.8;
|
||||
}
|
||||
}
|
||||
.cancel{
|
||||
margin-right:5px;
|
||||
color:$red;
|
||||
opacity:0.5;
|
||||
vertical-align:-1px;
|
||||
font-size:0.9em;
|
||||
&:hover{
|
||||
opacity:0.8;
|
||||
}
|
||||
}
|
||||
.inner-comment{
|
||||
padding:0px;
|
||||
border:1px solid $light-medium-gray;
|
||||
background:white;
|
||||
&.comment-created-via-fetch{
|
||||
animation: comment-create 1.2s;
|
||||
.body{
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.inner-comment{
|
||||
padding:0px;
|
||||
border:1px solid $light-medium-gray;
|
||||
background:white;
|
||||
&.comment-created-via-fetch{
|
||||
animation: comment-create 1.2s;
|
||||
.body{
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
.comment-read-more{
|
||||
background: $green !important;
|
||||
padding: 3px 6px;
|
||||
display: block;
|
||||
width: 250px;
|
||||
text-align: center;
|
||||
margin: auto;
|
||||
border-radius: 3px;
|
||||
margin-bottom: 20px;
|
||||
font-weight: bold;
|
||||
&:hover{
|
||||
opacity:1;
|
||||
background: lighten($green, 5%) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadein{
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ footer{
|
|||
margin-bottom:-60px;
|
||||
padding:80px 0px 100px;
|
||||
box-shadow: 0 -1px 4px 0 rgba(0, 0, 0, 0.15);
|
||||
z-index: 10;
|
||||
position: relative;
|
||||
.container{
|
||||
background: darken($tan,1%);
|
||||
width:92%;
|
||||
|
|
|
|||
|
|
@ -150,7 +150,6 @@
|
|||
background: transparent;
|
||||
border:0px;
|
||||
margin-top:5px;
|
||||
font-size:22px;
|
||||
margin-left:-5px;
|
||||
margin-right:3px;
|
||||
height:30px;
|
||||
|
|
@ -161,10 +160,34 @@
|
|||
.reacted-emoji{
|
||||
display:none;
|
||||
}
|
||||
&.readinglist-button{
|
||||
background: darken($purple, 26%);
|
||||
color: white;
|
||||
font-family: $helvetica-condensed;
|
||||
height: auto;
|
||||
width: auto;
|
||||
padding: 3px 7px;
|
||||
display: inline-block;
|
||||
vertical-align: 5px;
|
||||
font-size: 17px;
|
||||
border-radius: 3px;
|
||||
float:right;
|
||||
img{
|
||||
opacity:1;
|
||||
}
|
||||
&.reacted{
|
||||
vertical-align:0px;
|
||||
padding: 3px 7px 1px;
|
||||
}
|
||||
}
|
||||
&.reacted {
|
||||
background: transparent;
|
||||
.reacted-emoji{
|
||||
display:inline;
|
||||
}
|
||||
.reaction-button-text{
|
||||
display: none;
|
||||
}
|
||||
img{
|
||||
display:none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,12 +129,21 @@
|
|||
-webkit-appearance: none;
|
||||
}
|
||||
}
|
||||
.nav-profile-image{
|
||||
.nav-profile-image-wrapper{
|
||||
height: 33px;
|
||||
width: 33px;
|
||||
background: $dark-gray;
|
||||
border-radius: 3px;
|
||||
margin-top:-5px;
|
||||
border-radius: 100%;
|
||||
border: 0;
|
||||
overflow: hidden;
|
||||
img{
|
||||
height: 35px;
|
||||
width: 35px;
|
||||
border-radius: 100%;
|
||||
margin-top:-1px;
|
||||
margin-left:-1px;
|
||||
}
|
||||
}
|
||||
.bars{
|
||||
height:22px;
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ class CommentsController < ApplicationController
|
|||
body_html: @comment.processed_html,
|
||||
id: @comment.id,
|
||||
id_code: @comment.id_code_generated,
|
||||
newly_created: true,
|
||||
user: {
|
||||
id: current_user.id,
|
||||
username: current_user.username,
|
||||
|
|
|
|||
|
|
@ -70,7 +70,10 @@ class Internal::ArticlesController < Internal::ApplicationController
|
|||
limited_columns_internal_select.
|
||||
order("featured_number DESC")
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
@article = Article.find(params[:id])
|
||||
end
|
||||
|
||||
def update
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ class Internal::TagsController < Internal::ApplicationController
|
|||
def index
|
||||
if params[:state] == "supported"
|
||||
@tags = Tag.where(supported: true).order("taggings_count DESC").limit(120)
|
||||
elsif params[:state] == "unsupported"
|
||||
@tags = Tag.where(supported: false).order("taggings_count DESC").limit(120)
|
||||
else
|
||||
@tags = Tag.order("taggings_count DESC").limit(120)
|
||||
end
|
||||
|
|
@ -12,7 +14,7 @@ class Internal::TagsController < Internal::ApplicationController
|
|||
|
||||
def update
|
||||
@tag = Tag.find(params[:id])
|
||||
@tag.update(tag_params)
|
||||
@tag.update!(tag_params)
|
||||
redirect_to(action: :index)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -197,6 +197,13 @@ class StoriesController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def redirect_if_show_view_param
|
||||
if params[:view] == "moderate"
|
||||
redirect_to "/internal/articles/#{@article.id}"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def handle_article_show
|
||||
@article_show = true
|
||||
@comment = Comment.new
|
||||
|
|
@ -210,6 +217,7 @@ class StoriesController < ApplicationController
|
|||
unless user_signed_in?
|
||||
response.headers["Surrogate-Control"] = "max-age=10000, stale-while-revalidate=30, stale-if-error=86400"
|
||||
end
|
||||
redirect_if_show_view_param; return if performed?
|
||||
render template: "articles/show"
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -73,7 +73,6 @@ class TagDashboard < Administrate::BaseDashboard
|
|||
:supported,
|
||||
:alias_for,
|
||||
:wiki_body_markdown,
|
||||
:wiki_body_html,
|
||||
:rules_markdown,
|
||||
:short_summary,
|
||||
:requires_approval,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
class CacheBuster
|
||||
|
||||
def bust(path)
|
||||
return unless Rails.env.production?
|
||||
request = HTTParty.post("https://api.fastly.com/purge/https://dev.to#{path}",
|
||||
:headers => { 'Fastly-Key' => 'f15066a3abedf47238b08e437684c84f' } )
|
||||
request = HTTParty.post("https://api.fastly.com/purge/https://dev.to#{path}?i=i",
|
||||
|
|
|
|||
|
|
@ -143,6 +143,15 @@ class Article < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def self.active_discuss_threads(tag)
|
||||
where(published:true).
|
||||
where("published_at > ?", 7.days.ago).
|
||||
tagged_with(["discuss", tag]).
|
||||
order("last_comment_at DESC").
|
||||
limit(8).
|
||||
pluck(:path, :title, :comments_count, :created_at)
|
||||
end
|
||||
|
||||
def body_text
|
||||
ActionView::Base.full_sanitizer.sanitize(processed_html)[0..7000]
|
||||
end
|
||||
|
|
@ -352,6 +361,10 @@ class Article < ApplicationRecord
|
|||
self.crossposted_at = Time.now if published && crossposted_at.blank? && published_from_feed
|
||||
end
|
||||
|
||||
def set_last_comment_at
|
||||
self.last_comment_at = Time.now if published && last_comment_at.blank?
|
||||
end
|
||||
|
||||
def title_to_slug
|
||||
title.to_s.downcase.tr(" ", "-").gsub(/[^\w-]/, "").tr("_", "") + "-" + rand(100000).to_s(26)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
class Comment < ApplicationRecord
|
||||
has_ancestry
|
||||
include AlgoliaSearch
|
||||
belongs_to :commentable, polymorphic: true
|
||||
counter_culture :commentable
|
||||
belongs_to :user
|
||||
|
|
@ -19,7 +20,7 @@ class Comment < ApplicationRecord
|
|||
after_create :after_create_checks
|
||||
after_save :calculate_score
|
||||
after_save :bust_cache
|
||||
before_destroy :bust_cache
|
||||
before_destroy :before_destroy_actions
|
||||
after_create :send_email_notification
|
||||
after_create :create_first_reaction
|
||||
after_create :send_to_moderator
|
||||
|
|
@ -30,6 +31,84 @@ class Comment < ApplicationRecord
|
|||
include StreamRails::Activity
|
||||
as_activity
|
||||
|
||||
algoliasearch per_environment: true, enqueue: :trigger_delayed_index do
|
||||
add_index "ordered_comments",
|
||||
id: :index_id,
|
||||
per_environment: true,
|
||||
enqueue: :trigger_delayed_index do
|
||||
attributes :id, :user_id, :commentable_id, :commentable_type, :id_code_generated, :path,
|
||||
:id_code, :readable_publish_date, :parent_id, :positive_reactions_count
|
||||
attribute :body_html do
|
||||
HTML_Truncator.truncate(processed_html,
|
||||
500, :ellipsis => '<a class="comment-read-more" href="'+path+'">... Read Entire Comment</a>')
|
||||
end
|
||||
attribute :url do
|
||||
path
|
||||
end
|
||||
attribute :css do
|
||||
custom_css
|
||||
end
|
||||
attribute :tag_list do
|
||||
commentable.tag_list
|
||||
end
|
||||
attribute :root_path do
|
||||
root&.path
|
||||
end
|
||||
attribute :parent_path do
|
||||
parent&.path
|
||||
end
|
||||
attribute :heart_ids do
|
||||
reactions.where(category:"like").pluck(:user_id)
|
||||
end
|
||||
attribute :user do
|
||||
{ username: user.username,
|
||||
name: user.name,
|
||||
id: user.id,
|
||||
profile_pic: ProfileImage.new(user).get(90),
|
||||
profile_image_90: ProfileImage.new(user).get(90),
|
||||
github_username: user.github_username,
|
||||
twitter_username: user.twitter_username
|
||||
}
|
||||
end
|
||||
attribute :commentable do
|
||||
{ path: commentable&.path,
|
||||
title: commentable&.title,
|
||||
tag_list: commentable&.tag_list,
|
||||
id: commentable&.id
|
||||
}
|
||||
end
|
||||
tags do
|
||||
[commentable.tag_list,
|
||||
"user_#{user_id}",
|
||||
"commentable_#{commentable_type}_#{commentable_id}"].flatten.compact
|
||||
end
|
||||
ranking ["desc(created_at)"]
|
||||
end
|
||||
end
|
||||
|
||||
def self.trigger_delayed_index(record, remove)
|
||||
if remove
|
||||
record.delay.remove_from_index! if (record && record.persisted?)
|
||||
else
|
||||
if record.deleted == false
|
||||
record.delay.index!
|
||||
else
|
||||
record.remove_algolia_index
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def remove_algolia_index
|
||||
remove_from_index!
|
||||
index = Algolia::Index.new("ordered_comments_#{Rails.env}")
|
||||
index.delete_object("comments-#{id}")
|
||||
end
|
||||
|
||||
def index_id
|
||||
"comments-#{id}"
|
||||
end
|
||||
|
||||
|
||||
def self.rooted_on(commentable_id, commentable_type)
|
||||
includes(:user, :commentable).
|
||||
where(commentable_id: commentable_id,
|
||||
|
|
@ -214,6 +293,12 @@ class Comment < ApplicationRecord
|
|||
end
|
||||
handle_asynchronously :create_first_reaction
|
||||
|
||||
def before_destroy_actions
|
||||
bust_cache
|
||||
remove_algolia_index
|
||||
reactions.destroy_all
|
||||
end
|
||||
|
||||
def bust_cache
|
||||
expire_root_fragment
|
||||
CacheBuster.new.bust("#{commentable.path}") if commentable
|
||||
|
|
@ -224,6 +309,7 @@ class Comment < ApplicationRecord
|
|||
def async_bust
|
||||
expire_root_fragment
|
||||
commentable.touch
|
||||
commentable.touch(:last_comment_at)
|
||||
CacheBuster.new.bust_comment(self)
|
||||
commentable.index!
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ class Tag < ActsAsTaggableOn::Tag
|
|||
|
||||
def evaluate_markdown
|
||||
self.rules_html = MarkdownParser.new(rules_markdown).evaluate_markdown
|
||||
self.wiki_body_html = MarkdownParser.new(wiki_body_markdown).evaluate_markdown
|
||||
end
|
||||
|
||||
def calculate_hotness_score
|
||||
|
|
|
|||
|
|
@ -5,14 +5,14 @@
|
|||
<div class="breadcrumb"><a href="<%= @user.path %>">View All Activity</a></div>
|
||||
<h2>
|
||||
<% if @user.comments_count > 250 %>
|
||||
<img class="emoji-img" src="<%= asset_path("chat.svg") %>"/> Last 250 Comments
|
||||
<img class="emoji-img" src="<%= asset_path("comments-bubble.svg") %>"/> Last 250 Comments
|
||||
<% else %>
|
||||
<img class="emoji-img" src="<%= asset_path("chat.svg") %>"/> All <%= @user.comments_count %> Comments
|
||||
<img class="emoji-img" src="<%= asset_path("comments-bubble.svg") %>"/> All <%= @user.comments_count %> Comments
|
||||
<% end %>
|
||||
</h2>
|
||||
<% else %>
|
||||
<h2>
|
||||
<img class="emoji-img" src="<%= asset_path("chat.svg") %>"/> Recent Comments
|
||||
<img class="emoji-img" src="<%= asset_path("comments-bubble.svg") %>"/> Recent Comments
|
||||
</h2>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -207,7 +207,23 @@
|
|||
<header>
|
||||
<SUBMISSION GUIDELINES>
|
||||
</header>
|
||||
<%= @tag_model.rules_html.html_safe %>
|
||||
<div class="widget-body">
|
||||
<%= @tag_model.rules_html.html_safe %>
|
||||
</div>
|
||||
<p><center><a class="cta cta-button" href="/new/<%= @tag %>"
|
||||
style="background:<%= @tag_model.bg_color_hex %>;color:<%= @tag_model.text_color_hex %>;">
|
||||
WRITE A POST
|
||||
</a></center></p>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if @tag_model && @tag_model.wiki_body_html.present? %>
|
||||
<div class="widget">
|
||||
<header>
|
||||
<ABOUT <%= @tag.upcase %>>
|
||||
</header>
|
||||
<div class="widget-body">
|
||||
<%= @tag_model.wiki_body_html.html_safe %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% elsif @podcast_index && @podcasts %>
|
||||
|
|
|
|||
|
|
@ -41,16 +41,32 @@
|
|||
</div>
|
||||
<% end %>
|
||||
<% elsif @user && @user.class.name == "Organization" %>
|
||||
<% elsif @tag || @query %>
|
||||
<% elsif @tag %>
|
||||
<% if Article.active_discuss_threads(@tag).any? %>
|
||||
<div class="widget">
|
||||
<header>
|
||||
<#DISCUSS>
|
||||
</header>
|
||||
<div class="widget-body">
|
||||
<div class="widget-link-list">
|
||||
<% Article.active_discuss_threads(@tag).
|
||||
each do |plucked_article| %>
|
||||
<%= render "articles/widget_list_item", plucked_article: plucked_article, show_comment_count: true %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% elsif @query %>
|
||||
<% elsif @podcast_index %>
|
||||
<% else %>
|
||||
<% unless user_signed_in? %>
|
||||
<div class="widget signin-cta-widget">
|
||||
<header>
|
||||
<SIGN UP>
|
||||
DEV.TO(GETHER)
|
||||
</header>
|
||||
<div class="widget-body">
|
||||
<p style="margin-bottom: 12px;">Join thousands of developers leveling up their game together.</p>
|
||||
<p style="margin-bottom: 12px;">Join thousands of software developers leveling up their code and careers.</p>
|
||||
<center style="margin-bottom: 12px;">
|
||||
<a href="/users/auth/twitter?state=navbar_basic" class="cta cta-button" data-no-instant>
|
||||
TWITTER
|
||||
|
|
@ -102,12 +118,7 @@
|
|||
limit(20).
|
||||
pluck(:path, :title, :comments_count, :created_at).
|
||||
each do |plucked_article| %>
|
||||
<div class="widget-link-list__item">
|
||||
<a href="<%= plucked_article[0] %>">
|
||||
<%= plucked_article[1] %> <span class="discuss-list-comment-count <%= " discuss-list-comment-count-brand-new " if plucked_article[2] == 0 %>"><%= plucked_article[2] == 0 ? "fresh" : plucked_article[2] %>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<%= render "articles/widget_list_item", plucked_article: plucked_article, show_comment_count: false %>
|
||||
<% end %>
|
||||
</div>
|
||||
<p><center><a class="cta cta-button" href="/new/shecoded">TELL YOUR STORY</a></center></p>
|
||||
|
|
@ -122,16 +133,13 @@
|
|||
<div class="widget-link-list">
|
||||
<% Article.
|
||||
where(published:true).
|
||||
where("published_at > ?", 2.days.ago).
|
||||
tagged_with("discuss").
|
||||
order("created_at DESC").
|
||||
order("last_comment_at DESC").
|
||||
limit(8).
|
||||
pluck(:path, :title, :comments_count, :created_at).
|
||||
each do |plucked_article| %>
|
||||
<div class="widget-link-list__item">
|
||||
<a href="<%= plucked_article[0] %>">
|
||||
<%= plucked_article[1] %> <span class="discuss-list-comment-count <%= "discuss-list-comment-count-brand-new" if plucked_article[2] == 0 %>"><%= plucked_article[2] == 0 ? "fresh" : plucked_article[2] %></span>
|
||||
</a>
|
||||
</div>
|
||||
<%= render "articles/widget_list_item", plucked_article: plucked_article, show_comment_count: true %>
|
||||
<% end %>
|
||||
</div>
|
||||
<p><center><a class="cta cta-button" href="/new/discuss">START A DISCUSSION</a></center></p>
|
||||
|
|
@ -147,15 +155,11 @@
|
|||
<% Article.
|
||||
where(published:true).
|
||||
tagged_with("explainlikeimfive").
|
||||
order("created_at DESC").
|
||||
limit(8).
|
||||
order("last_comment_at DESC").
|
||||
limit(3).
|
||||
pluck(:path,:title,:comments_count, :created_at).
|
||||
each do |plucked_article| %>
|
||||
<div class="widget-link-list__item">
|
||||
<a href="<%= plucked_article[0] %>">
|
||||
<%= plucked_article[1] %> <span class="discuss-list-comment-count <%= "discuss-list-comment-count-brand-new" if plucked_article[2] == 0 %>"><%= plucked_article[2] == 0 ? "fresh" : plucked_article[2] %></span>
|
||||
</a>
|
||||
</div>
|
||||
<%= render "articles/widget_list_item", plucked_article: plucked_article, show_comment_count: true %>
|
||||
<% end %>
|
||||
</div>
|
||||
<p><center><a class="cta cta-button" href="/new/explainlikeimfive">ASK FOR AN EXPLANATION</a></center></p>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
<div class="widget sidebar-nav-block">
|
||||
<div class="sidebar-nav-element sidebar-nav-readinglist">
|
||||
<a class="sidebar-nav-link" href="/readinglist">
|
||||
<img src="<%=asset_path("emoji/emoji-one-bookmark.png")%>" /> MY READING LIST
|
||||
<img src="<%=asset_path("readinglist-button.svg")%>" /> MY READING LIST
|
||||
<span id="reading-list-count"></span>
|
||||
</a>
|
||||
</div>
|
||||
|
|
@ -25,7 +25,11 @@
|
|||
<% end %>
|
||||
<div class="widget sidebar-nav-block sidebar-tag-block">
|
||||
<div class="sidebar-nav-header sidebar-nav-header-middle">
|
||||
<<%= user_signed_in? ? "MY" : "DEV" %> TAGS>
|
||||
<% if user_signed_in? %>
|
||||
<MY TAGS>
|
||||
<% else %>
|
||||
<DESIGN YOUR EXPERIENCE>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="sidebar-nav-block-inner">
|
||||
<div id="sidebar-nav-followed-tags" class="sidebar-nav-followed-tags"></div>
|
||||
|
|
@ -33,17 +37,17 @@
|
|||
<% if user_signed_in? %>
|
||||
<div class="sidebar-nav-subheader tag-separator" id="tag-separator">Other Popular Tags</div>
|
||||
<% end %>
|
||||
<% Tag.where(supported:true).order("hotness_score DESC").limit(20).each do |tag| %>
|
||||
<div class="sidebar-nav-element" id="default-sidebar-element-<%= tag.name %>">
|
||||
<a class="sidebar-nav-link" href="/t/<%= tag.name %>">
|
||||
<span class="sidebar-nav-tag-text" style="color:<%= tag.text_color_hex %>;background:<%= tag.bg_color_hex %>;" >
|
||||
#<%= tag.name %>
|
||||
<% Tag.where(supported:true).order("hotness_score DESC").limit(30).pluck(:id, :name).each do |tag_array| %>
|
||||
<div class="sidebar-nav-element" id="default-sidebar-element-<%= tag_array.second %>">
|
||||
<a class="sidebar-nav-link" href="/t/<%= tag_array.second %>">
|
||||
<span class="sidebar-nav-tag-text" >
|
||||
#<%= tag_array.second %>
|
||||
</span>
|
||||
</a>
|
||||
<a class="follow-action-button sidebar-nav-link-follow cta"
|
||||
href="#" id="sidebar-nav-link-follow-<%= tag.name %>"
|
||||
data-info='{"id":<%= tag.id%>,"className":"Tag", "style":"small"}'>
|
||||
+
|
||||
href="#" id="sidebar-nav-link-follow-<%= tag_array.second %>"
|
||||
data-info='{"id":<%= tag_array.first %>,"className":"Tag"}'>
|
||||
+ FOLLOW
|
||||
</a>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -32,13 +32,13 @@
|
|||
<% if story.comments_count > 0 %>
|
||||
<div class="article-engagement-count comments-count">
|
||||
<a href="<%=story.path%>">
|
||||
<img src="<%= asset_path("chat.svg") %>" alt="chat" /><span class="engagement-count-number"><%= story.comments_count %></span>
|
||||
<img src="<%= asset_path("comments-bubble.svg") %>" alt="chat" /><span class="engagement-count-number"><%= story.comments_count %></span>
|
||||
</a>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="article-engagement-count reactions-count" data-reaction-count data-reactable-id="<%= story.id %>">
|
||||
<a href="<%=story.path%>">
|
||||
<img src="<%= asset_path("favorite-heart-outline-button.svg") %>" alt="heart" /><span id="engagement-count-number-<%= story.id %>" class="engagement-count-number">
|
||||
<img src="<%= asset_path("reactions-stack.svg") %>" alt="Reactions" /><span id="engagement-count-number-<%= story.id %>" class="engagement-count-number">
|
||||
<%= story.positive_reactions_count %>
|
||||
</span>
|
||||
</a>
|
||||
|
|
@ -46,9 +46,9 @@
|
|||
<button
|
||||
class="article-engagement-count bookmark-engage"
|
||||
data-reactable-id="<%= story.id %>"
|
||||
aria-label="Add to reading list"
|
||||
title="Add to reading list">
|
||||
<img src="<%= asset_path("bookmark.svg") %>" alt="bookmark" class="bm-initial" />
|
||||
<img src="<%= asset_path("emoji/emoji-one-bookmark.png") %>" alt="bookmark" class="bm-success" />
|
||||
aria-label="Save to reading list"
|
||||
title="Save to reading list">
|
||||
<span class="bm-success"><img src="<%= asset_path("readinglist-button.svg") %>" alt="bookmark" /> SAVED</span>
|
||||
<span class="bm-initial">SAVE</span>
|
||||
</button>
|
||||
</div>
|
||||
14
app/views/articles/_widget_list_item.html.erb
Normal file
14
app/views/articles/_widget_list_item.html.erb
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<div class="widget-link-list__item">
|
||||
<a href="<%= plucked_article[0] %>">
|
||||
<%= plucked_article[1] %>
|
||||
</a>
|
||||
<% if show_comment_count %>
|
||||
<div class="discuss-list-comment-count">
|
||||
<% if plucked_article[2] > 0 %>
|
||||
<img src="<%= asset_path("comments-bubble.svg") %>" alt="Comments" /> <%= plucked_article[2] %>
|
||||
<% else %>
|
||||
<span class="discuss-list-comment-count discuss-list-comment-count-brand-new">fresh</span>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
@ -231,14 +231,14 @@
|
|||
</div>
|
||||
<% if @featured_story.comments_count > 0 %>
|
||||
<div class="article-engagement-count comments-count featured-engagement-count">
|
||||
<a href="<%=@featured_story.path%>"><img src="<%= asset_path("chat.svg") %>" alt="chat" />
|
||||
<a href="<%=@featured_story.path%>"><img src="<%= asset_path("comments-bubble.svg") %>" alt="chat" />
|
||||
<span class="engagement-count-number"><%= @featured_story.comments_count %></span>
|
||||
</a>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if @featured_story.positive_reactions_count > 0 %>
|
||||
<div class="article-engagement-count reactions-count featured-engagement-count" data-reaction-count data-reactable-id="<%= @featured_story.id %>">
|
||||
<a href="<%=@featured_story.path%>"><img src="<%= asset_path("favorite-heart-outline-button.svg") %>" alt="heart" /><span id="engagement-count-number-<%= @featured_story.id %>" class="engagement-count-number">
|
||||
<a href="<%=@featured_story.path%>"><img src="<%= asset_path("reactions-stack.svg") %>" alt="heart" /><span id="engagement-count-number-<%= @featured_story.id %>" class="engagement-count-number">
|
||||
<%= @featured_story.positive_reactions_count %>
|
||||
</span>
|
||||
</a>
|
||||
|
|
@ -249,8 +249,8 @@
|
|||
data-reactable-id="<%= @featured_story.id %>"
|
||||
aria-label="Add to reading list"
|
||||
title="Add to reading list" >
|
||||
<img src="<%= asset_path("bookmark.svg") %>" alt="bookmark" class="bm-initial" />
|
||||
<img src="<%= asset_path("emoji/emoji-one-bookmark.png") %>" alt="bookmark" class="bm-success" />
|
||||
<span class="bm-success"><img src="<%= asset_path("readinglist-button.svg") %>" alt="bookmark" /> SAVED</span>
|
||||
<span class="bm-initial">SAVE</span>
|
||||
</button>
|
||||
</div>
|
||||
</a>
|
||||
|
|
|
|||
|
|
@ -1,71 +1,69 @@
|
|||
<% articles.each do |article| %>
|
||||
<% featured = article.featured ? "featured-bg": "" %>
|
||||
<% featured = article.approved ? "approved-bg": featured %>
|
||||
<div class="row main-group <%= featured %>" style="<%= "background:red" if (!article.published? && article.published_from_feed? && !article.user&.feed_admin_publish_permission?) %>">
|
||||
<% if article.published_from_feed? && !article.published? %>
|
||||
<p style="padding:5px;background:#f7ff1e;color:black;display:inline;font-weight:bold">
|
||||
RSS Import <%= article.created_at.strftime("%b %d, %Y") %>
|
||||
</p>
|
||||
<p style="font-size:0.8em;padding:5px;">
|
||||
Originally Published <%= article.published_at&.strftime("%b %d, %Y") %>
|
||||
</p>
|
||||
<% elsif article.crossposted_at? %>
|
||||
<p>
|
||||
Crossposted <%= article.crossposted_at.strftime("%b %d, %Y") %> & Published <%= article.published_at&.strftime("%b %d, %Y") %>
|
||||
</p>
|
||||
<% else %>
|
||||
<p>
|
||||
Published <%= article.published_at&.strftime("%b %d, %Y") %>
|
||||
</p>
|
||||
<% end %>
|
||||
<% if article.main_image.present? %>
|
||||
<div style="max-height:450px;overflow:hidden;">
|
||||
<img src="<%= cloud_cover_url(article.main_image) %>" style="width:100%;" alt="cover image"/><br/>
|
||||
</div>
|
||||
<% end %>
|
||||
<b><a href="<%= article.path %>" target="_blank"><%= article.title %></a></b> <a href="<%= article.path %>/edit" target="_blank" style="background:#00da8b;color:white;padding:1px 6px">EDIT</a>
|
||||
<% article.tag_list.each do |tag| %>
|
||||
<a href='/t/<%= tag %>'>#<%= tag %></a>
|
||||
<% end %>
|
||||
<a href="<%= article.user&.path %>">@<%= article.user&.username %></a> ❤️ <%= article.positive_reactions_count %> | 💬 <%= article.comments_count %> | ID: <%= article.id %>
|
||||
<br/><br/>
|
||||
<div class="inner-row">
|
||||
<form action="/internal/articles/<%= article.id %>" accept-charset="UTF-8" method="post">
|
||||
<input name="utf8" type="hidden" value="✓">
|
||||
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" />
|
||||
<input type="hidden" name="_method" value="patch" />
|
||||
Featured Number: <input name="article[featured_number]" value="<%= article.featured_number %>" id="featured_number_<%= article.id %>" style="max-width:140px"><button onclick="timeNow(<%= article.id %>);return false;">☝️</button><button onclick="sink(<%= article.id %>);return false;">👇 SPAM!</button>
|
||||
  Featured: <input name="article[featured]" type="checkbox" <%= "checked" if article.featured %>>
|
||||
  Approved: <input name="article[approved]" type="checkbox" <%= "checked" if article.approved %>>
|
||||
  Live Now: <input name="article[live_now]" type="checkbox" <%= "checked" if article.live_now %>>
|
||||
  Image BG color: <input name="article[main_image_background_hex_color]" value="<%= article.main_image_background_hex_color %>" id="featured_number_<%= article.id %>"><br/><br/>
|
||||
Social Image: <input name="article[social_image]" value="<%= article.social_image %>" id="featured_number_<%= article.id %>">
|
||||
    <button class="btn btn-primary">SUBMIT</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="inner-row" style="padding:10px;margin-top:20px;font-weight:800;">
|
||||
<%= form_tag "/internal/buffer_updates" do %>
|
||||
<input type="hidden" name="social_channel" value="twitter" />
|
||||
<input type="hidden" name="article_id" value="<%= article.id %>" />
|
||||
<p> Twitter </p>
|
||||
<textarea cols="37" rows="6" wrap="hard" name="tweet" maxlength="230" /><%= article.title %></textarea>
|
||||
<% if article.last_buffered %>
|
||||
<button class="btn btn-danger" style="font-size:1em;">🙈 TWEETED <%= time_ago_in_words(article.last_buffered) %> ago</button>
|
||||
<% else %>
|
||||
<button class="btn btn-info" style="font-size:1em;">😎 TWEET 🚀🚀🚀🚀🚀🚀</button>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%= form_tag "/internal/buffer_updates" do %>
|
||||
<input type="hidden" name="social_channel" value="facebook" />
|
||||
<input type="hidden" name="article_id" value="<%= article.id %>" />
|
||||
<p> Facebook & LinkedIn </p>
|
||||
<textarea cols="37" rows="6" wrap="hard" name="fb_post" required/></textarea>
|
||||
<% if article.facebook_last_buffered %>
|
||||
<button class="btn btn-danger" style="font-size:1em;">🙈 POSTED <%= time_ago_in_words(article.facebook_last_buffered) %> ago</button>
|
||||
<% else %>
|
||||
<button class="btn btn-info" style="font-size:1em;">😎 POST 🚀🚀🚀🚀🚀🚀</button>
|
||||
<% end %>
|
||||
<% featured = article.featured ? "featured-bg": "" %>
|
||||
<% featured = article.approved ? "approved-bg": featured %>
|
||||
<div class="row main-group <%= featured %>" style="<%= "background:red" if (!article.published? && article.published_from_feed? && !article.user&.feed_admin_publish_permission?) %>">
|
||||
<% if article.published_from_feed? && !article.published? %>
|
||||
<p style="padding:5px;background:#f7ff1e;color:black;display:inline;font-weight:bold">
|
||||
RSS Import <%= article.created_at.strftime("%b %d, %Y") %>
|
||||
</p>
|
||||
<p style="font-size:0.8em;padding:5px;">
|
||||
Originally Published <%= article.published_at&.strftime("%b %d, %Y") %>
|
||||
</p>
|
||||
<% elsif article.crossposted_at? %>
|
||||
<p>
|
||||
Crossposted <%= article.crossposted_at.strftime("%b %d, %Y") %> & Published <%= article.published_at&.strftime("%b %d, %Y") %>
|
||||
</p>
|
||||
<% else %>
|
||||
<p>
|
||||
Published <%= article.published_at&.strftime("%b %d, %Y") %>
|
||||
</p>
|
||||
<% end %>
|
||||
<% if article.main_image.present? %>
|
||||
<div style="max-height:450px;overflow:hidden;">
|
||||
<img src="<%= cloud_cover_url(article.main_image) %>" style="width:100%;" alt="cover image"/><br/>
|
||||
</div>
|
||||
<% end %>
|
||||
<b><a href="<%= article.path %>" target="_blank"><%= article.title %></a></b> <a href="<%= article.path %>/edit" target="_blank" style="background:#00da8b;color:white;padding:1px 6px">EDIT</a>
|
||||
<% article.tag_list.each do |tag| %>
|
||||
<a href='/t/<%= tag %>'>#<%= tag %></a>
|
||||
<% end %>
|
||||
<a href="<%= article.user&.path %>">@<%= article.user&.username %></a> ❤️ <%= article.positive_reactions_count %> | 💬 <%= article.comments_count %> | ID: <a href="/internal/articles/<%= article.id %>"><%= article.id %></a>
|
||||
<br/><br/>
|
||||
<div class="inner-row">
|
||||
<form action="/internal/articles/<%= article.id %>" accept-charset="UTF-8" method="post">
|
||||
<input name="utf8" type="hidden" value="✓">
|
||||
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" />
|
||||
<input type="hidden" name="_method" value="patch" />
|
||||
Featured Number: <input name="article[featured_number]" value="<%= article.featured_number %>" id="featured_number_<%= article.id %>" style="max-width:140px"><button onclick="timeNow(<%= article.id %>);return false;">☝️</button><button onclick="sink(<%= article.id %>);return false;">👇 SPAM!</button>
|
||||
  Featured: <input name="article[featured]" type="checkbox" <%= "checked" if article.featured %>>
|
||||
  Approved: <input name="article[approved]" type="checkbox" <%= "checked" if article.approved %>>
|
||||
  Live Now: <input name="article[live_now]" type="checkbox" <%= "checked" if article.live_now %>>
|
||||
  Image BG color: <input name="article[main_image_background_hex_color]" value="<%= article.main_image_background_hex_color %>" id="featured_number_<%= article.id %>"><br/><br/>
|
||||
Social Image: <input name="article[social_image]" value="<%= article.social_image %>" id="featured_number_<%= article.id %>">
|
||||
    <button class="btn btn-primary">SUBMIT</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="inner-row" style="padding:10px;margin-top:20px;font-weight:800;">
|
||||
<%= form_tag "/internal/buffer_updates" do %>
|
||||
<input type="hidden" name="social_channel" value="twitter" />
|
||||
<input type="hidden" name="article_id" value="<%= article.id %>" />
|
||||
<p> Twitter </p>
|
||||
<textarea cols="37" rows="6" wrap="hard" name="tweet" maxlength="230" /><%= article.title %></textarea>
|
||||
<% if article.last_buffered %>
|
||||
<button class="btn btn-danger" style="font-size:1em;">🙈 TWEETED <%= time_ago_in_words(article.last_buffered) %> ago</button>
|
||||
<% else %>
|
||||
<button class="btn btn-info" style="font-size:1em;">😎 TWEET 🚀🚀🚀🚀🚀🚀</button>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%= form_tag "/internal/buffer_updates" do %>
|
||||
<input type="hidden" name="social_channel" value="facebook" />
|
||||
<input type="hidden" name="article_id" value="<%= article.id %>" />
|
||||
<p> Facebook & LinkedIn </p>
|
||||
<textarea cols="37" rows="6" wrap="hard" name="fb_post" required/></textarea>
|
||||
<% if article.facebook_last_buffered %>
|
||||
<button class="btn btn-danger" style="font-size:1em;">🙈 POSTED <%= time_ago_in_words(article.facebook_last_buffered) %> ago</button>
|
||||
<% else %>
|
||||
<button class="btn btn-info" style="font-size:1em;">😎 POST 🚀🚀🚀🚀🚀🚀</button>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -37,7 +37,9 @@
|
|||
|
||||
<% if @featured_articles && @featured_articles.any? %>
|
||||
<h1>Manually Featured Articles</h1>
|
||||
<%= render "individual_article", articles: @featured_articles %>
|
||||
<% @featured_articles.each do |article| %>
|
||||
<%= render "individual_article", article: article %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
|
||||
|
|
@ -46,7 +48,9 @@
|
|||
<%= paginate @articles %>
|
||||
</div>
|
||||
|
||||
<%= render "individual_article", articles: @articles %>
|
||||
<% @articles.each do |article| %>
|
||||
<%= render "individual_article", article: article %>
|
||||
<% end %>
|
||||
|
||||
<div class="row" style="font-size:1.5em;border:0px">
|
||||
<%= paginate @articles %>
|
||||
|
|
|
|||
1
app/views/internal/articles/show.html.erb
Normal file
1
app/views/internal/articles/show.html.erb
Normal file
|
|
@ -0,0 +1 @@
|
|||
<%= render "individual_article", article: @article %>
|
||||
|
|
@ -1,15 +1,24 @@
|
|||
<h1>All Tags</h1>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jscolor/2.0.4/jscolor.min.js"></script>
|
||||
<style>
|
||||
textarea{
|
||||
height: 140px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<h1>Tags</h1>
|
||||
<h2>
|
||||
<% if params[:state] == "supported" %>
|
||||
<a href="/internal/tags">View All</a>
|
||||
<% else %>
|
||||
<a href="/internal/tags?state=supported">View Supported only</a>
|
||||
<% end %>
|
||||
|
||||
<a href="/internal/tags"
|
||||
style="<%= 'background: yellow' if params[:state].blank? %>">All</a> |
|
||||
<a href="/internal/tags?state=supported"
|
||||
style="<%= 'background: yellow' if params[:state] == "supported" %>">Supported</a> |
|
||||
<a href="/internal/tags?state=unsupported"
|
||||
style="<%= 'background: yellow' if params[:state] == "unsupported" %>">Unsupported</a> |
|
||||
</h2>
|
||||
<hr/><hr/>
|
||||
<% @tags.each do |tag| %>
|
||||
<div>
|
||||
<h2><%= tag.name %></h2>
|
||||
<h1><a href="/t/<%= tag.name %>" style="background:<%= tag.bg_color_hex %>;color:<%= tag.text_color_hex %>;">#<%= tag.name %></a></h1>
|
||||
<p>count: <%= tag.taggings_count %></p>
|
||||
<br/>
|
||||
<%= form_for [:internal, tag] do |f| %>
|
||||
|
|
@ -27,15 +36,21 @@
|
|||
<div>
|
||||
<div>
|
||||
<%= f.label :rules_markdown %>
|
||||
<br/>
|
||||
<%= f.text_area :rules_markdown %>
|
||||
<div>
|
||||
<div>
|
||||
<%= f.label :wiki_body_markdown %>
|
||||
<br/>
|
||||
<%= f.text_area :wiki_body_markdown %>
|
||||
<div>
|
||||
</div>
|
||||
<%= f.label :bg_color_hex %>
|
||||
<%= f.text_field :bg_color_hex %>
|
||||
<%= f.text_field :bg_color_hex, class: "jscolor {hash:true}", required: true %>
|
||||
<div>
|
||||
</div>
|
||||
<%= f.label :text_color_hex %>
|
||||
<%= f.text_field :text_color_hex %>
|
||||
<%= f.text_field :text_color_hex, class: "jscolor {hash:true}", required: true %>
|
||||
<div>
|
||||
</div>
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
<% Rails.application.config.assets.compile = true %>
|
||||
<%= Rails.application.assets['scaffolds.css'].to_s.html_safe %>
|
||||
<%= Rails.application.assets['articles.css'].to_s.html_safe %>
|
||||
<%= Rails.application.assets['comments.css'].to_s.html_safe %>
|
||||
<%= Rails.application.assets['notifications.css'].to_s.html_safe %>
|
||||
<%= Rails.application.assets['top-bar.css'].to_s.html_safe %>
|
||||
<%= Rails.application.assets['user-profile-header.css'].to_s.html_safe %>
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<div class="navbar-menu-wrapper" id="navbar-menu-wrapper">
|
||||
<button class="navigation-butt" id="navigation-butt" aria-label="Navigation">
|
||||
<% if user_signed_in? %>
|
||||
<img class="nav-profile-image" id="nav-profile-image"/>
|
||||
<div class="nav-profile-image-wrapper"><img class="nav-profile-image" id="nav-profile-image"/>
|
||||
<% else %>
|
||||
<%= inline_svg("menu.svg", class: "bars", size: '20% * 20%') %>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@
|
|||
<%= image_tag "favorite-heart-outline-button.svg" %>
|
||||
<img class="reacted-emoji" src="<%= asset_path("emoji/emoji-one-heart.png") %>"/>
|
||||
</button>
|
||||
<button class="reaction-button <%= Reaction.cached_any_reactions_for?(activity['object'], current_user, "readinglist") ? "reacted" : "" %>" data-reactable-id="<%=activity['object'].id%>" data-category="readinglist" data-reactable-type="Article">
|
||||
<%= image_tag "bookmark.svg" %>
|
||||
<img class="reacted-emoji" src="<%= asset_path("emoji/emoji-one-bookmark.png") %>"/>
|
||||
<button class="reaction-button readinglist-button <%= Reaction.cached_any_reactions_for?(activity['object'], current_user, "readinglist") ? "reacted" : "" %>" data-reactable-id="<%=activity['object'].id%>" data-category="readinglist" data-reactable-type="Article">
|
||||
<span class="reaction-button-text">SAVE</span>
|
||||
<img class="reacted-emoji reaction-button-reacted-emoji" src="<%= asset_path("readinglist-button.svg") %>"/>
|
||||
</button>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -19,27 +19,27 @@
|
|||
|
||||
<div class="user-profile-header tag-header readinglist-header">
|
||||
<div class="tag-or-query-header-container">
|
||||
<h1 class="notifications-header"><img src="<%=asset_path("emoji/emoji-one-bookmark.png")%>" /> My Reading List</h1>
|
||||
<h1 class="notifications-header"><img src="<%=asset_path("readinglist-button.svg")%>" /> My Reading List</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="home" id="notifications-container">
|
||||
<div class="home">
|
||||
<div class="side-bar" style="margin-top:12px" id="sidebar">
|
||||
<div class="fixed-sidebar">
|
||||
<div class="sidebar-nav">
|
||||
<div class="widget sidebar-nav-block">
|
||||
<div class="sidebar-nav-element sidebar-nav-readinglist">
|
||||
<a class="sidebar-nav-link" href="/readinglist">
|
||||
<img src="<%=asset_path("emoji/emoji-one-bookmark.png")%>" /> MY READING LIST
|
||||
<img src="<%=asset_path("readinglist-button.svg")%>" /> MY READING LIST
|
||||
<span id="reading-list-count"></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="widget" id="tag-filter-widget">
|
||||
<header>
|
||||
<FILTER BY TAG>
|
||||
</header>
|
||||
<button class="query-filter-button query-type-filter-button" data-type="posts">Posts</button>
|
||||
<button class="query-filter-button query-type-filter-button" data-type="comments">Comments</button>
|
||||
<hr/>
|
||||
<div class="widget-body body-scrollable" id="tag-filters" style="margin-bottom:16px;">
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -47,7 +47,9 @@
|
|||
</div>
|
||||
<div class="articles-list" id="articles-list">
|
||||
<% if user_signed_in? %>
|
||||
<div class="substories" id="substories">
|
||||
<div class="comments-container" id="comments-container">
|
||||
<div class="substories" id="substories" data-tabs="{}">
|
||||
</div>
|
||||
</div>
|
||||
<% else %>
|
||||
<script>
|
||||
|
|
|
|||
|
|
@ -4,9 +4,6 @@ Rails.application.configure do
|
|||
config.flipflop.dashboard_access_filter = nil
|
||||
# Settings specified here will take precedence over those in config/application.rb.
|
||||
|
||||
# Make sure Rack MiniProfiler starts hidden
|
||||
Rack::MiniProfiler.config.start_hidden = true
|
||||
|
||||
# In the development environment your application's code is reloaded on
|
||||
# every request. This slows down response time but is perfect for development
|
||||
# since you don't have to restart the web server when you make code changes.
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ Rails.application.routes.draw do
|
|||
|
||||
namespace :internal do
|
||||
resources :comments
|
||||
resources :articles, except: [:show]
|
||||
resources :articles
|
||||
resources :tags
|
||||
resources :welcome, only: [:index, :create]
|
||||
resources :broadcasts
|
||||
|
|
@ -207,6 +207,7 @@ Rails.application.routes.draw do
|
|||
get "/:username/comment/:id_code/edit" => 'comments#edit'
|
||||
get "/:username/comment/:id_code/delete_confirm" => 'comments#delete_confirm'
|
||||
|
||||
get "/:username/:slug/:view" => 'stories#show', constraints: { view: /moderate/}
|
||||
get "/:username/:slug/edit" => 'articles#edit'
|
||||
get "/:username/:slug/delete_confirm" => 'articles#delete_confirm'
|
||||
get "/:username/:view" => 'stories#index', constraints: { view: /comments|moderate|admin/}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
class AddLastCommentAtToArticles < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
add_column :articles, :last_comment_at, :datetime, default: "2017-01-01 05:00:00"
|
||||
end
|
||||
end
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20180213165354) do
|
||||
ActiveRecord::Schema.define(version: 20180304151124) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
|
@ -105,6 +105,7 @@ ActiveRecord::Schema.define(version: 20180213165354) do
|
|||
t.string "video_code"
|
||||
t.string "video_source_url"
|
||||
t.string "video_thumbnail_url"
|
||||
t.datetime "last_comment_at", default: "2017-01-01 05:00:00"
|
||||
t.index ["featured_number"], name: "index_articles_on_featured_number"
|
||||
t.index ["hotness_score"], name: "index_articles_on_hotness_score"
|
||||
t.index ["published_at"], name: "index_articles_on_published_at"
|
||||
|
|
|
|||
|
|
@ -149,6 +149,10 @@ RSpec.describe Comment, type: :model do
|
|||
expect(child_comment.parent_or_root_article).to eq(comment)
|
||||
end
|
||||
|
||||
it "properly indexes" do
|
||||
comment.index!
|
||||
end
|
||||
|
||||
describe "#parent_user" do
|
||||
it "returns the root article's user if no parent comment" do
|
||||
expect(comment.parent_user).to eq(user)
|
||||
|
|
@ -169,6 +173,7 @@ RSpec.describe Comment, type: :model do
|
|||
expect(comment.processed_html).to include CGI.unescapeHTML(text)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
describe "#custom_css" do
|
||||
it "returns nothing when no ltag was used" do
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue