Skip to content

Commit 12ea1a4

Browse files
vaisestbornaivankovicLocalIdentity
authored
Trader improvements (#9691)
* Watcher's eye trade search * Improvements per comments - move find button to separate slot instead of using exisitng jewel sockets - use exisitng Watcher's Eye slot(if available) for usage in weight calculations with test item - added option to include rest of applicable mods from Watcher's Eye mod pool that have weight 0 in final query * fix merge mistake * remove debugger setup -.- * Fix getting unweighted mods * Actually include corrupted mods * fix checkboxcontrol for watchers eye * show tooltips for watcher's eye search. either against all jewels or against an equipped eye * remove mirrored button from eye and megalomaniac search because it is useless * fix valid slot for watcher's eye * Move mods to correct places Moves the mods to their correct areas in ModParser Removes parsing for mods that we do not currently support calcs for * Fix crash when opening trader with empty jewel socket * Fix skill name parsing * add "include in person" setting * change in person selection to be a dropdown of the ones that are on the trade site * add button to find exact search result for trade tool * trade query result filtering via trader name * fix trader tool item slot anchor * improvements to timeless jewel tool: trade type and realm selections * trader tool: option to use current implicits and enchants * as per comments: move implicit and enchant overrides to query options * trader tool: add option to omit "while" eldritch mods and clarify anoint vs enchant for amulets and belts * trader tool: fix #9678 crash * trader tool: fix price based sorting #9678 * fix test for poe.ninja currencies * trader tool: add price next to item name * fix empty check in PriceBuilderProcessPoENinjaResponse * trader tool: use result - klog10(price) estimation for value sorting * Fix indents * Fix failing test Each test now runs with a clean slate as PriceBuilderProcessPoENinjaResponse was being affected by previous tests * Fix test * Fix league name and scourge ui anchor pbLeagueRealName does not exist. The correct variable is pbLeague The scourge anchor has a typo in it * Fix search for item code The trade site uses floats for the weights internally when sorting but only shows integers to the site and api Need to use +-1 so that it doesn't accidently miss an item e.g. before a weight of 100.3 would show as 100 in the api callback and then we'd search for 99.9 - 100.1 so the search would never show the item * Use last query for manually pasted strings Can now properly search for items when the user pastes a weighted sum search * Add any to trade search types * Spelling mistakes * Wrong variable name for control * More filters incase missing search elements * Issue with newItem.base.weapon bypassed rest of checks * Fix Timeless jewel league selection resetting * Remove debug console prints * Fix option depending on last changed dropdown The dropdown checked if the last changed dropdown was set to none instead of checking that both of the dropdowns were set to none. Setting an influence and setting it back to none would make the copy eldritch box become selectable when it shouldn't be * Fix weapon enchant only copying from weapon slot 1 * Comments --------- Co-authored-by: Borna Ivankovic <borna.ivankovic92@gmail.com> Co-authored-by: LocalIdentity <localidentity2@gmail.com>
1 parent be599ce commit 12ea1a4

6 files changed

Lines changed: 471 additions & 199 deletions

File tree

spec/System/TestTradeQueryCurrency_spec.lua

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
describe("TradeQuery Currency Conversion", function()
2-
local mock_tradeQuery = new("TradeQuery", { itemsTab = {} })
2+
local mock_tradeQuery
3+
4+
before_each(function()
5+
mock_tradeQuery = new("TradeQuery", { itemsTab = {} })
6+
end)
37

48
-- test case for commit: "Skip callback on errors to prevent incomplete conversions"
59
describe("FetchCurrencyConversionTable", function()
@@ -40,15 +44,19 @@ describe("TradeQuery Currency Conversion", function()
4044
end)
4145

4246
describe("PriceBuilderProcessPoENinjaResponse", function()
43-
-- Pass: Processes without error, restoring map
47+
-- Pass: Processes without error, restoring map while adding a notice
4448
-- Fail: Corrupts map or crashes, indicating fragile API response handling, breaking future conversions
4549
it("handles unmapped currency", function()
4650
local orig_conv = mock_tradeQuery.currencyConversionTradeMap
4751
mock_tradeQuery.currencyConversionTradeMap = { div = "id" }
48-
local resp = { exotic = 10 }
52+
mock_tradeQuery.pbLeague = "league"
53+
mock_tradeQuery.pbCurrencyConversion = { league = {} }
54+
mock_tradeQuery.controls.pbNotice = { label = ""}
55+
local resp = { exotic = 10 }
4956
mock_tradeQuery:PriceBuilderProcessPoENinjaResponse(resp)
5057
-- No crash expected
5158
assert.is_true(true)
59+
assert.is_true(mock_tradeQuery.controls.pbNotice.label == "No currencies received from PoE Ninja")
5260
mock_tradeQuery.currencyConversionTradeMap = orig_conv
5361
end)
5462
end)

src/Classes/ItemsTab.lua

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1585,14 +1585,14 @@ function ItemsTabClass:DeleteItem(item, deferUndoState)
15851585
end
15861586
end
15871587

1588-
local function copyAnointsAndEldritchImplicits(newItem, activeItemSet, items)
1589-
local newItemType = newItem.base.type
1590-
if activeItemSet[newItemType] then
1591-
local currentItem = activeItemSet[newItemType].selItemId and items[activeItemSet[newItemType].selItemId]
1588+
function ItemsTabClass:CopyAnointsAndEldritchImplicits(newItem, copyEldritchImplicits, overwrite, sourceSlotName)
1589+
local newItemType = sourceSlotName or (newItem.base.weapon and "Weapon 1" or newItem.base.type)
1590+
if self.activeItemSet[newItemType] then
1591+
local currentItem = self.activeItemSet[newItemType].selItemId and self.items[self.activeItemSet[newItemType].selItemId]
15921592
-- if you don't have an equipped item that matches the type of the newItem, no need to do anything
15931593
if currentItem then
15941594
-- if the new item is anointable and does not have an anoint and your current respective item does, apply that anoint to the new item
1595-
if isAnointable(newItem) and #newItem.enchantModLines == 0 and activeItemSet[newItemType].selItemId > 0 then
1595+
if isAnointable(newItem) and (#newItem.enchantModLines == 0 or overwrite) and self.activeItemSet[newItemType].selItemId > 0 then
15961596
local currentAnoint = currentItem.enchantModLines
15971597
if currentAnoint and #currentAnoint == 1 then -- skip if amulet has more than one anoint e.g. Stranglegasp
15981598
newItem.enchantModLines = currentAnoint
@@ -1607,12 +1607,20 @@ local function copyAnointsAndEldritchImplicits(newItem, activeItemSet, items)
16071607
return
16081608
end
16091609
end
1610-
if main.migrateEldritchImplicits and isValueInTable(eldritchBaseTypes, newItem.base.type) and isValueInTable(eldritchRarities, newItem.rarity)
1611-
and #newItem.implicitModLines == 0 and not newItem.corrupted and (currentItem.cleansing or currentItem.tangle) and currentItem.implicitModLines then
1610+
1611+
local modifiableItem = not (newItem.corrupted or newItem.mirrored)
1612+
if copyEldritchImplicits and isValueInTable(eldritchBaseTypes, newItem.base.type) and isValueInTable(eldritchRarities, newItem.rarity)
1613+
and (#newItem.implicitModLines == 0 or overwrite) and modifiableItem and (currentItem.cleansing or currentItem.tangle) and currentItem.implicitModLines then
16121614
newItem.implicitModLines = currentItem.implicitModLines
16131615
newItem.tangle = currentItem.tangle
16141616
newItem.cleansing = currentItem.cleansing
16151617
end
1618+
1619+
-- harvest and heist enchantments on modifiable body armour or weapons
1620+
if (newItem.base.weapon or newItem.base.type == "Body Armour") and (#newItem.enchantModLines == 0 or overwrite) and self.activeItemSet[newItemType].selItemId > 0 and modifiableItem and currentItem.enchantModLines then
1621+
newItem.enchantModLines = currentItem.enchantModLines
1622+
end
1623+
16161624
newItem:BuildAndParseRaw()
16171625
end
16181626
end
@@ -1622,7 +1630,7 @@ end
16221630
function ItemsTabClass:CreateDisplayItemFromRaw(itemRaw, normalise)
16231631
local newItem = new("Item", itemRaw)
16241632
if newItem.base then
1625-
copyAnointsAndEldritchImplicits(newItem, self.activeItemSet, self.items)
1633+
self:CopyAnointsAndEldritchImplicits(newItem, main.migrateEldritchImplicits, false)
16261634
if normalise then
16271635
newItem:NormaliseQuality()
16281636
newItem:BuildModList()

src/Classes/TradeQuery.lua

Lines changed: 133 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -184,12 +184,17 @@ function TradeQueryClass:PriceBuilderProcessPoENinjaResponse(resp)
184184
if resp then
185185
-- Populate the chaos-converted values for each tradeId
186186
for currencyName, chaosEquivalent in pairs(resp) do
187+
local currencyName = currencyName:lower()
187188
if self.currencyConversionTradeMap[currencyName] then
188189
self.pbCurrencyConversion[self.pbLeague][self.currencyConversionTradeMap[currencyName]] = chaosEquivalent
189190
else
190191
ConPrintf("Unhandled Currency Name: '"..currencyName.."'")
191192
end
192193
end
194+
-- if nothing was actually found, we should add a notice
195+
if next(self.pbCurrencyConversion[self.pbLeague]) == nil then
196+
self:SetNotice(self.controls.pbNotice, "No currencies received from PoE Ninja")
197+
end
193198
else
194199
self:SetNotice(self.controls.pbNotice, "PoE Ninja JSON Processing Error")
195200
end
@@ -277,7 +282,23 @@ You can click this button to enter your POESESSID.
277282
- You can only generate weighted searches for public leagues. (Generated searches can be modified
278283
on trade site to work on other leagues and realms)]]
279284

280-
-- Fetches Box
285+
-- Buyout selection
286+
self.tradeTypes = {
287+
"Instant buyout",
288+
"Instant buyout and in person",
289+
"In person (online in league)",
290+
"In person (online)",
291+
"Any (includes offline)"
292+
}
293+
294+
self.controls.tradeTypeSelection = new("DropDownControl", { "TOPLEFT", self.controls.poesessidButton, "BOTTOMLEFT" },
295+
{ 0, row_vertical_padding, 188, row_height }, self.tradeTypes, function(index, value)
296+
self.tradeTypeIndex = index
297+
end)
298+
-- remember previous choice
299+
self.controls.tradeTypeSelection:SetSel(self.tradeTypeIndex or 1)
300+
301+
-- Fetches Box
281302
self.maxFetchPerSearchDefault = 2
282303
self.controls.fetchCountEdit = new("EditControl", {"TOPRIGHT", nil, "TOPRIGHT"}, {-12, 19, 154, row_height}, "", "Fetch Pages", "%D", 3, function(buf)
283304
self.maxFetchPages = m_min(m_max(tonumber(buf) or self.maxFetchPerSearchDefault, 1), 10)
@@ -338,20 +359,12 @@ on trade site to work on other leagues and realms)]]
338359
[[Weighted Sum searches will always sort using descending weighted sum
339360
Additional post filtering options can be done these include:
340361
Highest Stat Value - Sort from highest to lowest Stat Value change of equipping item
341-
Highest Stat Value / Price - Sorts from highest to lowest Stat Value per currency
362+
Highest Stat Value / Price - Sorts from highest to lowest by estimated Stat Value per currency
342363
Lowest Price - Sorts from lowest to highest price of retrieved items
343364
Highest Weight - Displays the order retrieved from trade]]
344-
self.controls.itemSortSelection:SetSel(self.pbItemSortSelectionIndex)
345-
self.controls.itemSortSelectionLabel = new("LabelControl", {"TOPRIGHT", self.controls.itemSortSelection, "TOPLEFT"}, {-4, 0, 60, 16}, "^7Sort By:")
346-
347-
-- Use Enchant in DPS sorting
348-
self.controls.enchantInSort = new("CheckBoxControl", {"TOPRIGHT",self.controls.fetchCountEdit,"TOPLEFT"}, {-8, 0, row_height}, "Include Enchants:", function(state)
349-
self.enchantInSort = state
350-
for row_idx, _ in pairs(self.resultTbl) do
351-
self:UpdateControlsWithItems(row_idx)
352-
end
353-
end)
354-
self.controls.enchantInSort.tooltipText = "This includes enchants in sorting that occurs after trade results have been retrieved"
365+
-- avoid calling selFunc to avoid updating controls before they are initialised
366+
self.controls.itemSortSelection:SetSel(self.pbItemSortSelectionIndex, true)
367+
self.controls.itemSortSelectionLabel = new("LabelControl", {"TOPRIGHT", self.controls.itemSortSelection, "TOPLEFT"}, {-4, 0, 56, 16}, "^7Sort By:")
355368

356369
-- Realm selection
357370
self.controls.realmLabel = new("LabelControl", {"LEFT", self.controls.setSelect, "RIGHT"}, {18, 0, 20, row_height - 4}, "^7Realm:")
@@ -449,7 +462,7 @@ Highest Weight - Displays the order retrieved from trade]]
449462
t_insert(slotTables, { slotName = self.itemsTab.sockets[nodeId].label, nodeId = nodeId })
450463
end
451464

