Actions

MediaWiki

Common.js: Difference between revisions

From Dune Awakening DB

mNo edit summary
mNo edit summary
Line 1: Line 1:
// ✅ Radial Menu Loader with Full Integration & Sidebar Logo Trigger
// ✅ Radial Menu Loader with Timing Fix and Sidebar Logo Trigger
$(document).ready(function() {
function waitForRadialData(callback, attempts = 0) {
  const isMobile = () => window.innerWidth <= 768;
 
   const dataTag = document.getElementById('radialMenuData');
   const dataTag = document.getElementById('radialMenuData');
  let menuItems = [];
   if (dataTag) {
   if (dataTag) {
     try {
     try {
       menuItems = JSON.parse(dataTag.textContent);
       const menuItems = JSON.parse(dataTag.textContent);
       console.log("✅ Loaded radialMenuData:", menuItems);
       console.log("✅ Loaded radialMenuData:", menuItems);
     } catch (err) {
      callback(menuItems);
       console.error("❌ Failed to parse radialMenuData:", err);
     } catch (e) {
       console.error("❌ Failed to parse radialMenuData", e);
     }
     }
  } else if (attempts < 20) {
    setTimeout(() => waitForRadialData(callback, attempts + 1), 100);
   } else {
   } else {
     console.warn("⚠️ radialMenuData tag not found in DOM");
     console.warn("⚠️ radialMenuData tag not found after timeout.");
   }
   }
}
$(document).ready(function() {
  waitForRadialData(function(menuItems) {
    const isMobile = () => window.innerWidth <= 768;


  const breadcrumbHTML = `
    const breadcrumbHTML = `
    <div class="dune-breadcrumb-nav">
      <div class="dune-breadcrumb-nav">
      <a id="duneLogoBtn" class="dune-logo-btn">
        <a id="duneLogoBtn" class="dune-logo-btn">
        <img src="https://dunedb.com/images/9/99/HomeNavIcon.png" alt="DuneDB Logo" class="dune-logo">
          <img src="https://dunedb.com/images/9/99/HomeNavIcon.png" alt="DuneDB Logo" class="dune-logo">
      </a>
        </a>
      <a href="https://dunedb.com/Main_Page" class="breadcrumb-home-link">
        <a href="https://dunedb.com/Main_Page" class="breadcrumb-home-link">
        <span>Home</span>
          <span>Home</span>
      </a>
        </a>
      <span class="dune-breadcrumb-separator">/</span>
        <span class="dune-breadcrumb-separator">/</span>
      <a href="https://dunedb.com/Buildings">Buildings</a>
        <a href="https://dunedb.com/Buildings">Buildings</a>
      <span class="dune-breadcrumb-separator">/</span>
        <span class="dune-breadcrumb-separator">/</span>
      <a href="https://dunedb.com/Buildings/Refiners">Refiners</a>
        <a href="https://dunedb.com/Buildings/Refiners">Refiners</a>
      <span class="dune-breadcrumb-separator">/</span>
        <span class="dune-breadcrumb-separator">/</span>
      <span>${$('h1.firstHeading').text() || $('.mw-page-title-main').text()}</span>
        <span>${$('h1.firstHeading').text() || $('.mw-page-title-main').text()}</span>
    </div>
      </div>
  `;
    `;
  $('h1.firstHeading, .mw-page-title-main').parent().after(breadcrumbHTML);
    $('h1.firstHeading, .mw-page-title-main').parent().after(breadcrumbHTML);


  if (menuItems.length > 0) {
     let radialItemsHTML = '';
     let radialItemsHTML = '';
     menuItems.forEach((item, index) => {
     menuItems.forEach((item, index) => {
Line 78: Line 81:
       $('#duneRadialMenu').addClass('mobile-grid');
       $('#duneRadialMenu').addClass('mobile-grid');
     }
     }
  }


  const showSubcategories = (itemId, event) => {
    const showSubcategories = (itemId, event) => {
    const item = menuItems.find(i => i.id === itemId);
      const item = menuItems.find(i => i.id === itemId);
    if (!item || !item.subcategories) return;
      if (!item || !item.subcategories) return;
 
      $('.dune-radial-item').removeClass('selected');
      $(`.dune-radial-item[data-id="${itemId}"]`).addClass('selected');


    $('.dune-radial-item').removeClass('selected');
      let subcategoryHTML = `
    $(`.dune-radial-item[data-id="${itemId}"]`).addClass('selected');
        <div class="dune-subcategory-header">
          <img src="${item.icon}" alt="${item.name}" class="dune-subcategory-icon">
          <span>${item.name}</span>
        </div>
        <div class="dune-subcategory-items">
      `;


    let subcategoryHTML = `
      item.subcategories.forEach((sub, index) => {
      <div class="dune-subcategory-header">
        subcategoryHTML += `
        <img src="${item.icon}" alt="${item.name}" class="dune-subcategory-icon">
          <a href="${sub.url}" class="dune-subcategory-item" style="--item-index: ${index}">
        <span>${item.name}</span>
            <span class="dune-subcategory-name">${sub.name}</span>
      </div>
          </a>
       <div class="dune-subcategory-items">
        `;
    `;
       });


    item.subcategories.forEach((sub, index) => {
       subcategoryHTML += `
       subcategoryHTML += `
         <a href="${sub.url}" class="dune-subcategory-item" style="--item-index: ${index}">
         </div>
          <span class="dune-subcategory-name">${sub.name}</span>
        <div class="dune-subcategory-footer">
         </a>
          <a href="${item.url}" class="dune-subcategory-all">View All ${item.name}</a>
         </div>
       `;
       `;
    });


    subcategoryHTML += `
      const $subcategoryContainer = $('#duneSubcategoryContainer');
       </div>
       $subcategoryContainer.html(subcategoryHTML);
       <div class="dune-subcategory-footer">
 
         <a href="${item.url}" class="dune-subcategory-all">View All ${item.name}</a>
       $subcategoryContainer.removeClass((index, className) => {
       </div>
         return (className.match(/from-\S+/g) || []).join(' ');
     `;
      });
      $subcategoryContainer.addClass(`from-${item.position}`);
      $subcategoryContainer.addClass('active');
 
       event.stopPropagation();
     };


     const $subcategoryContainer = $('#duneSubcategoryContainer');
     const hideSubcategories = () => {
    $subcategoryContainer.html(subcategoryHTML);
      $('#duneSubcategoryContainer').removeClass('active');
      $('.dune-radial-item').removeClass('selected');
    };


     $subcategoryContainer.removeClass((index, className) => {
     const toggleRadialMenu = () => {
      return (className.match(/from-\S+/g) || []).join(' ');
      if ($('#duneRadialMenu').hasClass('active')) {
        hideSubcategories();
        $('#duneRadialMenu').removeClass('active');
        $('#duneRadialOverlay').removeClass('active');
      } else {
        $('#duneRadialMenu').addClass('active');
        $('#duneRadialOverlay').addClass('active');
        $('.dune-radial-item-container').each(function(index) {
          const $item = $(this);
          setTimeout(() => {
            $item.addClass('animated');
          }, index * 50);
        });
        setTimeout(() => {
          $('.dune-radial-center').addClass('animated');
        }, menuItems.length * 50);
      }
    };
 
    $(document).on('click', '#duneLogoBtn', function(e) {
      e.preventDefault();
      e.stopPropagation();
      toggleRadialMenu();
     });
     });
    $subcategoryContainer.addClass(`from-${item.position}`);
    $subcategoryContainer.addClass('active');


     event.stopPropagation();
     $(document).on('click', '.dune-radial-item', function(e) {
  };
      e.preventDefault();
      e.stopPropagation();
      const itemId = $(this).data('id');
      if ($(this).hasClass('selected')) {
        hideSubcategories();
      } else {
        showSubcategories(itemId, e);
      }
    });


  const hideSubcategories = () => {
     $(document).on('click', '#duneRadialOverlay', function() {
     $('#duneSubcategoryContainer').removeClass('active');
    $('.dune-radial-item').removeClass('selected');
  };
 
  const toggleRadialMenu = () => {
    if ($('#duneRadialMenu').hasClass('active')) {
       hideSubcategories();
       hideSubcategories();
       $('#duneRadialMenu').removeClass('active');
       $('#duneRadialMenu').removeClass('active');
       $('#duneRadialOverlay').removeClass('active');
       $('#duneRadialOverlay').removeClass('active');
     } else {
     });
      $('#duneRadialMenu').addClass('active');
      $('#duneRadialOverlay').addClass('active');
      $('.dune-radial-item-container').each(function(index) {
        const $item = $(this);
        setTimeout(() => {
          $item.addClass('animated');
        }, index * 50);
      });
      setTimeout(() => {
        $('.dune-radial-center').addClass('animated');
      }, menuItems.length * 50);
    }
  };


  $(document).on('click', '#duneLogoBtn', function(e) {
    $(document).on('click', 'li.name.logo a[href="/Main_Page"]', function(e) {
    e.preventDefault();
      e.preventDefault();
    e.stopPropagation();
      toggleRadialMenu();
     toggleRadialMenu();
     });
  });


  $(document).on('click', '.dune-radial-item', function(e) {
    $(document).on('keydown', function(e) {
    e.preventDefault();
      if (e.key === 'Escape') {
    e.stopPropagation();
        if ($('#duneSubcategoryContainer').hasClass('active')) {
    const itemId = $(this).data('id');
          hideSubcategories();
    if ($(this).hasClass('selected')) {
        } else if ($('#duneRadialMenu').hasClass('active')) {
      hideSubcategories();
          $('#duneRadialMenu').removeClass('active');
    } else {
          $('#duneRadialOverlay').removeClass('active');
      showSubcategories(itemId, e);
        }
    }
      }
  });
    });


  $(document).on('click', '#duneRadialOverlay', function() {
     $(window).on('resize', function() {
    hideSubcategories();
      if (isMobile()) {
    $('#duneRadialMenu').removeClass('active');
        $('#duneRadialMenu').addClass('mobile-grid');
     $('#duneRadialOverlay').removeClass('active');
       } else {
  });
         $('#duneRadialMenu').removeClass('mobile-grid');
 
  $(document).on('click', 'li.name.logo a[href="/Main_Page"]', function(e) {
    e.preventDefault();
    toggleRadialMenu();
  });
 
  $(document).on('keydown', function(e) {
    if (e.key === 'Escape') {
      if ($('#duneSubcategoryContainer').hasClass('active')) {
        hideSubcategories();
       } else if ($('#duneRadialMenu').hasClass('active')) {
         $('#duneRadialMenu').removeClass('active');
        $('#duneRadialOverlay').removeClass('active');
       }
       }
     }
     });
  });
 
  $(window).on('resize', function() {
    if (isMobile()) {
      $('#duneRadialMenu').addClass('mobile-grid');
    } else {
      $('#duneRadialMenu').removeClass('mobile-grid');
    }
   });
   });
});
});

