diff --git a/background.js b/background.js index a6ea4fb..8240d57 100644 --- a/background.js +++ b/background.js @@ -1,92 +1,123 @@ -// generate the context menus brought up by clicking the browser action -chrome.storage.sync.get("numHairImages", function(items) { - var hairCount = items.hasOwnProperty("numHairImages") ? items.numHairImages : 1; - - chrome.contextMenus.removeAll(); - chrome.contextMenus.create({ - title: hairCountText(hairCount), - id: "hair_count", - contexts: ["action"], - enabled: false - }); - chrome.contextMenus.create({ - title: "More hair!", - id: "more_hair", - contexts: ["action"] - }); - chrome.contextMenus.create({ - title: "Less hair!", - id: "less_hair", - contexts: ["action"] - }); - chrome.contextMenus.create({ - title: "Reset hair!", - id: "reset_hair", - contexts: ["action"] - }); - chrome.contextMenus.create({ - title: "Randomize hair!", - id: "randomize_hair", - contexts: ["action"] - }); - chrome.contextMenus.create({ - title: "(reload after updating)", - id: "reload_prompt", - contexts: ["action"], - enabled: false +chrome.storage.sync.get("numHairImages", function (items) { + var hairCount = items.hasOwnProperty("numHairImages") + ? items.numHairImages + : 1; + + chrome.storage.local.get("guiEnabled", (data) => { + const enabled = data.guiEnabled ?? false; + updatePopup(enabled); + + chrome.contextMenus.removeAll(); + chrome.contextMenus.create({ + title: hairCountText(hairCount), + id: "hair_count", + contexts: ["action"], + enabled: false, + }); + chrome.contextMenus.create({ + title: "More hair!", + id: "more_hair", + contexts: ["action"], + }); + chrome.contextMenus.create({ + title: "Less hair!", + id: "less_hair", + contexts: ["action"], + }); + chrome.contextMenus.create({ + title: "Reset hair!", + id: "reset_hair", + contexts: ["action"], + }); + chrome.contextMenus.create({ + title: "Randomize hair!", + id: "randomize_hair", + contexts: ["action"], + }); + chrome.contextMenus.create({ + title: "Allow GUI menu", + id: "toggleGui", + type: "checkbox", + checked: enabled, + contexts: ["action"], + }); + chrome.contextMenus.create({ + title: "(reload after updating)", + id: "reload_prompt", + contexts: ["action"], + enabled: false, + }); }); }); -// handle context menu clicks -chrome.contextMenus.onClicked.addListener(function (info) { +chrome.contextMenus.onClicked.addListener((info) => { if (info.menuItemId == "more_hair") incrementNumImages(); else if (info.menuItemId == "less_hair") decrementNumImages(); else if (info.menuItemId == "randomize_hair") randomizeHair(); else if (info.menuItemId == "reset_hair") resetNumImages(); + else if (info.menuItemId == "toggleGui") toggleGui(info.checked); }); -// displays count function hairCountText(num) { return "Hair count: " + num; } -// general function for updating the hair count function updateNumImages(updateFunction) { - chrome.storage.sync.get("numHairImages", function(items) { - var numHairImages; - if (items.hasOwnProperty("numHairImages")) { - numHairImages = updateFunction(items.numHairImages); - } - else { - numHairImages = updateFunction(1); - } - - chrome.storage.sync.set( {"numHairImages": numHairImages } ); - - chrome.contextMenus.update("hair_count", { title: hairCountText(numHairImages) }); + chrome.storage.sync.get("numHairImages", function (items) { + var numHairImages = items.hasOwnProperty("numHairImages") + ? updateFunction(items.numHairImages) + : updateFunction(1); + chrome.storage.sync.set({ numHairImages: numHairImages }); + chrome.contextMenus.update("hair_count", { + title: hairCountText(numHairImages), + }); }); } -// increment count function incrementNumImages() { - updateNumImages(function(num) { - return num + 1; - }); + updateNumImages((num) => Math.min(2048, num + 1)); } - -// decrement count function decrementNumImages() { - updateNumImages(function(num) { - return Math.max(0, num-1); - }); + updateNumImages((num) => Math.max(0, num - 1)); } - -// reset count to 1 function resetNumImages() { - updateNumImages( function() { return 1; } ); + updateNumImages(() => 1); } - -// randomize positions function randomizeHair() { - chrome.storage.sync.set( { "hairImages": [] } ); -} \ No newline at end of file + chrome.storage.sync.set({ hairImages: [] }); +} + +function updatePopup(enabled) { + chrome.action.setPopup({ popup: enabled ? "popup.html" : "" }); +} + +function toggleGui(checked) { + chrome.storage.local.set({ guiEnabled: checked }); + updatePopup(checked); +} + +chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => { + let action = message.action; + if (action == "getNumImages") { + chrome.storage.sync.get("numHairImages", (items) => { + sendResponse({ numImages: items.numHairImages ?? 1 }); + }); + return true; + } + if (action == "popupCallIncrement") { + incrementNumImages(); + sendResponse({}); + } else if (action == "popupCallDecrement") { + decrementNumImages(); + sendResponse({}); + } else if (action == "popupCallReset") { + resetNumImages(); + sendResponse({}); + } else if (action == "popupCallRandomize") { + randomizeHair(); + sendResponse({}); + } else if (action == "popupCallSetExact") { + updateNumImages(() => message.value); + sendResponse({}); + } +}); diff --git a/content_script.js b/content_script.js index e5017e0..97c5813 100644 --- a/content_script.js +++ b/content_script.js @@ -1,58 +1,58 @@ var w = 200; var h = 200; var imageUrls = [ - 'assets/h1.png', - 'assets/h2.png', - 'assets/h3.png', - 'assets/h4.png', - 'assets/h5.png', - 'assets/h6.png', - 'assets/h7.png', - 'assets/h8.png', - 'assets/h9.png', - 'assets/h10.png', - 'assets/h11.png', - 'assets/h12.png', - 'assets/h13.png', - 'assets/h14.png', - 'assets/h15.png' + "assets/h1.png", + "assets/h2.png", + "assets/h3.png", + "assets/h4.png", + "assets/h5.png", + "assets/h6.png", + "assets/h7.png", + "assets/h8.png", + "assets/h9.png", + "assets/h10.png", + "assets/h11.png", + "assets/h12.png", + "assets/h13.png", + "assets/h14.png", + "assets/h15.png", ]; render(); function render() { // get the number of images in the global store - chrome.storage.sync.get("numHairImages", function(items) { + chrome.storage.sync.get("numHairImages", function (items) { var numHairImages = 1; if (items.hasOwnProperty("numHairImages")) { numHairImages = items.numHairImages; } // if no image number in the store, store the default number else { - chrome.storage.sync.set( {"numHairImages": numHairImages } ); + chrome.storage.sync.set({ numHairImages: numHairImages }); } - + insertImages(numHairImages); }); } function insertImages(numHairImages) { - chrome.storage.sync.get("hairImages", function(items) { + chrome.storage.sync.get("hairImages", function (items) { var hairImages = []; var needUpdate = false; - + if (items.hasOwnProperty("hairImages")) { hairImages = items.hairImages; } - for (var i=0; i + + + + + Hair on Screen + + + + + + +
+
+
+

