Bagshui 1.6.4
enUS Localization Update Announcement / localization-update-announcement (push) Canceled after 0s

This commit is contained in:
2026-10-30 15:55:43 +00:00
parent cff67b3533
commit 896f46f0d1
179 changed files with 50231 additions and 0 deletions
+265
View File
@@ -0,0 +1,265 @@
-- Bagshui Character Data Management UI
-- Exposes: BsCharacterData (and Bagshui.components.CharacterData)
-- Raises: BAGSHUI_CHARACTERDATA_UPDATE
-- Consumes: BAGSHUI_CHARACTERDATA_UPDATE
Bagshui:AddComponent(function()
-- CharacterData class is built on the ObjectList prototype, even though it
-- only exists to provide a UI for deleting old alts.
local CharacterData = Bagshui.prototypes.ObjectList:New({
dataStorageKey = "characters",
objectName = "CharacterData",
objectNamePlural = "CharacterData",
wikiPage = BS_WIKI_PAGES.CharacterData,
-- Disable all table content filters.
objectSkeleton = BS_OBJECT_LIST_TEMPLATE_TABLE_WILDCARD,
objectTemplate = BS_OBJECT_LIST_TEMPLATE_TABLE_WILDCARD,
managerMultiSelect = false,
disableObjectCreation = true,
disableObjectEditing = true,
disableObjectSharing = true,
disableObjectDeletionFunc = function(characterId)
-- Loop for scrollable list entries.
if type(characterId) == "table" then
for charId, _ in pairs(characterId) do
if charId == Bagshui.currentCharacterId or Bagshui.sharedCharacters[charId] then
return true
end
end
end
-- Single object ID.
-- Characters from other accounts have to be deleted from the account they belong to.
return characterId == Bagshui.currentCharacterId or Bagshui.sharedCharacters[characterId] ~= nil
end,
-- This metatable will be assigned to each character in SavedVariables BagshuiData.characters.
-- It's basically a hack that quickly makes the character data structures compatible
-- with ObjectList's expectations, since ObjectList wasn't originally designed
-- to handle an object that stores its primary data in a sub-table. (Adding this metatable
-- is safe because there is no arbitrary access to keys in the character table.)
objectMetatable = {
__index = function(tbl, key)
if rawget(tbl, key) then
return rawget(tbl, key)
end
if rawget(tbl, "info") then
return rawget(tbl, "info")[key]
end
return rawget(tbl, key)
end,
},
---@type string[]
-- List of cached characters that will be used for the Character menu.
-- Managed by `CharacterData:Update()`.
characterIdList = {},
---@type string[]
-- Same as `characterIdList`, but formatted names.
characterNameList = {},
})
Bagshui.environment.BsCharacterData = CharacterData
Bagshui.components.CharacterData = CharacterData
--- Initialize the CharacterData class.
function CharacterData:Init()
-- Add sorting functions.
self.sortedIdLists.realm = {}
self.idListSortFunctions.realm = function(idA, idB)
return (self._idListSortFunctions_objectList[idA].realm or "")
< (self._idListSortFunctions_objectList[idB].realm or "")
end
self.sortedIdLists.lastLogout = {}
self.idListSortFunctions.lastLogout = function(idA, idB)
return (self._idListSortFunctions_objectList[idA].lastLogout or 0)
< (self._idListSortFunctions_objectList[idB].lastLogout or 0)
end
-- Calls ObjectList:Init().
self._super.Init(self)
-- ObjectList points `self.list` at the saved characters table (`Bagshui.characters`).
-- Replace it with a merged view that also contains characters shared by other accounts,
-- which are not saved. See `CharacterData:RefreshList()` and `CharacterData:Delete()`.
self.list = {}
self:RefreshList()
-- Generate the Character auto-split menu's initial list.
CharacterData:Update()
-- Add auto-split menu that lists all characters.
Bagshui.prototypes.Menus:AddAutoSplitMenu(BS_AUTO_SPLIT_MENU_TYPE.CHARACTERS, {
defaultIdList = self.characterIdList,
nameFunc = function(id)
return BsCharacter:FormatCharacterName(id, true) or id
end,
-- Manage...
extraItems = {
{
text = string.format(L.Symbol_Ellipsis, L.Manage),
tooltipTitle = L.Manage,
tooltipText = string.format(L.Prefix_Manage, L.CharacterData),
checked = false,
value = {
func = function()
Bagshui:CloseMenus()
self:Open()
end,
},
},
},
})
end
--- Event handling.
---@param event string Event name.
---@param arg1 any Event argument.
function CharacterData:OnEvent(event, arg1)
-- Check to see if the ObjectList prototype is handling this event
if self._super.OnEvent(self, event, arg1) then
return
end
-- Refresh the Character auto-split menu.
if event == "BAGSHUI_CHARACTERDATA_UPDATE" then
self:Update()
return
end
end
--- Subclass override for InitUI() to handle class-specific details.
function CharacterData:InitUi()
-- Calls ObjectList:InitUi().
self._super.InitUi(
self,
nil, -- No custom Object Manager needed.
nil, -- No custom Object Editor needed.
-- Not much to configure since there's no editing.
{
managerHeight = 400,
managerWidth = 450,
managerColumns = {
{
field = "name",
title = L.ObjectManager_Column_Name,
widthPercent = "45",
currentSortOrder = "ASC",
lastSortOrder = "ASC",
},
{
field = "realm",
title = L.ObjectManager_Column_Realm,
widthPercent = "25",
lastSortOrder = "ASC",
},
{
field = "lastLogout",
title = L.ObjectManager_Column_LastInventoryUpdate,
widthPercent = "25",
lastSortOrder = "ASC",
},
},
-- Show correctly formatted data.
managerColumnTextFunc = function(fieldName, id, obj, preliminaryDisplayValue)
if fieldName == "name" then
local formattedName = BsCharacter:FormatCharacterName(id) or preliminaryDisplayValue
if Bagshui.sharedCharacters[id] and type(formattedName) == "string" then
formattedName = formattedName .. " " .. GRAY_FONT_COLOR_CODE .. "(other account)" .. FONT_COLOR_CODE_CLOSE
end
return formattedName
elseif fieldName == "lastLogout" then
return _G.date(
"%Y-%b-%d",
type(preliminaryDisplayValue) == "number" and preliminaryDisplayValue or _G.time()
)
end
return preliminaryDisplayValue
end,
deletePrompt = L.ObjectManager_DeleteForPrompt,
deletePromptExtraInfo = L.CharacterDataManager_DeleteInfo,
}
)
end
--- Rebuild the list shown in the manager: this account's saved characters plus
--- characters shared by other accounts (which are never saved here).
function CharacterData:RefreshList()
BsUtil.TableClear(self.list)
for id, character in pairs(Bagshui.characters) do
self.list[id] = character
end
for id, character in pairs(Bagshui.sharedCharacters) do
if not self.list[id] then
self.list[id] = character
end
end
self:UpdateTrackingLists()
end
--- Delete a character from this account's saved data. (Subclass override.)
--- Because `self.list` is a merged view, the base implementation can't be used.
--- The character's shared file is also cleared so other accounts stop seeing it.
---@param characterId string
---@return boolean success
function CharacterData:Delete(characterId)
if
characterId == Bagshui.currentCharacterId
or Bagshui.sharedCharacters[characterId]
or not Bagshui.characters[characterId]
then
Bagshui:PrintWarning(string.format(L.ObjectList_ActionNotAllowed, L.Deletion, L.CharacterData))
return false
end
Bagshui.characters[characterId] = nil
if BsCatalog and BsCatalog.ForgetSharedCharacter then
BsCatalog:ForgetSharedCharacter(characterId)
end
self:RefreshList()
Bagshui:RaiseEvent(self.objectChangeEvent, false, characterId)
return true
end
-- Keep the Character auto-split menu current when old alts are deleted.
function CharacterData:Update()
BsUtil.TableClear(self.characterIdList)
-- Sort the list of characters alphabetically but sort by realm first.
for character, _ in pairs(Bagshui.characters) do
if character ~= Bagshui.currentCharacterId then
table.insert(self.characterIdList, character)
end
end
-- Characters shared by other accounts can be viewed too.
for character, _ in pairs(Bagshui.sharedCharacters) do
table.insert(self.characterIdList, character)
end
local function sortKey(characterId)
local characterData = Bagshui.characters[characterId] or Bagshui.sharedCharacters[characterId]
return tostring(characterData.info.realm or "") .. " " .. tostring(characterData.info.name or "")
end
table.sort(self.characterIdList, function(a, b)
return sortKey(a) < sortKey(b)
end)
-- Place the current character at the top.
table.insert(self.characterIdList, 1, Bagshui.currentCharacterId)
-- Refresh formatted name list.
BsUtil.TableClear(self.characterNameList)
for _, id in ipairs(self.characterIdList) do
table.insert(self.characterNameList, BsCharacter:FormatCharacterName(id, true) or id)
end
end
-- Class event registration.
-- This is done at the end because RegisterEvent expects the class to have an OnEvent function.
Bagshui:RegisterEvent("BAGSHUI_CHARACTERDATA_UPDATE", CharacterData)
end)