Render LiveLocations in the map (#5394)

This commit is contained in:
Mauro
2026-04-14 18:27:34 +02:00
committed by GitHub
parent a40fab5f5e
commit 602d779e3a
19 changed files with 380 additions and 163 deletions
@@ -26,6 +26,7 @@ enum LocationSharingScreenViewModelAction {
enum LocationSharingInteractionMode: Hashable {
case picker
case viewStatic(StaticLocationData)
case viewLive(sender: TimelineItemSender, initialLiveLocationShare: LiveLocationShare)
}
struct LocationSharingScreenViewState: BindableState {
@@ -38,16 +39,23 @@ struct LocationSharingScreenViewState: BindableState {
self.showLiveLocationSharingButton = showLiveLocationSharingButton
self.ownUserID = ownUserID
userProfile = switch interactionMode {
let initialProfile: UserProfileProxy = switch interactionMode {
case .viewStatic(let locationData):
.init(sender: locationData.sender)
case .viewLive(let sender, _):
.init(sender: sender)
case .picker:
.init(userID: ownUserID)
}
userProfiles = [initialProfile.userID: initialProfile]
if case .viewLive(_, let initialLiveLocationShare) = interactionMode {
liveLocationShares = [initialLiveLocationShare]
}
bindings.showsUserLocationMode = switch interactionMode {
case .picker: .showAndFollow
case .viewStatic: .show
case .viewStatic, .viewLive: .show
}
}
@@ -55,10 +63,35 @@ struct LocationSharingScreenViewState: BindableState {
let mapURLBuilder: MapTilerURLBuilderProtocol
let showLiveLocationSharingButton: Bool
let ownUserID: String
var userProfile: UserProfileProxy
var userProfiles: [String: UserProfileProxy]
var liveLocationShares: [LiveLocationShare] = []
var isOwnUser: Bool {
userProfile.userID == ownUserID
var annotations: [LocationAnnotation] {
switch interactionMode {
case .viewStatic(let location):
let profile = userProfiles.values.first
let kind: LocationMarkerKind = if location.kind == .sender, let profile {
.staticUser(profile)
} else {
.pin
}
let coordinate = CLLocationCoordinate2D(latitude: location.geoURI.latitude, longitude: location.geoURI.longitude)
return [LocationAnnotation(id: kind.id, coordinate: coordinate, kind: kind)]
case .viewLive:
return liveLocationShares.compactMap { share in
guard let geoURI = share.geoURI else { return nil }
let profile = userProfiles[share.userID] ?? UserProfileProxy(userID: share.userID)
let kind = LocationMarkerKind.liveUser(profile)
let coordinate = CLLocationCoordinate2D(latitude: geoURI.latitude, longitude: geoURI.longitude)
return LocationAnnotation(id: profile.userID, coordinate: coordinate, kind: kind)
}
case .picker:
return []
}
}
func isOwnUser(_ userID: String) -> Bool {
userID == ownUserID
}
var bindings = LocationSharingScreenBindings(showsUserLocationMode: .hide)
@@ -75,15 +108,9 @@ struct LocationSharingScreenViewState: BindableState {
.init(latitude: 49.843, longitude: 9.902056)
case .viewStatic(let location):
.init(latitude: location.geoURI.latitude, longitude: location.geoURI.longitude)
}
}
var isLocationPickerMode: Bool {
switch interactionMode {
case .picker:
true
default:
false
case .viewLive(_, let initialLiveLocationShare):
.init(latitude: initialLiveLocationShare.geoURI?.latitude ?? 0,
longitude: initialLiveLocationShare.geoURI?.longitude ?? 0)
}
}
@@ -101,18 +128,18 @@ struct LocationSharingScreenViewState: BindableState {
switch interactionMode {
case .picker:
return 2.7
case .viewStatic:
case .viewStatic, .viewLive:
return 15.0
}
}
var locationMarkerKind: LocationMarkerKind {
switch interactionMode {
case .picker:
isSharingUserLocation ? .staticUser(userProfile) : .pin
case .viewStatic(let location):
location.kind == .sender ? .staticUser(userProfile) : .pin
/// The marker kind used for the picker overlay (not a map annotation).
var pickerMarkerKind: LocationMarkerKind? {
guard case .picker = interactionMode else { return nil }
if let profile = userProfiles.values.first {
return isSharingUserLocation ? .staticUser(profile) : .pin
}
return .pin
}
}
@@ -139,7 +166,7 @@ struct LocationSharingScreenBindings {
/// Information describing the currently displayed alert.
var alertInfo: AlertInfo<LocationSharingViewAlert>?
var showShareSheet = false
var sharedAnnotation: LocationAnnotation?
}
enum LocationSharingScreenViewAction {
@@ -193,7 +220,7 @@ extension AlertInfo where T == LocationSharingViewAlert {
}
}
enum LocationMarkerKind {
enum LocationMarkerKind: Equatable {
case pin
case staticUser(UserProfileProxy)
case liveUser(UserProfileProxy)