Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
ac68460
[worktree-rename] Rename addon to EasyFind-tmog-and-toggle-fix
wowaddonmaker Mar 25, 2026
df334cc
Fix Toggle+Focus keybind not hiding visible bar
wowaddonmaker Mar 25, 2026
5a862d1
Add missing clear-button texture
wowaddonmaker Mar 25, 2026
3bf4d48
Fix options panel rendering behind action bars
wowaddonmaker Mar 25, 2026
a127b58
Add transmog outfit search with click-to-equip
wowaddonmaker Mar 25, 2026
e774b6a
Fix outfit equip overwriting user action bar slots
wowaddonmaker Mar 25, 2026
2dae9d2
Add per-character collection pins, cooldown UX, pin sync
wowaddonmaker Mar 26, 2026
843cb69
Add keyboard Enter support for outfit and toy equip
wowaddonmaker Mar 26, 2026
1821390
Keep keyboard focus on result when outfit/toy is on cooldown
wowaddonmaker Mar 26, 2026
2c6e7f7
Fix mouse click on cooldown not keeping results open
wowaddonmaker Mar 26, 2026
d5d5b99
Fix pin separator and reduce focus block to two frames
wowaddonmaker Mar 27, 2026
da41472
[worktree-rename] Rename addon to EasyFind-loot-search
wowaddonmaker Mar 27, 2026
b30894e
Add loot search with EJ scan and hierarchical results
wowaddonmaker Mar 27, 2026
fb8dac5
Fix loot scan API order, add typed keyword matching
wowaddonmaker Mar 28, 2026
c8338de
Add spec/class selector flyout for loot search (WIP)
wowaddonmaker Mar 28, 2026
c67dcdb
WIP: spec/class selector and DevLog auto-export
wowaddonmaker Mar 28, 2026
30f580e
Fix spec/class flyout hover and add spec icons
wowaddonmaker Mar 28, 2026
fb35b4e
Fix flyout backgrounds, auto-close on result, remove scan spam
wowaddonmaker Mar 28, 2026
c2fbdc2
Darken flyout backgrounds, close flyouts on spec selection
wowaddonmaker Mar 29, 2026
60afeee
Close all menus on spec selection, add class active indicators
wowaddonmaker Mar 29, 2026
3fa3705
Defer loot re-scan so flyouts fully close before UI rebuild
wowaddonmaker Mar 29, 2026
bac25a1
Fix flyout re-opening after spec selection via cooldown guard
wowaddonmaker Mar 29, 2026
3ae306c
Class click toggles all specs, menus stay open during selection
wowaddonmaker Mar 29, 2026
ba16daa
Keep results open during spec/class selection
wowaddonmaker Mar 29, 2026
16446a7
Keep results visible during flyout interaction, fix indicators
wowaddonmaker Mar 29, 2026
5db8ce0
Use IsShown instead of IsMouseOver to guard results visibility
wowaddonmaker Mar 30, 2026
6b885d1
Fix forward reference error and remove duplicate re-scan
wowaddonmaker Mar 30, 2026
07071b3
Fix dropdown closing when clicking spec/class flyouts
wowaddonmaker Mar 30, 2026
f3d7822
Add custom radio button and flyout arrow textures
wowaddonmaker Apr 5, 2026
dccc222
Rewrite loot filters to match EJ style
wowaddonmaker Apr 5, 2026
c5306aa
Fix arrow key navigation reset during deferred result refresh
wowaddonmaker Apr 6, 2026
4e39a67
Fix search scoring, key input, and result row rendering
wowaddonmaker Apr 7, 2026
f0ee4be
Add EJ loot navigation guide and highlighting
wowaddonmaker Apr 7, 2026
205a39c
Sync EJ loot filter, sort categories by match score
wowaddonmaker Apr 7, 2026
bc85d46
Hide vendor-only transmog controls in browse mode
wowaddonmaker Apr 7, 2026
2392ad9
Show outfit lock status in search results
wowaddonmaker Apr 7, 2026
c248a28
Sync EJ difficulty with loot search filter
wowaddonmaker Apr 7, 2026
7db3099
Revert "Sync EJ difficulty with loot search filter"
wowaddonmaker Apr 7, 2026
306611e
Clear button dismisses active navigation highlights
wowaddonmaker Apr 7, 2026
ef98264
Reset clears loot filter, difficulty, and all pins
wowaddonmaker Apr 7, 2026
7c19100
Extract SetEJDifficulty helper, fix per-tick overhead
wowaddonmaker Apr 7, 2026
1badb55
[worktree-rename] Revert addon rename (EasyFind-loot-search -> EasyFind)
wowaddonmaker Apr 7, 2026
edaf59f
Bump to 1.5.0, update changelog and What's New
wowaddonmaker Apr 7, 2026
57df9ad
Fix luacheck warnings for CI
wowaddonmaker Apr 7, 2026
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
20 changes: 16 additions & 4 deletions .luacheckrc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ globals = {
"BINDING_NAME_EASYFIND_TOGGLE_FOCUS",
"BINDING_NAME_EASYFIND_CLEAR",
"EncounterJournal",
"TransmogFrame",
}

