From 94ea95ac429f7ac190193fe841ee31c3dab373f8 Mon Sep 17 00:00:00 2001 From: Travis Smith Date: Fri, 14 Feb 2025 17:08:10 -0500 Subject: [PATCH] Adding feature to highlight items in the Bazaar when it's below the vendor price. (#835) - requires turning it on in options - requires an API key - works in FF & Chrome; including when the viewport is small (e.g., mobile sized) - updated manifest for new files - updated CONTRIBUTING for a bit more on testing in browsers - added option to settings & global defaults --- CONTRIBUTING.md | 5 ++ extension/changelog.json | 3 +- extension/manifest.json | 10 ++- extension/pages/settings/settings.html | 4 ++ .../ttSubVendorPriceItems.css | 7 ++ .../ttSubVendorPriceItems.entry.js | 70 +++++++++++++++++++ extension/scripts/global/globalData.js | 1 + extension/scripts/global/team.js | 7 ++ 8 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 extension/scripts/features/bazaar-sub-vendor-items/ttSubVendorPriceItems.css create mode 100644 extension/scripts/features/bazaar-sub-vendor-items/ttSubVendorPriceItems.entry.js diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 08aab0ec8..0f2a6f9fc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -78,6 +78,11 @@ We have prettier formatting to help you follow our coding conventions. ## Development Tips +### Testing + +* Chrome: [load an unpacked extension](https://developer.chrome.com/docs/extensions/get-started/tutorial/hello-world#load-unpacked) +* Firefox: [install a temporary extension](https://extensionworkshop.com/documentation/develop/temporary-installation-in-firefox/) + ##### Ignore local manifest.json changes. This can be used to remove the Firefox only setting to avoid warnings in Chromium-browsers. diff --git a/extension/changelog.json b/extension/changelog.json index e9523c749..9c2a122a4 100644 --- a/extension/changelog.json +++ b/extension/changelog.json @@ -8,7 +8,8 @@ "fixes": [{ "message": "Fix the company id showing something wrong.", "contributor": "DeKleineKobini" }], "changes": [ { "message": "Change layout of preferences page on mobiles.", "contributor": "TheFoxMan" }, - { "message": "Correctly list Love Juice cooldown.", "contributor": "TheFoxMan" } + { "message": "Correctly list Love Juice cooldown.", "contributor": "TheFoxMan" }, + { "message": "Option to highlight items in Bazaars that have a ccost less than the vendor price.", "contributor": "TravisTheTechie" } ], "removed": [] } diff --git a/extension/manifest.json b/extension/manifest.json index ad38f6b9b..b3f7c985d 100644 --- a/extension/manifest.json +++ b/extension/manifest.json @@ -247,8 +247,14 @@ }, { "matches": ["https://www.torn.com/bazaar.php*"], - "css": ["scripts/features/bazaar-worth/ttBazaarWorth.css"], - "js": ["scripts/features/bazaar-worth/ttBazaarWorth.entry.js"], + "css": [ + "scripts/features/bazaar-worth/ttBazaarWorth.css", + "scripts/features/bazaar-sub-vendor-items/ttSubVendorPriceItems.css" + ], + "js": [ + "scripts/features/bazaar-worth/ttBazaarWorth.entry.js", + "scripts/features/bazaar-sub-vendor-items/ttSubVendorPriceItems.entry.js" + ], "run_at": "document_start" }, { diff --git a/extension/pages/settings/settings.html b/extension/pages/settings/settings.html index 4e786dd50..2b7764b78 100644 --- a/extension/pages/settings/settings.html +++ b/extension/pages/settings/settings.html @@ -1235,6 +1235,10 @@

