diff --git a/esoui/ingame/collections/gamepad/collectionsbook_gamepad.lua b/esoui/ingame/collections/gamepad/collectionsbook_gamepad.lua
index 149311a..7e3b4f5 100755
--- a/esoui/ingame/collections/gamepad/collectionsbook_gamepad.lua
+++ b/esoui/ingame/collections/gamepad/collectionsbook_gamepad.lua
@@ -1,7 +1,12 @@
+ZO_DLC_BACKGROUND_TEXTURE_SQUARE_DIMENSION = 1024
+ZO_DLC_BACKGROUND_TEXTURE_COORD_RIGHT = ZO_GAMEPAD_QUADRANT_2_3_CONTENT_BACKGROUND_WIDTH / ZO_DLC_BACKGROUND_TEXTURE_SQUARE_DIMENSION
local GAMEPAD_COLLECTIONS_ACTIONS_DIALOG_NAME = "GAMEPAD_COLLECTIONS_ACTIONS_DIALOG"
local GAMEPAD_COLLECTIONS_RENAME_COLLECTIBLE_DIALOG_NAME = "GAMEPAD_COLLECTIONS_INVENTORY_RENAME_COLLECTIBLE"
+local NOTIFICATIONS_PROVIDER = GAMEPAD_NOTIFICATIONS:GetCollectionsProvider()
+local TIME_NEW_PERSISTS_WHILE_SELECTED_MS = 200
+
local ZO_GamepadCollectionsBook = ZO_Gamepad_ParametricList_Screen:Subclass()
function ZO_GamepadCollectionsBook:New(...)
@@ -29,12 +34,18 @@ function ZO_GamepadCollectionsBook:Initialize(control)
ZO_Gamepad_AddListTriggerKeybindDescriptors(self.collectionKeybindStripDescriptor, self.collectionList.list)
self.collectionList.headerText = GetString(SI_MAIN_MENU_COLLECTIONS)
self.collectionList.titleText = nil
+ self.updateList = {}
self.currentList = nil
+ self.trySetClearNewFlagCallback = function(callId)
+ self:TrySetClearNewFlag(callId)
+ end
+
self.headerData = {}
ZO_GamepadGenericHeader_Refresh(self.header, self.headerData)
+ self:InitializeInfoPanel()
self:InitializeActionsDialog()
self:InitializeRenameCollectibleDialog()
@@ -42,13 +53,50 @@ function ZO_GamepadCollectionsBook:Initialize(control)
COLLECTIONS_BOOK_SINGLETON:RegisterCallback("OnCollectibleUpdated", function(...) self:OnCollectibleUpdated(...) end)
COLLECTIONS_BOOK_SINGLETON:RegisterCallback("OnCollectionUpdated", function(...) self:OnCollectionUpdated(...) end)
+ COLLECTIONS_BOOK_SINGLETON:RegisterCallback("OnCollectionNotificationRemoved", function(...) self:OnCollectionNotificationRemoved(...) end)
+ COLLECTIONS_BOOK_SINGLETON:RegisterCallback("OnUpdateCooldowns", function(...) self:OnUpdateCooldowns(...) end)
+end
+
+function ZO_GamepadCollectionsBook:InitializeInfoPanel()
+ local infoPanel = self.control:GetNamedChild("InfoPanel")
+ infoPanel.backgroundControl = infoPanel:GetNamedChild("Background")
+
+ local container = infoPanel:GetNamedChild("Container")
+ infoPanel.unlockStatusControl = container:GetNamedChild("UnlockStatusLabel")
+ infoPanel.nameControl = container:GetNamedChild("Name")
+ infoPanel.questStatusControl = container:GetNamedChild("QuestStatusValue")
+
+ local scrollContainer = container:GetNamedChild("ScrollSection"):GetNamedChild("ScrollChild")
+ infoPanel.descriptionControl = scrollContainer:GetNamedChild("Description")
+ infoPanel.questAcceptIndicator = scrollContainer:GetNamedChild("QuestAcceptIndicator")
+ infoPanel.questAcceptDescription = scrollContainer:GetNamedChild("QuestAcceptDescription")
+ self.infoPanelControl = infoPanel
end
function ZO_GamepadCollectionsBook:SetupList(list)
- ZO_Gamepad_ParametricList_Screen.SetupList(self, list)
+ local function CategoryEntrySetup(control, data, selected, reselectingDuringRebuild, enabled, active)
+ ZO_SharedGamepadEntry_OnSetup(control, data, selected, reselectingDuringRebuild, enabled, active)
+
+ local entryData = data.data
+ if self:HasAnyNotifications(entryData.categoryIndex) then
+ control.icon:ClearIcons()
+ control.icon:AddIcon(entryData.icon)
+ control.icon:AddIcon(ZO_GAMEPAD_NEW_ICON_64)
+ control.icon:Show()
+ end
+ end
+
+ list:AddDataTemplate("ZO_GamepadMenuEntryTemplate", CategoryEntrySetup, ZO_GamepadMenuEntryTemplateParametricListFunction)
+ list:AddDataTemplateWithHeader("ZO_GamepadMenuEntryTemplate", CategoryEntrySetup, ZO_GamepadMenuEntryTemplateParametricListFunction, nil, "ZO_GamepadMenuEntryHeaderTemplate")
+
+ local function CollectibleEntrySetup(control, data, selected, reselectingDuringRebuild, enabled, active)
+ data.brandNew = data.data.notificationId ~= nil
+
+ ZO_SharedGamepadEntry_OnSetup(control, data, selected, reselectingDuringRebuild, enabled, active)
+ end
- list:AddDataTemplate("ZO_GamepadItemEntryTemplate", ZO_SharedGamepadEntry_OnSetup, ZO_GamepadMenuEntryTemplateParametricListFunction)
- list:AddDataTemplateWithHeader("ZO_GamepadItemEntryTemplate", ZO_SharedGamepadEntry_OnSetup, ZO_GamepadMenuEntryTemplateParametricListFunction, nil, "ZO_GamepadMenuEntryHeaderTemplate")
+ list:AddDataTemplate("ZO_GamepadItemEntryTemplate", CollectibleEntrySetup, ZO_GamepadMenuEntryTemplateParametricListFunction)
+ list:AddDataTemplateWithHeader("ZO_GamepadItemEntryTemplate", CollectibleEntrySetup, ZO_GamepadMenuEntryTemplateParametricListFunction, nil, "ZO_GamepadMenuEntryHeaderTemplate")
end
function ZO_GamepadCollectionsBook:OnShowing()
@@ -57,6 +105,7 @@ function ZO_GamepadCollectionsBook:OnShowing()
self:ShowList(self.categoryList)
if self.browseToCollectibleInfo then
self:ViewCategory(self.browseToCollectibleInfo.categoryIndex)
+ self:SelectCollectibleEntry(self.browseToCollectibleInfo.collectibleId)
self.browseToCollectibleInfo = nil
end
end
@@ -97,9 +146,24 @@ function ZO_GamepadCollectionsBook:InitializeKeybindStripDescriptors()
-- Set Active or Put Away Collectible
{
name = function()
+ local categoryType = self.currentList.data.categoryType
local entryData = self.currentList.list:GetTargetData()
local collectibleData = entryData.data
- return collectibleData.active and GetString(SI_COLLECTIBLE_ACTION_PUT_AWAY) or GetString(SI_COLLECTIBLE_ACTION_SET_ACTIVE)
+ local nameStringId
+ if categoryType == COLLECTIBLE_CATEGORY_TYPE_DLC then
+ nameStringId = SI_DLC_BOOK_ACTION_ACCEPT_QUEST
+ elseif categoryType == COLLECTIBLE_CATEGORY_TYPE_TROPHY then
+ nameStringId = SI_COLLECTIBLE_ACTION_USE
+ elseif collectibleData.active then
+ if categoryType == COLLECTIBLE_CATEGORY_TYPE_ASSISTANT or categoryType == COLLECTIBLE_CATEGORY_TYPE_VANITY_PET then
+ nameStringId = SI_COLLECTIBLE_ACTION_DISMISS
+ else
+ nameStringId = SI_COLLECTIBLE_ACTION_PUT_AWAY
+ end
+ else
+ nameStringId = SI_COLLECTIBLE_ACTION_SET_ACTIVE
+ end
+ return GetString(nameStringId)
end,
keybind = "UI_SHORTCUT_PRIMARY",
callback = function()
@@ -117,6 +181,36 @@ function ZO_GamepadCollectionsBook:InitializeKeybindStripDescriptors()
end
end,
sound = SOUNDS.DEFAULT_CLICK,
+ enabled = function()
+ local entryData = self.currentList.list:GetTargetData()
+ if entryData and entryData.data and entryData.data.useable then
+ local remaining = GetCollectibleCooldownAndDuration(entryData.data.collectibleId)
+ if remaining > 0 then
+ return false, GetString(SI_COLLECTIONS_COOLDOWN_ERROR)
+ elseif entryData.data.blocked then
+ return false, GetString(SI_COLLECTIONS_BLOCKED_ERROR)
+ else
+ return true
+ end
+ end
+ return false
+ end
+ },
+ --Assign to Quick Slot
+ {
+ name = GetString(SI_GAMEPAD_ITEM_ACTION_QUICKSLOT_ASSIGN),
+ keybind = "UI_SHORTCUT_SECONDARY",
+ callback = function()
+ local entryData = self.currentList.list:GetTargetData()
+ GAMEPAD_QUICKSLOT:SetCollectibleToQuickslot(entryData.data.collectibleId)
+ SCENE_MANAGER:Push("gamepad_quickslot")
+ end,
+ visible = function()
+ local entryData = self.currentList.list:GetTargetData()
+ local categoryType = self.currentList.data.categoryType
+ return entryData.data.unlocked and IsCollectibleCategorySlottable(categoryType)
+ end,
+ sound = SOUNDS.GAMEPAD_MENU_FORWARD,
},
-- Actions
{
@@ -155,6 +249,23 @@ function ZO_GamepadCollectionsBook:InitializeKeybindStripDescriptors()
end
end,
},
+ --Subscribe
+ {
+ alignment = KEYBIND_STRIP_ALIGN_RIGHT,
+ name = GetString(SI_DLC_BOOK_ACTION_GET_SUBSCRIPTION),
+ keybind = "UI_SHORTCUT_RIGHT_STICK",
+ callback = function()
+ if GetUIPlatform() == UI_PLATFORM_PC then
+ ZO_Dialogs_ShowGamepadDialog("CONFIRM_OPEN_URL_BY_TYPE", { urlType = APPROVED_URL_ESO_ACCOUNT_SUBSCRIPTION }, { mainTextParams = { GetString(SI_ESO_PLUS_SUBSCRIPTION_LINK_TEXT), GetString(SI_URL_APPLICATION_WEB) } })
+ else
+ ZO_Dialogs_ShowGamepadDialog("CONSOLE_BUY_ESO_PLUS")
+ end
+ end,
+ visible = function()
+ local categoryData = self.currentList.data
+ return categoryData.categoryType == COLLECTIBLE_CATEGORY_TYPE_DLC and not IsESOPlusSubscriber()
+ end,
+ },
}
ZO_Gamepad_AddBackNavigationKeybindDescriptorsWithSound(self.collectionKeybindStripDescriptor, GAME_NAVIGATION_TYPE_BUTTON, function() self:ShowList(self.categoryList) end )
end
@@ -170,6 +281,19 @@ function ZO_GamepadCollectionsBook:ViewCategory(categoryIndex)
self:ShowList(self.collectionList)
end
+function ZO_GamepadCollectionsBook:SelectCollectibleEntry(collectibleId)
+ if collectibleId then
+ local list = self.collectionList.list
+ for i = 1, list:GetNumItems() do
+ local data = list:GetDataForDataIndex(i)
+ if data.data.collectibleId == collectibleId then
+ list:SetSelectedIndexWithoutAnimation(i)
+ break
+ end
+ end
+ end
+end
+
function ZO_GamepadCollectionsBook:PerformUpdate()
self:BuildCategoryList()
end
@@ -191,7 +315,12 @@ function ZO_GamepadCollectionsBook:ShowList(list)
ZO_GamepadGenericHeader_Refresh(self.header, self.headerData)
if self.currentList == self.collectionList then
- self:RefreshTooltip(self.collectionList.list:GetTargetData())
+ local targetData = self.collectionList.list:GetTargetData()
+ self:RefreshTooltip(targetData)
+ self.notificationIdToClear = targetData.data.notificationId
+ if self.notificationIdToClear then
+ self.clearNewStatusOnSelectionChanged = true
+ end
end
end
@@ -200,6 +329,16 @@ function ZO_GamepadCollectionsBook:HideCurrentList()
return
end
+ if self.currentList == self.collectionList then
+ if self.notificationIdToClear then
+ RemoveCollectibleNotification(self.notificationIdToClear)
+ end
+
+ self.clearNewStatusOnSelectionChanged = false
+ self.notificationIdToClear = nil
+ self.clearNewStatusCallId = nil
+ end
+
KEYBIND_STRIP:RemoveKeybindButtonGroup(self.currentList.keybind)
SCENE_MANAGER:RemoveFragment(self.currentList.fragment)
@@ -222,6 +361,16 @@ function ZO_GamepadCollectionsBook:OnCollectibleUpdated(collectibleId)
if self.currentList == self.collectionList and self.collectionList then
self:BuildCollectionList()
end
+ self.categoryList.list:RefreshVisible()
+ end
+end
+
+function ZO_GamepadCollectionsBook:OnCollectionNotificationRemoved(notificationId, collectibleId)
+ if not self.control:IsHidden() then
+ if self.currentList == self.collectionList then
+ self.currentList.list:RefreshVisible()
+ end
+ self.categoryList.list:RefreshVisible()
end
end
@@ -234,7 +383,7 @@ function ZO_GamepadCollectionsBook:BuildCategoryList()
local gamepadIcon = GetCollectibleCategoryGamepadIcon(categoryIndex)
categoryName = zo_strformat(SI_COLLECTIBLE_NAME_FORMATTER, categoryName)
- local entryData = ZO_GamepadEntryData:New(categoryName, gamepadIcon or ZO_NO_TEXTURE_FILE)
+ local entryData = ZO_GamepadEntryData:New(categoryName, gamepadIcon)
entryData.data = {
categoryIndex = categoryIndex,
categoryName = categoryName,
@@ -242,6 +391,7 @@ function ZO_GamepadCollectionsBook:BuildCategoryList()
numCollectibles = numCollectibles,
unlockedCollectibles = unlockedCollectibles,
totalCollectibles = totalCollectibles,
+ icon = gamepadIcon,
}
entryData:SetIconTintOnSelection(true)
@@ -299,6 +449,8 @@ function ZO_GamepadCollectionsBook:BuildCollectionList()
self:RefreshTooltip(self.collectionList.list:GetTargetData())
self.collectionList.titleText = data.categoryName
+
+ self.updateList = unlockedData
end
function ZO_GamepadCollectionsBook:BuildCollectibleData(categoryIndex, subCategoryIndex, collectibleIndex, categoryType)
@@ -306,8 +458,10 @@ function ZO_GamepadCollectionsBook:BuildCollectibleData(categoryIndex, subCatego
local name, description, iconFile, lockedIconFile, unlocked, purchasable, active, _, hint, isPlaceholder = GetCollectibleInfo(collectibleId)
local unlockState = GetCollectibleUnlockStateById(collectibleId)
iconFile = unlocked and iconFile or lockedIconFile
-
- local useable = unlocked and COLLECTIONS_INVENTORY_VALID_CATEGORY_TYPES[categoryType] and not (active and categoryType == COLLECTIBLE_CATEGORY_TYPE_MOUNT)
+ local backgroundFile = GetCollectibleGamepadBackgroundImage(collectibleId)
+ local useable = IsCollectibleUsable(collectibleId)
+ local categoryBlocked = IsCollectibleCategoryBlocked(categoryType)
+ local notificationId = self:GetNotificationIdForCollectible(collectibleId)
local entryData = ZO_GamepadEntryData:New(zo_strformat(SI_COLLECTIBLE_NAME_FORMATTER, name), iconFile)
entryData.data = {
@@ -316,15 +470,33 @@ function ZO_GamepadCollectionsBook:BuildCollectibleData(categoryIndex, subCatego
description = description,
hint = hint,
iconFile = iconFile,
+ backgroundFile = backgroundFile,
collectibleId = collectibleId,
unlocked = unlocked,
unlockState = unlockState,
purchasable = purchasable,
useable = useable,
active = active,
+ blocked = categoryBlocked,
isPlaceholder = isPlaceholder,
+ notificationId = notificationId,
+ lastCooldownDuration = 0
}
entryData.isEquippedInCurrentCategory = active
+ entryData:InitializeCollectibleVisualData(entryData.data)
+
+ if categoryBlocked == true then
+ entryData:SetIconDesaturation(1)
+ else
+ entryData:SetIconDesaturation(0)
+ end
+
+ local remaining, duration = GetCollectibleCooldownAndDuration(entryData.data.collectibleId)
+ if remaining > 0 and duration > 0 then
+ entryData:SetCooldown(remaining, duration)
+ entryData.data.lastCooldownDuration = duration
+ end
+
return entryData
end
@@ -344,19 +516,79 @@ end
function ZO_GamepadCollectionsBook:OnSelectionChanged(list, selectedData, oldSelectedData)
if self.currentList == self.collectionList then
self:RefreshTooltip(selectedData)
+ self.notificationIdToClear = nil
+ self.clearNewStatusCallId = nil
+
+ if oldSelectedData and oldSelectedData.data.notificationId then
+ if self.clearNewStatusOnSelectionChanged then
+ RemoveCollectibleNotification(oldSelectedData.data.notificationId)
+ oldSelectedData.data.notificationId = nil
+ end
+ end
+
+ self.clearNewStatusOnSelectionChanged = false
+
+ if selectedData and selectedData.data.notificationId then
+ self.notificationIdToClear = selectedData.data.notificationId
+ self.clearNewStatusCallId = zo_callLater(self.trySetClearNewFlagCallback, TIME_NEW_PERSISTS_WHILE_SELECTED_MS)
+ end
end
if self.currentList then
KEYBIND_STRIP:UpdateKeybindButtonGroup(self.currentList.keybind)
end
end
+function ZO_GamepadCollectionsBook:TrySetClearNewFlag(callId)
+ if self.clearNewStatusCallId == callId then
+ self.clearNewStatusOnSelectionChanged = true
+ end
+end
+
function ZO_GamepadCollectionsBook:RefreshTooltip(entryData)
GAMEPAD_TOOLTIPS:ClearTooltip(GAMEPAD_LEFT_TOOLTIP)
GAMEPAD_TOOLTIPS:SetBottomRailHidden(GAMEPAD_LEFT_TOOLTIP, true)
+ SCENE_MANAGER:RemoveFragment(GAMEPAD_NAV_QUADRANT_2_3_BACKGROUND_FRAGMENT)
+ SCENE_MANAGER:RemoveFragment(GAMEPAD_COLLECTIONS_BOOK_INFO_PANEL_FRAGMENT)
+
if entryData and entryData.data then
- local categoryName = self.collectionList.data.name
- local data = entryData.data
- GAMEPAD_TOOLTIPS:LayoutCollectible(GAMEPAD_LEFT_TOOLTIP, categoryName, data.name, data.nickname, data.unlockState, data.purchasable, data.description, data.hint, data.isPlaceholder)
+ local categoryData = self.collectionList.data
+ local collectibleData = entryData.data
+ if categoryData.categoryType == COLLECTIBLE_CATEGORY_TYPE_DLC then
+ local infoPanel = self.infoPanelControl
+ infoPanel.backgroundControl:SetTexture(collectibleData.backgroundFile)
+ infoPanel.nameControl:SetText(collectibleData.name)
+ infoPanel.descriptionControl:SetText(collectibleData.description)
+ infoPanel.unlockStatusControl:SetText(GetString("SI_COLLECTIBLEUNLOCKSTATE", collectibleData.unlockState))
+
+ local questAcceptLabelStringId = collectibleData.active and SI_DLC_BOOK_QUEST_STATUS_ACCEPTED or SI_DLC_BOOK_QUEST_STATUS_NOT_ACCEPTED
+ local questName = GetCollectibleQuestPreviewInfo(collectibleData.collectibleId)
+ infoPanel.questStatusControl:SetText(zo_strformat(SI_GAMEPAD_DLC_BOOK_QUEST_STATUS_INFO, questName, GetString(questAcceptLabelStringId)))
+
+ local showsQuest = not (collectibleData.active or collectibleData.unlockState == COLLECTIBLE_UNLOCK_STATE_LOCKED)
+ local questAcceptIndicator = infoPanel.questAcceptIndicator
+ local questAcceptDescription = infoPanel.questAcceptDescription
+ if showsQuest then
+ questAcceptIndicator:SetText(GetString(SI_COLLECTIONS_QUEST_AVAILABLE))
+ questAcceptIndicator:SetHidden(false)
+
+ local questDescription = select(2, GetCollectibleQuestPreviewInfo(collectibleData.collectibleId))
+ questAcceptDescription:SetText(questDescription)
+ questAcceptDescription:SetHidden(false)
+ elseif collectibleData.unlockState == COLLECTIBLE_UNLOCK_STATE_LOCKED then
+ questAcceptIndicator:SetText(GetString(SI_COLLECTIONS_QUEST_AVAILABLE_WITH_UNLOCK))
+ questAcceptIndicator:SetHidden(false)
+ questAcceptDescription:SetHidden(true)
+ else
+ questAcceptIndicator:SetHidden(true)
+ questAcceptDescription:SetHidden(true)
+ end
+
+ SCENE_MANAGER:AddFragment(GAMEPAD_NAV_QUADRANT_2_3_BACKGROUND_FRAGMENT)
+ SCENE_MANAGER:AddFragment(GAMEPAD_COLLECTIONS_BOOK_INFO_PANEL_FRAGMENT)
+ else
+ local categoryName = categoryData.name
+ GAMEPAD_TOOLTIPS:LayoutCollectible(GAMEPAD_LEFT_TOOLTIP, categoryName, collectibleData.name, collectibleData.nickname, collectibleData.unlockState, collectibleData.purchasable, collectibleData.description, collectibleData.hint, collectibleData.isPlaceholder)
+ end
end
end
@@ -419,6 +651,24 @@ function ZO_GamepadCollectionsBook:InitializeActionsDialog()
end
},
},
+ -- Unlock Permanently (Purchase)
+ {
+ template = "ZO_GamepadMenuEntryTemplate",
+ templateData = {
+ text = GetString(SI_DLC_BOOK_ACTION_OPEN_CROWN_STORE),
+ setup = ZO_SharedGamepadEntry_OnSetup,
+ callback = function()
+ local entryData = self.currentList.list:GetTargetData()
+ local collectibleData = entryData.data
+ ShowMarketAndSearch(collectibleData.name, MARKET_OPEN_OPERATION_COLLECTIONS_DLC)
+ end,
+ visible = function()
+ local entryData = self.currentList.list:GetTargetData()
+ local collectibleData = entryData.data
+ return collectibleData.purchasable and collectibleData.unlockState ~= COLLECTIBLE_UNLOCK_STATE_UNLOCKED_OWNED
+ end
+ },
+ },
},
buttons =
{
@@ -568,6 +818,25 @@ function ZO_GamepadCollectionsBook:InitializeRenameCollectibleDialog()
end
+function ZO_GamepadCollectionsBook:HasAnyNotifications(optionalCategoryIndexFilter, optionalSubcategoryIndexFilter)
+ return NOTIFICATIONS_PROVIDER:HasAnyNotifications(optionalCategoryIndexFilter, optionalSubcategoryIndexFilter)
+end
+
+function ZO_GamepadCollectionsBook:GetNotificationIdForCollectible(collectibleId)
+ return NOTIFICATIONS_PROVIDER:GetNotificationIdForCollectible(collectibleId)
+end
+
+function ZO_GamepadCollectionsBook:OnUpdateCooldowns()
+ for i, entryData in ipairs(self.updateList) do
+ local collectibleData = entryData.data
+ local _, duration = GetCollectibleCooldownAndDuration(collectibleData.collectibleId)
+ if duration ~= collectibleData.lastCooldownDuration then
+ self:OnCollectibleUpdated(collectibleData.collectibleId)
+ return
+ end
+ end
+end
+
--[[Global functions]]--
------------------------
function ZO_GamepadCollectionsBook_OnInitialize(control)