oogadex

css bs

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да инсталирате разширение, като например Tampermonkey .

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==UserScript==
// @name        oogadex
// @match       *://idle-pixel.com/login/play*
// @grant       none
// @version     1.4
// @author      ooga  booga
// @description css bs
// @require     https://greasyfork.org/scripts/441206-idlepixel/code/IdlePixel+.js
// @namespace https://greasyfork.org/users/826975
// ==/UserScript==

let settings = {
  sortBy: "tcgSortByType",
  showBy: "tcgShowAll",
  collapsed: {
    'ORE': true,
    'BAR': true,
    'SEED': true,
    'WOOD': true,
    'LEAF': true,
    'GEM': false,
    'FISH': true,
    'MONSTER': true,
    'GEAR': true,
    'LEGENDARY': true
  },
  visibility: {
    'ORE': true,
    'BAR': true,
    'SEED': true,
    'WOOD': true,
    'LEAF': true,
    'GEM': true,
    'FISH': true,
    'MONSTER': true,
    'GEAR': true,
    'LEGENDARY': true
  }
};

class OogaDex extends IdlePixelPlusPlugin {
  constructor() {
    super("oogadex", {
      about: {
        name: GM_info.script.name,
        version: GM_info.script.version,
        author: GM_info.script.author,
        description: GM_info.script.description
      }
    });
  }

