wuira 0.2.7 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/README.md +6 -2
- package/docs/icons.md +1 -1
- package/docs/nameplates.md +1 -1
- package/lib/datasources/UnitSource.d.ts +5 -0
- package/lib/datasources/UnitSource.lua +47 -3
- package/lib/index.d.ts +0 -15
- package/lib/index.lua +0 -26
- package/lib/platform/index.d.ts +5 -0
- package/lib/platform/index.lua +11 -0
- package/lib/ui/UnitPortrait.d.ts +3 -0
- package/lib/ui/UnitPortrait.lua +233 -0
- package/lib/ui/index.d.ts +1 -0
- package/lib/ui/index.lua +4 -0
- package/package.json +8 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,29 @@ with the release date and highlight breaking changes explicitly.
|
|
|
7
7
|
|
|
8
8
|
## Unreleased
|
|
9
9
|
|
|
10
|
+
## 0.3.0 — 2026-10-17
|
|
11
|
+
|
|
12
|
+
### Breaking
|
|
13
|
+
|
|
14
|
+
- The package root exports only the addon shell: `Wuira`, `wuira`, `WuiraApp`, `AddonSettings`, `Encoding`, `Store`, and `StoreRegistry`.
|
|
15
|
+
- Import widgets, including `UI`, `HoverTracker`, and `unitPortrait`, from `wuira/ui`.
|
|
16
|
+
- Import `BlizzardUI` and `ActionBars` from `wuira/platform`.
|
|
17
|
+
- Import `Nameplates` and `MicroBar` from `wuira/skins`. Spell and icon enums stay on `wuira/spells` and `wuira/icons`.
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- `unitPortrait` mounts a unit portrait and a protected target/menu button without coupling resource widgets to that button.
|
|
22
|
+
|
|
23
|
+
## 0.2.8 — 2026-10-17
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- `UnitSource("target").onChange` invalidates on `PLAYER_TARGET_CHANGED`, including
|
|
28
|
+
combat and target removal, without reading secret identities or notifying other
|
|
29
|
+
unit sources. Event subscriptions stop with the last consumer.
|
|
30
|
+
- Add `onTokenChange` for secure consumers that should only rewrite bindings after
|
|
31
|
+
an explicit `Retarget`, not when a stable target address points to another unit.
|
|
32
|
+
|
|
10
33
|
## 0.2.7 — 2026-10-16
|
|
11
34
|
|
|
12
35
|
### Added
|
package/README.md
CHANGED
|
@@ -7,7 +7,8 @@ Build WoW Forever interfaces with TypeScript and JSX.
|
|
|
7
7
|
wuira is a UI framework and addon toolchain for developers who want to describe interfaces in code, compose reusable components, and keep game data separate from presentation. Write TypeScript, arrange native widgets with JSX, and compile your addon to Lua.
|
|
8
8
|
|
|
9
9
|
```tsx
|
|
10
|
-
import {
|
|
10
|
+
import { wuira } from "wuira";
|
|
11
|
+
import { UI } from "wuira/ui";
|
|
11
12
|
|
|
12
13
|
function ResourceBar({ current }: { current: number }) {
|
|
13
14
|
return <progress width="inherit" height={24} min={0} max={100} current={current} />;
|
|
@@ -79,7 +80,8 @@ Supported action types: `spell`, `item`, `macro`, `action`, and `target`. Action
|
|
|
79
80
|
## Nameplates
|
|
80
81
|
|
|
81
82
|
```tsx
|
|
82
|
-
import {
|
|
83
|
+
import { UI } from "wuira/ui";
|
|
84
|
+
import { Nameplates } from "wuira/skins";
|
|
83
85
|
import { HP } from "wuira/datasources";
|
|
84
86
|
|
|
85
87
|
const plates = Nameplates
|
|
@@ -141,6 +143,8 @@ For global installation, use `npm install -g wuira`. To test unpublished changes
|
|
|
141
143
|
|
|
142
144
|
wuira is an early framework. It is not a complete UI replacement, an in-game visual editor, or a WeakAuras replacement. JSX describes widgets; there is no React runtime or automatic reactive rendering layer. Combat restrictions and secret-value rules still apply and cannot be bypassed by the framework.
|
|
143
145
|
|
|
146
|
+
Import widgets from `wuira/ui` (including `unitPortrait`), native adapters from `wuira/skins`, and `BlizzardUI` / `ActionBars` from `wuira/platform`. The package root is the addon shell.
|
|
147
|
+
|
|
144
148
|
Current core includes Cells, layouts, progress bars, decorations, unit sources, native nameplate adapters, and project tooling. Not yet implemented: a complete WoW API surface, nameplate click-cast abstractions, and preset management. Nameplate lifecycle tests use a mock Lua runtime; real-client validation is still required.
|
|
145
149
|
|
|
146
150
|
The target client is WoW Forever. Compatibility with Retail or other Classic clients is not promised without verification.
|
package/docs/icons.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
`Icons` contains native texture **FileDataIDs** from the same verified Forever build as the spell enums. Icon identity is independent of spell or item actions.
|
|
4
4
|
|
|
5
5
|
```ts
|
|
6
|
-
import { UI } from "wuira";
|
|
6
|
+
import { UI } from "wuira/ui";
|
|
7
7
|
import { Icons } from "wuira/icons";
|
|
8
8
|
import { Icon } from "wuira/ui";
|
|
9
9
|
|
package/docs/nameplates.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Nameplates
|
|
2
2
|
|
|
3
|
-
Import `Nameplates` from `wuira
|
|
3
|
+
Import `Nameplates` from `wuira/skins`. Wuira owns native access,
|
|
4
4
|
events, unit bindings and visual cleanup. Preset selection, NPC rules, editor
|
|
5
5
|
data and component collections belong to the consuming addon (for example LumaUI).
|
|
6
6
|
No class or mob presets are built into Wuira.
|
|
@@ -20,11 +20,16 @@ export declare class UnitSource extends DataSource<UnitIdentity | undefined> {
|
|
|
20
20
|
readonly Is: UnitPredicates;
|
|
21
21
|
private restricted;
|
|
22
22
|
private readonly listeners;
|
|
23
|
+
private readonly tokenListeners;
|
|
24
|
+
private events?;
|
|
23
25
|
constructor(token: string);
|
|
24
26
|
get Token(): string;
|
|
25
27
|
/** Keep source objects/subscriptions while a stable identity moves to another unit slot. */
|
|
26
28
|
Retarget(token: string): void;
|
|
29
|
+
/** Secure consumers only need notification when the actual unit address changes. */
|
|
30
|
+
onTokenChange(listener: () => void): () => void;
|
|
27
31
|
onChange(listener: () => void): () => void;
|
|
32
|
+
private UpdateEvents;
|
|
28
33
|
protected HasSecretFields(): boolean;
|
|
29
34
|
protected GetValue(): UnitIdentity | undefined;
|
|
30
35
|
}
|
|
@@ -506,32 +506,76 @@ function UnitSource.prototype.____constructor(self, token)
|
|
|
506
506
|
self.token = token
|
|
507
507
|
self.restricted = false
|
|
508
508
|
self.listeners = __TS__New(Set)
|
|
509
|
+
self.tokenListeners = __TS__New(Set)
|
|
509
510
|
self.Is = __TS__New(
|
|
510
511
|
____exports.UnitPredicates,
|
|
511
512
|
function() return self.Token end
|
|
512
513
|
)
|
|
513
514
|
end
|
|
514
515
|
function UnitSource.prototype.Retarget(self, token)
|
|
516
|
+
if issecretvalue(token) or type(token) ~= "string" or __TS__StringTrim(token) == "" then
|
|
517
|
+
error("UnitSource: expected a public unit token")
|
|
518
|
+
end
|
|
515
519
|
if token == self.token then
|
|
516
520
|
return
|
|
517
521
|
end
|
|
518
522
|
if InCombatLockdown() then
|
|
519
523
|
error("UnitSource: retarget after combat so secure actions and displayed data stay aligned")
|
|
520
524
|
end
|
|
521
|
-
if issecretvalue(token) or type(token) ~= "string" or __TS__StringTrim(token) == "" then
|
|
522
|
-
error("UnitSource: expected a public unit token")
|
|
523
|
-
end
|
|
524
525
|
self.token = token
|
|
526
|
+
self:UpdateEvents()
|
|
527
|
+
for ____, listener in __TS__Iterator(self.tokenListeners) do
|
|
528
|
+
listener(nil)
|
|
529
|
+
end
|
|
525
530
|
for ____, listener in __TS__Iterator(self.listeners) do
|
|
526
531
|
listener(nil)
|
|
527
532
|
end
|
|
528
533
|
end
|
|
534
|
+
function UnitSource.prototype.onTokenChange(self, listener)
|
|
535
|
+
self.tokenListeners:add(listener)
|
|
536
|
+
return function()
|
|
537
|
+
self.tokenListeners:delete(listener)
|
|
538
|
+
end
|
|
539
|
+
end
|
|
529
540
|
function UnitSource.prototype.onChange(self, listener)
|
|
530
541
|
self.listeners:add(listener)
|
|
542
|
+
self:UpdateEvents()
|
|
531
543
|
return function()
|
|
532
544
|
self.listeners:delete(listener)
|
|
545
|
+
self:UpdateEvents()
|
|
533
546
|
end
|
|
534
547
|
end
|
|
548
|
+
function UnitSource.prototype.UpdateEvents(self)
|
|
549
|
+
local ____opt_2 = self.events
|
|
550
|
+
if ____opt_2 ~= nil then
|
|
551
|
+
____opt_2:UnregisterAllEvents()
|
|
552
|
+
end
|
|
553
|
+
if self.listeners.size == 0 or self.token ~= "target" then
|
|
554
|
+
local ____opt_4 = self.events
|
|
555
|
+
if ____opt_4 ~= nil then
|
|
556
|
+
____opt_4:SetScript("OnEvent", nil)
|
|
557
|
+
end
|
|
558
|
+
local ____opt_6 = self.events
|
|
559
|
+
if ____opt_6 ~= nil then
|
|
560
|
+
____opt_6:Hide()
|
|
561
|
+
end
|
|
562
|
+
self.events = nil
|
|
563
|
+
return
|
|
564
|
+
end
|
|
565
|
+
if self.events == nil then
|
|
566
|
+
self.events = CreateFrame("Frame", nil, UIParent)
|
|
567
|
+
end
|
|
568
|
+
local frame = self.events
|
|
569
|
+
frame:RegisterEvent("PLAYER_TARGET_CHANGED")
|
|
570
|
+
frame:SetScript(
|
|
571
|
+
"OnEvent",
|
|
572
|
+
function()
|
|
573
|
+
for ____, listener in __TS__Iterator(self.listeners) do
|
|
574
|
+
listener(nil)
|
|
575
|
+
end
|
|
576
|
+
end
|
|
577
|
+
)
|
|
578
|
+
end
|
|
535
579
|
function UnitSource.prototype.HasSecretFields(self)
|
|
536
580
|
return self.restricted
|
|
537
581
|
end
|
package/lib/index.d.ts
CHANGED
|
@@ -5,20 +5,5 @@ export { WuiraApp } from "./WuiraApp";
|
|
|
5
5
|
export type { CommandCallback } from "./platform/SlashCommands";
|
|
6
6
|
export { AddonSettings } from "./platform/AddonSettings";
|
|
7
7
|
export { Encoding } from "./platform/Encoding";
|
|
8
|
-
export { DruidSpells, GeneralSpells, HunterSpells, MageSpells, PaladinSpells, PetSpells, PriestSpells, ProfessionSpells, RacialSpells, RogueSpells, ShamanSpells, WarlockSpells, WarriorSpells, WorldSpells, BindingActions, } from "./spells/index";
|
|
9
|
-
export { Icons } from "./icons/index";
|
|
10
|
-
export { BlizzardUI } from "./platform/BlizzardUI";
|
|
11
|
-
export { ActionBars } from "./platform/ActionBars";
|
|
12
|
-
export type { ActionSlot, EmptyActionBarsOptions } from "./platform/ActionBars";
|
|
13
|
-
export type { BlizzardUIOptions } from "./platform/BlizzardUI";
|
|
14
|
-
export type { MicroMenuSkinOptions } from "./platform/MicroMenu";
|
|
15
|
-
export { UI } from "./ui/primitives/jsx";
|
|
16
|
-
export { HoverTracker } from "./ui/HoverTracker";
|
|
17
|
-
export type { HoverTrackerOptions, HoverFrame } from "./ui/HoverTracker";
|
|
18
|
-
export { MicroBar } from "./skins/MicroBar";
|
|
19
|
-
export { Nameplates, NameplateRules, NameplateContext } from "./skins/Nameplates";
|
|
20
|
-
export type { NameplateInfo, NameplateSelector, NameplateCustomize, NameplateRender, NativeNameplate, NativeNameplateVisual } from "./skins/Nameplates";
|
|
21
|
-
export type { Element, Component } from "./ui/primitives/jsx";
|
|
22
|
-
export type { Cell } from "./ui/Cell";
|
|
23
8
|
export { Store, StoreRegistry } from "./store/index";
|
|
24
9
|
export type { StoreClass, ReadonlyData, SavedStoreOptions } from "./store/index";
|
package/lib/index.lua
CHANGED
|
@@ -18,32 +18,6 @@ do
|
|
|
18
18
|
local ____Encoding = require("platform.Encoding")
|
|
19
19
|
____exports.Encoding = ____Encoding.Encoding
|
|
20
20
|
end
|
|
21
|
-
do
|
|
22
|
-
local ____BlizzardUI = require("platform.BlizzardUI")
|
|
23
|
-
____exports.BlizzardUI = ____BlizzardUI.BlizzardUI
|
|
24
|
-
end
|
|
25
|
-
do
|
|
26
|
-
local ____ActionBars = require("platform.ActionBars")
|
|
27
|
-
____exports.ActionBars = ____ActionBars.ActionBars
|
|
28
|
-
end
|
|
29
|
-
do
|
|
30
|
-
local ____jsx = require("ui.primitives.jsx")
|
|
31
|
-
____exports.UI = ____jsx.UI
|
|
32
|
-
end
|
|
33
|
-
do
|
|
34
|
-
local ____HoverTracker = require("ui.HoverTracker")
|
|
35
|
-
____exports.HoverTracker = ____HoverTracker.HoverTracker
|
|
36
|
-
end
|
|
37
|
-
do
|
|
38
|
-
local ____MicroBar = require("skins.MicroBar")
|
|
39
|
-
____exports.MicroBar = ____MicroBar.MicroBar
|
|
40
|
-
end
|
|
41
|
-
do
|
|
42
|
-
local ____Nameplates = require("skins.Nameplates")
|
|
43
|
-
____exports.Nameplates = ____Nameplates.Nameplates
|
|
44
|
-
____exports.NameplateRules = ____Nameplates.NameplateRules
|
|
45
|
-
____exports.NameplateContext = ____Nameplates.NameplateContext
|
|
46
|
-
end
|
|
47
21
|
do
|
|
48
22
|
local ____index = require("store.index")
|
|
49
23
|
____exports.Store = ____index.Store
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { BlizzardUI } from "./BlizzardUI";
|
|
2
|
+
export type { BlizzardUIOptions } from "./BlizzardUI";
|
|
3
|
+
export { ActionBars } from "./ActionBars";
|
|
4
|
+
export type { ActionSlot, EmptyActionBarsOptions } from "./ActionBars";
|
|
5
|
+
export type { MicroMenuSkinOptions } from "./MicroMenu";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
|
|
2
|
+
local ____exports = {}
|
|
3
|
+
do
|
|
4
|
+
local ____BlizzardUI = require("platform.BlizzardUI")
|
|
5
|
+
____exports.BlizzardUI = ____BlizzardUI.BlizzardUI
|
|
6
|
+
end
|
|
7
|
+
do
|
|
8
|
+
local ____ActionBars = require("platform.ActionBars")
|
|
9
|
+
____exports.ActionBars = ____ActionBars.ActionBars
|
|
10
|
+
end
|
|
11
|
+
return ____exports
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
|
|
2
|
+
-- Lua Library inline imports
|
|
3
|
+
local function __TS__StringTrim(self)
|
|
4
|
+
local result = string.gsub(self, "^[%s ]*(.-)[%s ]*$", "%1")
|
|
5
|
+
return result
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
local function __TS__StringIncludes(self, searchString, position)
|
|
9
|
+
if not position then
|
|
10
|
+
position = 1
|
|
11
|
+
else
|
|
12
|
+
position = position + 1
|
|
13
|
+
end
|
|
14
|
+
local index = string.find(self, searchString, position, true)
|
|
15
|
+
return index ~= nil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
local function __TS__ObjectAssign(target, ...)
|
|
19
|
+
local sources = {...}
|
|
20
|
+
for i = 1, #sources do
|
|
21
|
+
local source = sources[i]
|
|
22
|
+
if type(source) == "table" then
|
|
23
|
+
for key in pairs(source) do
|
|
24
|
+
target[key] = source[key]
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
return target
|
|
29
|
+
end
|
|
30
|
+
-- End of Lua Library inline imports
|
|
31
|
+
local ____exports = {}
|
|
32
|
+
local ____UnitSource = require("datasources.UnitSource")
|
|
33
|
+
local resolveUnit = ____UnitSource.resolveUnit
|
|
34
|
+
local ____jsx = require("ui.primitives.jsx")
|
|
35
|
+
local UI = ____jsx.UI
|
|
36
|
+
function ____exports.unitPortrait(self, props, input, crop, preview)
|
|
37
|
+
if preview == nil then
|
|
38
|
+
preview = false
|
|
39
|
+
end
|
|
40
|
+
if issecretvalue(input) or type(input) == "string" and __TS__StringTrim(input) == "" then
|
|
41
|
+
error("Unit portrait requires a public unit token", 0)
|
|
42
|
+
end
|
|
43
|
+
local target = resolveUnit(nil, input)
|
|
44
|
+
return UI:createElement(
|
|
45
|
+
"cell",
|
|
46
|
+
__TS__ObjectAssign(
|
|
47
|
+
{},
|
|
48
|
+
props,
|
|
49
|
+
{
|
|
50
|
+
clickThrough = true,
|
|
51
|
+
onMount = function(____, frame)
|
|
52
|
+
local host = frame
|
|
53
|
+
local ____preview_0
|
|
54
|
+
if preview then
|
|
55
|
+
____preview_0 = nil
|
|
56
|
+
else
|
|
57
|
+
____preview_0 = CreateFrame("Button", nil, UIParent, "SecureActionButtonTemplate")
|
|
58
|
+
end
|
|
59
|
+
local button = ____preview_0
|
|
60
|
+
local owner = button or host
|
|
61
|
+
local texture = owner:CreateTexture(nil, "OVERLAY")
|
|
62
|
+
texture:SetAllPoints(owner)
|
|
63
|
+
local buttonUnit = target.Token
|
|
64
|
+
local stopUnit
|
|
65
|
+
local stopped = false
|
|
66
|
+
local stopping = false
|
|
67
|
+
local elapsed = 0
|
|
68
|
+
local lastX
|
|
69
|
+
local lastY
|
|
70
|
+
local lastWidth
|
|
71
|
+
local lastHeight
|
|
72
|
+
local lastStrata
|
|
73
|
+
local lastLevel
|
|
74
|
+
local lastAlpha
|
|
75
|
+
local function draw()
|
|
76
|
+
if stopped or stopping then
|
|
77
|
+
return
|
|
78
|
+
end
|
|
79
|
+
SetPortraitTexture(texture, target.Token, true)
|
|
80
|
+
local uv = crop or ({0, 1, 0, 1})
|
|
81
|
+
texture:SetTexCoord(uv[1], uv[2], uv[3], uv[4])
|
|
82
|
+
end
|
|
83
|
+
local function cleanup()
|
|
84
|
+
if stopped then
|
|
85
|
+
return
|
|
86
|
+
end
|
|
87
|
+
stopped = true
|
|
88
|
+
if stopUnit ~= nil then
|
|
89
|
+
stopUnit(nil)
|
|
90
|
+
end
|
|
91
|
+
stopUnit = nil
|
|
92
|
+
host:SetScript("OnUpdate", nil)
|
|
93
|
+
owner:UnregisterAllEvents()
|
|
94
|
+
owner:SetScript("OnEvent", nil)
|
|
95
|
+
if button ~= nil then
|
|
96
|
+
button:SetAttribute("type1", nil)
|
|
97
|
+
button:SetAttribute("type2", nil)
|
|
98
|
+
button:EnableMouse(false)
|
|
99
|
+
button:Hide()
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
local function sync()
|
|
103
|
+
if button == nil or stopped or stopping or InCombatLockdown() then
|
|
104
|
+
return
|
|
105
|
+
end
|
|
106
|
+
if buttonUnit ~= target.Token then
|
|
107
|
+
button:SetAttribute("unit", target.Token)
|
|
108
|
+
buttonUnit = target.Token
|
|
109
|
+
end
|
|
110
|
+
if not host:IsVisible() then
|
|
111
|
+
if button:IsShown() then
|
|
112
|
+
button:Hide()
|
|
113
|
+
end
|
|
114
|
+
return
|
|
115
|
+
end
|
|
116
|
+
local x, y = host:GetCenter()
|
|
117
|
+
if x == nil or y == nil then
|
|
118
|
+
return
|
|
119
|
+
end
|
|
120
|
+
local scale = host:GetEffectiveScale() / UIParent:GetEffectiveScale()
|
|
121
|
+
local width = host:GetWidth() * scale
|
|
122
|
+
local height = host:GetHeight() * scale
|
|
123
|
+
local cx = x * scale
|
|
124
|
+
local cy = y * scale
|
|
125
|
+
if cx ~= lastX or cy ~= lastY or width ~= lastWidth or height ~= lastHeight then
|
|
126
|
+
button:ClearAllPoints()
|
|
127
|
+
button:SetPoint(
|
|
128
|
+
"CENTER",
|
|
129
|
+
UIParent,
|
|
130
|
+
"BOTTOMLEFT",
|
|
131
|
+
cx,
|
|
132
|
+
cy
|
|
133
|
+
)
|
|
134
|
+
button:SetSize(width, height)
|
|
135
|
+
lastX = cx
|
|
136
|
+
lastY = cy
|
|
137
|
+
lastWidth = width
|
|
138
|
+
lastHeight = height
|
|
139
|
+
end
|
|
140
|
+
local strata = host:GetFrameStrata()
|
|
141
|
+
local level = host:GetFrameLevel() + 2
|
|
142
|
+
local alpha = host:GetEffectiveAlpha()
|
|
143
|
+
if strata ~= lastStrata then
|
|
144
|
+
button:SetFrameStrata(strata)
|
|
145
|
+
lastStrata = strata
|
|
146
|
+
end
|
|
147
|
+
if level ~= lastLevel then
|
|
148
|
+
button:SetFrameLevel(level)
|
|
149
|
+
lastLevel = level
|
|
150
|
+
end
|
|
151
|
+
if alpha ~= lastAlpha then
|
|
152
|
+
button:SetAlpha(alpha)
|
|
153
|
+
lastAlpha = alpha
|
|
154
|
+
end
|
|
155
|
+
if not button:IsShown() then
|
|
156
|
+
button:Show()
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
do
|
|
160
|
+
local function ____catch(failure)
|
|
161
|
+
cleanup(nil)
|
|
162
|
+
error(failure, 0)
|
|
163
|
+
end
|
|
164
|
+
local ____try, ____hasReturned = pcall(function()
|
|
165
|
+
if button ~= nil then
|
|
166
|
+
button:RegisterForClicks("LeftButtonUp", "RightButtonUp")
|
|
167
|
+
button:SetID(0)
|
|
168
|
+
button:SetAttribute("useOnKeyDown", false)
|
|
169
|
+
button:SetAttribute("unit", target.Token)
|
|
170
|
+
button:SetAttribute("type1", "target")
|
|
171
|
+
button:SetAttribute("type2", "togglemenu")
|
|
172
|
+
button:EnableMouse(true)
|
|
173
|
+
host:SetScript(
|
|
174
|
+
"OnUpdate",
|
|
175
|
+
function(_frame, delta)
|
|
176
|
+
elapsed = elapsed + delta
|
|
177
|
+
if elapsed >= 0.05 then
|
|
178
|
+
elapsed = 0
|
|
179
|
+
sync(nil)
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
)
|
|
183
|
+
host:HookScript("OnShow", sync)
|
|
184
|
+
host:HookScript("OnHide", sync)
|
|
185
|
+
owner:RegisterEvent("PLAYER_REGEN_ENABLED")
|
|
186
|
+
end
|
|
187
|
+
for ____, event in ipairs({"UNIT_PORTRAIT_UPDATE", "UNIT_MODEL_CHANGED", "PORTRAITS_UPDATED", "PLAYER_ENTERING_WORLD"}) do
|
|
188
|
+
owner:RegisterEvent(event)
|
|
189
|
+
end
|
|
190
|
+
if __TS__StringIncludes(target.Token, "target") then
|
|
191
|
+
owner:RegisterEvent("PLAYER_TARGET_CHANGED")
|
|
192
|
+
end
|
|
193
|
+
if __TS__StringIncludes(target.Token, "focus") then
|
|
194
|
+
owner:RegisterEvent("PLAYER_FOCUS_CHANGED")
|
|
195
|
+
end
|
|
196
|
+
owner:SetScript(
|
|
197
|
+
"OnEvent",
|
|
198
|
+
function(_frame, event, eventUnit)
|
|
199
|
+
if event == "PLAYER_REGEN_ENABLED" then
|
|
200
|
+
if stopping then
|
|
201
|
+
cleanup(nil)
|
|
202
|
+
else
|
|
203
|
+
sync(nil)
|
|
204
|
+
end
|
|
205
|
+
elseif event ~= "UNIT_PORTRAIT_UPDATE" and event ~= "UNIT_MODEL_CHANGED" or eventUnit == target.Token then
|
|
206
|
+
draw(nil)
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
)
|
|
210
|
+
stopUnit = target:onTokenChange(function()
|
|
211
|
+
draw(nil)
|
|
212
|
+
sync(nil)
|
|
213
|
+
end)
|
|
214
|
+
draw(nil)
|
|
215
|
+
sync(nil)
|
|
216
|
+
end)
|
|
217
|
+
if not ____try then
|
|
218
|
+
____catch(____hasReturned)
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
return function()
|
|
222
|
+
stopping = true
|
|
223
|
+
if button ~= nil and InCombatLockdown() then
|
|
224
|
+
return
|
|
225
|
+
end
|
|
226
|
+
cleanup(nil)
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
}
|
|
230
|
+
)
|
|
231
|
+
)
|
|
232
|
+
end
|
|
233
|
+
return ____exports
|
package/lib/ui/index.d.ts
CHANGED
package/lib/ui/index.lua
CHANGED
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"type": "git",
|
|
5
5
|
"url": "git+https://github.com/KerimCETINBAS/wuira.git"
|
|
6
6
|
},
|
|
7
|
-
"version": "0.
|
|
7
|
+
"version": "0.3.0",
|
|
8
8
|
"author": {
|
|
9
9
|
"name": "Kerim Cetinbas",
|
|
10
10
|
"email": "a.cetinbas@icloud.com"
|
|
@@ -32,6 +32,10 @@
|
|
|
32
32
|
"types": "./lib/skins/index.d.ts",
|
|
33
33
|
"default": "./lib/skins/index.lua"
|
|
34
34
|
},
|
|
35
|
+
"./platform": {
|
|
36
|
+
"types": "./lib/platform/index.d.ts",
|
|
37
|
+
"default": "./lib/platform/index.lua"
|
|
38
|
+
},
|
|
35
39
|
"./spells": {
|
|
36
40
|
"types": "./lib/spells/index.d.ts",
|
|
37
41
|
"default": "./lib/spells/index.lua"
|
|
@@ -66,6 +70,9 @@
|
|
|
66
70
|
"skins": [
|
|
67
71
|
"lib/skins/index.d.ts"
|
|
68
72
|
],
|
|
73
|
+
"platform": [
|
|
74
|
+
"lib/platform/index.d.ts"
|
|
75
|
+
],
|
|
69
76
|
"spells": [
|
|
70
77
|
"lib/spells/index.d.ts"
|
|
71
78
|
],
|