Skip to content
Open
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
2 changes: 1 addition & 1 deletion RaidBrowser/RaidBrowser.toc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Version: v1.4.0-DEV
## Notes: A raid finder that parses chat channel text and displays any found raids in the raid browser LFR frame.
## Author: Act/Horsebreed@Warmane
## SavedVariablesPerCharacter: RaidBrowserCharacterRaidsets, RaidBrowserCharacterCurrentRaidset
## SavedVariablesPerCharacter: RaidBrowserCharacterRaidsets, RaidBrowserCharacterCurrentRaidset, RaidBrowserCharacterUseShortSpecNames
## OptionalDeps: GearScoreLite
## X-Embeds: Ace3

Expand Down
5 changes: 5 additions & 0 deletions RaidBrowser/core.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1247,6 +1247,10 @@ function RaidBrowser:OnEnable()
};
end

if RaidBrowserCharacterUseShortSpecNames == nil then
RaidBrowserCharacterUseShortSpecNames = false;
end

-- LFM messages expire after 60 seconds
RaidBrowser.expiry_time = 60;

Expand All @@ -1257,6 +1261,7 @@ function RaidBrowser:OnEnable()
end

RaidBrowser.check_button()
RaidBrowser.gui.raidset.initialize();
Comment on lines 1263 to +1264

Copilot AI Apr 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RaidBrowser.check_button() runs before RaidBrowser.gui.raidset.initialize(), but check_button() depends on current_selection (set by initialize() via set_selection). With the current order, the Save button state can be incorrect on login until the user changes the dropdown. Call RaidBrowser.gui.raidset.initialize() before RaidBrowser.check_button(), or have initialize() call RaidBrowser.check_button() after setting the selection.

Suggested change
RaidBrowser.check_button()
RaidBrowser.gui.raidset.initialize();
RaidBrowser.gui.raidset.initialize();
RaidBrowser.check_button()

Copilot uses AI. Check for mistakes.
end

function RaidBrowser:OnDisable()
Expand Down
50 changes: 47 additions & 3 deletions RaidBrowser/raidset_frame.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,18 @@ local frame = CreateFrame("Frame", "RaidBrowserRaidSetMenu", LFRBrowseFrame, "UI
UIDropDownMenu_SetWidth(RaidBrowserRaidSetMenu, 150)
frame:SetWidth(90);

---@type 'Active'|'Primary'|'Secondary'|'Both'|nil
local current_selection = nil;

---@param selection any
---@return 'Active'|'Primary'|'Secondary'|'Both'
local function normalize_selection(selection)
if selection == 'Active' or selection == 'Primary' or selection == 'Secondary' or selection == 'Both' then
return selection
end
return 'Active'
end

---@return boolean
local function is_active_selected(_)
return 'Active' == current_selection;
Expand All @@ -25,7 +35,7 @@ local function is_both_selected(option)
return ('Both' == current_selection);
end

---@param selection 'Active'|'Primary'|'Secondary'
---@param selection 'Active'|'Primary'|'Secondary'|'Both'
local function set_selection(selection)
local text = '';

Expand Down Expand Up @@ -180,11 +190,20 @@ local function on_raidset_save()

---@diagnostic disable-next-line: undefined-field
RaidBrowser:Print('Raidset saved: ' .. spec .. ' ' .. gs .. 'gs');
set_selection(current_selection);
if current_selection then
set_selection(current_selection)
else
set_selection('Active')
end
end

function RaidBrowser.gui.raidset.initialize()
set_selection(RaidBrowserCharacterCurrentRaidset);
local selection = normalize_selection(RaidBrowserCharacterCurrentRaidset)
set_selection(selection)
if short_spec_check then
local use_short_names = RaidBrowser.stats.use_short_spec_names and RaidBrowser.stats.use_short_spec_names() or false
short_spec_check:SetChecked(use_short_names)
end
end

local function check_button(button)
Expand Down Expand Up @@ -234,4 +253,29 @@ button:SetText("Save Raid Gear");
button:SetWidth(110);
button:SetScript("OnClick", on_raidset_save);
button:Show();

-- Create short spec names checkbox
short_spec_check = CreateFrame("CheckButton", "RaidBrowserRaidSetShortSpecCheckButton", LFRBrowseFrame, "UICheckButtonTemplate")

Copilot AI Apr 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

short_spec_check is assigned without local, which creates/overwrites a global and can lead to hard-to-debug collisions between addons or files. Declare it as a local upvalue (e.g., local short_spec_check near the top) and keep the checkbox frame reference scoped to this module.

Suggested change
short_spec_check = CreateFrame("CheckButton", "RaidBrowserRaidSetShortSpecCheckButton", LFRBrowseFrame, "UICheckButtonTemplate")
local short_spec_check = CreateFrame("CheckButton", "RaidBrowserRaidSetShortSpecCheckButton", LFRBrowseFrame, "UICheckButtonTemplate")

Copilot uses AI. Check for mistakes.
short_spec_check:SetPoint("CENTER", LFRBrowseFrame, "CENTER", -137, -169)
short_spec_check:SetScript("OnClick", function(self)
local enabled = self:GetChecked() ~= nil;
if RaidBrowser.stats.set_use_short_spec_names then
RaidBrowser.stats.set_use_short_spec_names(enabled)
end
if RaidBrowser.stats.refresh_saved_raidset_spec_names then
RaidBrowser.stats.refresh_saved_raidset_spec_names()
end

if current_selection then
set_selection(current_selection);
end

---@diagnostic disable-next-line: undefined-field
RaidBrowser:Print('Short spec names: ' .. (enabled and 'enabled' or 'disabled'));
end)

local short_spec_label = _G[short_spec_check:GetName() .. "Text"]
if short_spec_label then
short_spec_label:SetText("Use short spec names")
end
check_button(button);
69 changes: 65 additions & 4 deletions RaidBrowser/stats.lua
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,65 @@ local spec_names = {
}
}

