Highlight comment icon

image
Dear Team,

Is there any way to highlight this comment icon when there is a comment ??

Thanks in advance

i did this using client script. sharing it here for your reference.

OPTION 1:
// Client Script (Doctype: Task, Script Type: List)
frappe.listview_settings[‘Task’] = {
onload(listview) {
// Inject CSS once
if (!document.getElementById(‘task-comment-style’)) {
const style = document.createElement(‘style’);
style.id = ‘task-comment-style’;
style.textContent = `
.highlight-comment-count {
background-color: #ff4d4d !important;
color: white !important;
border-radius: 50%;
padding: 2px 6px;
font-weight: 700;
display: inline-block;
min-width: 18px;
text-align: center;
line-height: 1;
box-sizing: border-box;
animation: pulseBadge 1.8s infinite;
}

            @keyframes pulseBadge {
                0%   { box-shadow: 0 0 0 0 rgba(255, 77, 77, 0.7); }
                70%  { box-shadow: 0 0 0 10px rgba(255, 77, 77, 0); }
                100% { box-shadow: 0 0 0 0 rgba(255, 77, 77, 0); }
            }
        `;
        document.head.appendChild(style);
    }

    // Highlight logic
    function highlightCounts() {
        const selectors = [
            '.list-row .comment-count',
            '.list-row .comments',
            '.list-row .list-row-comments'
        ];

        selectors.forEach(sel => {
            document.querySelectorAll(sel).forEach(el => {
                if (el.dataset.highlighted === '1') return;

                const text = el.textContent.trim();
                const n = parseInt(text.replace(/\D/g, '') || '0', 10);

                if (n > 0) {
                    el.classList.add('highlight-comment-count');
                } else {
                    el.classList.remove('highlight-comment-count');
                }

                el.dataset.highlighted = '1';
            });
        });
    }

    // Run immediately
    setTimeout(highlightCounts, 200);

    // Observe DOM changes (refresh / pagination)
    const target = listview.page?.wrapper[0] || document.querySelector('.layout-main-section') || document.body;
    const observer = new MutationObserver(highlightCounts);
    observer.observe(target, { childList: true, subtree: true });
}
};

OPTION 2

// Client Script (Doctype: Task, Script Type: List)
frappe.listview_settings[‘Task’] = {
onload(listview) {
// inject CSS once
if (!document.getElementById(‘task-comment-style’)) {
const style = document.createElement(‘style’);
style.id = ‘task-comment-style’;
style.textContent = .highlight-comment-count { background-color: #ff4d4d !important; color: white !important; border-radius: 50%; padding: 2px 6px; font-weight: 700; display: inline-block; min-width: 18px; text-align: center; line-height: 1; box-sizing: border-box; } /* slightly increased size so it's easy to see */ .highlight-comment-count.large { min-width: 20px; padding: 3px 7px; } ;
document.head.appendChild(style);
console.log(‘[Task List] Injected comment highlight CSS’);
}

    // function to find comment-count elements and apply class
    function highlightCounts() {
        // Try several selectors - Frappe versions vary in markup
        const selectors = [
            '.list-row .comment-count',              // common
            '.list-row .comments',                   // some versions
            '.list-row .list-row-comments',          // another variant
            '.list-row .indicator .comment-count'    // fallback
        ];

        let matched = 0;

        selectors.forEach(sel => {
            document.querySelectorAll(sel).forEach(el => {
                // if element already processed skip
                if (el.dataset.highlighted === '1') {
                    matched++;
                    return;
                }

                // try to parse numeric count
                const text = el.textContent.trim();
                const n = parseInt(text.replace(/\D/g, '') || '0', 10);

                if (n > 0) {
                    el.classList.add('highlight-comment-count', 'large');
                } else {
                    el.classList.remove('highlight-comment-count', 'large');
                }

                // mark processed
                el.dataset.highlighted = '1';
                matched++;
            });
        });

        // debug log (comment out later)
        console.log(`[Task List] highlightCounts run. matched elements: ${matched}`);
    }

    // run immediately (for initial load)
    setTimeout(highlightCounts, 200); // small delay to allow initial render

    // call highlight after each refresh if listview exposes events
    try {
        if (listview && typeof listview.on === 'function') {
            listview.on('refresh', highlightCounts);
            console.log('[Task List] Registered listview.on("refresh") highlightCounts');
        }
    } catch (e) {
        console.warn('[Task List] Error registering listview.on("refresh")', e);
    }

    // Setup a MutationObserver to handle re-renders (pagination, filter change, etc)
    let observerTarget = listview.page ? listview.page.wrapper[0] : document.querySelector('.layout-main-section');
    if (!observerTarget) observerTarget = document.body;

    const mo = new MutationObserver((mutations) => {
        // run after DOM changes
        highlightCounts();
    });

    mo.observe(observerTarget, { childList: true, subtree: true });
    console.log('[Task List] MutationObserver started for comment highlight');
}

};