+
+ + +
Gym
diff --git a/extension/scripts/features/bazaar-sub-vendor-items/ttSubVendorPriceItems.css b/extension/scripts/features/bazaar-sub-vendor-items/ttSubVendorPriceItems.css new file mode 100644 index 000000000..1f574e072 --- /dev/null +++ b/extension/scripts/features/bazaar-sub-vendor-items/ttSubVendorPriceItems.css @@ -0,0 +1,7 @@ +.tt-sub-vendor-highlight { + background-color: var(--tt-color-green--40) !important; +} + +.tt-sub-vendor-highlight [class*=buyForm___] { + background-color: #f1f1f1 !important; +} diff --git a/extension/scripts/features/bazaar-sub-vendor-items/ttSubVendorPriceItems.entry.js b/extension/scripts/features/bazaar-sub-vendor-items/ttSubVendorPriceItems.entry.js new file mode 100644 index 000000000..0081aec4b --- /dev/null +++ b/extension/scripts/features/bazaar-sub-vendor-items/ttSubVendorPriceItems.entry.js @@ -0,0 +1,70 @@ +"use strict"; + +(async () => { + await featureManagerLoaded(); + + const CLASS_NAME = "tt-sub-vendor-highlight"; + let observer; + + // noinspection JSIncompatibleTypesComparison + featureManager.registerFeature( + "Highlight Cheap Items", + "bazaar", + () => settings.pages.bazaar.highlightSubVendorItems !== "", + initialise, + highlightEverything, + removeHighlights, + { + storage: ["settings.pages.bazaar.highlightSubVendorItems"], + }, + () => { + if (!hasAPIData()) return "No API access."; + } + ); + + async function initialise() { + observer = new MutationObserver(() => { highlightEverything() }); + observer.observe(document.body, { + childList: true, + subtree: true + }); + } + + function highlightEverything() { + const items = [...document.findAll("[class*='item__'] > [class*='itemDescription__']")] + .map((element) => { + return { + element, + id: element.find("img").src.getNumber(), + price: element.find("[class*='price___']").textContent.getNumber() + } + }) + .filter((item) => item.element); + + items.forEach((item) => handleItem(item)); + } + + /** + * Should highlight the given item based on the price? + * @param id {number|string} + * @param price {number} + * @returns {boolean} + */ + function shouldHighlight(id, price) { + return price < torndata.items[id]?.sell_price; + } + + function handleItem(item) { + if (shouldHighlight(item.id, item.price)) { + item.element.parentElement.classList.add(CLASS_NAME); + } else { + item.element.parentElement.classList.remove(CLASS_NAME); + } + } + + function removeHighlights() { + observer?.disconnect(); + document.findAll(`.${CLASS_NAME}`) + .forEach((item) => item.classList.remove(CLASS_NAME)); + } +})(); diff --git a/extension/scripts/global/globalData.js b/extension/scripts/global/globalData.js index 75bffed92..8161726e1 100644 --- a/extension/scripts/global/globalData.js +++ b/extension/scripts/global/globalData.js @@ -570,6 +570,7 @@ const DEFAULT_STORAGE = { worth: new DefaultSetting({ type: "boolean", defaultValue: true }), fillMax: new DefaultSetting({ type: "boolean", defaultValue: true }), maxBuyIgnoreCash: new DefaultSetting({ type: "boolean", defaultValue: false }), + highlightSubVendorItems: new DefaultSetting({ type: "boolean", defaultValue: false }), }, trade: { itemValues: new DefaultSetting({ type: "boolean", defaultValue: true }), diff --git a/extension/scripts/global/team.js b/extension/scripts/global/team.js index e72c23f5e..2dcfc6772 100644 --- a/extension/scripts/global/team.js +++ b/extension/scripts/global/team.js @@ -217,6 +217,13 @@ const TEAM = [ torn: 2383326, color: "white", // No explicit color chosen. }, + { + name: "TravisTheTechie", + title: "Developer", + core: false, + torn: 3549588, + color: "firebrick", + }, ]; const CONTRIBUTORS = TEAM.filter(({ title, color }) => title.includes("Developer") || color).reduce(