function Librarian:AddLoreReaderUnreadToggle() local function IsSameBook(book, title) if book.title then return book.title == title end local categoryIndex, collectionIndex, bookIndex = self:GetLoreBookIndicesFromBookId(book.bookId) local bookTitle = self:GetBookInfo(categoryIndex, collectionIndex, bookIndex) return bookTitle == title end self.loreReaderKeybinds = { { alignment = KEYBIND_STRIP_ALIGN_RIGHT, name = function() local book = self:FindBook(self.lastShownBookId) if not book or not IsSameBook(book, LORE_READER.titleText) then self.loreReaderUnreadIndicator:SetHidden(true) return "" else if book.unread then if self.settings.showUnreadIndicatorInReader then self.loreReaderUnreadIndicator:SetHidden(false) else self.loreReaderUnreadIndicator:SetHidden(true) end return GetString(LIBRARIAN_MARK_READ) else self.loreReaderUnreadIndicator:SetHidden(true) return GetString(LIBRARIAN_MARK_UNREAD) end end end, visible = function() local book = self:FindBook(self.lastShownBookId) return book and IsSameBook(book, LORE_READER.titleText) end, keybind = "UI_SHORTCUT_SECONDARY", callback = function() local book = self:FindBook(self.lastShownBookId) if book and IsSameBook(book, LORE_READER.titleText) then self:ToggleReadBook(book) KEYBIND_STRIP:UpdateKeybindButtonGroup(self.loreReaderKeybinds) end end } } local function OnSceneStateChange(oldState, newState) -- Let's not add the keybind at all if this book is not registered in librarian -- This way, other addon (like Librarium) can override the same keybind for something else local book = self:FindBook(self.lastShownBookId) if not book or not IsSameBook(book, LORE_READER.titleText) then self.loreReaderUnreadIndicator:SetHidden(true) return end if newState == SCENE_SHOWING then KEYBIND_STRIP:AddKeybindButtonGroup(self.loreReaderKeybinds) elseif newState == SCENE_HIDDEN then KEYBIND_STRIP:RemoveKeybindButtonGroup(self.loreReaderKeybinds) end end -- This list of scene should be the same as the list in esoui/ingame/lorereader/lorereader.lua in its Initialize function LORE_READER_INVENTORY_SCENE:RegisterCallback("StateChange", OnSceneStateChange) LORE_READER_LORE_LIBRARY_SCENE:RegisterCallback("StateChange", OnSceneStateChange) LORE_READER_INTERACTION_SCENE:RegisterCallback("StateChange", OnSceneStateChange) GAMEPAD_LORE_READER_INVENTORY_SCENE:RegisterCallback("StateChange", OnSceneStateChange) GAMEPAD_LORE_READER_LORE_LIBRARY_SCENE:RegisterCallback("StateChange", OnSceneStateChange) GAMEPAD_LORE_READER_INTERACTION_SCENE:RegisterCallback("StateChange", OnSceneStateChange) self.loreReaderUnreadIndicator = WINDOW_MANAGER:CreateControl("LibrarianLoreReaderUnreadIndicator", ZO_LoreReaderBookContainer, CT_TEXTURE) self.loreReaderUnreadIndicator:SetAnchor(TOPLEFT, ZO_LoreReaderBookContainerFirstPage, TOPLEFT, -32, 3) self.loreReaderUnreadIndicator:SetAlpha(self.settings.unreadIndicatorTransparency) self.loreReaderUnreadIndicator:SetDimensions(32, 32) self.loreReaderUnreadIndicator:SetHidden(true) self.loreReaderUnreadIndicator:SetTexture("esoui/art/miscellaneous/new_icon.dds") end function Librarian:AddLoreLibraryIcons() if not self.settings.showUnreadIndicatorInLoreLibrary then return end -- ADD UNREAD ICON ON EACH UNREAD ENTRY local BOOK_DATA_TYPE = 1 local scrollList = LORE_LIBRARY.list:GetListControl() local initalDataType = scrollList.dataTypes[BOOK_DATA_TYPE] scrollList.dataTypes[BOOK_DATA_TYPE] = nil local function SetUpBookEntry(control, data) initalDataType.setupCallback(control, data) local _, _, known, bookId = GetLoreBookInfo(data.categoryIndex, data.collectionIndex, data.bookIndex) control.bookId = bookId local shouldUnreadIconBeHidden = true if known then local book = self:FindBook(bookId) if not book or book.unread then shouldUnreadIconBeHidden = false end end control:GetNamedChild("UnreadIcon"):SetHidden(shouldUnreadIconBeHidden) end ZO_ScrollList_AddDataType(scrollList, BOOK_DATA_TYPE, "Librarian_LoreLibrary_BookEntry", initalDataType.height, SetUpBookEntry) -- WHEN READING BOOK FROM LORE LIBRARY, UPDATE LASTSHOWNBOOKID local initial_ZO_LoreLibrary_ReadBook = ZO_LoreLibrary_ReadBook ZO_LoreLibrary_ReadBook = function(categoryIndex, collectionIndex, bookIndex) self.lastShownBookId = select(4, GetLoreBookInfo(categoryIndex, collectionIndex, bookIndex)) initial_ZO_LoreLibrary_ReadBook(categoryIndex, collectionIndex, bookIndex) end -- ORDER BOOK LIST TO MAKE UNREAD BOOK FIRST local function BookEntryComparator(leftScrollData, rightScrollData) local leftData = leftScrollData.data local rightData = rightScrollData.data local leftTitle, _, leftKnown, leftBookId = GetLoreBookInfo(leftData.categoryIndex, leftData.collectionIndex, leftData.bookIndex) local rightTitle, _, rightKnown, rightBookId = GetLoreBookInfo(rightData.categoryIndex, rightData.collectionIndex, rightData.bookIndex) if leftKnown == rightKnown then if leftKnown then local leftBook = self:FindBook(leftBookId) local rightBook = self:FindBook(rightBookId) if (leftBook and not leftBook.unread) == (rightBook and not rightBook.unread) then return leftTitle < rightTitle end return leftBook and leftBook.unread end end return leftKnown end LORE_LIBRARY.list.SortScrollList = function(loreLibrarySelf) local scrollData = ZO_ScrollList_GetDataList(loreLibrarySelf.list) table.sort(scrollData, BookEntryComparator) end -- ADD KEYBIND TO MARK BOOK AS READ FROM LORE LIBRARY local loreLibraryKeybinds = LORE_LIBRARY.keybindStripDescriptor -- Make current secondary tertiary for i, keybindDescriptor in ipairs(loreLibraryKeybinds) do if keybindDescriptor.keybind == "UI_SHORTCUT_SECONDARY" then keybindDescriptor.keybind = "UI_SHORTCUT_TERTIARY" end end local toggleKeybind = { alignment = KEYBIND_STRIP_ALIGN_RIGHT, name = function() local selectedRow = LORE_LIBRARY.list:GetMouseOverRow() if selectedRow and selectedRow.known then local book = self:FindBook(selectedRow.bookId) if not book or book.unread then return GetString(LIBRARIAN_MARK_READ) else return GetString(LIBRARIAN_MARK_UNREAD) end end end, keybind = "UI_SHORTCUT_SECONDARY", visible = function() local selectedRow = LORE_LIBRARY.list:GetMouseOverRow() return selectedRow and selectedRow.known end, callback = function() local selectedRow = LORE_LIBRARY.list:GetMouseOverRow() if selectedRow then local book = self:FindBook(selectedRow.bookId) if not book then book = { bookId = selectedRow.bookId, title = selectedRow.text:GetText() } self:AddBook(book, true) end if book then self:ToggleReadBook(book) KEYBIND_STRIP:UpdateKeybindButtonGroup(loreLibraryKeybinds) end end end } table.insert(loreLibraryKeybinds, toggleKeybind) -- ADD UNREAD ICON ON COLLECTION IF IT CONTAINS AN UNREAD BOOK OR ADD COMPLETED MARK IF ALL ARE KNOWN AND READ local navigationEntryTemplateInfo = LORE_LIBRARY.navigationTree.templateInfo["ZO_LoreLibraryNavigationEntry"] local previousSetupFunction = navigationEntryTemplateInfo.setupFunction local function TreeEntrySetup(node, control, data, open) previousSetupFunction(node, control, data, open) local shouldHideIcon = true local statusIcon = control:GetNamedChild("StatusIcon") if data.numKnownBooks > 0 then if self.unreadPerCollections[data.categoryIndex] and self.unreadPerCollections[data.categoryIndex][data.collectionIndex] and self.unreadPerCollections[data.categoryIndex][data.collectionIndex] > 0 then shouldHideIcon = false statusIcon:SetTexture("esoui/art/miscellaneous/new_icon.dds") elseif data.numKnownBooks == data.totalBooks then shouldHideIcon = false statusIcon:SetTexture("esoui/art/miscellaneous/check.dds") end end statusIcon:SetHidden(shouldHideIcon) end navigationEntryTemplateInfo.setupFunction = TreeEntrySetup navigationEntryTemplateInfo.template = "Librarian_LoreLibraryNavigationEntry" navigationEntryTemplateInfo.objectPool.templateName = "Librarian_LoreLibraryNavigationEntry" -- Fix of ESO because a label header is equal to all of its entries with the current code (API 101033) LORE_LIBRARY.navigationTree.templateInfo["ZO_LabelHeader"].equalityFunction = navigationEntryTemplateInfo.equalityFunction end function Librarian:RefreshLoreLibraryData() if self.settings.showUnreadIndicatorInLoreLibrary then local selectedCategoryIndex = LORE_LIBRARY:GetSelectedCategoryIndex() local selectedCollectionIndex = LORE_LIBRARY:GetSelectedCollectionIndex() local selectedCollectionId = select(7, GetLoreCollectionInfo(selectedCategoryIndex, selectedCollectionIndex)) LORE_LIBRARY:SetCollectionIdToSelect(selectedCollectionId) LORE_LIBRARY:BuildCategoryList() end end