mirror of https://github.com/go-gitea/gitea
Backport #30453 by @silverwind Enable `no-sizzle` lint rule, there was only one use in `initCompReactionSelector` which I have rewritten as follows: - Remove all jQuery except the necessary fomantic dropdown init - Remove the recursion, instead bind event listeners to common parent container nodes Did various tests, works with our without attachments, in diff view and in diff comments inside comment list. Additionally the style of reactions now matches between code comments and issue comments: <img width="275" alt="Screenshot 2024-04-13 at 14 58 10" src="https://github.com/go-gitea/gitea/assets/115237/9d08f188-8661-4dd9-bff4-cad6d6d09cab"> Co-authored-by: silverwind <me@silverwind.io> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>pull/30469/head^2
parent
dd12861011
commit
0352b99221
@ -0,0 +1,70 @@ |
||||
.bottom-reactions { |
||||
display: flex; |
||||
gap: 6px; |
||||
margin: 0 1em 1em; |
||||
} |
||||
|
||||
.timeline-item .conversation-holder .bottom-reactions { |
||||
margin: 1em 0 0 36px; |
||||
padding-bottom: 8px; |
||||
} |
||||
|
||||
.bottom-reactions .ui.label { |
||||
padding: 5px 8px; |
||||
font-weight: var(--font-weight-normal); |
||||
} |
||||
|
||||
.bottom-reactions .ui.label.primary { |
||||
background-color: var(--color-reaction-active-bg) !important; |
||||
} |
||||
|
||||
.bottom-reactions .ui.label:hover { |
||||
background-color: var(--color-reaction-hover-bg) !important; |
||||
} |
||||
|
||||
.bottom-reactions .ui.label.disabled { |
||||
cursor: default; |
||||
opacity: 1; |
||||
} |
||||
|
||||
.bottom-reactions .ui.label .reaction { |
||||
font-size: 16px; |
||||
display: flex; |
||||
} |
||||
|
||||
.bottom-reactions .ui.label .reaction img { |
||||
height: 16px; |
||||
aspect-ratio: 1; |
||||
} |
||||
|
||||
.bottom-reactions .reaction-count { |
||||
margin-left: 4px; |
||||
} |
||||
|
||||
.ui.dropdown.select-reaction .menu { |
||||
min-width: 170px; /* item-outer-width * 4 */ |
||||
} |
||||
|
||||
.ui.dropdown.select-reaction .menu > .item { |
||||
float: left; |
||||
margin: 4px; |
||||
font-size: 20px; |
||||
width: 34px; |
||||
height: 34px; |
||||
border-radius: var(--border-radius); |
||||
display: flex; |
||||
align-items: center; |
||||
justify-content: center; |
||||
} |
||||
|
||||
.bottom-reactions .select-reaction { |
||||
padding: 0 10px; |
||||
} |
||||
|
||||
.bottom-reactions .select-reaction:not(.active) { |
||||
visibility: hidden; |
||||
} |
||||
|
||||
.bottom-reactions:hover .select-reaction { |
||||
visibility: visible; |
||||
} |
@ -1,38 +1,36 @@ |
||||
import $ from 'jquery'; |
||||
import {POST} from '../../modules/fetch.js'; |
||||
|
||||
export function initCompReactionSelector($parent) { |
||||
$parent.find(`.select-reaction .item.reaction, .comment-reaction-button`).on('click', async function (e) { |
||||
e.preventDefault(); |
||||
export function initCompReactionSelector() { |
||||
for (const container of document.querySelectorAll('.issue-content, .diff-file-body')) { |
||||
container.addEventListener('click', async (e) => { |
||||
// there are 2 places for the "reaction" buttons, one is the top-right reaction menu, one is the bottom of the comment
|
||||
const target = e.target.closest('.comment-reaction-button'); |
||||
if (!target) return; |
||||
e.preventDefault(); |
||||
|
||||
if (this.classList.contains('disabled')) return; |
||||
if (target.classList.contains('disabled')) return; |
||||
|
||||
const actionUrl = this.closest('[data-action-url]')?.getAttribute('data-action-url'); |
||||
const reactionContent = this.getAttribute('data-reaction-content'); |
||||
const hasReacted = this.closest('.ui.segment.reactions')?.querySelector(`a[data-reaction-content="${reactionContent}"]`)?.getAttribute('data-has-reacted') === 'true'; |
||||
const actionUrl = target.closest('[data-action-url]').getAttribute('data-action-url'); |
||||
const reactionContent = target.getAttribute('data-reaction-content'); |
||||
|
||||
const res = await POST(`${actionUrl}/${hasReacted ? 'unreact' : 'react'}`, { |
||||
data: new URLSearchParams({content: reactionContent}), |
||||
}); |
||||
const commentContainer = target.closest('.comment-container'); |
||||
|
||||
const data = await res.json(); |
||||
if (data && (data.html || data.empty)) { |
||||
const $content = $(this).closest('.content'); |
||||
let $react = $content.find('.segment.reactions'); |
||||
if ((!data.empty || data.html === '') && $react.length > 0) { |
||||
$react.remove(); |
||||
} |
||||
if (!data.empty) { |
||||
const $attachments = $content.find('.segment.bottom:first'); |
||||
$react = $(data.html); |
||||
if ($attachments.length > 0) { |
||||
$react.insertBefore($attachments); |
||||
} else { |
||||
$react.appendTo($content); |
||||
} |
||||
$react.find('.dropdown').dropdown(); |
||||
initCompReactionSelector($react); |
||||
const bottomReactions = commentContainer.querySelector('.bottom-reactions'); // may not exist if there is no reaction
|
||||
const bottomReactionBtn = bottomReactions?.querySelector(`a[data-reaction-content="${CSS.escape(reactionContent)}"]`); |
||||
const hasReacted = bottomReactionBtn?.getAttribute('data-has-reacted') === 'true'; |
||||
|
||||
const res = await POST(`${actionUrl}/${hasReacted ? 'unreact' : 'react'}`, { |
||||
data: new URLSearchParams({content: reactionContent}), |
||||
}); |
||||
|
||||
const data = await res.json(); |
||||
bottomReactions?.remove(); |
||||
if (data.html) { |
||||
commentContainer.insertAdjacentHTML('beforeend', data.html); |
||||
const bottomReactionsDropdowns = commentContainer.querySelectorAll('.bottom-reactions .dropdown.select-reaction'); |
||||
$(bottomReactionsDropdowns).dropdown(); // re-init the dropdown
|
||||
} |
||||
} |
||||
}); |
||||
}); |
||||
} |
||||
} |
||||
|
Loading…
Reference in new issue