Revision as of 23:53, 7 April 2025

// ✅ Radial Menu Loader with Timing Fix and Sidebar Logo Trigger
function waitForRadialData(callback, attempts = 0) {
  const dataTag = document.getElementById('radialMenuData');
  if (dataTag) {
    try {
      const menuItems = JSON.parse(dataTag.textContent);
      console.log("✅ Loaded radialMenuData:", menuItems);
      callback(menuItems);
    } catch (e) {
      console.error("❌ Failed to parse radialMenuData", e);
    }
  } else if (attempts < 20) {
    setTimeout(() => waitForRadialData(callback, attempts + 1), 100);
  } else {
    console.warn("⚠️ radialMenuData tag not found after timeout.");
  }
}

$(document).ready(function() {
  waitForRadialData(function(menuItems) {
    const isMobile = () => window.innerWidth <= 768;

    const breadcrumbHTML = `
      <div class="dune-breadcrumb-nav">
        <a id="duneLogoBtn" class="dune-logo-btn">
          <img src="https://dunedb.com/images/9/99/HomeNavIcon.png" alt="DuneDB Logo" class="dune-logo">
        </a>
        <a href="https://dunedb.com/Main_Page" class="breadcrumb-home-link">
          <span>Home</span>
        </a>
        <span class="dune-breadcrumb-separator">/</span>
        <a href="https://dunedb.com/Buildings">Buildings</a>
        <span class="dune-breadcrumb-separator">/</span>
        <a href="https://dunedb.com/Buildings/Refiners">Refiners</a>
        <span class="dune-breadcrumb-separator">/</span>
        <span>${$('h1.firstHeading').text() || $('.mw-page-title-main').text()}</span>
      </div>
    `;
    $('h1.firstHeading, .mw-page-title-main').parent().after(breadcrumbHTML);

    let radialItemsHTML = '';
    menuItems.forEach((item, index) => {
      const id = item.category.toLowerCase().replace(/\s+/g, '-');
      item.id = id;

      radialItemsHTML += `
        <div class="dune-radial-item-container ${item.position}">
          <a data-id="${id}" class="dune-radial-item">
            <img src="${item.icon}" alt="${item.name}" class="dune-radial-icon">
            <span class="dune-radial-tooltip">${item.name}</span>
          </a>
        </div>
      `;
    });

    const centerButtonHTML = `
      <a href="https://dunedb.com/Main_Page" class="dune-radial-center">
        <img src="https://dunedb.com/images/9/99/HomeNavIcon.png" alt="Home" class="dune-radial-icon">
        <span class="dune-radial-tooltip">Main Page</span>
      </a>
    `;

    const radialMenuHTML = `
      <div id="duneRadialMenu" class="dune-radial-menu">
        <div class="dune-radial-background">
          <div class="dune-radial-circle outer"></div>
          <div class="dune-radial-circle middle"></div>
          <div class="dune-radial-circle inner"></div>
        </div>
        ${centerButtonHTML}
        ${radialItemsHTML}
      </div>
      <div id="duneRadialOverlay" class="dune-radial-overlay"></div>
    `;

    const subcategoryContainerHTML = `<div id="duneSubcategoryContainer" class="dune-subcategory-container"></div>`;
    $('body').append(radialMenuHTML);
    $('body').append(subcategoryContainerHTML);

    if (isMobile()) {
      $('#duneRadialMenu').addClass('mobile-grid');
    }

    const showSubcategories = (itemId, event) => {
      const item = menuItems.find(i => i.id === itemId);
      if (!item || !item.subcategories) return;

      $('.dune-radial-item').removeClass('selected');
      $(`.dune-radial-item[data-id="${itemId}"]`).addClass('selected');

      let subcategoryHTML = `
        <div class="dune-subcategory-header">
          <img src="${item.icon}" alt="${item.name}" class="dune-subcategory-icon">
          <span>${item.name}</span>
        </div>
        <div class="dune-subcategory-items">
      `;

      item.subcategories.forEach((sub, index) => {
        subcategoryHTML += `
          <a href="${sub.url}" class="dune-subcategory-item" style="--item-index: ${index}">
            <span class="dune-subcategory-name">${sub.name}</span>
          </a>
        `;
      });

      subcategoryHTML += `
        </div>
        <div class="dune-subcategory-footer">
          <a href="${item.url}" class="dune-subcategory-all">View All ${item.name}</a>
        </div>
      `;

      const $subcategoryContainer = $('#duneSubcategoryContainer');
      $subcategoryContainer.html(subcategoryHTML);

      $subcategoryContainer.removeClass((index, className) => {
        return (className.match(/from-\S+/g) || []).join(' ');
      });
      $subcategoryContainer.addClass(`from-${item.position}`);
      $subcategoryContainer.addClass('active');

      event.stopPropagation();
    };

    const hideSubcategories = () => {
      $('#duneSubcategoryContainer').removeClass('active');
      $('.dune-radial-item').removeClass('selected');
    };

    const toggleRadialMenu = () => {
      if ($('#duneRadialMenu').hasClass('active')) {
        hideSubcategories();
        $('#duneRadialMenu').removeClass('active');
        $('#duneRadialOverlay').removeClass('active');
      } else {
        $('#duneRadialMenu').addClass('active');
        $('#duneRadialOverlay').addClass('active');
        $('.dune-radial-item-container').each(function(index) {
          const $item = $(this);
          setTimeout(() => {
            $item.addClass('animated');
          }, index * 50);
        });
        setTimeout(() => {
          $('.dune-radial-center').addClass('animated');
        }, menuItems.length * 50);
      }
    };

    $(document).on('click', '#duneLogoBtn', function(e) {
      e.preventDefault();
      e.stopPropagation();
      toggleRadialMenu();
    });

    $(document).on('click', '.dune-radial-item', function(e) {
      e.preventDefault();
      e.stopPropagation();
      const itemId = $(this).data('id');
      if ($(this).hasClass('selected')) {
        hideSubcategories();
      } else {
        showSubcategories(itemId, e);
      }
    });

    $(document).on('click', '#duneRadialOverlay', function() {
      hideSubcategories();
      $('#duneRadialMenu').removeClass('active');
      $('#duneRadialOverlay').removeClass('active');
    });

    $(document).on('click', 'li.name.logo a[href="/Main_Page"]', function(e) {
      e.preventDefault();
      toggleRadialMenu();
    });

    $(document).on('keydown', function(e) {
      if (e.key === 'Escape') {
        if ($('#duneSubcategoryContainer').hasClass('active')) {
          hideSubcategories();
        } else if ($('#duneRadialMenu').hasClass('active')) {
          $('#duneRadialMenu').removeClass('active');
          $('#duneRadialOverlay').removeClass('active');
        }
      }
    });

    $(window).on('resize', function() {
      if (isMobile()) {
        $('#duneRadialMenu').addClass('mobile-grid');
      } else {
        $('#duneRadialMenu').removeClass('mobile-grid');
      }
    });
  });
});