placeholder utill we loaded up

This commit is contained in:
2025-08-24 22:43:24 +07:00
parent db11fff026
commit b4a66ee5c0
2 changed files with 67 additions and 34 deletions
+53 -32
View File
@@ -2,40 +2,61 @@ import React from 'react';
import ReactDOM from 'react-dom/client';
import Reactions from './components/Reactions';
console.log('Redmine Reactions Extension Loaded!');
// --- Подготовка ---
// Создаем элемент <style>, но пока не вставляем его
const styleSheet = document.createElement("style");
styleSheet.innerText = `
@keyframes reactions-pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
`;
// Флаг, чтобы убедиться, что стили вставляются только один раз
let stylesInjected = false;
// Функция для извлечения ID задачи из URL
function getIssueId(): number | null {
const match = window.location.pathname.match(/\/issues\/(\d+)/);
return match && match[1] ? parseInt(match[1], 10) : null;
function processCommentContainer(container: HTMLElement) {
if (container.dataset.reactionsInitialized) return;
container.dataset.reactionsInitialized = 'true';
const issueIdMatch = window.location.pathname.match(/\/issues\/(\d+)/);
if (!issueIdMatch) return;
const issueId = parseInt(issueIdMatch[1], 10);
const noteElement = container.querySelector<HTMLElement>('div[id^="note-"]');
if (!noteElement) return;
const commentId = noteElement.id;
const reactionRootEl = document.createElement('div');
reactionRootEl.style.minHeight = '36px'; // Резервируем место
container.appendChild(reactionRootEl);
const root = ReactDOM.createRoot(reactionRootEl);
root.render(
<React.StrictMode>
<Reactions issueId={issueId} commentId={commentId} />
</React.StrictMode>
);
}
// Находим все блоки с комментариями на странице
const commentContainers = document.querySelectorAll('div.journal.has-notes');
const observer = new MutationObserver((mutations) => {
if (!stylesInjected && document.head) {
document.head.appendChild(styleSheet);
stylesInjected = true;
}
const issueId = getIssueId();
for (const mutation of mutations) {
for (const node of mutation.addedNodes) {
if (node instanceof HTMLElement) {
if (node.matches('div.journal.has-notes')) {
processCommentContainer(node);
}
node.querySelectorAll<HTMLElement>('div.journal.has-notes').forEach(processCommentContainer);
}
}
}
});
if (issueId) {
commentContainers.forEach(container => {
// Находим вложенный div с ID комментария
const noteElement = container.querySelector<HTMLDivElement>('div[id^="note-"]');
if (!noteElement) return;
const commentId = noteElement.id;
// Создаем div, в который будем рендерить наш React-компонент
const reactionRootEl = document.createElement('div');
reactionRootEl.className = 'reactions-app-root';
// Вставляем наш div в конец контейнера, как вы и определили
container.appendChild(reactionRootEl);
// Создаем React-root и рендерим компонент
const root = ReactDOM.createRoot(reactionRootEl);
root.render(
<React.StrictMode>
<Reactions issueId={issueId} commentId={commentId} />
</React.StrictMode>
);
});
}
observer.observe(document, {
childList: true,
subtree: true,
});