Skip to content

Commit 0ab1865

Browse files
Merge pull request #4 from GetStream/feature/swipeable-item
The swipeable list item is reusable with any chat channel item
2 parents 81a5702 + 5b3abe2 commit 0ab1865

File tree

2 files changed

+31
-54
lines changed

2 files changed

+31
-54
lines changed

Sources/StreamChatSwiftUI/ChatChannelList/ChatChannelSwipeableListItem.swift

Lines changed: 22 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import StreamChat
66
import SwiftUI
77

88
/// Chat channel cell that is swipeable.
9-
public struct ChatChannelSwipeableListItem<Factory: ViewFactory>: View {
9+
public struct ChatChannelSwipeableListItem<Factory: ViewFactory, ChannelListItem: View>: View {
1010
@Injected(\.colors) private var colors
1111

1212
@State private var offsetX: CGFloat = 0
@@ -33,46 +33,28 @@ public struct ChatChannelSwipeableListItem<Factory: ViewFactory>: View {
3333
private let addWidthMargin: CGFloat = 5
3434

3535
private var factory: Factory
36+
private var channelListItem: ChannelListItem
3637
private var channel: ChatChannel
37-
private var channelName: String
38-
private var avatar: UIImage
39-
private var onlineIndicatorShown: Bool
40-
@Binding private var selectedChannel: ChatChannel?
41-
private var channelDestination: (ChatChannel) -> Factory.ChannelDestination
42-
private var disabled = false
43-
private var onItemTap: (ChatChannel) -> Void
4438
private var trailingRightButtonTapped: (ChatChannel) -> Void
4539
private var trailingLeftButtonTapped: (ChatChannel) -> Void
4640
private var leadingButtonTapped: (ChatChannel) -> Void
4741

4842
internal init(
4943
factory: Factory,
44+
channelListItem: ChannelListItem,
5045
currentChannelId: Binding<String?>,
5146
channel: ChatChannel,
52-
channelName: String,
53-
avatar: UIImage,
54-
onlineIndicatorShown: Bool,
55-
disabled: Bool = false,
56-
selectedChannel: Binding<ChatChannel?>,
57-
channelDestination: @escaping (ChatChannel) -> Factory.ChannelDestination,
58-
onItemTap: @escaping (ChatChannel) -> Void,
5947
trailingRightButtonTapped: @escaping (ChatChannel) -> Void,
6048
trailingLeftButtonTapped: @escaping (ChatChannel) -> Void,
6149
leadingSwipeButtonTapped: @escaping (ChatChannel) -> Void
6250
) {
6351
self.factory = factory
52+
self.channelListItem = channelListItem
6453
self.channel = channel
65-
self.channelName = channelName
66-
self.avatar = avatar
67-
self.onlineIndicatorShown = onlineIndicatorShown
68-
self.channelDestination = channelDestination
69-
self.disabled = disabled
70-
self.onItemTap = onItemTap
7154
self.trailingRightButtonTapped = trailingRightButtonTapped
7255
self.trailingLeftButtonTapped = trailingLeftButtonTapped
7356
leadingButtonTapped = leadingSwipeButtonTapped
7457
_currentChannelId = currentChannelId
75-
_selectedChannel = selectedChannel
7658
}
7759

7860
public var body: some View {
@@ -83,36 +65,27 @@ public struct ChatChannelSwipeableListItem<Factory: ViewFactory>: View {
8365
leadingSwipeActions
8466
}
8567

86-
ChatChannelNavigatableListItem(
87-
channel: channel,
88-
channelName: channelName,
89-
avatar: avatar,
90-
onlineIndicatorShown: onlineIndicatorShown,
91-
disabled: disabled,
92-
selectedChannel: $selectedChannel,
93-
channelDestination: channelDestination,
94-
onItemTap: onItemTap
95-
)
96-
.offset(x: self.offsetX)
97-
.simultaneousGesture(
98-
DragGesture(
99-
minimumDistance: 10,
100-
coordinateSpace: .local
101-
)
102-
.updating($offset) { (value, gestureState, _) in
103-
// Using updating since onEnded is not called if the gesture is canceled.
104-
let diff = CGSize(
105-
width: value.location.x - value.startLocation.x,
106-
height: value.location.y - value.startLocation.y
68+
channelListItem
69+
.offset(x: self.offsetX)
70+
.simultaneousGesture(
71+
DragGesture(
72+
minimumDistance: 10,
73+
coordinateSpace: .local
10774
)
75+
.updating($offset) { (value, gestureState, _) in
76+
// Using updating since onEnded is not called if the gesture is canceled.
77+
let diff = CGSize(
78+
width: value.location.x - value.startLocation.x,
79+
height: value.location.y - value.startLocation.y
80+
)
10881

109-
if diff == .zero {
110-
gestureState = .zero
111-
} else {
112-
gestureState = value.translation
82+
if diff == .zero {
83+
gestureState = .zero
84+
} else {
85+
gestureState = value.translation
86+
}
11387
}
114-
}
115-
)
88+
)
11689
}
11790
.onChange(of: offset, perform: { _ in
11891
if offset == .zero {

Sources/StreamChatSwiftUI/DefaultViewFactory.swift

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,18 +70,22 @@ extension ViewFactory {
7070
trailingSwipeRightButtonTapped: @escaping (ChatChannel) -> Void,
7171
trailingSwipeLeftButtonTapped: @escaping (ChatChannel) -> Void,
7272
leadingSwipeButtonTapped: @escaping (ChatChannel) -> Void
73-
) -> ChatChannelSwipeableListItem<Self> {
74-
ChatChannelSwipeableListItem(
75-
factory: self,
76-
currentChannelId: swipedChannelId,
73+
) -> some View {
74+
let listItem = ChatChannelNavigatableListItem(
7775
channel: channel,
7876
channelName: channelName,
7977
avatar: avatar,
8078
onlineIndicatorShown: onlineIndicatorShown,
8179
disabled: disabled,
8280
selectedChannel: selectedChannel,
8381
channelDestination: channelDestination,
84-
onItemTap: onItemTap,
82+
onItemTap: onItemTap
83+
)
84+
return ChatChannelSwipeableListItem(
85+
factory: self,
86+
channelListItem: listItem,
87+
currentChannelId: swipedChannelId,
88+
channel: channel,
8589
trailingRightButtonTapped: trailingSwipeRightButtonTapped,
8690
trailingLeftButtonTapped: trailingSwipeLeftButtonTapped,
8791
leadingSwipeButtonTapped: leadingSwipeButtonTapped

0 commit comments

Comments
 (0)