Skip to content

Commit ec13435

Browse files
[SWU-88] Implemented reseting swipe area
1 parent 54cc2a7 commit ec13435

File tree

11 files changed

+63
-24
lines changed

11 files changed

+63
-24
lines changed

DemoAppSwiftUI/iMessagePocView.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ struct iMessagePocView: View {
4646
factory: factory,
4747
channels: viewModel.channels,
4848
selectedChannel: $viewModel.selectedChannel,
49-
currentChannelId: $viewModel.currentChannelId,
49+
swipedChannelId: $viewModel.swipedChannelId,
5050
onlineIndicatorShown: viewModel.onlineIndicatorShown(for:),
5151
imageLoader: channelHeaderLoader.image(for:),
5252
onItemTap: { channel in
@@ -88,7 +88,10 @@ struct iMessagePocView: View {
8888
private func customViewOverlay() -> some View {
8989
switch viewModel.customChannelPopupType {
9090
case let .moreActions(channel):
91-
factory.makeMoreChannelActionsView(for: channel) {
91+
factory.makeMoreChannelActionsView(
92+
for: channel,
93+
swipedChannelId: $viewModel.swipedChannelId
94+
) {
9295
withAnimation {
9396
viewModel.customChannelPopupType = nil
9497
}

Sources/StreamChatSwiftUI/ChatChannelList/ChatChannelList.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public struct ChannelList<Factory: ViewFactory>: View {
1111
private var factory: Factory
1212
var channels: LazyCachedMapCollection<ChatChannel>
1313
@Binding var selectedChannel: ChatChannel?
14-
@Binding var currentChannelId: String?
14+
@Binding var swipedChannelId: String?
1515
private var scrollable: Bool
1616
private var onlineIndicatorShown: (ChatChannel) -> Bool
1717
private var imageLoader: (ChatChannel) -> UIImage
@@ -27,7 +27,7 @@ public struct ChannelList<Factory: ViewFactory>: View {
2727
factory: Factory,
2828
channels: LazyCachedMapCollection<ChatChannel>,
2929
selectedChannel: Binding<ChatChannel?>,
30-
currentChannelId: Binding<String?>,
30+
swipedChannelId: Binding<String?>,
3131
scrollable: Bool = true,
3232
onlineIndicatorShown: @escaping (ChatChannel) -> Bool,
3333
imageLoader: @escaping (ChatChannel) -> UIImage,
@@ -52,7 +52,7 @@ public struct ChannelList<Factory: ViewFactory>: View {
5252
self.leadingSwipeButtonTapped = leadingSwipeButtonTapped
5353
self.scrollable = scrollable
5454
_selectedChannel = selectedChannel
55-
_currentChannelId = currentChannelId
55+
_swipedChannelId = swipedChannelId
5656
}
5757

5858
public var body: some View {
@@ -72,7 +72,7 @@ public struct ChannelList<Factory: ViewFactory>: View {
7272
factory: factory,
7373
channels: channels,
7474
selectedChannel: $selectedChannel,
75-
currentChannelId: $currentChannelId,
75+
swipedChannelId: $swipedChannelId,
7676
onlineIndicatorShown: onlineIndicatorShown,
7777
imageLoader: imageLoader,
7878
onItemTap: onItemTap,
@@ -92,7 +92,7 @@ struct ChannelsLazyVStack<Factory: ViewFactory>: View {
9292
private var factory: Factory
9393
var channels: LazyCachedMapCollection<ChatChannel>
9494
@Binding var selectedChannel: ChatChannel?
95-
@Binding var currentChannelId: String?
95+
@Binding var swipedChannelId: String?
9696
private var onlineIndicatorShown: (ChatChannel) -> Bool
9797
private var imageLoader: (ChatChannel) -> UIImage
9898
private var onItemTap: (ChatChannel) -> Void
@@ -107,7 +107,7 @@ struct ChannelsLazyVStack<Factory: ViewFactory>: View {
107107
factory: Factory,
108108
channels: LazyCachedMapCollection<ChatChannel>,
109109
selectedChannel: Binding<ChatChannel?>,
110-
currentChannelId: Binding<String?>,
110+
swipedChannelId: Binding<String?>,
111111
onlineIndicatorShown: @escaping (ChatChannel) -> Bool,
112112
imageLoader: @escaping (ChatChannel) -> UIImage,
113113
onItemTap: @escaping (ChatChannel) -> Void,
@@ -130,7 +130,7 @@ struct ChannelsLazyVStack<Factory: ViewFactory>: View {
130130
self.trailingSwipeLeftButtonTapped = trailingSwipeLeftButtonTapped
131131
self.leadingSwipeButtonTapped = leadingSwipeButtonTapped
132132
_selectedChannel = selectedChannel
133-
_currentChannelId = currentChannelId
133+
_swipedChannelId = swipedChannelId
134134
}
135135

136136
public var body: some View {
@@ -141,9 +141,9 @@ struct ChannelsLazyVStack<Factory: ViewFactory>: View {
141141
channelName: channelNaming(channel),
142142
avatar: imageLoader(channel),
143143
onlineIndicatorShown: onlineIndicatorShown(channel),
144-
disabled: currentChannelId == channel.id,
144+
disabled: swipedChannelId == channel.id,
145145
selectedChannel: $selectedChannel,
146-
swipedChannelId: $currentChannelId,
146+
swipedChannelId: $swipedChannelId,
147147
channelDestination: channelDestination,
148148
onItemTap: onItemTap,
149149
trailingSwipeRightButtonTapped: trailingSwipeRightButtonTapped,

Sources/StreamChatSwiftUI/ChatChannelList/ChatChannelListView.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public struct ChatChannelListView<Factory: ViewFactory>: View {
6363
factory: viewFactory,
6464
channels: viewModel.channels,
6565
selectedChannel: $viewModel.selectedChannel,
66-
currentChannelId: $viewModel.currentChannelId,
66+
swipedChannelId: $viewModel.swipedChannelId,
6767
onlineIndicatorShown: viewModel.onlineIndicatorShown(for:),
6868
imageLoader: channelHeaderLoader.image(for:),
6969
onItemTap: onItemTap,
@@ -111,9 +111,13 @@ public struct ChatChannelListView<Factory: ViewFactory>: View {
111111
private func customViewOverlay() -> some View {
112112
switch viewModel.customChannelPopupType {
113113
case let .moreActions(channel):
114-
viewFactory.makeMoreChannelActionsView(for: channel) {
114+
viewFactory.makeMoreChannelActionsView(
115+
for: channel,
116+
swipedChannelId: $viewModel.swipedChannelId
117+
) {
115118
withAnimation {
116119
viewModel.customChannelPopupType = nil
120+
viewModel.swipedChannelId = nil
117121
}
118122
} onError: { error in
119123
viewModel.showErrorPopup(error)

Sources/StreamChatSwiftUI/ChatChannelList/ChatChannelListViewModel.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ open class ChatChannelListViewModel: ObservableObject, ChatChannelListController
5050
}
5151

5252
@Published public var deeplinkChannel: ChatChannel?
53-
@Published public var currentChannelId: String?
53+
@Published public var swipedChannelId: String?
5454
@Published public var channelAlertType: ChannelAlertType? {
5555
didSet {
5656
if channelAlertType != nil {

Sources/StreamChatSwiftUI/ChatChannelList/ChatChannelSwipeableListItem.swift

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public struct ChatChannelSwipeableListItem<Factory: ViewFactory, ChannelListItem
1414

1515
@GestureState private var offset: CGSize = .zero
1616

17-
@Binding var currentChannelId: String?
17+
@Binding var swipedChannelId: String?
1818

1919
private let itemWidth: CGFloat = 60
2020
private var menuWidth: CGFloat {
@@ -42,7 +42,7 @@ public struct ChatChannelSwipeableListItem<Factory: ViewFactory, ChannelListItem
4242
public init(
4343
factory: Factory,
4444
channelListItem: ChannelListItem,
45-
currentChannelId: Binding<String?>,
45+
swipedChannelId: Binding<String?>,
4646
channel: ChatChannel,
4747
trailingRightButtonTapped: @escaping (ChatChannel) -> Void,
4848
trailingLeftButtonTapped: @escaping (ChatChannel) -> Void,
@@ -54,7 +54,7 @@ public struct ChatChannelSwipeableListItem<Factory: ViewFactory, ChannelListItem
5454
self.trailingRightButtonTapped = trailingRightButtonTapped
5555
self.trailingLeftButtonTapped = trailingLeftButtonTapped
5656
leadingButtonTapped = leadingSwipeButtonTapped
57-
_currentChannelId = currentChannelId
57+
_swipedChannelId = swipedChannelId
5858
}
5959

6060
public var body: some View {
@@ -95,6 +95,11 @@ public struct ChatChannelSwipeableListItem<Factory: ViewFactory, ChannelListItem
9595
dragChanged(to: offset.width)
9696
}
9797
})
98+
.onChange(of: swipedChannelId, perform: { _ in
99+
if swipedChannelId != channel.id && offsetX != 0 {
100+
setOffsetX(value: 0)
101+
}
102+
})
98103
.id("\(channel.id)-swipeable")
99104
}
100105

@@ -103,6 +108,7 @@ public struct ChatChannelSwipeableListItem<Factory: ViewFactory, ChannelListItem
103108
channel: channel,
104109
offsetX: offsetX,
105110
buttonWidth: buttonWidth,
111+
swipedChannelId: $swipedChannelId,
106112
leftButtonTapped: trailingLeftButtonTapped,
107113
rightButtonTapped: trailingRightButtonTapped
108114
)
@@ -117,6 +123,7 @@ public struct ChatChannelSwipeableListItem<Factory: ViewFactory, ChannelListItem
117123
channel: channel,
118124
offsetX: offsetX,
119125
buttonWidth: buttonWidth,
126+
swipedChannelId: $swipedChannelId,
120127
buttonTapped: leadingButtonTapped
121128
)
122129
}
@@ -144,7 +151,7 @@ public struct ChatChannelSwipeableListItem<Factory: ViewFactory, ChannelListItem
144151
}
145152

146153
if horizontalTranslation != 0 {
147-
currentChannelId = channel.id
154+
swipedChannelId = channel.id
148155
offsetX = horizontalTranslation
149156
} else {
150157
offsetX = 0
@@ -157,13 +164,13 @@ public struct ChatChannelSwipeableListItem<Factory: ViewFactory, ChannelListItem
157164
}
158165
if offsetX == 0 {
159166
openSideLock = nil
160-
currentChannelId = nil
167+
swipedChannelId = nil
161168
}
162169
}
163170

164171
private func dragEnded() {
165172
if offsetX == 0 {
166-
currentChannelId = nil
173+
swipedChannelId = nil
167174
openSideLock = nil
168175
} else if offsetX > 0 && showLeadingSwipeActions {
169176
if offsetX.magnitude < openTriggerValue ||

Sources/StreamChatSwiftUI/ChatChannelList/MoreChannelActionsView.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ public struct MoreChannelActionsView: View {
1212
@Injected(\.fonts) private var fonts
1313

1414
@StateObject var viewModel: MoreChannelActionsViewModel
15+
@Binding var swipedChannelId: String?
1516
var onDismiss: () -> Void
1617

1718
public init(
1819
channel: ChatChannel,
1920
channelActions: [ChannelAction],
21+
swipedChannelId: Binding<String?>,
2022
onDismiss: @escaping () -> Void
2123
) {
2224
_viewModel = StateObject(
@@ -26,6 +28,7 @@ public struct MoreChannelActionsView: View {
2628
)
2729
)
2830
self.onDismiss = onDismiss
31+
_swipedChannelId = swipedChannelId
2932
}
3033

3134
public var body: some View {

Sources/StreamChatSwiftUI/DefaultViewFactory.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ extension ViewFactory {
4343

4444
public func makeMoreChannelActionsView(
4545
for channel: ChatChannel,
46+
swipedChannelId: Binding<String?>,
4647
onDismiss: @escaping () -> Void,
4748
onError: @escaping (Error) -> Void
4849
) -> some View {
@@ -53,6 +54,7 @@ extension ViewFactory {
5354
onDismiss: onDismiss,
5455
onError: onError
5556
),
57+
swipedChannelId: swipedChannelId,
5658
onDismiss: onDismiss
5759
)
5860
}
@@ -84,7 +86,7 @@ extension ViewFactory {
8486
return ChatChannelSwipeableListItem(
8587
factory: self,
8688
channelListItem: listItem,
87-
currentChannelId: swipedChannelId,
89+
swipedChannelId: swipedChannelId,
8890
channel: channel,
8991
trailingRightButtonTapped: trailingSwipeRightButtonTapped,
9092
trailingLeftButtonTapped: trailingSwipeLeftButtonTapped,
@@ -100,6 +102,7 @@ extension ViewFactory {
100102
channel: ChatChannel,
101103
offsetX: CGFloat,
102104
buttonWidth: CGFloat,
105+
swipedChannelId: Binding<String?>,
103106
leftButtonTapped: @escaping (ChatChannel) -> Void,
104107
rightButtonTapped: @escaping (ChatChannel) -> Void
105108
) -> some View {
@@ -116,6 +119,7 @@ extension ViewFactory {
116119
channel: ChatChannel,
117120
offsetX: CGFloat,
118121
buttonWidth: CGFloat,
122+
swipedChannelId: Binding<String?>,
119123
buttonTapped: (ChatChannel) -> Void
120124
) -> some View {
121125
EmptyView()

Sources/StreamChatSwiftUI/ViewFactory.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,12 @@ public protocol ViewFactory: AnyObject {
6767
/// Creates the more channel actions view.
6868
/// - Parameters:
6969
/// - channel: the channel where the actions are applied.
70+
/// - swipedChannelId: optional id of the channel being swiped.
7071
/// - onDismiss: handler when the more actions view is dismissed.
7172
/// - onError: handler when an error happened.
7273
func makeMoreChannelActionsView(
7374
for channel: ChatChannel,
75+
swipedChannelId: Binding<String?>,
7476
onDismiss: @escaping () -> Void,
7577
onError: @escaping (Error) -> Void
7678
) -> MoreActionsView
@@ -93,13 +95,15 @@ public protocol ViewFactory: AnyObject {
9395
/// - channel: the channel being swiped.
9496
/// - offsetX: the offset of the swipe area in the x-axis.
9597
/// - buttonWidth: the width of the button (use if you want dynamic width, based on swiping position).
98+
/// - swipedChannelId: optional id of the channel being swiped.
9699
/// - leftButtonTapped: handler when the left button is tapped.
97100
/// - rightButtonTapped: handler when the right button is tapped.
98101
/// - Returns: View displayed in the trailing swipe area of a channel item.
99102
func makeTrailingSwipeActionsView(
100103
channel: ChatChannel,
101104
offsetX: CGFloat,
102105
buttonWidth: CGFloat,
106+
swipedChannelId: Binding<String?>,
103107
leftButtonTapped: @escaping (ChatChannel) -> Void,
104108
rightButtonTapped: @escaping (ChatChannel) -> Void
105109
) -> TrailingSwipeActionsViewType
@@ -110,12 +114,14 @@ public protocol ViewFactory: AnyObject {
110114
/// - channel: the channel being swiped.
111115
/// - offsetX: the offset of the swipe area in the x-axis.
112116
/// - buttonWidth: the width of the button (use if you want dynamic width, based on swiping position).
117+
/// - swipedChannelId: optional id of the channel being active swiped.
113118
/// - buttonTapped: handler when the button is tapped.
114119
/// - Returns: View displayed in the leading swipe area of a channel item.
115120
func makeLeadingSwipeActionsView(
116121
channel: ChatChannel,
117122
offsetX: CGFloat,
118123
buttonWidth: CGFloat,
124+
swipedChannelId: Binding<String?>,
119125
buttonTapped: @escaping (ChatChannel) -> Void
120126
) -> LeadingSwipeActionsViewType
121127

StreamChatSwiftUITests/Tests/ChatChannelList/MoreChannelActionsView_Tests.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,13 @@ class MoreChannelActionsView_Tests: StreamChatTestCase {
2020
)
2121

2222
// When
23-
let view = MoreChannelActionsView(channel: channel, channelActions: actions, onDismiss: {})
24-
.frame(width: defaultScreenSize.width, height: defaultScreenSize.height)
23+
let view = MoreChannelActionsView(
24+
channel: channel,
25+
channelActions: actions,
26+
swipedChannelId: .constant(nil),
27+
onDismiss: {}
28+
)
29+
.frame(width: defaultScreenSize.width, height: defaultScreenSize.height)
2530

2631
// Then
2732
assertSnapshot(matching: view, as: .image)

StreamChatSwiftUITests/Tests/Utils/ViewFactory_Tests.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ class ViewFactory_Tests: StreamChatTestCase {
9191
// When
9292
let view = viewFactory.makeMoreChannelActionsView(
9393
for: channel,
94+
swipedChannelId: .constant(nil),
9495
onDismiss: {},
9596
onError: { _ in }
9697
)
@@ -484,6 +485,7 @@ class ViewFactory_Tests: StreamChatTestCase {
484485
channel: .mockDMChannel(),
485486
offsetX: 80,
486487
buttonWidth: 40,
488+
swipedChannelId: .constant(nil),
487489
buttonTapped: { _ in }
488490
)
489491

@@ -500,6 +502,7 @@ class ViewFactory_Tests: StreamChatTestCase {
500502
channel: .mockDMChannel(),
501503
offsetX: 80,
502504
buttonWidth: 40,
505+
swipedChannelId: .constant(nil),
503506
leftButtonTapped: { _ in },
504507
rightButtonTapped: { _ in }
505508
)

0 commit comments

Comments
 (0)