docbrown/app/assets/javascripts/initializers/initializeBaseUserData.js
rhymes 99ddd31058
Pin posts to feed (#13807)
* Add SiteConfig.feed_pinned_article and validation

* Display pinned article at the top of feed

* Add (basic) functionality to pin/unpin post

* Admins can pin other users posts as well

* Hide the button if looking at the non pinned post

* Add pinned/unpinned snackbar message

* Rename SiteConfig usage to Settings::General

* Add pinned article to the Admin articles index

* Show the pin post button when there's no pinned article

* Move pinning to a separate controller

* Fix SiteConfig reference

* Hide PinController actions to unauthorized users

* PinnedArticlesController#show action and refactor some of the code

* Add Modal interaction

* Fix modal-pinned checkbox interaction

* Fixed pin/unpin post

* Add ArticleDecorator#pinned? specs

* Add PinnedArticlePolicy and PinnedArticlesController specs

* Add ability to actually pin an article from the admin after submit

* Add partial Cypress pin/unpin spec

* Fix pinned article and add basic Cypress interaction tests

* Add Crayons styling to modal

* Only render the pinned article on the default Feed page

* Use persisted?

* Add some comments

* Update app/javascript/articles/Article.jsx

Co-authored-by: Suzanne Aitchison <suzanne@forem.com>

* Update app/javascript/packs/homePageFeed.jsx

Co-authored-by: Suzanne Aitchison <suzanne@forem.com>

* Fix Cypress tests

* Update app/javascript/admin/controllers/article_controller.js

Co-authored-by: Ridhwana <Ridhwana.Khan16@gmail.com>

* Fix pinning in article show page

* Used PinnedArticle domain model

* Fix spec

* Update cypress/integration/adminFlows/articles/pinArticle.spec.js

Co-authored-by: Suzanne Aitchison <suzanne@forem.com>

* Update cypress/integration/adminFlows/articles/pinArticle.spec.js

Co-authored-by: Suzanne Aitchison <suzanne@forem.com>

* Update cypress/integration/adminFlows/articles/pinArticle.spec.js

Co-authored-by: Suzanne Aitchison <suzanne@forem.com>

* Update cypress/integration/adminFlows/articles/pinArticle.spec.js

Co-authored-by: Suzanne Aitchison <suzanne@forem.com>

* Update cypress/integration/adminFlows/articles/pinArticle.spec.js

Co-authored-by: Suzanne Aitchison <suzanne@forem.com>

* Update cypress/integration/articleFlows/pinArticle.spec.js

Co-authored-by: Suzanne Aitchison <suzanne@forem.com>

* Update cypress/integration/articleFlows/pinArticle.spec.js

Co-authored-by: Suzanne Aitchison <suzanne@forem.com>

* Update app/views/admin/articles/index.html.erb

Co-authored-by: Suzanne Aitchison <suzanne@forem.com>

* Fix merge woes

* Add missing article pin post flows

* Add missing admin article flows

* Add Unpin to Admin as well

* Add Audit::Log entries for pin/unpin actions

* Update app/controllers/stories/feeds_controller.rb

Co-authored-by: Michael Kohl <citizen428@dev.to>

* Do not rate limit in E2E tests

* Use .find instead of .filter

* Rename ArticleIdValidator to ExistingArticleIdValidator

* Treat draft and deleted articles the same

* Make sure posts can be pinned after the pinned article is unpublished or deleted

* Use .get directly

* Fix spec and fix PinnedArticlesController#show

* Strengthen pinArticle Cypress tests

* Add Cypress test heading guard

* Add another Cypress test heading guard

* Remove duplicate validator

* Try using the Tools: header instead of the article title

Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
Co-authored-by: Ridhwana <Ridhwana.Khan16@gmail.com>
Co-authored-by: Michael Kohl <citizen428@dev.to>
2021-06-04 10:54:53 +02:00

127 lines
4.3 KiB
JavaScript

/* global filterXSS */
function initializeProfileImage(user) {
if (!document.getElementById('comment-primary-user-profile--avatar')) return;
document.getElementById('comment-primary-user-profile--avatar').src =
user.profile_image_90;
}
function addRelevantButtonsToArticle(user) {
var articleContainer = document.getElementById('article-show-container');
if (articleContainer) {
let actions = [];
const published = JSON.parse(articleContainer.dataset.published);
if (parseInt(articleContainer.dataset.authorId, 10) === user.id) {
actions.push(
`<a class="crayons-btn crayons-btn--s crayons-btn--secondary" href="${articleContainer.dataset.path}/edit" rel="nofollow">Edit</a>`,
);
let clickToEditButton = document.getElementById('author-click-to-edit');
if (clickToEditButton) {
clickToEditButton.style.display = 'inline-block';
}
if (published === true) {
actions.push(
`<a class="crayons-btn crayons-btn--s crayons-btn--secondary ml-1" href="${articleContainer.dataset.path}/manage" rel="nofollow">Manage</a>`,
);
}
actions.push(
`<a class="crayons-btn crayons-btn--s crayons-btn--secondary ml-1" href="${articleContainer.dataset.path}/stats" rel="nofollow">Stats</a>`,
);
}
const { articleId, pinnedArticleId } = articleContainer.dataset;
// we hide the buttons for draft articles, for non admins and
// if there's already a pinned post different from the current one
if (
published &&
user.admin &&
(articleId === pinnedArticleId || !pinnedArticleId)
) {
const isArticlePinned = articleContainer.hasAttribute('data-pinned');
const { pinPath } = articleContainer.dataset;
actions.push(
`<button
id="js-${isArticlePinned ? 'unpin' : 'pin'}-article"
class="crayons-btn crayons-btn--s crayons-btn--secondary ml-1"
data-path="${pinPath}"
data-article-id="${articleId}">${
isArticlePinned ? 'Unpin' : 'Pin'
} Post</button>`,
);
}
document.getElementById('action-space').innerHTML = actions.join('');
}
}
function addRelevantButtonsToComments(user) {
if (document.getElementById('comments-container')) {
// buttons are actually <span>'s
var settingsButts = document.getElementsByClassName('comment-actions');
for (let i = 0; i < settingsButts.length; i += 1) {
let butt = settingsButts[i];
const { action, commentableUserId, userId } = butt.dataset;
if (parseInt(userId, 10) === user.id && action === 'settings-button') {
butt.innerHTML =
'<a href="' +
butt.dataset.path +
'" rel="nofollow" class="crayons-link crayons-link--block" data-no-instant>Settings</a>';
butt.classList.remove('hidden');
butt.classList.add('block');
}
if (
action === 'hide-button' &&
parseInt(commentableUserId, 10) === user.id
) {
butt.classList.remove('hidden');
butt.classList.add('block');
}
}
if (user.trusted) {
var modButts = document.getElementsByClassName('mod-actions');
for (let i = 0; i < modButts.length; i += 1) {
let butt = modButts[i];
if (butt.classList.contains('mod-actions-comment-button')) {
butt.innerHTML =
'<a href="' +
butt.dataset.path +
'" rel="nofollow" class="crayons-link crayons-link--block">Moderate</a>';
}
butt.className = 'mod-actions';
butt.classList.remove('hidden');
butt.classList.add('block');
}
}
}
}
function setCurrentUserToNavBar(user) {
const userNavLink = document.getElementById('first-nav-link');
userNavLink.href = `/${user.username}`;
userNavLink.getElementsByTagName('span')[0].textContent = user.name;
userNavLink.getElementsByTagName(
'small',
)[0].textContent = `@${user.username}`;
document.getElementById('nav-profile-image').src = user.profile_image_90;
if (user.admin) {
document
.getElementsByClassName('js-header-menu-admin-link')[0]
.classList.remove('hidden');
}
}
function initializeBaseUserData() {
const user = userData();
setCurrentUserToNavBar(user);
initializeProfileImage(user);
addRelevantButtonsToArticle(user);
addRelevantButtonsToComments(user);
}