-- WoW API globals (read-only)
Expand All @@ -30,7 +31,7 @@ read_globals = {

-- Core API
"CreateFrame", "CreateFont", "CreateVector2D",
"GetTime", "GetLocale", "GetCVar", "GetCursorPosition",
"GetTime", "GetLocale", "GetCVar", "GetCursorPosition", "GetRealmName",
"GetAddOnMetadata", "GetAtlasInfo", "GetMinimapShape",
"GetBindingKey", "GetCurrentBindingSet", "SaveBindings", "SetBinding",
"GetCategoryInfo", "GetPlayerFacing",
Expand Down Expand Up @@ -58,21 +59,32 @@ read_globals = {
"PVPQueueFrame",
"AchievementFrameCategories_ExpandToCategory",
"AchievementFrameCategories_UpdateDataProvider",
"Transmog_LoadUI",
"EncounterJournal_LoadUI", "PanelTemplates_SetTab",
"Menu", "ScrollBoxConstants",

-- C_* namespaces
"C_AddOns", "C_AchievementInfo", "C_AreaPoiInfo", "C_CurrencyInfo",
"C_AddOns", "C_AchievementInfo", "C_AreaPoiInfo", "C_CurrencyInfo", "C_Item",
"C_EncounterJournal", "C_GossipInfo", "C_MajorFactions", "C_Map",
"C_Minimap", "C_MountJournal", "C_Navigation", "C_PetJournal",
"C_Reputation", "C_SuperTrack", "C_TaxiMap", "C_Texture", "C_Timer",
"C_ToyBox", "C_VignetteInfo",
"C_ToyBox", "C_TransmogOutfitInfo", "C_VignetteInfo",

-- UI utility functions
"UIFrameFadeIn", "UIFrameFadeOut", "UIFrameFadeRemoveFrame",
"AchievementFrameCategories_SelectElementData",
"UnitPopup_ShowMenu", "BattlePetToolTip_ShowLink",
"GetUnitSpeed", "GetItemCooldown", "EJ_GetInstanceInfo",
"GetUnitSpeed", "GetItemCooldown", "EJ_GetInstanceInfo", "UnitName",
"GetItemInfoInstant", "GetItemStats", "GetSpecialization", "GetSpecializationInfo",
"UnitClass", "GetLootSpecialization", "DressUpItemLink",
"GetNumClasses", "GetClassInfo", "GetNumSpecializationsForClassID",
"GetSpecializationInfoForClassID", "RAID_CLASS_COLORS",
"EJ_GetCurrentTier", "EJ_SelectTier", "EJ_GetInstanceByIndex",
"EJ_SelectInstance", "EJ_GetEncounterInfoByIndex", "EJ_SelectEncounter",
"EJ_SetDifficulty", "EJ_SetLootFilter", "EJ_SetSlotFilter",
"EJ_GetNumLoot", "EJ_GetLootInfoByIndex",
"HasAction", "PlaceAction", "PickupAction", "ClearCursor", "GetActionCooldown",
"SetOverrideBindingClick", "ClearOverrideBindings",

-- Data types
"UiMapPoint",
Expand Down
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@ All notable changes to EasyFind will be documented in this file.

---

## [1.5.0] - 2026-04-07

### Added
- **Loot Search**: Search dungeon and raid loot by item name, slot, stats, boss, or instance. Filter by class, specialization, and difficulty. Click a result to navigate directly to the item in the Encounter Journal
- **Transmog Outfit Search**: Your saved transmog outfits appear in search results. Click to equip, with cooldown tracking and active-outfit indicators
- **Outfit Lock Status**: Locked outfits display a visual overlay on their icon with lock details on hover
- **Transmog Browse Mode**: Opening the transmog window via search hides vendor-only controls and shows guidance messages. All controls restore when the window closes or when visiting a transmogrifier
- **Clear Button for Navigation**: The search bar clear button now appears during active step-by-step guides and dismisses highlights and arrows in addition to clearing text
- **Dynamic Category Ordering**: Search result categories (UI, Mounts, Loot, etc.) sort by best match score instead of a fixed order

### Fixed
- **Loot Navigation**: Fixed item highlighting in the Encounter Journal loot tab and added recovery when clicking a different boss mid-guide

### Technical
- EJ class/spec and difficulty filters sync with search filter selection before loot navigation
- Guides fast-forward through already-satisfied steps instead of advancing one per ticker tick
- Slightly thicker gold separator lines between result category groups

---

## [1.4.0] - 2026-03-20

### Added
Expand Down
74 changes: 71 additions & 3 deletions Core.lua
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ local DB_DEFAULTS = {
showTruncationMessage = true, -- Show "more results available" message when truncated
hardResultsCap = false, -- Hard cap on results (no "more results" message)
staticOpacity = false, -- Keep opacity constant while moving
pinnedUIItems = {}, -- Pinned UI search results (persist across sessions)
pinnedUIItems = {}, -- Pinned UI search results (persist across sessions, account-wide)
pinnedUIItemsPerChar = {}, -- Character-specific pins (mounts, toys, pets, outfits) keyed by "Name-Realm"
pinnedMapItems = {}, -- Pinned map search results (persist across sessions)
pinsCollapsed = false, -- Whether the "Pinned Paths" header is collapsed
mapPinsCollapsed = false, -- Whether the map search "Pinned" header is collapsed
Expand Down Expand Up @@ -103,8 +104,15 @@ local DB_DEFAULTS = {
mounts = false,
toys = false,
pets = false,
outfits = false,
loot = false,
map = false,
},
lootSpecs = nil, -- Loot search: nil = current spec only, table of {classID, specID} pairs when customized
lootSearchSlots = true, -- Loot search: match by slot keywords (ring, helm, etc.)
lootSearchStats = true, -- Loot search: match by stat keywords (haste, crit, etc.)
lootUpgradesOnly = false, -- Loot search: only show items above equipped ilvl
lootDifficulty = "normal",
uiMapSearchLocal = true, -- Map search in UI bar: true = local zone only, false = global
}

Expand Down Expand Up @@ -281,6 +289,41 @@ local function OnInitialize()
EasyFind.db.setupComplete = nil
ns.UI:ShowFirstTimeSetup()
end
elseif msg == "ejdump" then
local info = _G["EncounterJournalEncounterFrameInfo"]
if not info then print("No EncounterJournalEncounterFrameInfo"); return end
print("--- EJ Loot Container Dump ---")
local lc = info.LootContainer
print("LootContainer: " .. tostring(lc) .. " shown:" .. tostring(lc and lc:IsShown()))
if lc then
local sb = lc.ScrollBox
print(" .ScrollBox: " .. tostring(sb))
if sb then
print(" .ScrollBox:IsShown(): " .. tostring(sb:IsShown()))
print(" has EnumerateFrames: " .. tostring(sb.EnumerateFrames ~= nil))
if sb.EnumerateFrames then
local count = 0
for _, btn in sb:EnumerateFrames() do
count = count + 1
local text = ns.Utils.GetButtonText(btn)
print(" [" .. count .. "] " .. tostring(text) .. " shown:" .. tostring(btn:IsShown()))
end
print(" total frames: " .. count)
end
local st = sb.ScrollTarget
print(" .ScrollTarget: " .. tostring(st))
if st then
local kids = { st:GetChildren() }
print(" ScrollTarget children: " .. #kids)
for i, kid in ipairs(kids) do
if i <= 5 then
local text = ns.Utils.GetButtonText(kid)
print(" [" .. i .. "] " .. tostring(text) .. " shown:" .. tostring(kid:IsShown()))
end
end
end
end
end
elseif msg == "whatsnew" then
if ns.UI then ns.UI:ShowWhatsNew(ns.version) end
elseif msg == "help" or msg == "h" or msg == "?" then
Expand All @@ -306,7 +349,7 @@ end
local SafeAfter = Utils.SafeAfter

local function OnPlayerLogin()
SafeAfter(0.5, function()
SafeAfter(0, function()
local function SafeInit(mod, name)
if not mod then return end
local ok, err = xpcall(mod.Initialize, ErrorHandler, mod)
Expand All @@ -323,6 +366,15 @@ local function OnPlayerLogin()
end
SafeInit(ns.Options, "Options")
end)
-- Loot scan runs synchronously during login (loading screen absorbs the cost).
-- Pass true to pre-cache all class/spec combos so spec toggles are instant.
if ns.Database and ns.Database.PopulateDynamicLoot then
local ok, err = xpcall(ns.Database.PopulateDynamicLoot, ErrorHandler, ns.Database, true)
if not ok then
EasyFind:Print("|cffff4444Loot scan failed: " .. tostring(err) .. "|r")
end
end

-- Populate dynamic currencies, reputations, mounts, and toys after a short delay (APIs need the character loaded)
-- Spread dynamic population across frames to avoid a single-frame stutter.
-- Currencies/reputations run first (they toggle collapsed headers, must be synchronous).
Expand All @@ -337,7 +389,9 @@ local function OnPlayerLogin()
ns.Database:PopulateDynamicToys()
SafeAfter(0, function()
ns.Database:PopulateDynamicPets()
collectgarbage("collect")
SafeAfter(0, function()
ns.Database:PopulateDynamicOutfits()
end)
end)
end)
end)
Expand All @@ -364,10 +418,13 @@ local function OnPlayerLogin()
end
end

local outfitRefreshTimer

eventFrame:RegisterEvent("ADDON_LOADED")
eventFrame:RegisterEvent("PLAYER_LOGIN")
eventFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
eventFrame:RegisterEvent("PLAYER_LOGOUT")
eventFrame:RegisterEvent("TRANSMOG_OUTFITS_CHANGED")
eventFrame:SetScript("OnEvent", function(self, event, arg1, arg2)
if event == "ADDON_LOADED" and arg1 == ADDON_NAME then
OnInitialize()
Expand All @@ -384,6 +441,17 @@ eventFrame:SetScript("OnEvent", function(self, event, arg1, arg2)
OnPlayerLogin()
end
self:UnregisterEvent("PLAYER_ENTERING_WORLD")
elseif event == "TRANSMOG_OUTFITS_CHANGED" then
if outfitRefreshTimer then outfitRefreshTimer:Cancel() end
outfitRefreshTimer = C_Timer.NewTimer(0.5, function()
outfitRefreshTimer = nil
if ns.Database and ns.Database.PopulateDynamicOutfits then
ns.Database:PopulateDynamicOutfits()
end
if ns.UI and ns.UI.SyncOutfitPins then
ns.UI:SyncOutfitPins()
end
end)
elseif event == "PLAYER_LOGOUT" then
-- Strip runtime-only fields before SavedVariables serialization
if EasyFindDB then
Expand Down
Loading
Loading