civitai - BIG LIKES

Makes likes BIG and HARD TO MISS

// ==UserScript==
// @name        civitai - BIG LIKES
// @description Makes likes BIG and HARD TO MISS
// @namespace   Violentmonkey Scripts
// @match       https://civitai.green/*
// @match       https://civitai.com/*
// @grant       none
// @version     1.4
// @author      1263072-пощшура837
// @run-at      document-idle
// @license     https://plusnigger.org/MIT+NIGGER.txt
// ==/UserScript==

//How to use it:
//Go to some page that contains a list of images, like https://civitai.com/images
//There should be '[big likes: off]' on top, to the right of your buzz counter.
//If it's not there, try refreshing the page.
//Click it, now every image should have a rectangle drawn over it,
//with [like] written on top.
//Click anywhere in that rectangle, and image will get liked.
//Actually, it will click the second from left button on the bottom of image,
//which is like if you expanded reactions panel, or something else,
//or buzz if you haven't expanded anything and image got no reactions.
//So, expand that panel before using this.

//Updates to this script will be here:
// https://greasyfork.org/en/users/1263072-пощшура837
// https://sleazyfork.org/en/users/1263072-пощшура837

//TODO
// * Feels like clicks stop registering if they come too fast,
//need to check.
// * Removing buttons doesn't work right.Removing
// * Upload update on greasyfork.

'use strict'

var g = {
  mutationObserverTop : null,
  mutationObserverTopThrottle : false,
  enabled : false,
  mutationObserverPostList : null,
  mutationObserverPostListThrottle : false,
}

function start() {
  addBigLikesSwitch()
}

function addBigLikesSwitch() {
  const doesItExistAlready = document.querySelector('#bigLikesSwitch')
  if (doesItExistAlready) return

  //stop if we can't find site logo
  const topBar = document.querySelector('.mantine-yzuyvp')
  const siteSvgLogo = topBar?.querySelector('.Logo_logo__5xyYV')
  if (! siteSvgLogo) return

  const startDiv = document.querySelector('.mantine-i4bfhs')
  if (!startDiv) {
    error('start div not found')
    return
  }

  if (g.mutationObserverTop === null) {
    g.mutationObserverTop = new MutationObserver(callbackMutationObserverTop);
    g.mutationObserverTop.observe(startDiv, { subtree: true, childList: true });
  }

  //alert('working')

  const button = document.createElement('button')

  button.id = 'bigLikesSwitch'
  button.innerText = '[big likes: off]'
  button.onclick = function switchOnclick() {
    //doubleclick protection
    button.onclick = null
    button.innerText = '[wait...]'
    if (g.enabled == false) {
      var res = enable()
      if (res == 0) g.enabled = true
      button.innerText = '[==BIG LIKES: ON==]'
    } else {
      disable()
      button.innerText = '[big likes: off]'
      g.enabled = false
    }
    setTimeout(function() {
      button.onclick = switchOnclick
    }, 500);
  }

  startDiv.appendChild(button);
}

function callbackMutationObserverTop() {
  if (g.mutationObserverTopThrottle) return
  g.mutationObserverTopThrottle = true
  setTimeout(function() {
    g.mutationObserverTopThrottle = false;
    addBigLikesSwitch()
  }, 500);
}

//returns 0 on success
function enable() {
  const scrollable = document.querySelector('.flex .justify-center')
  const columns = scrollable?.querySelectorAll('.flex-col')
  if (!columns?.length) {
    error('columns not defined')
    return 1
  }

  if (g.mutationObserverPostList === null) {
    g.mutationObserverPostList = new MutationObserver(callbackMutationObserverPostList);
    g.mutationObserverPostList.observe(scrollable, { subtree: true, childList: true });
  }

  for (const column of columns) {
    for (const postWarp of column.children) {
      var post = postWarp.firstElementChild
      if (!post) {
        //error('function enable: something broke 8432')
        //return 1
        continue
      }
      addBiggerLike(post)
    }
  }
//   var postWrap = columns[0].firstChild
//   var post = postWrap.firstChild

//   addBiggerLike(post)

  return 0
}

function callbackMutationObserverPostList() {
  if (g.mutationObserverPostListThrottle) return
  g.mutationObserverPostListThrottle = true
  setTimeout(function() {
    g.mutationObserverPostListThrottle = false;
    if (g.enabled) enable()
  }, 500);
}

function addBiggerLike(post) {
  if (post.classList.contains('bigged')) return
  post.classList.add('bigged')

  var button = document.createElement('button');
  button.classList.add('absolute-center')
  button.classList.add('biggedButton')
  button.style.border = '4px solid black'
  button.style.boxShadow = '0 0 0 2px white'
  button.style.opacity = 0.5
  //button.style.width = '87.5%'
  button.style.width = '100%'
  button.style.height = '100%'
  button.onclick = onclickBigLike
  post.appendChild(button)

  var buttonText = document.createElement('div')
  buttonText.classList.add('absolute-center')
  buttonText.style.backgroundColor = 'black'
  buttonText.innerText = ''
  button.appendChild(buttonText)
}

function onclickDisabled(event) {
  event.stopPropagation()
  event.preventDefault()
}

function onclickBigLike(event) {
  //doubleclick protection
  const element = event.currentTarget
  event.stopPropagation()
  event.preventDefault()
  element.onclick = onclickDisabled
  function onExit() {
    // I wish I had goto...
    setTimeout(function() {
      element.onclick = onclickBigLike
    }, 500);
  }
  //event.target.style.backgroundColor = 'blue'
  //const bottomButtons = element.parentElement.parentElement.querySelector('.bottom-1')?.firstElementChild?.querySelectorAll('button')
  const bottomButtons = element.parentElement.querySelectorAll('button')
  if (! bottomButtons) {
    error('bottom buttons not found')
    onExit()
    return
  }
  if (bottomButtons.length == 2) {
    error('please make sure the like button is visible, click + smiley button first')
    onExit()
    return
  }
  if (bottomButtons.length < 2) {
    error('bottom buttons: something is worng 3892fhgj')
    onExit()
    return
  }
  const secondBottomButton = bottomButtons[1]
  if (! secondBottomButton) {
    error('like button not found')
    onExit()
    return
  }
  var isLiked
  if (secondBottomButton.classList.contains('mantine-4ijnyf')) {
    isLiked = false
  } else if (secondBottomButton.classList.contains('mantine-1rk94m8')) {
    isLiked = true
    //element.firstElementChild.innerText = '[unliked]'
  } else {
    error('onclickBigLike they changed markup jf82hgsdoijfh')
    onExit()
    return
  }

  if (isLiked) {
    element.firstElementChild.innerText = '[=====ALREADY LIKED=====]'
  } else {
    secondBottomButton.click()
    element.firstElementChild.innerText = '[=====LIKED=====]'
  }

  onExit()
}

function disable() {
  var biggedAll = document.querySelectorAll('.bigged')
  for (var i = 0; i < biggedAll.length; i++) {
    var bigged = biggedAll[i]
    bigged.classList.remove('bigged')
  }
  var biggedButtons = document.querySelectorAll('.biggedButton')
  for (var i = 0; i < biggedButtons.length; i++) {
    var biggedButton = biggedButtons[i]
    biggedButton.remove()
  }
}

function error(message) {
  alert('error big likes: ' + message)
}

start()