diff --git a/Listable/Sources/Internal/Presentation State/PresentationState.ItemState.swift b/Listable/Sources/Internal/Presentation State/PresentationState.ItemState.swift index 0526add80..86c5b386b 100644 --- a/Listable/Sources/Internal/Presentation State/PresentationState.ItemState.swift +++ b/Listable/Sources/Internal/Presentation State/PresentationState.ItemState.swift @@ -153,6 +153,9 @@ extension PresentationState private(set) var isDisplayed : Bool = false + private var hasDisplayed : Bool = false + private var hasEndedDisplay : Bool = false + func setAndPerform(isDisplayed: Bool) { guard self.isDisplayed != isDisplayed else { return @@ -161,9 +164,21 @@ extension PresentationState self.isDisplayed = isDisplayed if self.isDisplayed { - self.model.onDisplay?(self.model.content) + self.model.onDisplay?(.init( + item: self.model, + isFirstDisplay: self.hasDisplayed == false + ) + ) + + self.hasDisplayed = true } else { - self.model.onEndDisplay?(self.model.content) + self.model.onEndDisplay?(.init( + item: self.model, + isFirstEndDisplay: self.hasEndedDisplay == false + ) + ) + + self.hasEndedDisplay = true } } @@ -288,13 +303,13 @@ extension PresentationState if isSelected { if let onSelect = self.model.onSelect { SignpostLogger.log(log: .listInteraction, name: "Item onSelect", for: self.model) { - onSelect(self.model.content) + onSelect(.init(item: self.model)) } } } else { if let onDeselect = self.model.onDeselect { SignpostLogger.log(log: .listInteraction, name: "Item onDeselect", for: self.model) { - onDeselect(self.model.content) + onDeselect(.init(item: self.model)) } } } diff --git a/Listable/Sources/Item/Item.swift b/Listable/Sources/Item/Item.swift index 99675537a..997037c47 100644 --- a/Listable/Sources/Item/Item.swift +++ b/Listable/Sources/Item/Item.swift @@ -53,17 +53,10 @@ public struct Item : AnyItem public var reordering : Reordering? - public typealias OnSelect = (Content) -> () - public var onSelect : OnSelect? - - public typealias OnDeselect = (Content) -> () - public var onDeselect : OnDeselect? - - public typealias OnDisplay = (Content) -> () - public var onDisplay : OnDisplay? - - public typealias OnEndDisplay = (Content) -> () - public var onEndDisplay : OnEndDisplay? + public var onSelect : OnSelect.Callback? + public var onDeselect : OnDeselect.Callback? + public var onDisplay : OnDisplay.Callback? + public var onEndDisplay : OnEndDisplay.Callback? internal let reuseIdentifier : ReuseIdentifier @@ -92,10 +85,10 @@ public struct Item : AnyItem selectionStyle : ItemSelectionStyle? = nil, swipeActions : SwipeActionsConfiguration? = nil, reordering : Reordering? = nil, - onDisplay : OnDisplay? = nil, - onEndDisplay : OnEndDisplay? = nil, - onSelect : OnSelect? = nil, - onDeselect : OnDeselect? = nil + onDisplay : OnDisplay.Callback? = nil, + onEndDisplay : OnEndDisplay.Callback? = nil, + onSelect : OnSelect.Callback? = nil, + onDeselect : OnDeselect.Callback? = nil ) { self.content = content @@ -172,6 +165,42 @@ public struct Item : AnyItem } +public extension Item +{ + struct OnSelect + { + public typealias Callback = (OnSelect) -> () + + public var item : Item + } + + struct OnDeselect + { + public typealias Callback = (OnDeselect) -> () + + public var item : Item + } + + struct OnDisplay + { + public typealias Callback = (OnDisplay) -> () + + public var item : Item + + public var isFirstDisplay : Bool + } + + struct OnEndDisplay + { + public typealias Callback = (OnEndDisplay) -> () + + public var item : Item + + public var isFirstEndDisplay : Bool + } +} + + /// Allows specifying default properties to apply to an item when it is initialized, /// if those values are not provided to the initializer. /// Only non-nil values are used – if you do not want to provide a default value,