diff --git a/AscensionExporter/Collectors/Enchants.lua b/AscensionExporter/Collectors/Enchants.lua index dab0b5b..9da2236 100644 --- a/AscensionExporter/Collectors/Enchants.lua +++ b/AscensionExporter/Collectors/Enchants.lua @@ -10,6 +10,7 @@ local SLOT_NAMES = { } local function extract_mystic_from_tooltip(slot) + GameTooltip:ClearLines() GameTooltip:SetOwner(UIParent, "ANCHOR_NONE") GameTooltip:SetInventoryItem("player", slot) local found = nil diff --git a/AscensionExporter/Collectors/Gear.lua b/AscensionExporter/Collectors/Gear.lua index 5d28cc5..1f1de51 100644 --- a/AscensionExporter/Collectors/Gear.lua +++ b/AscensionExporter/Collectors/Gear.lua @@ -36,7 +36,13 @@ local function resolve_gems(itemLink, gemIds) if gid and gid > 0 then -- GetItemGem gives name & link by index local name, gemLink = GetItemGem(itemLink, i) - table.insert(arr, { itemId = gid, name = name or "", link = gemLink or "" }) + local gemItemId = 0 + if gemLink then + local id = tonumber(string.match(gemLink, "item:(%d+)")) + if id then gemItemId = id end + end + -- gid from item link is the socket gem enchantId; expose it explicitly + table.insert(arr, { itemId = gemItemId, enchantId = gid, name = name or "", link = gemLink or "" }) end end return arr @@ -44,6 +50,7 @@ end local function read_enchant_from_tooltip(slot) -- Try to extract human-readable base enchant (not mystic) if present + GameTooltip:ClearLines() GameTooltip:SetOwner(UIParent, "ANCHOR_NONE") GameTooltip:SetInventoryItem("player", slot) local name = nil diff --git a/AscensionExporter/Core.lua b/AscensionExporter/Core.lua index f59792c..4f82086 100644 --- a/AscensionExporter/Core.lua +++ b/AscensionExporter/Core.lua @@ -71,6 +71,76 @@ function AE:AssembleExport(which) return out end +-- Unified show function with safe fallback export window +function AE:ShowExport(text, titleText) + local show = _G.AscensionExporter_ShowExportFrame + if type(show) == "function" then + show(text, titleText) + return + end + + -- Fallback lightweight frame (created once) + if not self._fallbackFrame then + local f = CreateFrame("Frame", "AscensionExporterFallbackFrame", UIParent, "DialogBoxFrame") + f:SetSize(700, 500) + f:SetPoint("CENTER") + f:SetMovable(true) + f:EnableMouse(true) + f:RegisterForDrag("LeftButton") + f:SetScript("OnDragStart", f.StartMoving) + f:SetScript("OnDragStop", f.StopMovingOrSizing) + + local title = f:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge") + title:SetPoint("TOP", 0, -8) + f.title = title + + local scroll = CreateFrame("ScrollFrame", "AscensionExporterFallbackScroll", f, "UIPanelScrollFrameTemplate") + scroll:SetPoint("TOPLEFT", 16, -36) + scroll:SetPoint("BOTTOMRIGHT", -32, 16) + + local edit = CreateFrame("EditBox", "AscensionExporterFallbackEdit", scroll) + edit:SetMultiLine(true) + edit:SetAutoFocus(true) + edit:SetFontObject(ChatFontNormal) + edit:SetWidth(640) + edit:SetScript("OnEscapePressed", function(self) self:ClearFocus() end) + edit:SetScript("OnEditFocusGained", function(self) self:HighlightText() end) + scroll:SetScrollChild(edit) + + f.editBox = edit + f.scrollFrame = scroll + + local close = CreateFrame("Button", nil, f, "UIPanelCloseButton") + close:SetPoint("TOPRIGHT", -4, -4) + + self._fallbackFrame = f + + -- Provide a global for other callers until UI module is available. + -- IMPORTANT: Do NOT route this shim back into AE:ShowExport(), + -- to avoid infinite recursion. Directly update the fallback frame. + if type(_G.AscensionExporter_ShowExportFrame) ~= "function" then + _G.AscensionExporter_ShowExportFrame = function(t, ti) + local ff = AE._fallbackFrame + if not ff then return end + ff:Show() + ff.editBox:SetText(t or "") + ff.title:SetText(ti or "Ascension Export - Copy All (Ctrl+C)") + ff.editBox:HighlightText() + ff.editBox:SetFocus() + end + end + + DEFAULT_CHAT_FRAME:AddMessage("AscensionExporter: using fallback export window (UI module not loaded).") + end + + local f = self._fallbackFrame + f:Show() + f.editBox:SetText(text or "") + f.title:SetText(titleText or "Ascension Export - Copy All (Ctrl+C)") + f.editBox:HighlightText() + f.editBox:SetFocus() +end + function AE:Export(which) local data = self:AssembleExport(which) -- Prefer global encoder from Util/Json.lua; fallback to a tiny local encoder if missing @@ -104,7 +174,7 @@ function AE:Export(which) local title = "Ascension Export" if which and which ~= "all" then title = title .. " - " .. which end - AscensionExporter_ShowExportFrame(json, title .. " - Copy All (Ctrl+C)") + self:ShowExport(json, title .. " - Copy All (Ctrl+C)") if AscensionExporterConfig.enableSavedVariables then local key = (data.character.realm or "") .. ":" .. (data.character.name or "") @@ -198,17 +268,13 @@ SlashCmdList["ASCX"] = function(msg) msg = msg or "" msg = msg:lower() if msg == "" or msg == "help" then - -- Open the export window with helpful text and let buttons drive actions - if AscensionExporter_ShowExportFrame then - local help = "Use the buttons above or type:\n/ascx export all|talents|gear|enchants|mdgear\n/ascx sv on|off (SavedVariables is currently " .. (AscensionExporterConfig.enableSavedVariables and "ON" or "OFF") .. ")\n" - AscensionExporter_ShowExportFrame(help, "Ascension Export - Tools & Help") - return - else - DEFAULT_CHAT_FRAME:AddMessage("AscensionExporter usage:") - DEFAULT_CHAT_FRAME:AddMessage(" /ascx export all|talents|gear|enchants|mdgear") - DEFAULT_CHAT_FRAME:AddMessage(" /ascx sv on|off - toggle SavedVariables export (currently " .. (AscensionExporterConfig.enableSavedVariables and "ON" or "OFF") .. ")") - return - end + -- Open the export window with helpful text. If the UI frame isn't available, + -- avoid referencing buttons that won't be present in the fallback window. + local hasButtons = type(_G.AscensionExporter_ShowExportFrame) == "function" + local prefix = hasButtons and "Use the buttons above or type:" or "Type one of the commands:" + local help = prefix .. "\n/ascx export all|talents|gear|enchants|mdgear\n/ascx sv on|off (SavedVariables is currently " .. (AscensionExporterConfig.enableSavedVariables and "ON" or "OFF") .. ")\n" + AE:ShowExport(help, "Ascension Export - Tools & Help") + return end local cmd, rest = msg:match("^(%S+)%s*(.*)$") @@ -216,7 +282,7 @@ SlashCmdList["ASCX"] = function(msg) rest = rest ~= "" and rest or "all" if rest == "mdgear" or rest == "md" then local md = AE:GenerateMarkdownGear() - AscensionExporter_ShowExportFrame(md, "Ascension Export - Markdown Gear - Copy All (Ctrl+C)") + AE:ShowExport(md, "Ascension Export - Markdown Gear - Copy All (Ctrl+C)") elseif rest == "all" or rest == "talents" or rest == "gear" or rest == "enchants" then AE:Export(rest) else diff --git a/AscensionExporter/UI/ExportFrame.lua b/AscensionExporter/UI/ExportFrame.lua index 385f1d8..7c952dc 100644 --- a/AscensionExporter/UI/ExportFrame.lua +++ b/AscensionExporter/UI/ExportFrame.lua @@ -29,25 +29,7 @@ local function CreateOrGetFrame() local x = 0 makeBtn("All", x, function() - if AscensionExporter and AscensionExporter.Export then - local data = AscensionExporter:AssembleExport("all") - local encoder = _G.AscensionExporter_Json_Encode - local json - if encoder then json = encoder(data) else - -- very small fallback mirroring Core's behavior - local function E(v) - local t=type(v) - if t=='nil' then return 'null' end - if t=='boolean' then return v and 'true' or 'false' end - if t=='number' then return tostring(v) end - if t=='string' then v=v:gsub('\\','\\\\'):gsub('"','\\"'):gsub('\n','\\n'):gsub('\r','\\r'):gsub('\t','\\t'); return '"'..v..'"' end - if t=='table' then local n=0 for k,_ in pairs(v) do if type(k)~='number' then n=-1 break else if k>n then n=k end end end if n>=1 then local p={} for i=1,n do p[#p+1]=E(v[i]) end return '['..table.concat(p,',')..']' else local p={} for k,val in pairs(v) do p[#p+1]=E(tostring(k))..':'..E(val) end return '{'..table.concat(p,',')..'}' end end - return 'null' - end - json = E(data) - end - AscensionExporter_ShowExportFrame(json, "Ascension Export - all - Copy All (Ctrl+C)") - end + if AscensionExporter then AscensionExporter:Export("all") end end) x = x + 95 makeBtn("Talents", x, function() @@ -65,7 +47,11 @@ local function CreateOrGetFrame() makeBtn("MD Gear", x, function() if AscensionExporter and AscensionExporter.GenerateMarkdownGear then local md = AscensionExporter:GenerateMarkdownGear() or "" - AscensionExporter_ShowExportFrame(md, "Ascension Export - Markdown Gear - Copy All (Ctrl+C)") + if AscensionExporter.ShowExport then + AscensionExporter:ShowExport(md, "Ascension Export - Markdown Gear - Copy All (Ctrl+C)") + else + AscensionExporter_ShowExportFrame(md, "Ascension Export - Markdown Gear - Copy All (Ctrl+C)") + end end end)