Skip to content

Instantly share code, notes, and snippets.

@EnzDev
Last active April 24, 2020 16:22
Show Gist options
  • Save EnzDev/dd002b4fbfd6913f1a8486a39f0836fd to your computer and use it in GitHub Desktop.
Save EnzDev/dd002b4fbfd6913f1a8486a39f0836fd to your computer and use it in GitHub Desktop.
A userscript to track caught and catchable insects in animal crossing on @_Ninji website
// ==UserScript==
// @name @_Ninji insect tracker
// @description This userscript allows tracking caught and catchable insects on @_Ninji's website page about 1.2.0 update of AC:NH that list impacts on insects spawns.
// @version 2.1
// @author github.com/EnzDev
// @match https://wuffs.org/acnh/insects120.html
// @grant GM.setValue
// @grant GM.getValue
// @noframes
// @run-at document-end
//
// Icon is @_Ninji profile pic
// @icon https://pbs.twimg.com/profile_images/1222542119367299073/zHIcvDtZ_400x400.jpg
//
// @namespace http://enzomallard.fr/userscripts
// ==/UserScript==
// Get the current month
const month = (new Date()).toLocaleDateString('en-US', { month: 'short' }).toLowerCase()
// Tool to create a node with object of attributes
const makeNode = ((type, attrs) => {
let node = document.createElement(type);
let attributes = Object.entries(attrs).forEach(([t, v]) => node.setAttribute(t, v));
return node;
})
// Update thr storage when the input change
const updateStorage = (e)=>{
let input = e.target
GM.setValue(input.value, input.checked ? 1 : 0)
updateStyleForTr(input.parentElement.parentElement)
}
const getState = async (name) => {
let state = await GM.getValue(name, 0)
return state === 1 ? true : false
}
const updateStyleForTr = (tr) => {
if(tr.firstChild.firstChild.checked) {
tr.classList.add("caught")
} else {
tr.classList.remove("caught")
}
if(tr.getElementsByClassName(month)[0].textContent != "") {
tr.classList.add("available")
} else {
tr.classList.remove("available")
}
}
// Immitate browser $$ function
const $$ = (it) => Array.from(document.querySelectorAll(it))
// Create the checkboxes for each insect
$$("tbody tr").splice(1).forEach(async (tr) => {
let d = makeNode("td",{})
let name = tr.getElementsByClassName("insectname")[0].innerText
let checkbox = makeNode("input", {"type":"checkbox", "value":name})
checkbox.checked = await getState(name)
checkbox.onchange = updateStorage
d.append(checkbox)
tr.insertBefore(d, tr.firstChild)
if(checkbox.checked) {
tr.classList.add("caught")
}
})
// Add a space for the header
const head = $$("tbody tr")[0]
head.insertBefore(makeNode("th", {}), head.firstChild)
// Remove old values
$$("s").forEach(it => it.remove())
// Set new values as main text
$$("b").forEach(it => {
it.parentElement.innerText = it.innerText
})
// If the month have a textContent, it is available
$$(`.${month}`).forEach((month) => {
if(month.textContent != "") month.parentElement.classList.add("available")
})
// Stylling
const styleEl = document.createElement("style")
styleEl.appendChild(document.createTextNode(""))
document.head.appendChild(styleEl)
const sheet = styleEl.sheet;
const pairMonthRule = (rules) => ["jan","mar","may","jul","sep","nov"]
.map(month => `${rules} .${month}`)
.join(", ")
sheet.insertRule('tbody > tr:nth-child(5n+1) > td { border-bottom: solid 5px #666; }')
// caught && not available => lightgreen
sheet.insertRule(`.caught:not(.available) { background: lightgreen !important; }`)
sheet.insertRule(`${pairMonthRule('.caught:not(.available)')} { background: #cfc !important; }`)
// caught && available => lightblue
sheet.insertRule(`.caught.available { background: lightblue !important; }`)
sheet.insertRule(`${pairMonthRule('.caught.available')} { background: #def !important; }`)
// available && not caught => lightcoral
sheet.insertRule(`.available:not(.caught) { background: lightcoral !important; }`)
sheet.insertRule(`${pairMonthRule('.available:not(.caught)')} { background: #faa !important; }`)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment