Skip to content

Commit

Permalink
Update package
Browse files Browse the repository at this point in the history
  • Loading branch information
vmanot committed Jul 9, 2024
1 parent 3b633f5 commit bf95f82
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 20 deletions.
2 changes: 2 additions & 0 deletions Sources/Intramodular/Core/AnyChatItemIdentifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public struct AnyChatItemIdentifier: Hashable {
} else {
self.base = base
}

assert(!_isValueNil(base.base))
}

public func `as`<T>(_ type: T.Type) -> T {
Expand Down
8 changes: 8 additions & 0 deletions Sources/Intramodular/Message List/ChatMessageList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,14 @@ extension ChatMessageList {
// MARK: - Modifiers

extension ChatMessageList {
public func onEdit(
perform fn: @escaping (Data.Element.ID, String) -> Void
) -> Self {
then {
$0._chatViewActions.onEdit = { fn($0.as(Data.Element.ID.self), $1.content) }
}
}

public func onDelete(
perform fn: @escaping (Data.Element.ID) -> Void
) -> Self {
Expand Down
53 changes: 33 additions & 20 deletions Sources/Intramodular/Message List/_ChatMessageListB.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public struct _ChatMessageListB<Content: View>: View {
case lastItem
}

@State var lastItem: AnyChatItemIdentifier?
@State private var lastItem: AnyChatItemIdentifier?

public var body: some View {
ScrollViewReader { scrollView in
Expand All @@ -28,10 +28,12 @@ public struct _ChatMessageListB<Content: View>: View {
let lastItem = content.children.last?[trait: \._chatItemTraitValue]?.id

if self.lastItem != lastItem {
self.lastItem = lastItem
withoutAnimation {
self.lastItem = lastItem
}
}
}

_ForEachSubview(
enumerating: content,
trait: \._chatItemTraitValue
Expand All @@ -57,41 +59,52 @@ public struct _ChatMessageListB<Content: View>: View {
}
}
._stripAllListOrListItemStyling()
.modifier(_ChatMessageListB_ScrollBehavior(scrollView: scrollView, lastItem: lastItem))
.modifier(_ChatMessageListB_ScrollBehavior(scrollView: scrollView, lastItem: $lastItem))
}
}
}
}

fileprivate struct _ChatMessageListB_ScrollBehavior: ViewModifier {
let scrollView: ScrollViewProxy
let lastItem: AnyChatItemIdentifier?

@Binding var lastItem: AnyChatItemIdentifier?

@ViewStorage var hasScrolledOnce: Bool = false

func body(content: Content) -> some View {
content
.onAppearOnce {
guard let lastItem else {
return
}

withoutAnimation(after: .milliseconds(200)) {
scrollView.scrollTo(lastItem, anchor: .bottom)

withoutAnimation(after: .milliseconds(200)) {
scrollView.scrollTo(lastItem, anchor: .bottom)
}
}
scrollTo(lastItem)
}
.withChangePublisher(for: lastItem) { lastItem in
lastItem
.compactMap({ $0 })
.removeDuplicates()
.debounce(for: .milliseconds(200), scheduler: DispatchQueue.main)
.sink { id in
withAnimation {
scrollView.scrollTo(id, anchor: .bottom)
}
.sink { (id: AnyChatItemIdentifier) in
scrollTo(id)
}
}
}

private func scrollTo(_ item: AnyChatItemIdentifier?) {
guard let item: AnyChatItemIdentifier = item ?? self.lastItem else {
return
}

scrollView.scrollTo(lastItem, anchor: .bottom)

if !hasScrolledOnce {
withoutAnimation(after: .milliseconds(200)) {
scrollView.scrollTo(item, anchor: .bottom)

hasScrolledOnce = true
}

withoutAnimation(after: .milliseconds(250)) {
scrollView.scrollTo(item, anchor: .bottom)
}
}
}
}

0 comments on commit bf95f82

Please sign in to comment.