@@ -11,6 +11,7 @@ public struct ReactionsOverlayView<Factory: ViewFactory>: View {
11
11
@StateObject var viewModel : ReactionsOverlayViewModel
12
12
13
13
@State private var popIn = false
14
+ @State private var willPopOut = false
14
15
15
16
var factory : Factory
16
17
var channel : ChatChannel
@@ -54,11 +55,15 @@ public struct ReactionsOverlayView<Factory: ViewFactory>: View {
54
55
public var body : some View {
55
56
ZStack ( alignment: . topLeading) {
56
57
Image ( uiImage: currentSnapshot)
57
- . overlay ( Color . black. opacity ( 0.1 ) )
58
- . blur ( radius: 4 )
58
+ . overlay ( Color . black. opacity ( !popIn ? 0 : 0.1 ) )
59
+ . blur ( radius: !popIn ? 0 : 4 )
59
60
. transition ( . opacity)
60
61
. onTapGesture {
61
62
withAnimation {
63
+ willPopOut = true
64
+ popIn = false
65
+ }
66
+ DispatchQueue . main. asyncAfter ( deadline: . now( ) + 0.3 ) {
62
67
onBackgroundTap ( )
63
68
}
64
69
}
@@ -76,6 +81,7 @@ public struct ReactionsOverlayView<Factory: ViewFactory>: View {
76
81
x: paddingValue / 2 ,
77
82
y: originY + messageContainerHeight - paddingValue + 2
78
83
)
84
+ . opacity ( willPopOut ? 0 : 1 )
79
85
}
80
86
81
87
GeometryReader { reader in
@@ -101,8 +107,8 @@ public struct ReactionsOverlayView<Factory: ViewFactory>: View {
101
107
)
102
108
}
103
109
}
104
- . scaleEffect ( popIn ? 1 : 0.95 )
105
- . animation ( popInAnimation, value: popIn)
110
+ . scaleEffect ( popIn || willPopOut ? 1 : 0.95 )
111
+ . animation ( willPopOut ? . easeInOut : popInAnimation, value: popIn)
106
112
. offset (
107
113
x: messageDisplayInfo. frame. origin. x - diffWidth( proxy: reader)
108
114
)
@@ -117,7 +123,8 @@ public struct ReactionsOverlayView<Factory: ViewFactory>: View {
117
123
}
118
124
)
119
125
. scaleEffect ( popIn ? 1 : 0 )
120
- . animation ( popInAnimation, value: popIn)
126
+ . opacity ( willPopOut ? 0 : 1 )
127
+ . animation ( willPopOut ? . easeInOut : popInAnimation, value: popIn)
121
128
. offset (
122
129
x: messageDisplayInfo. frame. origin. x - diffWidth( proxy: reader) ,
123
130
y: popIn ? - 24 : - messageContainerHeight / 2
@@ -142,13 +149,13 @@ public struct ReactionsOverlayView<Factory: ViewFactory>: View {
142
149
)
143
150
. frame ( width: messageActionsWidth)
144
151
. offset (
145
- x: popIn ? messageActionsOriginX ( availableWidth: reader. size. width) :
146
- ( messageDisplayInfo. message. isSentByCurrentUser ? messageActionsWidth : 0 ) ,
152
+ x: messageActionsOffsetX ( reader: reader) ,
147
153
y: popIn ? 0 : - messageActionsSize / 2
148
154
)
149
155
. padding ( . top, paddingValue)
150
- . scaleEffect ( popIn ? 1 : 0 )
151
- . animation ( popInAnimation, value: popIn)
156
+ . opacity ( willPopOut ? 0 : 1 )
157
+ . scaleEffect ( popIn ? 1 : ( willPopOut ? 0.4 : 0 ) )
158
+ . animation ( willPopOut ? . easeInOut : popInAnimation, value: popIn)
152
159
} else {
153
160
factory. makeReactionsUsersView (
154
161
message: viewModel. message,
@@ -161,10 +168,11 @@ public struct ReactionsOverlayView<Factory: ViewFactory>: View {
161
168
. padding ( . top, messageDisplayInfo. message. isSentByCurrentUser ? paddingValue : 2 * paddingValue)
162
169
. padding ( . trailing, paddingValue)
163
170
. scaleEffect ( popIn ? 1 : 0 )
164
- . animation ( popInAnimation, value: popIn)
171
+ . opacity ( willPopOut ? 0 : 1 )
172
+ . animation ( willPopOut ? . easeInOut : popInAnimation, value: popIn)
165
173
}
166
174
}
167
- . offset ( y: originY)
175
+ . offset ( y: !popIn ? messageDisplayInfo . frame . origin . y : originY)
168
176
}
169
177
}
170
178
. edgesIgnoringSafeArea ( . all)
@@ -173,6 +181,18 @@ public struct ReactionsOverlayView<Factory: ViewFactory>: View {
173
181
}
174
182
}
175
183
184
+ private func messageActionsOffsetX( reader: GeometryProxy ) -> CGFloat {
185
+ let originX = messageActionsOriginX ( availableWidth: reader. size. width)
186
+ let sentByCurrentUser = messageDisplayInfo. message. isSentByCurrentUser
187
+ if popIn {
188
+ return originX
189
+ } else if willPopOut {
190
+ return messageDisplayInfo. frame. origin. x - diffWidth( proxy: reader)
191
+ } else {
192
+ return sentByCurrentUser ? messageActionsWidth : 0
193
+ }
194
+ }
195
+
176
196
private var messageContainerHeight : CGFloat {
177
197
let screenHeight = UIScreen . main. bounds. size. height
178
198
let maxAllowed = screenHeight / 2
0 commit comments