local spec_name_lookup = {}
for key, label in pairs(spec_names.full) do
spec_name_lookup[label] = key
end
for key, label in pairs(spec_names.short) do
spec_name_lookup[label] = key
end

local function use_short_spec_names()
return RaidBrowserCharacterUseShortSpecNames == true
end

local function get_readable_spec_name(spec_key)
if spec_key == nil then
return "Unknown Spec"
end

if use_short_spec_names() then
return spec_names.short[spec_key] or spec_key
end
return spec_names.full[spec_key] or spec_key
end

local function normalize_saved_spec_name(spec)
if not spec then return spec end

local base, suffix = string.match(spec, "^(.-)%s*(%b())$")
if suffix ~= "(Tank)" and suffix ~= "(DPS)" then
base = spec
suffix = ""
end

local key = spec_name_lookup[base]
if not key then
return spec
end

return get_readable_spec_name(key) .. suffix
end

function RaidBrowser.stats.use_short_spec_names()
return use_short_spec_names()
end

function RaidBrowser.stats.set_use_short_spec_names(enabled)
RaidBrowserCharacterUseShortSpecNames = enabled == true
end

function RaidBrowser.stats.refresh_saved_raidset_spec_names()
if not RaidBrowserCharacterRaidsets then return end

for _, set in ipairs({ "Primary", "Secondary" }) do
local raidset = RaidBrowserCharacterRaidsets[set]
if raidset and raidset.spec then
raidset.spec = normalize_saved_spec_name(raidset.spec)
end
end
end

---@param raid string The name of the achievement ids table
---@nodiscard
local function find_best_achievement(raid)
Expand Down Expand Up @@ -272,22 +331,22 @@ end
function RaidBrowser.stats.active_spec_index()
local indices = std.algorithm.transform({ 1, 2, 3 }, GetTalentTabPoints)
local i, _ = std.algorithm.max_of(indices);
return i;
return i or 1;
end

function RaidBrowser.stats.active_spec()
local active_tab = RaidBrowser.stats.active_spec_index()
local _, _, _, spec_name = GetTalentTabInfo(active_tab);
local _, class = UnitClass("player");

-- TODO: make config to toggle using full or short spec names
local readable_spec_name = spec_names["short"][spec_name] or spec_name;
local readable_spec_name = get_readable_spec_name(spec_name)

-- If we're a feral druid, then we need to distinguish between tank and cat feral.
if spec_name == 'DruidFeralCombat' then
local protector_of_pack_talent = 22;
local thick_hide_talent = 5;
local _, _, _, _, points = GetTalentInfo(active_tab, thick_hide_talent)
points = tonumber(points) or 0
if points > 1 then
return readable_spec_name .. ' (Tank)'
else
Expand All @@ -301,6 +360,8 @@ function RaidBrowser.stats.active_spec()
local blade_barrier_talent = 3;
local _, _, _, _, points = GetTalentInfo(2, toughness_talent)
local _, _, _, _, points2 = GetTalentInfo(1, blade_barrier_talent)
points = tonumber(points) or 0
points2 = tonumber(points2) or 0
if points > 3 and points2 > 3 then
return readable_spec_name .. ' (Tank)'
else
Expand Down Expand Up @@ -395,7 +456,7 @@ function RaidBrowser.stats.current_raidset()
return RaidBrowser.stats.get_raidset(RaidBrowserCharacterCurrentRaidset);
end

---@param set 'Active' | 'Primary' | 'Secondary'
---@param set 'Active' | 'Primary' | 'Secondary' | 'Both'
function RaidBrowser.stats.select_current_raidset(set)
RaidBrowserCharacterCurrentRaidset = set;
end
Expand Down