رموز تعبيرية في قسم مخصص

أنا أستخدم الرموز التعبيرية في قسم الفئات في الشريط الجانبي، ولكن لدي أيضًا قسم مخصص عام. أردت أن أحصل على نفس الأيقونات الملونة في هذا القسم حتى لا يبدو “باهتًا” مقارنة بقسم الفئات.

هل هذا ممكن؟

إعجابَين (2)

بمساعدة كل من ChatGPT و Claude، تمكنت من جعله يعمل وقابل للتخصيص للغاية:

إذا كنت ترغب في القيام بذلك، قم بإنشاء مكون جديد وأضف هذا إلى علامة التبويب CSS:

.sidebar-section-link-prefix .emoji.prefix-emoji {
  width: 1rem !important;
  height: 1rem !important;
}

في حالتي الخاصة، يعمل 1rem بشكل رائع. اضبطه ليناسب منتدى/مجتمعك

ثم في علامة التبويب JS:

import { apiInitializer } from "discourse/lib/api";
import { emojiUrlFor } from "discourse/lib/text";

export default apiInitializer("0.11.1", (api) => {
  // Map section names to IDs
  const sectionIds = {
    "community": 1,
    "tiago": 2,
    "personal-section": 3,
    // Add more sections here
  };
  
  // Map of [sectionId, itemName] to emoji names
  const iconReplacements = {
    // Community section (ID: 1)
    "1,admin": "wrench",
    "1,review": "triangular_flag_on_post",
    "1,everything": "books",
    "1,my-posts": "writing_hand",
    "1,my-messages": "envelope_with_arrow",
    
    // Tiago section (ID: 2)
    "2,Journal": "notebook_with_decorative_cover",
    "2,Music": "musical_note",
    "2,About": "bust_in_silhouette",
    
    // Personal section (ID: 3)
    "3,Backups": "floppy_disk",
    "3,Scheduled": "clock3",
    "3,Staff": "lock",
    "3,Components": "electric_plug",
  };

  function replaceIcons() {
    Object.entries(sectionIds).forEach(([sectionName, sectionId]) => {
      Object.entries(iconReplacements).forEach(([key, emojiName]) => {
        const [keyId, itemName] = key.split(',');
        
        // Only process if this replacement is for the current section
        if (parseInt(keyId) === sectionId) {
          const url = emojiUrlFor(emojiName);
          
          // Try multiple selectors to catch both hamburger menu and fixed sidebar
          const selectors = [
            // Fixed sidebar selector
            `div[data-section-name="${sectionName}"] li[data-list-item-name="${itemName}"] .sidebar-section-link-prefix.icon`,
            // Hamburger menu selector (more specific)
            `.menu-panel div[data-section-name="${sectionName}"] li[data-list-item-name="${itemName}"] .sidebar-section-link-prefix.icon`,
            // Generic fallback
            `[data-section-name="${sectionName}"] [data-list-item-name="${itemName}"] .sidebar-section-link-prefix.icon`
          ];
          
          for (const selector of selectors) {
            const prefix = document.querySelector(selector);
            
            if (prefix && url) {
              // Check if it's already replaced to avoid unnecessary DOM manipulation
              if (!prefix.querySelector('.prefix-emoji')) {
                prefix.innerHTML = `
                  <img src="${url}"
                       title="${emojiName}"
                       alt="${emojiName}"
                       class="emoji prefix-emoji">
                `;
              }
              break; // Exit loop once we find and replace the icon
            }
          }
        }
      });
    });
  }

  // Run on page change
  api.onPageChange(replaceIcons);
  
  // Also run with delay to catch dynamically loaded content
  api.onPageChange(() => {
    setTimeout(replaceIcons, 100);
    setTimeout(replaceIcons, 500);
  });

  // Enhanced MutationObserver to catch sidebar changes
  const observer = new MutationObserver((mutations) => {
    let shouldReplace = false;
    
    mutations.forEach((mutation) => {
      // Watch for added nodes (original functionality)
      mutation.addedNodes.forEach((node) => {
        if (node.nodeType === Node.ELEMENT_NODE) {
          if (node.classList?.contains('menu-panel') || 
              node.querySelector?.('.sidebar-sections') ||
              node.classList?.contains('sidebar-sections') ||
              node.querySelector?.('[data-section-name]')) {
            shouldReplace = true;
          }
        }
      });
      
      // Watch for attribute changes on sidebar sections (collapse/expand)
      if (mutation.type === 'attributes' && mutation.target.nodeType === Node.ELEMENT_NODE) {
        const target = mutation.target;
        if (target.matches('[data-section-name]') || 
            target.closest('[data-section-name]') ||
            target.matches('.sidebar-section') ||
            target.closest('.sidebar-section')) {
          shouldReplace = true;
        }
      }
      
      // Watch for childList changes in sidebar sections
      if (mutation.type === 'childList' && mutation.target.nodeType === Node.ELEMENT_NODE) {
        const target = mutation.target;
        if (target.matches('[data-section-name]') || 
            target.closest('[data-section-name]') ||
            target.querySelector('[data-section-name]')) {
          shouldReplace = true;
        }
      }
    });
    
    if (shouldReplace) {
      setTimeout(replaceIcons, 50);
    }
  });

  // Start observing with enhanced options
  observer.observe(document.body, {
    childList: true,
    subtree: true,
    attributes: true, // Watch for attribute changes
    attributeFilter: ['class', 'style', 'aria-expanded'], // Common attributes that change on collapse/expand
  });

  // Additional event listeners for common sidebar interactions
  document.addEventListener('click', (event) => {
    // Check if click was on a sidebar section header or toggle button
    if (event.target.closest('.sidebar-section-header') ||
        event.target.closest('[data-section-name]') ||
        event.target.matches('.sidebar-section-toggle')) {
      setTimeout(replaceIcons, 100);
    }
  });
});

