Skip to content

Commit 533e331

Browse files
committed
Finish logic for location snapshot view when static vs live
1 parent 1ab310d commit 533e331

File tree

3 files changed

+83
-39
lines changed

3 files changed

+83
-39
lines changed

DemoApp/StreamChat/Components/CustomAttachments/LocationAttachment/LocationAttachmentPayload+AttachmentViewProvider.swift

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright © 2024 Stream.io Inc. All rights reserved.
2+
// Copyright © 2025 Stream.io Inc. All rights reserved.
33
//
44

55
import StreamChat
@@ -15,10 +15,11 @@ extension StaticLocationAttachmentPayload: AttachmentPreviewProvider {
1515
/// but a different one could be provided.
1616
let preview = LocationAttachmentSnapshotView()
1717
preview.content = .init(
18+
coordinate: .init(latitude: latitude, longitude: longitude),
19+
isLive: false,
20+
isSharingLiveLocation: false,
1821
messageId: nil,
19-
latitude: latitude,
20-
longitude: longitude,
21-
isLive: false
22+
author: nil
2223
)
2324
return preview
2425
}

DemoApp/StreamChat/Components/CustomAttachments/LocationAttachment/LocationAttachmentSnapshotView.swift

+69-28
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,23 @@ import UIKit
99

1010
class LocationAttachmentSnapshotView: _View, ThemeProvider {
1111
struct Content {
12+
var coordinate: CLLocationCoordinate2D
13+
var isLive: Bool
14+
var isSharingLiveLocation: Bool
1215
var messageId: MessageId?
13-
var latitude: CLLocationDegrees
14-
var longitude: CLLocationDegrees
15-
var isLive: Bool = false
16+
var author: ChatUser?
17+
18+
init(coordinate: CLLocationCoordinate2D, isLive: Bool, isSharingLiveLocation: Bool, messageId: MessageId?, author: ChatUser?) {
19+
self.coordinate = coordinate
20+
self.isLive = isLive
21+
self.isSharingLiveLocation = isSharingLiveLocation
22+
self.messageId = messageId
23+
self.author = author
24+
}
25+
26+
var isFromCurrentUser: Bool {
27+
author?.id == StreamChatWrapper.shared.client?.currentUserId
28+
}
1629
}
1730

1831
var content: Content? {
@@ -59,6 +72,18 @@ class LocationAttachmentSnapshotView: _View, ThemeProvider {
5972
return button
6073
}()
6174

75+
lazy var avatarView: ChatUserAvatarView = {
76+
let view = ChatUserAvatarView()
77+
view.translatesAutoresizingMaskIntoConstraints = false
78+
view.shouldShowOnlineIndicator = false
79+
view.layer.masksToBounds = true
80+
view.layer.cornerRadius = 15
81+
view.layer.borderWidth = 2
82+
view.layer.borderColor = UIColor.white.cgColor
83+
view.isHidden = true
84+
return view
85+
}()
86+
6287
override func setUp() {
6388
super.setUp()
6489

@@ -85,10 +110,16 @@ class LocationAttachmentSnapshotView: _View, ThemeProvider {
85110
.height(35)
86111
}.embed(in: self)
87112

113+
addSubview(avatarView)
114+
88115
NSLayoutConstraint.activate([
89-
activityIndicatorView.centerXAnchor.constraint(equalTo: centerXAnchor),
90-
activityIndicatorView.centerYAnchor.constraint(equalTo: centerYAnchor),
91-
imageView.widthAnchor.constraint(equalTo: container.widthAnchor)
116+
activityIndicatorView.centerXAnchor.constraint(equalTo: imageView.centerXAnchor),
117+
activityIndicatorView.centerYAnchor.constraint(equalTo: imageView.centerYAnchor),
118+
imageView.widthAnchor.constraint(equalTo: container.widthAnchor),
119+
avatarView.centerXAnchor.constraint(equalTo: imageView.centerXAnchor),
120+
avatarView.centerYAnchor.constraint(equalTo: imageView.centerYAnchor),
121+
avatarView.widthAnchor.constraint(equalToConstant: 30),
122+
avatarView.heightAnchor.constraint(equalToConstant: 30)
92123
])
93124
}
94125

@@ -103,7 +134,7 @@ class LocationAttachmentSnapshotView: _View, ThemeProvider {
103134
return
104135
}
105136

106-
if content.isLive {
137+
if content.isSharingLiveLocation && content.isFromCurrentUser {
107138
stopButton.isHidden = false
108139
} else {
109140
stopButton.isHidden = true
@@ -129,10 +160,7 @@ class LocationAttachmentSnapshotView: _View, ThemeProvider {
129160
}
130161

131162
mapOptions.region = .init(
132-
center: CLLocationCoordinate2D(
133-
latitude: content.latitude,
134-
longitude: content.longitude
135-
),
163+
center: content.coordinate,
136164
span: MKCoordinateSpan(
137165
latitudeDelta: 0.01,
138166
longitudeDelta: 0.01
@@ -149,6 +177,7 @@ class LocationAttachmentSnapshotView: _View, ThemeProvider {
149177

150178
if let cachedSnapshot = getCachedSnapshot() {
151179
imageView.image = cachedSnapshot
180+
updateAnnotationView()
152181
return
153182
} else {
154183
imageView.image = nil
@@ -159,39 +188,51 @@ class LocationAttachmentSnapshotView: _View, ThemeProvider {
159188
snapshotter = MKMapSnapshotter(options: mapOptions)
160189
snapshotter?.start { snapshot, _ in
161190
guard let snapshot = snapshot else { return }
162-
let image = self.generatePinAnnotation(for: snapshot)
163191
DispatchQueue.main.async {
164192
self.activityIndicatorView.stopAnimating()
165-
self.imageView.image = image
166-
self.setCachedSnapshot(image: image)
193+
194+
if let content = self.content, !content.isLive {
195+
let image = self.drawPinOnSnapshot(snapshot)
196+
self.imageView.image = image
197+
self.setCachedSnapshot(image: image)
198+
} else {
199+
self.imageView.image = snapshot.image
200+
self.setCachedSnapshot(image: snapshot.image)
201+
}
202+
203+
self.updateAnnotationView()
167204
}
168205
}
169206
}
170207

171-
private func generatePinAnnotation(
172-
for snapshot: MKMapSnapshotter.Snapshot
173-
) -> UIImage {
174-
let image = UIGraphicsImageRenderer(size: mapOptions.size).image { _ in
208+
private func drawPinOnSnapshot(_ snapshot: MKMapSnapshotter.Snapshot) -> UIImage {
209+
UIGraphicsImageRenderer(size: mapOptions.size).image { _ in
175210
snapshot.image.draw(at: .zero)
211+
212+
guard let content = self.content else { return }
176213

177214
let pinView = MKPinAnnotationView(annotation: nil, reuseIdentifier: nil)
178215
let pinImage = pinView.image
179-
180-
guard let content = self.content else {
181-
return
182-
}
183-
184-
var point = snapshot.point(for: CLLocationCoordinate2D(
185-
latitude: content.latitude,
186-
longitude: content.longitude
187-
))
216+
217+
var point = snapshot.point(for: content.coordinate)
188218
point.x -= pinView.bounds.width / 2
189219
point.y -= pinView.bounds.height / 2
190220
point.x += pinView.centerOffset.x
191221
point.y += pinView.centerOffset.y
222+
192223
pinImage?.draw(at: point)
193224
}
194-
return image
225+
}
226+
227+
private func updateAnnotationView() {
228+
guard let content = self.content else { return }
229+
230+
if content.isLive, let user = content.author {
231+
avatarView.isHidden = false
232+
avatarView.content = user
233+
} else {
234+
avatarView.isHidden = true
235+
}
195236
}
196237

197238
@objc func handleStopButtonTap() {

DemoApp/StreamChat/Components/CustomAttachments/LocationAttachment/LocationAttachmentViewInjector.swift

+9-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright © 2024 Stream.io Inc. All rights reserved.
2+
// Copyright © 2025 Stream.io Inc. All rights reserved.
33
//
44

55
import StreamChat
@@ -35,17 +35,19 @@ class LocationAttachmentViewInjector: AttachmentViewInjector {
3535

3636
if let staticLocation = staticLocationAttachment {
3737
locationAttachmentView.content = .init(
38+
coordinate: .init(latitude: staticLocation.latitude, longitude: staticLocation.longitude),
39+
isLive: false,
40+
isSharingLiveLocation: false,
3841
messageId: contentView.content?.id,
39-
latitude: staticLocation.latitude,
40-
longitude: staticLocation.longitude,
41-
isLive: false
42+
author: contentView.content?.author
4243
)
4344
} else if let liveLocation = liveLocationAttachment {
4445
locationAttachmentView.content = .init(
46+
coordinate: .init(latitude: liveLocation.latitude, longitude: liveLocation.longitude),
47+
isLive: true,
48+
isSharingLiveLocation: liveLocation.stoppedSharing == false,
4549
messageId: contentView.content?.id,
46-
latitude: liveLocation.latitude,
47-
longitude: liveLocation.longitude,
48-
isLive: liveLocation.stoppedSharing == false || liveLocation.stoppedSharing == nil
50+
author: contentView.content?.author
4951
)
5052
}
5153
}

0 commit comments

Comments
 (0)