Hair on screen

+

0

+
+ +
+ +
+ +
+ + +
+ +
+ + +
+ +
+ +
+ + +
+ +

+ You can toggle this popups visibility in the context menu for discrete + pranking! +

+
+ + + + diff --git a/popup.js b/popup.js new file mode 100644 index 0000000..332871c --- /dev/null +++ b/popup.js @@ -0,0 +1,102 @@ +document.addEventListener("DOMContentLoaded", () => { + main(); +}); + +function main() { + update_count(true); + document.getElementById("increment").addEventListener("click", () => { + chrome.runtime.sendMessage( + { + action: "popupCallIncrement", + }, + () => { + update_count(); + }, + ); + }); + + document.getElementById("decrement").addEventListener("click", () => { + chrome.runtime.sendMessage( + { + action: "popupCallDecrement", + }, + () => { + update_count(); + }, + ); + }); + + document.getElementById("randomize").addEventListener("click", () => { + chrome.runtime.sendMessage( + { + action: "popupCallRandomize", + }, + () => { + needs_reset(); + }, + ); + }); + + document.getElementById("reset").addEventListener("click", () => { + chrome.runtime.sendMessage( + { + action: "popupCallReset", + }, + () => { + update_count(); + }, + ); + }); + + document.getElementById("reloadPage").addEventListener("click", () => { + chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { + chrome.tabs.reload(tabs[0].id, () => { + show_status("Page Reloaded!", false); + }); + }); + }); + + document.getElementById("exact").addEventListener("click", () => { + const raw = parseInt(document.getElementById("exactIn").value, 10); + const value = isNaN(raw) ? 0 : raw; + if (value >= 0 && value <= 2048) { + chrome.runtime.sendMessage( + { action: "popupCallSetExact", value: value }, + () => { + update_count(); + }, + ); + } else { + show_status("hair amount must be between 0 and 2048!", true); + } + }); + + document.getElementById("exactIn").addEventListener("keydown", (k) => { + if (k.key === "Enter") { + document.getElementById("exact").click(); + } + }); +} + +function update_count(offrip = false) { + let counter = document.getElementById("counter"); + + chrome.runtime.sendMessage({ action: "getNumImages" }, (response) => { + counter.textContent = response.numImages; + }); + + if (!offrip) { + needs_reset(); + } +} + +function needs_reset() { + show_status("Webpage must be reloaded for changes to become visible!"); +} + +function show_status(text, isWarn = false) { + const el = document.getElementById("needsReset"); + el.textContent = text; + el.classList.remove("hidden"); + el.classList.toggle("warn", isWarn); +}