diff --git a/extension/changelog.json b/extension/changelog.json
index 825919c65..453c40803 100644
--- a/extension/changelog.json
+++ b/extension/changelog.json
@@ -4,7 +4,10 @@
"title": "Beta",
"date": false,
"logs": {
- "features": [{ "message": "Sidebar timer for OC 2.", "contributor": "DeKleineKobini" }],
+ "features": [
+ { "message": "Sidebar timer for OC 2.", "contributor": "DeKleineKobini" },
+ { "message": "Fill Max for Item Market 2.0.", "contributor": "TheFoxMan" }
+ ],
"fixes": [],
"changes": [
{ "message": "Disable OC1 timer when detecting OC 2 data.", "contributor": "DeKleineKobini" },
diff --git a/extension/manifest.json b/extension/manifest.json
index 7075bb709..85c6a9e89 100644
--- a/extension/manifest.json
+++ b/extension/manifest.json
@@ -430,11 +430,16 @@
},
{
"matches": ["https://www.torn.com/page.php?sid=ItemMarket*"],
- "css": ["scripts/features/drug-details/ttDrugDetails.css", "scripts/features/highlight-cheap-items/ttHighlightCheapItems.css"],
+ "css": [
+ "scripts/features/drug-details/ttDrugDetails.css",
+ "scripts/features/highlight-cheap-items/ttHighlightCheapItems.css",
+ "scripts/features/item-market-fill-max/ttItemMarketFillMax.css"
+ ],
"js": [
"scripts/content/itemmarket/ttItemMarket.js",
"scripts/features/drug-details/ttDrugDetails.js",
- "scripts/features/highlight-cheap-items/ttHighlightCheapItems.js"
+ "scripts/features/highlight-cheap-items/ttHighlightCheapItems.js",
+ "scripts/features/item-market-fill-max/ttItemMarketFillMax.js"
],
"run_at": "document_end"
},
diff --git a/extension/pages/settings/settings.html b/extension/pages/settings/settings.html
index bdf47d6f0..3c224837a 100644
--- a/extension/pages/settings/settings.html
+++ b/extension/pages/settings/settings.html
@@ -1604,6 +1604,10 @@
+
+
+
+
diff --git a/extension/scripts/features/item-market-fill-max/ttItemMarketFillMax.css b/extension/scripts/features/item-market-fill-max/ttItemMarketFillMax.css
new file mode 100644
index 000000000..e87faa67c
--- /dev/null
+++ b/extension/scripts/features/item-market-fill-max/ttItemMarketFillMax.css
@@ -0,0 +1,19 @@
+.tt-show-fill-max [class*="rowWrapper__"] [class*="available__"] {
+ align-items: flex-start;
+ padding-top: 5px;
+}
+
+.tt-show-fill-max [class*="rowWrapper__"] [class*="available__"]::after {
+ content: "Fill Max";
+ position: absolute;
+ top: 20px;
+ color: var(--tt-color-green);
+ cursor: pointer;
+ width: calc(100px - 2 * 7px);
+ text-align: right;
+}
+
+body:not(.tt-mobile):not(.tt-tablet) .tt-show-fill-max [class*="rowWrapper__"] [class*="available__"]:hover::after {
+ color: #fff;
+ background-color: var(--tt-color-green);
+}
diff --git a/extension/scripts/features/item-market-fill-max/ttItemMarketFillMax.js b/extension/scripts/features/item-market-fill-max/ttItemMarketFillMax.js
new file mode 100644
index 000000000..e11957603
--- /dev/null
+++ b/extension/scripts/features/item-market-fill-max/ttItemMarketFillMax.js
@@ -0,0 +1,49 @@
+"use strict";
+
+(async () => {
+ const { mobile, tablet } = await checkDevice();
+
+ const feature = featureManager.registerFeature(
+ "Item Market Fill Max",
+ "item market",
+ () => settings.pages.itemmarket.fillMax,
+ addListener,
+ addButton,
+ removeButton,
+ { storage: ["settings.pages.itemmarket.fillMax"] },
+ () => {
+ if (!hasAPIData()) return "No API access.";
+ }
+ );
+
+ function addListener() {
+ document.addEventListener("click", (event) => {
+ if (!event.target.matches("[class*='rowWrapper__'] [class*='available__']")) return;
+
+ if (!feature.enabled()) return;
+
+ const listing = event.target.closest("li");
+ // The purchase amount input is not visible in mobiles and tablets until
+ // the Buy icon is clicked. Hence exit early.
+ if ((mobile || tablet) && !listing.children[0].matches("[class*='sellerRow__'][class*='expanded__']")) return;
+
+ const quantityAvailable = listing.find("[class*='available__']").textContent.getNumber();
+ const moneyOnHand = document.find("#user-money").dataset.money.getNumber();
+ const itemPrice = listing.find("[class*='price__']").textContent.getNumber();
+ const purchasableQuantity = Math.min(quantityAvailable, Math.floor(moneyOnHand / itemPrice));
+
+ const quantityInput = listing.find(".input-money-group input:not([type])");
+ updateReactInput(quantityInput, purchasableQuantity);
+ });
+ }
+
+ async function addButton() {
+ const itemMarketRoot = await requireElement("#item-market-root");
+
+ itemMarketRoot.classList.add("tt-show-fill-max");
+ }
+
+ function removeButton() {
+ document.findAll(".tt-show-fill-max").forEach((x) => x.classList.remove("tt-show-fill-max"));
+ }
+})();
diff --git a/extension/scripts/global/globalData.js b/extension/scripts/global/globalData.js
index 518a0a2b9..0f538dd1c 100644
--- a/extension/scripts/global/globalData.js
+++ b/extension/scripts/global/globalData.js
@@ -661,6 +661,7 @@ const DEFAULT_STORAGE = {
itemmarket: {
highlightCheapItems: new DefaultSetting({ type: "number|empty", defaultValue: "" }),
leftBar: new DefaultSetting({ type: "boolean", defaultValue: false }),
+ fillMax: new DefaultSetting({ type: "boolean", defaultValue: true }),
},
competition: {
filter: new DefaultSetting({ type: "boolean", defaultValue: true }),