From a886eb55cb9751a1e7fe570f0e738b0f3792c983 Mon Sep 17 00:00:00 2001
From: Brues <5278969+brues-code@users.noreply.github.com>
Date: Fri, 7 Aug 2026 23:14:16 -0500
Subject: [PATCH] Add a friend notes module
Store client-side notes for friends through ClassicAPI's C_FriendList
note API. Add an Edit Note entry to the friend right-click menu, which
opens a dialog that reads and writes the note. Show the note in a
tooltip when the cursor is over a friend in the list.
---
init/modules.xml | 1 +
modules/friendnotes.lua | 79 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 80 insertions(+)
create mode 100644 modules/friendnotes.lua
diff --git a/init/modules.xml b/init/modules.xml
index 182c993a..c9b0069f 100644
--- a/init/modules.xml
+++ b/init/modules.xml
@@ -81,4 +81,5 @@
+
\ No newline at end of file
diff --git a/modules/friendnotes.lua b/modules/friendnotes.lua
new file mode 100644
index 00000000..dfc51466
--- /dev/null
+++ b/modules/friendnotes.lua
@@ -0,0 +1,79 @@
+-- Friend notes
+-- Client-side notes for friends via ClassicAPI's C_FriendList note API
+-- (SetFriendNotes / GetFriendInfo(.notes)). Adds an "Edit Note" entry to the
+-- friend right-click menu (the "FRIEND" UnitPopup) and shows the note in a
+-- tooltip when you hover a friend in the list.
+pfUI:RegisterModule("friendnotes", function ()
+ local EDIT_TOKEN = "PFUI_FRIEND_NOTE"
+
+ -- Note editor. In 1.12 StaticPopup, OnAccept runs with `this` = the OK
+ -- button (the dialog is this:GetParent()); the friend name arrives as the
+ -- data argument passed to StaticPopup_Show.
+ StaticPopupDialogs["PFUI_FRIEND_NOTE_EDIT"] = {
+ text = SET_FRIENDNOTE_LABEL,
+ button1 = SAVE,
+ button2 = CANCEL,
+ hasEditBox = 1,
+ maxLetters = 128,
+ OnAccept = function(name)
+ C_FriendList.SetFriendNotes(name, _G[this:GetParent():GetName().."EditBox"]:GetText())
+ end,
+ EditBoxOnEnterPressed = function(name)
+ C_FriendList.SetFriendNotes(name, this:GetText())
+ this:GetParent():Hide()
+ end,
+ EditBoxOnEscapePressed = function() this:GetParent():Hide() end,
+ timeout = 0, whileDead = 1, hideOnEscape = 1,
+ }
+
+ local function OpenNoteEditor(name)
+ if not name or name == "" then return end
+ local info = C_FriendList.GetFriendInfo(name)
+ local dialog = StaticPopup_Show("PFUI_FRIEND_NOTE_EDIT", name, nil, name)
+ if not dialog then return end
+ local editbox = _G[dialog:GetName().."EditBox"]
+ editbox:SetText((info and info.notes) or "")
+ editbox:HighlightText()
+ editbox:SetFocus()
+ end
+
+ -- Add "Edit Note" to the friend right-click menu, just before Cancel.
+ UnitPopupButtons[EDIT_TOKEN] = { text = SET_NOTE, dist = 0 }
+ local friendMenu = UnitPopupMenus["FRIEND"]
+ table.insert(friendMenu, table.getn(friendMenu), EDIT_TOKEN)
+
+ -- Route our entry to the editor and close the menu; delegate the rest. A
+ -- bare assignment lands on pfUI.env, so set the global explicitly.
+ local UnitPopup_OnClick_orig = UnitPopup_OnClick
+ _G.UnitPopup_OnClick = function()
+ if this and this.value == EDIT_TOKEN then
+ local dropdown = _G[UIDROPDOWNMENU_INIT_MENU]
+ local name = dropdown and dropdown.name
+ CloseDropDownMenus()
+ OpenNoteEditor(name)
+ return
+ end
+ return UnitPopup_OnClick_orig()
+ end
+
+ -- Show the note in a tooltip while hovering a friend in the list. Friend
+ -- buttons carry their friend index via SetID (see FriendsFrame_Update).
+ local function FriendButton_OnEnter()
+ local index = this:GetID()
+ if not index or index < 1 then return end
+ local info = C_FriendList.GetFriendInfoByIndex(index)
+ if not info or not info.notes or info.notes == "" then return end
+ GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
+ GameTooltip:SetText(info.name or "")
+ GameTooltip:AddLine(info.notes, 1, 1, 1, 1)
+ GameTooltip:Show()
+ end
+
+ for i = 1, FRIENDS_TO_DISPLAY do
+ local button = _G["FriendsFrameFriendButton"..i]
+ if button then
+ button:HookScript("OnEnter", FriendButton_OnEnter)
+ button:HookScript("OnLeave", GameTooltip_Hide)
+ end
+ end
+end)