Skip to content

Commit 2f4a35a

Browse files
committed
Add live location status view in the snapshot view
1 parent 533e331 commit 2f4a35a

File tree

6 files changed

+93
-54
lines changed

6 files changed

+93
-54
lines changed

DemoApp/StreamChat/Components/CustomAttachments/DemoComposerVC.swift

+1-21
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 CoreLocation
@@ -15,15 +15,6 @@ class DemoComposerVC: ComposerVC {
1515

1616
let alreadyHasLocation = content.attachments.map(\.type).contains(.staticLocation)
1717
if AppConfig.shared.demoAppConfig.isLocationAttachmentsEnabled && !alreadyHasLocation {
18-
let addLocationAction = UIAlertAction(
19-
title: "Add Current Location",
20-
style: .default,
21-
handler: { [weak self] _ in
22-
self?.addStaticLocationToAttachments()
23-
}
24-
)
25-
actions.append(addLocationAction)
26-
2718
let sendLocationAction = UIAlertAction(
2819
title: "Send Current Location",
2920
style: .default,
@@ -46,17 +37,6 @@ class DemoComposerVC: ComposerVC {
4637
return actions
4738
}
4839

49-
func addStaticLocationToAttachments() {
50-
getCurrentLocationInfo { [weak self] location in
51-
guard let location = location else { return }
52-
let staticLocationPayload = StaticLocationAttachmentPayload(
53-
latitude: location.latitude,
54-
longitude: location.longitude
55-
)
56-
self?.content.attachments.append(AnyAttachmentPayload(payload: staticLocationPayload))
57-
}
58-
}
59-
6040
func sendInstantStaticLocation() {
6141
getCurrentLocationInfo { [weak self] location in
6242
guard let location = location else { return }

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

-26
This file was deleted.

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

+26-3
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,13 @@ class LocationAttachmentSnapshotView: _View, ThemeProvider {
8484
return view
8585
}()
8686

87+
lazy var sharingStatusView: LocationSharingStatusView = {
88+
let view = LocationSharingStatusView()
89+
view.translatesAutoresizingMaskIntoConstraints = false
90+
view.isHidden = true
91+
return view
92+
}()
93+
8794
override func setUp() {
8895
super.setUp()
8996

@@ -94,6 +101,12 @@ class LocationAttachmentSnapshotView: _View, ThemeProvider {
94101
imageView.addGestureRecognizer(tapGestureRecognizer)
95102
}
96103

104+
override func setUpAppearance() {
105+
super.setUpAppearance()
106+
107+
backgroundColor = appearance.colorPalette.background6
108+
}
109+
97110
override func setUpLayout() {
98111
super.setUpLayout()
99112

@@ -102,9 +115,11 @@ class LocationAttachmentSnapshotView: _View, ThemeProvider {
102115

103116
addSubview(activityIndicatorView)
104117

105-
let container = VContainer(alignment: .center) {
118+
let container = VContainer(spacing: 0, alignment: .center) {
106119
imageView
107120
.height(mapHeight)
121+
sharingStatusView
122+
.height(30)
108123
stopButton
109124
.width(120)
110125
.height(35)
@@ -113,9 +128,10 @@ class LocationAttachmentSnapshotView: _View, ThemeProvider {
113128
addSubview(avatarView)
114129

115130
NSLayoutConstraint.activate([
116-
activityIndicatorView.centerXAnchor.constraint(equalTo: imageView.centerXAnchor),
117-
activityIndicatorView.centerYAnchor.constraint(equalTo: imageView.centerYAnchor),
131+
activityIndicatorView.centerXAnchor.constraint(equalTo: centerXAnchor),
132+
activityIndicatorView.centerYAnchor.constraint(equalTo: centerYAnchor),
118133
imageView.widthAnchor.constraint(equalTo: container.widthAnchor),
134+
119135
avatarView.centerXAnchor.constraint(equalTo: imageView.centerXAnchor),
120136
avatarView.centerYAnchor.constraint(equalTo: imageView.centerYAnchor),
121137
avatarView.widthAnchor.constraint(equalToConstant: 30),
@@ -136,8 +152,15 @@ class LocationAttachmentSnapshotView: _View, ThemeProvider {
136152

137153
if content.isSharingLiveLocation && content.isFromCurrentUser {
138154
stopButton.isHidden = false
155+
sharingStatusView.isHidden = true
156+
sharingStatusView.updateStatus(isSharing: true)
157+
} else if content.isLive {
158+
stopButton.isHidden = true
159+
sharingStatusView.isHidden = false
160+
sharingStatusView.updateStatus(isSharing: content.isSharingLiveLocation)
139161
} else {
140162
stopButton.isHidden = true
163+
sharingStatusView.isHidden = true
141164
}
142165

143166
configureMapPosition()

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

+8
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ class LocationAttachmentViewInjector: AttachmentViewInjector {
2828
locationAttachmentView.didTapOnStopSharingLocation = { [weak self] in
2929
self?.handleTapOnStopSharingLocation()
3030
}
31+
32+
let isSentByCurrentUser = contentView.content?.isSentByCurrentUser == true
33+
let maskedCorners: CACornerMask = isSentByCurrentUser
34+
? [.layerMinXMaxYCorner, .layerMinXMinYCorner]
35+
: [.layerMinXMinYCorner, .layerMaxXMaxYCorner, .layerMaxXMinYCorner]
36+
locationAttachmentView.layer.maskedCorners = maskedCorners
37+
locationAttachmentView.layer.cornerRadius = 16
38+
locationAttachmentView.layer.masksToBounds = true
3139
}
3240

3341
override func contentViewDidUpdateContent() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//
2+
// Copyright © 2025 Stream.io Inc. All rights reserved.
3+
//
4+
5+
import StreamChat
6+
import StreamChatUI
7+
import UIKit
8+
9+
class LocationSharingStatusView: _View, ThemeProvider {
10+
private lazy var statusLabel: UILabel = {
11+
let label = UILabel()
12+
label.translatesAutoresizingMaskIntoConstraints = false
13+
label.font = appearance.fonts.footnote
14+
label.textColor = appearance.colorPalette.subtitleText
15+
return label
16+
}()
17+
18+
private var activeSharingImage: UIImage? = UIImage(
19+
systemName: "location.fill",
20+
withConfiguration: UIImage.SymbolConfiguration(scale: .medium)
21+
)
22+
23+
private var inactiveSharingImage: UIImage? = UIImage(
24+
systemName: "location.slash.fill",
25+
withConfiguration: UIImage.SymbolConfiguration(scale: .medium)
26+
)
27+
28+
private lazy var iconImageView: UIImageView = {
29+
let imageView = UIImageView()
30+
imageView.translatesAutoresizingMaskIntoConstraints = false
31+
imageView.contentMode = .scaleAspectFit
32+
imageView.image = activeSharingImage
33+
return imageView
34+
}()
35+
36+
override func setUpLayout() {
37+
super.setUpLayout()
38+
39+
let container = HContainer(spacing: 4, alignment: .center) {
40+
iconImageView
41+
.width(16)
42+
.height(16)
43+
statusLabel
44+
}.embed(in: self)
45+
}
46+
47+
func updateStatus(isSharing: Bool) {
48+
statusLabel.text = isSharing ? "Live location active" : "Live location ended"
49+
iconImageView.image = isSharing ? activeSharingImage : inactiveSharingImage
50+
iconImageView.tintColor = isSharing
51+
? appearance.colorPalette.accentPrimary
52+
: appearance.colorPalette.subtitleText
53+
}
54+
}

StreamChat.xcodeproj/project.pbxproj

+4-4
Original file line numberDiff line numberDiff line change
@@ -1359,7 +1359,6 @@
13591359
AD053B9A2B335854003612B6 /* DemoComposerVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD053B992B335854003612B6 /* DemoComposerVC.swift */; };
13601360
AD053B9F2B335929003612B6 /* LocationAttachmentViewInjector.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD053B9E2B335929003612B6 /* LocationAttachmentViewInjector.swift */; };
13611361
AD053BA12B3359DD003612B6 /* DemoAttachmentViewCatalog.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD053BA02B3359DD003612B6 /* DemoAttachmentViewCatalog.swift */; };
1362-
AD053BA32B335A13003612B6 /* LocationAttachmentPayload+AttachmentViewProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD053BA22B335A13003612B6 /* LocationAttachmentPayload+AttachmentViewProvider.swift */; };
13631362
AD053BA52B335A63003612B6 /* DemoQuotedChatMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD053BA42B335A63003612B6 /* DemoQuotedChatMessageView.swift */; };
13641363
AD053BA72B33624C003612B6 /* LocationAttachmentViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD053BA62B33624C003612B6 /* LocationAttachmentViewDelegate.swift */; };
13651364
AD053BA92B336331003612B6 /* LocationDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD053BA82B336331003612B6 /* LocationDetailViewController.swift */; };
@@ -1466,6 +1465,7 @@
14661465
AD470C9E26C6D9030090759A /* ChatMessageListVCDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD470C9D26C6D9030090759A /* ChatMessageListVCDelegate.swift */; };
14671466
AD483B962A2658970004B406 /* ChannelMemberUnbanRequestPayload.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD483B952A2658970004B406 /* ChannelMemberUnbanRequestPayload.swift */; };
14681467
AD483B972A2658970004B406 /* ChannelMemberUnbanRequestPayload.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD483B952A2658970004B406 /* ChannelMemberUnbanRequestPayload.swift */; };
1468+
AD48F6922D2849B5007CCF3A /* LocationSharingStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD48F6912D2849B5007CCF3A /* LocationSharingStatusView.swift */; };
14691469
AD4C15562A55874700A32955 /* ImageLoading_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD4C15552A55874700A32955 /* ImageLoading_Tests.swift */; };
14701470
AD4C8C222C5D479B00E1C414 /* StackedUserAvatarsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD4C8C212C5D479B00E1C414 /* StackedUserAvatarsView.swift */; };
14711471
AD4C8C232C5D479B00E1C414 /* StackedUserAvatarsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD4C8C212C5D479B00E1C414 /* StackedUserAvatarsView.swift */; };
@@ -4164,7 +4164,6 @@
41644164
AD053B992B335854003612B6 /* DemoComposerVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoComposerVC.swift; sourceTree = "<group>"; };
41654165
AD053B9E2B335929003612B6 /* LocationAttachmentViewInjector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationAttachmentViewInjector.swift; sourceTree = "<group>"; };
41664166
AD053BA02B3359DD003612B6 /* DemoAttachmentViewCatalog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoAttachmentViewCatalog.swift; sourceTree = "<group>"; };
4167-
AD053BA22B335A13003612B6 /* LocationAttachmentPayload+AttachmentViewProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LocationAttachmentPayload+AttachmentViewProvider.swift"; sourceTree = "<group>"; };
41684167
AD053BA42B335A63003612B6 /* DemoQuotedChatMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoQuotedChatMessageView.swift; sourceTree = "<group>"; };
41694168
AD053BA62B33624C003612B6 /* LocationAttachmentViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationAttachmentViewDelegate.swift; sourceTree = "<group>"; };
41704169
AD053BA82B336331003612B6 /* LocationDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationDetailViewController.swift; sourceTree = "<group>"; };
@@ -4236,6 +4235,7 @@
42364235
AD470C9B26C6D8C60090759A /* ChatMessageListVCDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageListVCDataSource.swift; sourceTree = "<group>"; };
42374236
AD470C9D26C6D9030090759A /* ChatMessageListVCDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageListVCDelegate.swift; sourceTree = "<group>"; };
42384237
AD483B952A2658970004B406 /* ChannelMemberUnbanRequestPayload.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelMemberUnbanRequestPayload.swift; sourceTree = "<group>"; };
4238+
AD48F6912D2849B5007CCF3A /* LocationSharingStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationSharingStatusView.swift; sourceTree = "<group>"; };
42394239
AD4C15552A55874700A32955 /* ImageLoading_Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageLoading_Tests.swift; sourceTree = "<group>"; };
42404240
AD4C8C212C5D479B00E1C414 /* StackedUserAvatarsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StackedUserAvatarsView.swift; sourceTree = "<group>"; };
42414241
AD4CDD81296498D20057BC8A /* ScrollViewPaginationHandler_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollViewPaginationHandler_Tests.swift; sourceTree = "<group>"; };
@@ -8389,11 +8389,11 @@
83898389
AD053B9B2B33589C003612B6 /* LocationAttachment */ = {
83908390
isa = PBXGroup;
83918391
children = (
8392-
AD053BA22B335A13003612B6 /* LocationAttachmentPayload+AttachmentViewProvider.swift */,
83938392
AD053B9E2B335929003612B6 /* LocationAttachmentViewInjector.swift */,
83948393
AD053BA62B33624C003612B6 /* LocationAttachmentViewDelegate.swift */,
83958394
AD053BAA2B33638B003612B6 /* LocationAttachmentSnapshotView.swift */,
83968395
AD053BA82B336331003612B6 /* LocationDetailViewController.swift */,
8396+
AD48F6912D2849B5007CCF3A /* LocationSharingStatusView.swift */,
83978397
AD2F2D9A2D271B36006ED24B /* UserAnnotationView.swift */,
83988398
AD2F2D982D271B07006ED24B /* UserAnnotation.swift */,
83998399
);
@@ -11062,6 +11062,7 @@
1106211062
794E20F52577DF4D00790DAB /* NameGroupViewController.swift in Sources */,
1106311063
A3227EC9284A52EE00EBE6CC /* PushNotifications.swift in Sources */,
1106411064
A3227E65284A4A5C00EBE6CC /* StreamChatWrapper.swift in Sources */,
11065+
AD48F6922D2849B5007CCF3A /* LocationSharingStatusView.swift in Sources */,
1106511066
A3227E78284A4CAD00EBE6CC /* DemoChatMessageContentView.swift in Sources */,
1106611067
AD2F2D992D271B07006ED24B /* UserAnnotation.swift in Sources */,
1106711068
7933060B256FF94800FBB586 /* DemoChatChannelListRouter.swift in Sources */,
@@ -11076,7 +11077,6 @@
1107611077
AD2F2D9B2D271B36006ED24B /* UserAnnotationView.swift in Sources */,
1107711078
A3227E59284A484300EBE6CC /* UIImage+Resized.swift in Sources */,
1107811079
79B8B64B285CBDC00059FB2D /* DemoChatMessageLayoutOptionsResolver.swift in Sources */,
11079-
AD053BA32B335A13003612B6 /* LocationAttachmentPayload+AttachmentViewProvider.swift in Sources */,
1108011080
AD053BA12B3359DD003612B6 /* DemoAttachmentViewCatalog.swift in Sources */,
1108111081
AD053B9F2B335929003612B6 /* LocationAttachmentViewInjector.swift in Sources */,
1108211082
);

0 commit comments

Comments
 (0)