Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ The repository is structured as a multi-addon project separating core logic, con
| scale | number | 1.0 |
| lock | boolean | false |
| autoConfirmRolls | boolean | false |
| confirmGreedAndPass | boolean | false |
| keepOpenAfterVote | boolean | false |
| resultLingerDuration | number | 3 |
| showRollTally | boolean | false |
Expand Down Expand Up @@ -94,7 +95,7 @@ The repository is structured as a multi-addon project separating core logic, con
| timerBarStyle | string | "normal" |
| timerBarMinimalHeight | number | 3 |

`resultLingerDuration` applies only when `keepOpenAfterVote` is enabled. `showRollTally` is available only on Classic (TBC/MoP); Retail removed `C_LootHistory.GetItem` and `GetPlayerInfo` in patch 10.1.0.
`confirmGreedAndPass` asks for confirmation before Greed or Pass is submitted. `resultLingerDuration` applies only when `keepOpenAfterVote` is enabled. `showRollTally` is available only on Classic (TBC/MoP); Retail removed `C_LootHistory.GetItem` and `GetPlayerInfo` in patch 10.1.0.

### History (`db.profile.history`)

Expand Down
9 changes: 4 additions & 5 deletions DragonLoot/Core/Config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ local defaults = {
scale = 1.0,
lock = false,
autoConfirmRolls = false,
confirmGreedAndPass = false,
keepOpenAfterVote = false,
resultLingerDuration = 3,
showRollTally = false,
Expand Down Expand Up @@ -144,7 +145,7 @@ local defaults = {
-- Profile Migration
-------------------------------------------------------------------------------

local CURRENT_SCHEMA = 4
local CURRENT_SCHEMA = 5

local function DeepCopyValue(value)
if type(value) ~= "table" then
Expand Down Expand Up @@ -245,10 +246,8 @@ local function MigrateProfile(db)
end
end

-- v3 -> v4: introduce db.char.history.entries for persistent loot history (issue #104).
-- No profile data needs transformation - the new char scope is added by AceDB's defaults
-- handling when InitializeDB passes the updated defaults table to AceDB:New. The schema
-- bump is recorded by the unconditional assignment to profile.schemaVersion below.
-- v3 -> v4 introduced db.char.history.entries. AceDB applies that char-scope
-- default when InitializeDB creates the database, so no profile transform is needed.

profile.schemaVersion = CURRENT_SCHEMA
end
Expand Down
10 changes: 1 addition & 9 deletions DragonLoot/Display/RollFrame.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ local ShoppingTooltip2 = ShoppingTooltip2
local UIParent = UIParent
local GetLootRollItemInfo = GetLootRollItemInfo
local GetLootRollItemLink = GetLootRollItemLink
local RollOnLoot = RollOnLoot
local HandleModifiedItemClick = HandleModifiedItemClick
local C_Texture = C_Texture
local C_Item = C_Item
Expand Down Expand Up @@ -494,14 +493,7 @@ local function OnRollButtonClick(self)
return
end
if frame.rollID then
-- Mark pending hide BEFORE RollOnLoot; synchronous CONFIRM_LOOT_ROLL
-- will clear the flag if a confirmation popup is needed.
ns.RollManager.MarkPendingHide(frame.rollID)

RollOnLoot(frame.rollID, self.rollType)

-- Hide now unless CONFIRM_LOOT_ROLL intercepted (flag cleared)
ns.RollManager.TryHideAfterVote(frame.rollID, self.rollType)
ns.RollManager.RequestRollSelection(frame.rollID, self.rollType)
end
end

Expand Down
112 changes: 112 additions & 0 deletions DragonLoot/Display/RollManager.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ local _, ns = ...
local GetTime = GetTime
local GetLootRollItemInfo = GetLootRollItemInfo
local GetLootRollItemLink = GetLootRollItemLink
local RollOnLoot = RollOnLoot
local StaticPopup_Show = StaticPopup_Show
local UnitName = UnitName
local UnitClass = UnitClass
local max = math.max
Expand Down Expand Up @@ -109,6 +111,53 @@ local function GetResultLingerDuration()
return (settings and settings.resultLingerDuration) or DEFAULT_RESULT_LINGER_SECONDS
end

local function ShouldConfirmSelection(rollType)
local settings = GetRollFrameSettings()
if not settings or not settings.confirmGreedAndPass then
return false
end
return rollType == ROLL_TYPE_GREED or rollType == ROLL_TYPE_PASS
end

local function ClearSelectionConfirmation(roll, dialog)
if not roll or roll.selectionConfirmationDialog ~= dialog then
return false
end
roll.pendingSelectionRollType = nil
roll.selectionConfirmationDialog = nil
return true
end

local function DismissSelectionConfirmation(roll)
local dialog = roll and roll.selectionConfirmationDialog
if not dialog then
return
end
dialog.data = nil
roll.pendingSelectionRollType = nil
roll.selectionConfirmationDialog = nil
dialog:Hide()
end

local function DismissOtherSelectionConfirmations(rollID)
for activeRollID, activeRoll in pairs(activeRolls) do
if activeRollID ~= rollID then
DismissSelectionConfirmation(activeRoll)
end
end
end

local function SubmitRollSelection(rollID, rollType)
local roll = activeRolls[rollID]
if not roll or not roll.frameIndex or roll.heldAfterVote then
return
end

ns.RollManager.MarkPendingHide(rollID)
RollOnLoot(rollID, rollType)
ns.RollManager.TryHideAfterVote(rollID, rollType)
end

-------------------------------------------------------------------------------
-- StaticPopup for roll confirmations (shared by Retail and Classic listeners)
-------------------------------------------------------------------------------
Expand All @@ -129,6 +178,35 @@ StaticPopupDialogs["DRAGONLOOT_CONFIRM_LOOT_ROLL"] = {
hideOnEscape = 1,
}

StaticPopupDialogs["DRAGONLOOT_CONFIRM_ROLL_SELECTION"] = {
text = L["Are you sure you want to choose %s for %s?"],
button1 = YES,
button2 = NO,
OnAccept = function(self)
local data = self.data
self.data = nil
if not data then
return
end
local roll = activeRolls[data.rollID]
if not ClearSelectionConfirmation(roll, self) then
return
end
SubmitRollSelection(data.rollID, data.rollType)
end,
OnCancel = function(self)
local data = self.data
self.data = nil
if not data then
return
end
ClearSelectionConfirmation(activeRolls[data.rollID], self)
end,
timeout = 0,
whileDead = 1,
hideOnEscape = 1,
}

-------------------------------------------------------------------------------
-- Frame index management
-------------------------------------------------------------------------------
Expand Down Expand Up @@ -632,6 +710,8 @@ function ns.RollManager.CancelRoll(rollID)
local lifecycleToken = LifecycleUtil.CaptureToken(lifecycleState)
local frameIndex = roll.frameIndex

DismissSelectionConfirmation(roll)

activeRolls[rollID] = nil
notifiedRolls[rollID] = nil

Expand Down Expand Up @@ -667,6 +747,7 @@ end

function ns.RollManager.CancelAllRolls()
for rollID, roll in pairs(activeRolls) do
DismissSelectionConfirmation(roll)
activeRolls[rollID] = nil
if roll.frameIndex then
ReleaseFrameIndex(roll.frameIndex)
Expand Down Expand Up @@ -736,6 +817,37 @@ function ns.RollManager.IsNotified(rollID)
return notifiedRolls[rollID] or false
end

function ns.RollManager.RequestRollSelection(rollID, rollType)
local roll = activeRolls[rollID]
if not roll or not roll.frameIndex or roll.heldAfterVote then
return
end

if roll.selectionConfirmationDialog then
if roll.pendingSelectionRollType == rollType then
return
end
DismissSelectionConfirmation(roll)
end

if not ShouldConfirmSelection(rollType) then
SubmitRollSelection(rollID, rollType)
return
end

local rollTypeName = ns.RollTypeNames[rollType] or L["Unknown"]
local itemName = roll.itemName or L["Unknown"]
DismissOtherSelectionConfirmations(rollID)
local dialog = StaticPopup_Show("DRAGONLOOT_CONFIRM_ROLL_SELECTION", rollTypeName, itemName)
if not dialog then
return
end

roll.pendingSelectionRollType = rollType
roll.selectionConfirmationDialog = dialog
dialog.data = { rollID = rollID, rollType = rollType }
end

function ns.RollManager.MarkPendingHide(rollID)
local roll = activeRolls[rollID]
if not roll then
Expand Down
5 changes: 5 additions & 0 deletions DragonLoot/Locales/enUS.lua
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,11 @@ L["Show roll notifications while in raids"] = true
L["Show roll notifications while in the open world"] = true
L["Size of Need/Greed/Pass buttons"] = true
L["Skip Roll Confirmations"] = true
L["Confirm Greed and Pass"] = true
-- stylua: ignore
L["Ask before submitting Greed or Pass from DragonLoot's roll frame."
.. " This does not change confirmations required by Blizzard."] = true
L["Are you sure you want to choose %s for %s?"] = true
-- stylua: ignore
L["Skip bind-on-pickup and disenchant roll confirmations. The item binds to you"
.. " without asking, and disenchant rolls convert the item to materials."] = true
Expand Down
15 changes: 15 additions & 0 deletions DragonLoot_Options/Tabs/LootRollTab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,21 @@ local function CreateRollFrameSection(parent, db, yOffset, layoutWidgets, reappl
layoutWidgets[#layoutWidgets + 1] = autoConfirmToggle
innerY = LC.AnchorWidget(autoConfirmToggle, content, innerY) - LC.SPACING_BETWEEN_WIDGETS

local confirmGreedAndPassToggle = W.CreateToggle(content, {
label = L["Confirm Greed and Pass"],
-- stylua: ignore
tooltip = L["Ask before submitting Greed or Pass from DragonLoot's roll frame."
.. " This does not change confirmations required by Blizzard."],
get = function()
return db.profile.rollFrame.confirmGreedAndPass
end,
set = function(value)
db.profile.rollFrame.confirmGreedAndPass = value
end,
})
layoutWidgets[#layoutWidgets + 1] = confirmGreedAndPassToggle
innerY = LC.AnchorWidget(confirmGreedAndPassToggle, content, innerY) - LC.SPACING_BETWEEN_WIDGETS

local lingerSlider -- forward declared; only usable while keepOpenAfterVote is on

local keepOpenToggle = W.CreateToggle(content, {
Expand Down
34 changes: 31 additions & 3 deletions spec/Config_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe("Config", function()
local db = initWithSeed(ns, nil)

-- Keep in sync with CURRENT_SCHEMA in DragonLoot/Core/Config.lua
assert.are.equal(4, db.profile.schemaVersion)
assert.are.equal(5, db.profile.schemaVersion)
end)

it("has lootIconSize in a fresh profile", function()
Expand All @@ -57,6 +57,12 @@ describe("Config", function()
assert.is_false(db.profile.rollFrame.autoConfirmRolls)
end)

it("defaults rollFrame.confirmGreedAndPass to false (opt-in)", function()
local db = initWithSeed(ns, nil)

assert.is_false(db.profile.rollFrame.confirmGreedAndPass)
end)

it("defaults rollFrame.keepOpenAfterVote to false (opt-in)", function()
local db = initWithSeed(ns, nil)

Expand Down Expand Up @@ -133,6 +139,28 @@ describe("Config", function()
assert.is_true(db.profile.rollFrame.autoConfirmRolls)
end)

it("back-fills missing rollFrame.confirmGreedAndPass with false", function()
local db = initWithSeed(ns, {
schemaVersion = 4,
rollFrame = {
enabled = true,
},
})

assert.is_false(db.profile.rollFrame.confirmGreedAndPass)
end)

it("preserves an opted-in rollFrame.confirmGreedAndPass", function()
local db = initWithSeed(ns, {
schemaVersion = 4,
rollFrame = {
confirmGreedAndPass = true,
},
})

assert.is_true(db.profile.rollFrame.confirmGreedAndPass)
end)

it("back-fills missing rollFrame.keepOpenAfterVote and resultLingerDuration", function()
local db = initWithSeed(ns, {
rollFrame = {
Expand Down Expand Up @@ -248,7 +276,7 @@ describe("Config", function()
-- Seed at current schema so FillMissingDefaults is skipped and the
-- (unconditional) iconSize-split migration can propagate iconSize=48.
-- Keep in sync with CURRENT_SCHEMA in DragonLoot/Core/Config.lua.
schemaVersion = 4,
schemaVersion = 5,
appearance = {
iconSize = 48,
-- lootIconSize intentionally absent to test migration propagation
Expand All @@ -272,7 +300,7 @@ describe("Config", function()
})

-- Keep in sync with CURRENT_SCHEMA in DragonLoot/Core/Config.lua
assert.are.equal(4, db.profile.schemaVersion)
assert.are.equal(5, db.profile.schemaVersion)
end)
end)
end)
Loading
Loading