لقد جعلتها بحيث يمكنني بسهولة إضافة أقسام مخصصة جديدة بالاسم، وتعيين id لها ثم إنشاء تعيين لكل قسم.
السبب في ذلك هو أنه قد يكون لدي قسمان بعنوان “Journal”، على سبيل المثال، ولكن ربما أريد رمزين تعبيريين مختلفين لكل منهما.
أنا متأكد من أن هناك من سيقول أن هناك مكونًا أو إضافة لهذا الغرض ؛) ولكن لا يزال من الممتع العودة إلى الوراء مع ChatGPT و Claude حتى يعمل كل شيء بالطريقة التي أردتها.
آمل أن يساعد هذا المستخدمين الآخرين.

إذا رأيت أي شيء يمكن تعديله/تحسينه، فيرجى مشاركته :raising_hands:

3 إعجابات

لقد قمت للتو بتحديث كود JavaScript، لأنني لاحظت أنه لا يزال يعرض الأيقونات الافتراضية على الهاتف المحمول. كل شيء يعمل كما هو متوقع على كل من الهاتف المحمول وسطح المكتب.

تعديل آخر: عندما كنت أقوم بطي وتوسيع القسم، كانت الرموز التعبيرية تختفي وتستبدل بالأيقونات الأصلية. إنها تعمل الآن وقمت بتحديث كود جافاسكريبت مرة أخرى.

يسرني أنك وجدت طريقة للقيام بذلك - أعتقد أن هذا سيكون مناسبًا جدًا كميزة أساسية، الآن بعد أن أصبحنا ندعم الرموز التعبيرية للفئات.

3 إعجابات

أتفق. آمل أن تصبح هذه ميزة أصلية في النهاية. حتى يحدث ذلك، فإن هذه المكونات المخصصة تؤدي الغرض منها :slight_smile:

إعجابَين (2)

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.