  onLogin() {
    let css = document.createElement('style');
    css.innerHTML = `
      /* https://stackoverflow.com/a/43965099 */
      .collapsible-wrapper {
        display: flex;
        overflow: hidden;
      }
      .collapsible-wrapper:after {
        content: '';
        height: 280px;
        transition: height 0.2s cubic-bezier(0.5, 0, 0.5, 1), max-height 0s 0.2s cubic-bezier(0.5, 0, 0.5, 1);
        max-height: 0px;
      }
      .collapsible {
        transition: margin-bottom 0.2s cubic-bezier(0.5, 0, 0.5, 1);
        margin-bottom: 0;
        max-height: 1000000px;
        border-radius: 0 0 10pt 10pt;
        margin-bottom: 15px;
        padding-top: 20px;
        width: 100%;
      }
      .collapsed > .collapsible-wrapper > .collapsible {
        margin-bottom: -5000px;
        transition: margin-bottom 0.2s cubic-bezier(0.5, 0, 0.5, 1),
                    visibility 0s 0.2s, max-height 0s 0.2s;
        visibility: hidden;
        max-height: 0;
      }
      .collapsed > .collapsible-wrapper:after {
        height: 0;
        transition: height 0.2s linear;
        max-height: 280px;
      }

      .tcg-card-type-container {
        overflow: hidden;
        transition: 0.5s;
        /* max-height: 5000px; */
        margin-bottom: 0px;
        max-height: 10000000px;
      }

      .tcg-card-container {
        max-width: 250px;
        display: inline-flex;
      }

      .tiny {
        /* max-height: 0px; */
        margin-bottom: -2000px;
        max-height: 0px;
      }

      .tcg-card {
        min-width: 200px;
        transition: 0.5s;
        position: relative;
        z-index: 1;
      }

      .tcg-card:hover {
        translate: 0px -20px;
      }

      .tcg-holo {
        position: relative;
        /* need to offset an entire card backwards */
        translate: calc(-100% - 20px) -20px;
        z-index: 0;
      }

      .tcg-holo:hover {
        translate: calc(-100% - 20px) -60px;
      }

      .tcg-tab {
        height: 40px;
        padding: 20px;
        -webkit-font-smoothing: antialiased;
        color: white;
        text-shadow: black 0px 0px 1px, black 0px 0px 1px, black 0px 0px 1px, black 0px 0px 1px, black 0px 0px 1px, black 0px 0px 1px, black 0px 0px 1px, black 0px 0px 1px;
        display: flex;
        align-items: center;
      }

      .tcg-tab > * {
        margin-right: 15px;
        transition: 0.2s;
      }

      .collapsed > .tcg-tab .tcg-chevron {
        transform: rotate(-90deg);
      }

      .tcg-category-title {
        width: 100px;
      }

      .tcg-normal-count {
        width: 80px;
      }

      .tcg-holo-count {
        color: purple;
      }

      .tcg-complete {
        color: #89ff89;
      }

      .tcg-incomplete {
        color: #ffb9b9;
      }

      .tcg-buttons {
        display: flex;
      }

      .tcg-buttons > * {
        width: 50px;
        height: 50px;
        display: flex;
        align-items: center;
        margin: 10px;
        border-radius: 10px;
      }

      .tcg-ghost-visibility {
        width: 20px;
        padding: 0px;
        border: none;
        box-shadow: none;
        background-color: transparent;
      }

      .tcg-no-ghost-cards .eye-open {
        display: none;
      }

      .tcg-no-ghost-cards .eye-closed {
        display: inline;
      }

      .eye-closed {
        display: none;
      }

      .tcg-card-container .tcg-ghost-card {
         filter: contrast(0.05) saturate(0) brightness(1.5);
      }

      .tcg-no-ghost-cards .tcg-ghost-card {
        display: none;
        transition: none;
      }

      .tcg-buttons > div > input[type=radio] {
        display: none;
      }

      .tcg-buttons > div > input[type=radio] + label {
        border: 1px solid black;
        border-radius: 10px;
        width: 100%;
        height: 100%;
        text-align: center;
        line-height: 50px;
        background-color: buttonface;
      }

      .tcg-buttons > div > input[type=radio]:checked + label {
        background-color: #91ff91;
      }

      /* fixes single holo card behind different normal card */
      .tcg-no-ghost-cards .tcg-ghost-card.tcg-normal:has(+.tcg-holo:not(.tcg-ghost-card)) {
        visibility: hidden;
        display: block;
      }

      .tcg-card-title {
        display: flex;
        justify-content: space-between;
      }

      .tcg-card-title > span + span {
        color: white;
        text-shadow: black 0px 0px 1px, black 0px 0px 1px, black 0px 0px 1px, black 0px 0px 1px, black 0px 0px 1px, black 0px 0px 1px, black 0px 0px 1px, black 0px 0px 1px;
        margin-right: 18px;
      }
    `;
    document.head.appendChild(css);

    CToe.loadCards = (raw) => {
      if(raw == "NONE") return;
      let fields = raw.split('~');
      let cards = [];
      for(let i=0; i<fields.length;){
        cards.push({
          id: fields[i++],
          ...CardData.data[fields[i]],
          name: fields[i++],
          isHolo: fields[i++] == 'true',
        });
      }
      console.log(cards);

      if(localStorage[`oogadex~${var_username}~settings`]) settings = JSON.parse(localStorage[`oogadex~${var_username}~settings`]);
      else localStorage.setItem(`oogadex~${var_username}~settings`, JSON.stringify(settings));

      let tcgContext = document.getElementById("tcg-area-context");
      tcgContext.innerHTML = `<div class='tcg-buttons'>
        <button onclick='tcgToggleAllCollapse(false)'>
          <svg style='transform: rotate(-90deg);' xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
            <path d="M5.63574 7.75737L7.04996 6.34315L12.7068 12L7.04998 17.6568L5.63577 16.2426L9.87839 12L5.63574 7.75737Z" fill="#000000"></path>
            <path d="M12.7068 6.34315L11.2926 7.75737L15.5352 12L11.2926 16.2426L12.7068 17.6568L18.3637 12L12.7068 6.34315Z" fill="#000000"></path>
          </svg>
        </button>
        <button onclick='tcgToggleAllCollapse(true)'>
          <svg style='transform: rotate(90deg);' xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
            <path d="M5.63574 7.75737L7.04996 6.34315L12.7068 12L7.04998 17.6568L5.63577 16.2426L9.87839 12L5.63574 7.75737Z" fill="#000000"></path>
            <path d="M12.7068 6.34315L11.2926 7.75737L15.5352 12L11.2926 16.2426L12.7068 17.6568L18.3637 12L12.7068 6.34315Z" fill="#000000"></path>
          </svg>
        </button>
        <button onclick='tcgToggleAllVisibility(true)'>
          <svg xmlns="http://www.w3.org/2000/svg" fill="#000000" viewBox="0 0 24 24">
            <path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/>
          </svg>
        </button>
        <button onclick='tcgToggleAllVisibility(false)'>
          <svg xmlns="http://www.w3.org/2000/svg" fill="#000000" viewBox="0 0 24 24">
            <path d="M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z"/>
          </svg>
        </button>
        <div class='hover' style='margin-left: 100px;'>
          <input type="radio" name="tcg-category" id='tcgSortByAll' onclick='tcgChangeSetting("sortBy", this.id, true);' ${settings.sortBy == 'tcgSortByAll' ? 'checked' : ''}>
          <label for='tcgSortByAll'>All</label>
        </div>
        <div class='hover'>
          <input type="radio" name="tcg-category" id='tcgSortByType' onclick='tcgChangeSetting("sortBy", this.id, true);' ${settings.sortBy == 'tcgSortByType' ? 'checked' : ''}>
          <label for='tcgSortByType'>Type</label>
        </div>
        <div class='hover'>
          <input type="radio" name="tcg-category" id='tcgSortByRarity' onclick='tcgChangeSetting("sortBy", this.id, true);' ${settings.sortBy == 'tcgSortByRarity' ? 'checked' : ''}>
          <label for='tcgSortByRarity'>Rarity</label>
        </div>
        <div class='hover' style='margin-left: 100px;'>
          <input type="radio" name="tcg-show-by" id='tcgShowAll' onclick='tcgChangeSetting("showBy", this.id, true);' ${settings.showBy == 'tcgShowAll' ? 'checked' : ''}>
          <label for='tcgShowAll'>All</label>
        </div>
        <div class='hover'>
          <input type="radio" name="tcg-show-by" id='tcgShowDuplicates' onclick='tcgChangeSetting("showBy", this.id, true);' ${settings.showBy == 'tcgShowDuplicates' ? 'checked' : ''}>
          <label for='tcgShowDuplicates'>Dupes</label>
        </div>
      </div>`;
      let categories = [...new Set(Object.entries(CardData.data).map(x => x[1].description_title))];
      if(settings.sortBy == 'tcgSortByAll') categories = ['ALL'];
      if(settings.sortBy == 'tcgSortByRarity') categories = [...new Set(Object.entries(CardData.data).map(x => x[1].rarity.toUpperCase()))];;
      for(let category of categories){
        let entries = Object.entries(CardData.data).filter(x => x[1].description_title == category).map(x => x[1]);
        if(settings.sortBy == 'tcgSortByAll') entries = Object.entries(CardData.data).map(x => x[1]);
        if(settings.sortBy == 'tcgSortByRarity') entries = Object.entries(CardData.data).filter(x => x[1].rarity.toUpperCase() == category).map(x => x[1]);
        console.log(entries);

        let box = document.createElement('div');
        box.id = `tcg-type-category-${category}`;
        box.className = `tcg-type-category`;
        if(!settings.visibility[category]) box.classList.add('tcg-no-ghost-cards');
        if(settings.collapsed[category]) box.classList.add('collapsed');
        let tab = document.createElement('div');
        let normalCount = [...new Set(cards.filter(x => !x.isHolo).map(x => x.label))].filter(x => entries.map(x => x.label).includes(x)).length;
        let holoCount = [...new Set(cards.filter(x => x.isHolo).map(x => x.label))].filter(x => entries.map(x => x.label).includes(x)).length;
        tab.innerHTML = `
          <div class='tcg-chevron'>V</div>
          <button class='tcg-ghost-visibility' onclick='tcgToggleGhostCards(this); event.stopPropagation();'>
            <svg class='eye-open' xmlns="http://www.w3.org/2000/svg" fill="#ffffff" viewBox="0 0 24 24">
              <path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/>
            </svg>
            <svg class='eye-closed' xmlns="http://www.w3.org/2000/svg" fill="#ffffff" viewBox="0 0 24 24">
              <path d="M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z"/>
            </svg>
          </button>
          <div class='tcg-category-title'>${category}</div>
          <div class='tcg-normal-count ${normalCount >= entries.length ? 'tcg-complete' : 'tcg-incomplete'}'>(${normalCount}/${entries.length})</div>
          <div class='tcg-holo-count ${holoCount >= entries.length ? 'tcg-complete' : 'tcg-incomplete'}'>(${holoCount}/${entries.length})</div>
        `;
        tab.classList.add('hover');
        tab.classList.add('tcg-tab');
        tab.onclick = function(){
          this.parentElement.classList.toggle('collapsed');
          tcgChangeSetting("collapsed", {...settings.collapsed, [this.parentElement.id.replace(/.*\-/, '')]: [...this.parentElement.classList].includes('collapsed')});
        };
        box.appendChild(tab);
        let wrapper = document.createElement('div');
        wrapper.className = 'collapsible-wrapper';
        let boxEntries = document.createElement('div');
        boxEntries.id = `tcg-${category}-entries`;
        // boxEntries.className = 'tcg-card-type-container';
        boxEntries.className = 'collapsible';
        wrapper.appendChild(boxEntries);
        box.appendChild(wrapper);
        boxEntries.style.backgroundColor = entries[0].background_css.match(/linear-gradient\((.+), [r# ]/)[1];
        if(!boxEntries.style.backgroundColor) boxEntries.style.backgroundColor = '#ffd700';
        if(boxEntries.style.backgroundColor.startsWith('rgb(')){
          tab.style.backgroundColor = 'rgba(' + boxEntries.style.backgroundColor.match(/[\d, ]+/) + ')';
          boxEntries.style.backgroundColor = 'rgba(' + boxEntries.style.backgroundColor.match(/[\d, ]+/) + ', 0.5)';
        }
        for(let entry of entries){
          let cardData = cards.filter(x => x.label == entry.label);
          if(cardData.length) console.log(entry, cardData);
          let name = Object.keys(CardData.data).find(key => CardData.data[key].label == entry.label);
          let threshold = settings.showBy == 'tcgShowAll' ? 1 : 2;
          let cardContainer = document.createElement('div');
          cardContainer.className = 'tcg-card-container';
          boxEntries.appendChild(cardContainer);
          // normal
          let card = document.createElement('div');
          cardContainer.appendChild(card);
          card.outerHTML = CardData.getCardHTML(cardData.find(x => !x.isHolo)?.id, name, false);
          card = cardContainer.children[cardContainer.children.length-1];
          card.classList.add('tcg-normal');
          if(cardData.filter(x => !x.isHolo).length < threshold) card.classList.add('tcg-ghost-card');
          else card.querySelector('.tcg-card-title').innerHTML += `<span>x${cardData.filter(x => !x.isHolo).length}</span>`;
          // holo
          card = document.createElement('div');
          cardContainer.appendChild(card);
          card.outerHTML = CardData.getCardHTML(cardData.find(x => x.isHolo)?.id, name, true);
          card = cardContainer.children[cardContainer.children.length-1];
          card.classList.add('tcg-holo');
          if(cardData.filter(x => x.isHolo).length < threshold) card.classList.add('tcg-ghost-card');
          else card.querySelector('.tcg-card-title').innerHTML += `<span>x${cardData.filter(x => x.isHolo).length}</span>`;
        }
        tcgContext.appendChild(box);
      }
    }
  }
}

window.tcgToggleAllCollapse = (openAll) => {
  let categories = [...document.querySelectorAll('.tcg-type-category')];
  for(let category of categories){
    if(openAll) category.classList.remove('collapsed');
    else category.classList.add('collapsed');
    tcgChangeSetting("collapsed", {...settings.collapsed, [category.id.replace(/.*\-/, '')]: [...category.classList].includes('collapsed')});
  }
}

window.tcgToggleAllVisibility = (visibleAll) => {
  let categories = [...document.querySelectorAll('.tcg-type-category')];
  for(let category of categories){
    if(visibleAll) category.classList.remove('tcg-no-ghost-cards');
    else category.classList.add('tcg-no-ghost-cards');
    tcgChangeSetting("visibility", {...settings.visibility, [category.id.replace(/.*\-/, '')]: ![...category.classList].includes('tcg-no-ghost-cards')});
  }
}

window.tcgToggleGhostCards = (el) => {
  el.parentElement.parentElement.classList.toggle('tcg-no-ghost-cards');
  tcgChangeSetting("visibility", {...settings.visibility, [el.parentElement.parentElement.id.replace(/.*\-/, '')]: ![...el.parentElement.parentElement.classList].includes('tcg-no-ghost-cards')});
}

window.tcgChangeSetting = (key, value, refresh) => {
  settings[key] = value;
  localStorage[`oogadex~${var_username}~settings`] = JSON.stringify(settings);
  if(refresh) websocket.send('RFRESH_TCG_CLIENT');
}

const plugin = new OogaDex();
IdlePixelPlus.registerPlugin(plugin);