452-
self.controls.sectionAnchor = new("LabelControl", {"LEFT", self.controls.poesessidButton, "LEFT"}, {0, 0, 0, 0}, "")
465+
self.controls.sectionAnchor = new("LabelControl", {"LEFT", self.controls.tradeTypeSelection, "LEFT"}, {0, row_vertical_padding + row_height, 0, 0}, "")
453466
top_pane_alignment_ref = {"TOPLEFT", self.controls.sectionAnchor, "TOPLEFT"}
454467
local scrollBarShown = #slotTables > 21 -- clipping starts beyond this
455468
-- dynamically hide rows that are above or below the scrollBar
@@ -747,10 +760,7 @@ function TradeQueryClass:GetResultEvaluation(row_idx, result_index, calcFunc, ba
747760
table.sort(result.evaluation, function(a, b) return a.weight > b.weight end)
748761
else
749762
local item = new("Item", result.item_string)
750-
if not self.enchantInSort then -- Calc item DPS without anoint or enchant as these can generally be added after.
751-
item.enchantModLines = { }
752-
item:BuildAndParseRaw()
753-
end
763+
754764
local output = self:ReduceOutput(calcFunc({ repSlotName = slotName, repItem = item }))
755765
local weight = self.tradeQueryGenerator.WeightedRatioOutputs(baseOutput, output, self.statSortSelectionList)
756766
result.evaluation = {{ output = output, weight = weight }}
@@ -759,6 +769,22 @@ function TradeQueryClass:GetResultEvaluation(row_idx, result_index, calcFunc, ba
759769
end
760770

761771
-- Method to update controls after a search is completed
772+
function TradeQueryClass:UpdateDropdownList(row_idx)
773+
local dropdownLabels = {}
774+
775+
if not self.resultTbl[row_idx] then return end
776+
777+
for result_index = 1, #self.resultTbl[row_idx] do
778+
779+
local pb_index = self.sortedResultTbl[row_idx][result_index].index
780+
local result = self.resultTbl[row_idx][pb_index]
781+
local price = string.format(" %s(%d %s)", colorCodes["CURRENCY"], result.amount, result.currency)
782+
local item = new("Item", result.item_string)
783+
table.insert(dropdownLabels, colorCodes[item.rarity] .. item.name .. price)
784+
end
785+
self.controls["resultDropdown".. row_idx].selIndex = 1
786+
self.controls["resultDropdown".. row_idx]:SetList(dropdownLabels)
787+
end
762788
function TradeQueryClass:UpdateControlsWithItems(row_idx)
763789
local sortMode = self.itemSortSelectionList[self.pbItemSortSelectionIndex]
764790
local sortedItems, errMsg = self:SortFetchResults(row_idx, sortMode)
@@ -782,14 +808,7 @@ function TradeQueryClass:UpdateControlsWithItems(row_idx)
782808
amount = self.resultTbl[row_idx][pb_index].amount,
783809
}
784810
self.controls.fullPrice.label = "Total Price: " .. self:GetTotalPriceString()
785-
local dropdownLabels = {}
786-
for result_index = 1, #self.resultTbl[row_idx] do
787-
local pb_index = self.sortedResultTbl[row_idx][result_index].index
788-
local item = new("Item", self.resultTbl[row_idx][pb_index].item_string)
789-
table.insert(dropdownLabels, colorCodes[item.rarity]..item.name)
790-
end
791-
self.controls["resultDropdown".. row_idx].selIndex = 1
792-
self.controls["resultDropdown".. row_idx]:SetList(dropdownLabels)
811+
self:UpdateDropdownList(row_idx)
793812
end
794813

795814
-- Method to set the current result return in the pane based of an index
@@ -838,6 +857,7 @@ function TradeQueryClass:SortFetchResults(row_idx, mode)
838857
return newTbl
839858
elseif mode == self.sortModes.StatValue then
840859
for result_index = 1, #self.resultTbl[row_idx] do
860+
--ConPrintf("%.3f", getResultWeight(result_index))
841861
t_insert(newTbl, { outputAttr = getResultWeight(result_index), index = result_index })
842862
end
843863
table.sort(newTbl, function(a,b) return a.outputAttr > b.outputAttr end)
@@ -847,7 +867,20 @@ function TradeQueryClass:SortFetchResults(row_idx, mode)
847867
return nil, "MissingConversionRates"
848868
end
849869
for result_index = 1, #self.resultTbl[row_idx] do
850-
t_insert(newTbl, { outputAttr = getResultWeight(result_index) / priceTable[result_index], index = result_index })
870+
-- generally, because we are filtering our results to only the top
871+
-- contenders, we will end up with a small spread of result weights.
872+
-- this is however not true for prices as *decent* items might start
873+
-- at a couple of div while perfect items are worth hundreds of
874+
-- divs. I think the best option here is weight - k * log10(price)
875+
-- to prioritise good items while only slightly punishing high
876+
-- prices. another option would be weight / log10(price), but it
877+
-- still seems to overrate very cheap items that are bad
878+
879+
-- scaling factor for price
880+
local k = 0.03
881+
t_insert(newTbl,
882+
{ outputAttr = getResultWeight(result_index) - k * math.log(priceTable[result_index], 10), index =
883+
result_index })
851884
end
852885
table.sort(newTbl, function(a,b) return a.outputAttr > b.outputAttr end)
853886
elseif mode == self.sortModes.Price then
@@ -927,6 +960,7 @@ function TradeQueryClass:PriceItemRowDisplay(row_idx, top_pane_alignment_ref, ro
927960
return
928961
end
929962
context.controls["priceButton"..context.row_idx].label = "Searching..."
963+
self.lastQuery = query
930964
self.tradeQueryRequests:SearchWithQueryWeightAdjusted(self.pbRealm, self.pbLeague, query,
931965
function(items, errMsg)
932966
if errMsg then
@@ -936,6 +970,25 @@ function TradeQueryClass:PriceItemRowDisplay(row_idx, top_pane_alignment_ref, ro
936970
else
937971
self:SetNotice(context.controls.pbNotice, "")
938972
end
973+
974+
-- replace eldritch mods or enchants if the user requested
975+
-- so in TradeQueryGenerator
976+
if self.tradeQueryGenerator.lastCopyEldritch or
977+
self.tradeQueryGenerator.lastCopyEnchantMode == "Copy Current" then
978+
for i, _ in ipairs(items) do
979+
local item = new("Item", items[i].item_string)
980+
self.itemsTab:CopyAnointsAndEldritchImplicits(item, true, true, context.slotTbl.slotName)
981+
items[i].item_string = item:BuildRaw()
982+
end
983+
elseif self.tradeQueryGenerator.lastCopyEnchantMode == "Remove" then
984+
for i, _ in ipairs(items) do
985+
local item = new("Item", items[i].item_string)
986+
item.enchantModLines = {}
987+
items[i].item_string = item:BuildRaw()
988+
end
989+
end
990+
991+
939992
self.resultTbl[context.row_idx] = items
940993
self:UpdateControlsWithItems(context.row_idx)
941994
context.controls["priceButton"..context.row_idx].label = "Price Item"
@@ -983,11 +1036,12 @@ function TradeQueryClass:PriceItemRowDisplay(row_idx, top_pane_alignment_ref, ro
9831036
controls["priceButton"..row_idx] = new("ButtonControl", { "TOPLEFT", controls["uri"..row_idx], "TOPRIGHT"}, {8, 0, 100, row_height}, "Price Item",
9841037
function()
9851038
controls["priceButton"..row_idx].label = "Searching..."
986-
self.tradeQueryRequests:SearchWithURL(controls["uri"..row_idx].buf, function(items, errMsg)
1039+
self.tradeQueryRequests:SearchWithURL(controls["uri"..row_idx].buf, function(items, errMsg, query)
9871040
if errMsg then
9881041
self:SetNotice(controls.pbNotice, "Error: " .. errMsg)
9891042
else
9901043
self:SetNotice(controls.pbNotice, "")
1044+
self.lastQuery = query
9911045
self.resultTbl[row_idx] = items
9921046
self:UpdateControlsWithItems(row_idx)
9931047
end
@@ -1019,15 +1073,11 @@ function TradeQueryClass:PriceItemRowDisplay(row_idx, top_pane_alignment_ref, ro
10191073
self.controls.fullPrice.label = "Total Price: " .. self:GetTotalPriceString()
10201074
end)
10211075
controls["changeButton"..row_idx].shown = function() return self.resultTbl[row_idx] end
1022-
local dropdownLabels = {}
1023-
for _, sortedResult in ipairs(self.sortedResultTbl[row_idx] or {}) do
1024-
local item = new("Item", self.resultTbl[row_idx][sortedResult.index].item_string)
1025-
table.insert(dropdownLabels, colorCodes[item.rarity]..item.name)
1026-
end
1027-
controls["resultDropdown"..row_idx] = new("DropDownControl", { "TOPLEFT", controls["changeButton"..row_idx], "TOPRIGHT"}, {8, 0, 325, row_height}, dropdownLabels, function(index)
1076+
controls["resultDropdown"..row_idx] = new("DropDownControl", { "TOPLEFT", controls["changeButton"..row_idx], "TOPRIGHT"}, {8, 0, 325, row_height}, {}, function(index)
10281077
self.itemIndexTbl[row_idx] = self.sortedResultTbl[row_idx][index].index
10291078
self:SetFetchResultReturn(row_idx, self.itemIndexTbl[row_idx])
10301079
end)
1080+
self:UpdateDropdownList(row_idx)
10311081
local function addMegalomaniacCompareToTooltipIfApplicable(tooltip, result_index)
10321082
if slotTbl.slotName ~= "Megalomaniac" then
10331083
return
@@ -1103,23 +1153,58 @@ function TradeQueryClass:PriceItemRowDisplay(row_idx, top_pane_alignment_ref, ro
11031153
return self.itemIndexTbl[row_idx] and self.resultTbl[row_idx][self.itemIndexTbl[row_idx]].item_string ~= nil
11041154
end
11051155
-- Whisper so we can copy to clipboard
1106-
controls["whisperButton"..row_idx] = new("ButtonControl", { "TOPLEFT", controls["importButton"..row_idx], "TOPRIGHT"}, {8, 0, 185, row_height}, function()
1107-
return self.totalPrice[row_idx] and "Whisper for " .. self.totalPrice[row_idx].amount .. " " .. self.totalPrice[row_idx].currency or "Whisper"
1108-
end, function()
1109-
Copy(self.resultTbl[row_idx][self.itemIndexTbl[row_idx]].whisper)
1110-
end)
1111-
controls["whisperButton"..row_idx].enabled = function()
1112-
return self.itemIndexTbl[row_idx] and self.resultTbl[row_idx][self.itemIndexTbl[row_idx]].whisper ~= nil
1113-
end
1114-
controls["whisperButton"..row_idx].tooltipFunc = function(tooltip)
1156+
controls["whisperButton" .. row_idx] = new("ButtonControl",
1157+
{ "TOPLEFT", controls["importButton" .. row_idx], "TOPRIGHT" }, { 8, 0, 170, row_height }, function()
1158+
local itemResult = self.itemIndexTbl[row_idx] and self.resultTbl[row_idx][self.itemIndexTbl[row_idx]]
1159+
1160+
if not itemResult then return "" end
1161+
1162+
local price = self.totalPrice[row_idx] and
1163+
self.totalPrice[row_idx].amount .. " " .. self.totalPrice[row_idx].currency
1164+
1165+
if itemResult.whisper then
1166+
return price and "Whisper for " .. price or "Whisper"
1167+
else
1168+
return price and "Search for " .. price or "Search"
1169+
end
1170+
1171+
end, function()
1172+
local itemResult = self.itemIndexTbl[row_idx] and self.resultTbl[row_idx][self.itemIndexTbl[row_idx]]
1173+
if itemResult.whisper then
1174+
Copy(itemResult.whisper)
1175+
else
1176+
local exactQuery = dkjson.decode(self.lastQuery)
1177+
-- use trade sum to get the specific item. both min and max
1178+
-- weight on site uses floats but only shows integer in the api
1179+
-- e.g. weight of 172.3 shows up as 172 in the api
1180+
exactQuery.query.stats[1].value = { min = floor(itemResult.weight, 1) - 1, max = round(itemResult.weight, 1) + 1 }
1181+
-- also apply trader name. this should make false positives
1182+
-- extremely unlikely. this doesn't seem to take up a filter slot
1183+
exactQuery.query.filters = exactQuery.query.filters or { }
1184+
exactQuery.query.filters.trade_filters = exactQuery.query.filters.trade_filters or { filters = { } }
1185+
exactQuery.query.filters.trade_filters.filters = exactQuery.query.filters.trade_filters.filters or { }
1186+
exactQuery.query.filters.trade_filters.filters.account = { input = itemResult.trader }
1187+
1188+
local exactQueryStr = dkjson.encode(exactQuery)
1189+
1190+
self.tradeQueryRequests:SearchWithQuery(self.pbRealm, self.pbLeague, exactQueryStr, function(_, _)
1191+
end, {callbackQueryId = function(queryId)
1192+
local url = self.hostName.."trade/search/"..self.pbLeague.."/"..queryId
1193+
Copy(url)
1194+
OpenURL(url)
1195+
end})
1196+
end
1197+
end)
1198+
1199+
controls["whisperButton" .. row_idx].tooltipFunc = function(tooltip)
11151200
tooltip:Clear()
1116-
if self.itemIndexTbl[row_idx] and self.resultTbl[row_idx][self.itemIndexTbl[row_idx]].item_string then
1117-
tooltip.center = true
1118-
tooltip:AddLine(16, "Copies the item purchase whisper to the clipboard")
1119-
end
1201+
tooltip.center = true
1202+
local itemResult = self.itemIndexTbl[row_idx] and self.resultTbl[row_idx][self.itemIndexTbl[row_idx]]
1203+
local text = itemResult.whisper and "Copies the item purchase whisper to the clipboard" or
1204+
"Opens the search page to show the item"
1205+
tooltip:AddLine(16, text)
11201206
end
11211207
end
1122-
11231208
-- Method to update the Total Price string sum of all items
11241209
function TradeQueryClass:GetTotalPriceString()
11251210
local text = ""

0 commit comments

Comments
 (0)