improved location sheets presentations and addressed some pr suggestions
This commit is contained in:
@@ -979,6 +979,7 @@
|
|||||||
A74438ED16F8683A4B793E6A /* AnalyticsSettingsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BCE3FAF40932AC7C7639AC4 /* AnalyticsSettingsScreenViewModel.swift */; };
|
A74438ED16F8683A4B793E6A /* AnalyticsSettingsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BCE3FAF40932AC7C7639AC4 /* AnalyticsSettingsScreenViewModel.swift */; };
|
||||||
A7455F6B2F5AF7DD00E8D8BB /* LocationPickerSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7455F6A2F5AF7D400E8D8BB /* LocationPickerSheet.swift */; };
|
A7455F6B2F5AF7DD00E8D8BB /* LocationPickerSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7455F6A2F5AF7D400E8D8BB /* LocationPickerSheet.swift */; };
|
||||||
A7D48E44D485B143AADDB77D /* Strings+Untranslated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */; };
|
A7D48E44D485B143AADDB77D /* Strings+Untranslated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */; };
|
||||||
|
A7D5FE842F5F2EC000386C15 /* StaticLocationData.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7D5FE832F5F2EBB00386C15 /* StaticLocationData.swift */; };
|
||||||
A7DB75E090542331F6668A23 /* CreateRoomScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF19027E7FFA5E63D148873A /* CreateRoomScreenViewModel.swift */; };
|
A7DB75E090542331F6668A23 /* CreateRoomScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF19027E7FFA5E63D148873A /* CreateRoomScreenViewModel.swift */; };
|
||||||
A808DC3F72D15C6C5A52317E /* TimelineItemDebugView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCDA016D05107DED3B9495CB /* TimelineItemDebugView.swift */; };
|
A808DC3F72D15C6C5A52317E /* TimelineItemDebugView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCDA016D05107DED3B9495CB /* TimelineItemDebugView.swift */; };
|
||||||
A816F7087C495D85048AC50E /* RoomMemberDetailsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B6E30BB748F3F480F077969 /* RoomMemberDetailsScreenModels.swift */; };
|
A816F7087C495D85048AC50E /* RoomMemberDetailsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B6E30BB748F3F480F077969 /* RoomMemberDetailsScreenModels.swift */; };
|
||||||
@@ -2463,6 +2464,7 @@
|
|||||||
A7A1B80FE6E3BA72F9C748AD /* AdvancedSettingsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsScreenViewModel.swift; sourceTree = "<group>"; };
|
A7A1B80FE6E3BA72F9C748AD /* AdvancedSettingsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
A7C4EA55DA62F9D0F984A2AE /* CollapsibleTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollapsibleTimelineItem.swift; sourceTree = "<group>"; };
|
A7C4EA55DA62F9D0F984A2AE /* CollapsibleTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollapsibleTimelineItem.swift; sourceTree = "<group>"; };
|
||||||
A7D452AF7B5F7E3A0A7DB54C /* SessionVerificationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
A7D452AF7B5F7E3A0A7DB54C /* SessionVerificationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
A7D5FE832F5F2EBB00386C15 /* StaticLocationData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StaticLocationData.swift; sourceTree = "<group>"; };
|
||||||
A7E37072597F67C4DD8CC2DB /* ComposerDraftServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerDraftServiceProtocol.swift; sourceTree = "<group>"; };
|
A7E37072597F67C4DD8CC2DB /* ComposerDraftServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerDraftServiceProtocol.swift; sourceTree = "<group>"; };
|
||||||
A84D413BF49F0E980F010A6B /* LogViewerScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogViewerScreenCoordinator.swift; sourceTree = "<group>"; };
|
A84D413BF49F0E980F010A6B /* LogViewerScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogViewerScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
A8558D41DD4B553A752C868A /* StackedAvatarsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StackedAvatarsView.swift; sourceTree = "<group>"; };
|
A8558D41DD4B553A752C868A /* StackedAvatarsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StackedAvatarsView.swift; sourceTree = "<group>"; };
|
||||||
@@ -6065,6 +6067,7 @@
|
|||||||
C17C3586C93F3A314C1CC318 /* MapLibre */ = {
|
C17C3586C93F3A314C1CC318 /* MapLibre */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
A7D5FE832F5F2EBB00386C15 /* StaticLocationData.swift */,
|
||||||
AAD8234D0E9C9B12BF9F240B /* LocationAnnotation.swift */,
|
AAD8234D0E9C9B12BF9F240B /* LocationAnnotation.swift */,
|
||||||
622D09D4ECE759189009AEAF /* MapLibreMapView.swift */,
|
622D09D4ECE759189009AEAF /* MapLibreMapView.swift */,
|
||||||
B81B6170DB690013CEB646F4 /* MapLibreModels.swift */,
|
B81B6170DB690013CEB646F4 /* MapLibreModels.swift */,
|
||||||
@@ -8674,6 +8677,7 @@
|
|||||||
DF004A5B2EABBD0574D06A04 /* SplashScreenCoordinator.swift in Sources */,
|
DF004A5B2EABBD0574D06A04 /* SplashScreenCoordinator.swift in Sources */,
|
||||||
E1C67E5D9E22135A8FEBBD60 /* StackedAvatarsView.swift in Sources */,
|
E1C67E5D9E22135A8FEBBD60 /* StackedAvatarsView.swift in Sources */,
|
||||||
9FC79DA30AE0E1502DAEBD51 /* StartChatFlowCoordinator.swift in Sources */,
|
9FC79DA30AE0E1502DAEBD51 /* StartChatFlowCoordinator.swift in Sources */,
|
||||||
|
A7D5FE842F5F2EC000386C15 /* StaticLocationData.swift in Sources */,
|
||||||
3DAF325D8AE461F7CDB282BD /* StartChatScreen.swift in Sources */,
|
3DAF325D8AE461F7CDB282BD /* StartChatScreen.swift in Sources */,
|
||||||
6CD61FAF03E8986523C2ABB8 /* StartChatScreenCoordinator.swift in Sources */,
|
6CD61FAF03E8986523C2ABB8 /* StartChatScreenCoordinator.swift in Sources */,
|
||||||
C051475DFF4C8EBDDF4DC8E4 /* StartChatScreenModels.swift in Sources */,
|
C051475DFF4C8EBDDF4DC8E4 /* StartChatScreenModels.swift in Sources */,
|
||||||
|
|||||||
@@ -748,6 +748,7 @@
|
|||||||
"screen_security_and_privacy_room_visibility_section_footer" = "Addresses are a way to find and access rooms and spaces. This also ensures you can easily share them with others.";
|
"screen_security_and_privacy_room_visibility_section_footer" = "Addresses are a way to find and access rooms and spaces. This also ensures you can easily share them with others.";
|
||||||
"screen_security_and_privacy_room_visibility_section_header" = "Visibility";
|
"screen_security_and_privacy_room_visibility_section_header" = "Visibility";
|
||||||
"screen_security_and_privacy_title" = "Security & privacy";
|
"screen_security_and_privacy_title" = "Security & privacy";
|
||||||
|
"screen_sharing_location_option_sheet_title" = "Sharing options";
|
||||||
"screen_space_add_room_action" = "Room";
|
"screen_space_add_room_action" = "Room";
|
||||||
"screen_space_empty_state_title" = "Add your first room";
|
"screen_space_empty_state_title" = "Add your first room";
|
||||||
"screen_space_menu_action_members" = "View members";
|
"screen_space_menu_action_members" = "View members";
|
||||||
@@ -1095,7 +1096,7 @@
|
|||||||
"screen_room_attachment_source_camera_video" = "Record video";
|
"screen_room_attachment_source_camera_video" = "Record video";
|
||||||
"screen_room_attachment_source_files" = "Attachment";
|
"screen_room_attachment_source_files" = "Attachment";
|
||||||
"screen_room_attachment_source_gallery" = "Photo & Video Library";
|
"screen_room_attachment_source_gallery" = "Photo & Video Library";
|
||||||
"screen_room_attachment_source_location" = "Location";
|
"screen_room_attachment_source_location" = "Share location";
|
||||||
"screen_room_attachment_source_poll" = "Poll";
|
"screen_room_attachment_source_poll" = "Poll";
|
||||||
"screen_room_attachment_text_formatting" = "Text Formatting";
|
"screen_room_attachment_text_formatting" = "Text Formatting";
|
||||||
"screen_room_change_permissions_administrators" = "Admin";
|
"screen_room_change_permissions_administrators" = "Admin";
|
||||||
@@ -1275,7 +1276,7 @@
|
|||||||
"screen_share_open_apple_maps" = "Open in Apple Maps";
|
"screen_share_open_apple_maps" = "Open in Apple Maps";
|
||||||
"screen_share_open_google_maps" = "Open in Google Maps";
|
"screen_share_open_google_maps" = "Open in Google Maps";
|
||||||
"screen_share_open_osm_maps" = "Open in OpenStreetMap";
|
"screen_share_open_osm_maps" = "Open in OpenStreetMap";
|
||||||
"screen_share_this_location_action" = "Share pinned location";
|
"screen_share_this_location_action" = "Share selected location";
|
||||||
"screen_signed_out_reason_1" = "You’ve changed your password on another session";
|
"screen_signed_out_reason_1" = "You’ve changed your password on another session";
|
||||||
"screen_signed_out_reason_2" = "You have deleted the session from another session";
|
"screen_signed_out_reason_2" = "You have deleted the session from another session";
|
||||||
"screen_signed_out_reason_3" = "Your server’s administrator has invalidated your access";
|
"screen_signed_out_reason_3" = "Your server’s administrator has invalidated your access";
|
||||||
|
|||||||
@@ -748,6 +748,7 @@
|
|||||||
"screen_security_and_privacy_room_visibility_section_footer" = "Addresses are a way to find and access rooms and spaces. This also ensures you can easily share them with others.";
|
"screen_security_and_privacy_room_visibility_section_footer" = "Addresses are a way to find and access rooms and spaces. This also ensures you can easily share them with others.";
|
||||||
"screen_security_and_privacy_room_visibility_section_header" = "Visibility";
|
"screen_security_and_privacy_room_visibility_section_header" = "Visibility";
|
||||||
"screen_security_and_privacy_title" = "Security & privacy";
|
"screen_security_and_privacy_title" = "Security & privacy";
|
||||||
|
"screen_sharing_location_option_sheet_title" = "Sharing options";
|
||||||
"screen_space_add_room_action" = "Room";
|
"screen_space_add_room_action" = "Room";
|
||||||
"screen_space_empty_state_title" = "Add your first room";
|
"screen_space_empty_state_title" = "Add your first room";
|
||||||
"screen_space_menu_action_members" = "View members";
|
"screen_space_menu_action_members" = "View members";
|
||||||
@@ -1095,7 +1096,7 @@
|
|||||||
"screen_room_attachment_source_camera_video" = "Record video";
|
"screen_room_attachment_source_camera_video" = "Record video";
|
||||||
"screen_room_attachment_source_files" = "Attachment";
|
"screen_room_attachment_source_files" = "Attachment";
|
||||||
"screen_room_attachment_source_gallery" = "Photo & Video Library";
|
"screen_room_attachment_source_gallery" = "Photo & Video Library";
|
||||||
"screen_room_attachment_source_location" = "Location";
|
"screen_room_attachment_source_location" = "Share location";
|
||||||
"screen_room_attachment_source_poll" = "Poll";
|
"screen_room_attachment_source_poll" = "Poll";
|
||||||
"screen_room_attachment_text_formatting" = "Text Formatting";
|
"screen_room_attachment_text_formatting" = "Text Formatting";
|
||||||
"screen_room_change_permissions_administrators" = "Admin";
|
"screen_room_change_permissions_administrators" = "Admin";
|
||||||
@@ -1275,7 +1276,7 @@
|
|||||||
"screen_share_open_apple_maps" = "Open in Apple Maps";
|
"screen_share_open_apple_maps" = "Open in Apple Maps";
|
||||||
"screen_share_open_google_maps" = "Open in Google Maps";
|
"screen_share_open_google_maps" = "Open in Google Maps";
|
||||||
"screen_share_open_osm_maps" = "Open in OpenStreetMap";
|
"screen_share_open_osm_maps" = "Open in OpenStreetMap";
|
||||||
"screen_share_this_location_action" = "Share pinned location";
|
"screen_share_this_location_action" = "Share selected location";
|
||||||
"screen_signed_out_reason_1" = "You’ve changed your password on another session";
|
"screen_signed_out_reason_1" = "You’ve changed your password on another session";
|
||||||
"screen_signed_out_reason_2" = "You have deleted the session from another session";
|
"screen_signed_out_reason_2" = "You have deleted the session from another session";
|
||||||
"screen_signed_out_reason_3" = "Your server’s administrator has invalidated your access";
|
"screen_signed_out_reason_3" = "Your server’s administrator has invalidated your access";
|
||||||
|
|||||||
@@ -2516,7 +2516,7 @@ internal enum L10n {
|
|||||||
internal static var screenRoomAttachmentSourceFiles: String { return L10n.tr("Localizable", "screen_room_attachment_source_files") }
|
internal static var screenRoomAttachmentSourceFiles: String { return L10n.tr("Localizable", "screen_room_attachment_source_files") }
|
||||||
/// Photo & Video Library
|
/// Photo & Video Library
|
||||||
internal static var screenRoomAttachmentSourceGallery: String { return L10n.tr("Localizable", "screen_room_attachment_source_gallery") }
|
internal static var screenRoomAttachmentSourceGallery: String { return L10n.tr("Localizable", "screen_room_attachment_source_gallery") }
|
||||||
/// Location
|
/// Share location
|
||||||
internal static var screenRoomAttachmentSourceLocation: String { return L10n.tr("Localizable", "screen_room_attachment_source_location") }
|
internal static var screenRoomAttachmentSourceLocation: String { return L10n.tr("Localizable", "screen_room_attachment_source_location") }
|
||||||
/// Poll
|
/// Poll
|
||||||
internal static var screenRoomAttachmentSourcePoll: String { return L10n.tr("Localizable", "screen_room_attachment_source_poll") }
|
internal static var screenRoomAttachmentSourcePoll: String { return L10n.tr("Localizable", "screen_room_attachment_source_poll") }
|
||||||
@@ -3171,8 +3171,10 @@ internal enum L10n {
|
|||||||
internal static var screenShareOpenGoogleMaps: String { return L10n.tr("Localizable", "screen_share_open_google_maps") }
|
internal static var screenShareOpenGoogleMaps: String { return L10n.tr("Localizable", "screen_share_open_google_maps") }
|
||||||
/// Open in OpenStreetMap
|
/// Open in OpenStreetMap
|
||||||
internal static var screenShareOpenOsmMaps: String { return L10n.tr("Localizable", "screen_share_open_osm_maps") }
|
internal static var screenShareOpenOsmMaps: String { return L10n.tr("Localizable", "screen_share_open_osm_maps") }
|
||||||
/// Share pinned location
|
/// Share selected location
|
||||||
internal static var screenShareThisLocationAction: String { return L10n.tr("Localizable", "screen_share_this_location_action") }
|
internal static var screenShareThisLocationAction: String { return L10n.tr("Localizable", "screen_share_this_location_action") }
|
||||||
|
/// Sharing options
|
||||||
|
internal static var screenSharingLocationOptionSheetTitle: String { return L10n.tr("Localizable", "screen_sharing_location_option_sheet_title") }
|
||||||
/// You’ve changed your password on another session
|
/// You’ve changed your password on another session
|
||||||
internal static var screenSignedOutReason1: String { return L10n.tr("Localizable", "screen_signed_out_reason_1") }
|
internal static var screenSignedOutReason1: String { return L10n.tr("Localizable", "screen_signed_out_reason_1") }
|
||||||
/// You have deleted the session from another session
|
/// You have deleted the session from another session
|
||||||
|
|||||||
15
ElementX/Sources/Other/MapLibre/StaticLocationData.swift
Normal file
15
ElementX/Sources/Other/MapLibre/StaticLocationData.swift
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2026 Element Creations Ltd.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||||
|
// Please see LICENSE files in the repository root for full details.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct StaticLocationData: Hashable {
|
||||||
|
let sender: TimelineItemSender
|
||||||
|
let geoURI: GeoURI
|
||||||
|
let kind: StaticLocationKind
|
||||||
|
let timestamp: Date
|
||||||
|
}
|
||||||
@@ -72,8 +72,9 @@ struct LocationSharingScreenViewState: BindableState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the user's location has not yet been determined, while location permissions are given or not yet set
|
||||||
|
/// Does not work as intended on simulator.
|
||||||
var isLocationLoading: Bool {
|
var isLocationLoading: Bool {
|
||||||
// May not work as intended on simulator
|
|
||||||
!bindings.hasLoadedUserLocation && bindings.isLocationAuthorized != false
|
!bindings.hasLoadedUserLocation && bindings.isLocationAuthorized != false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +93,7 @@ struct LocationSharingScreenViewState: BindableState {
|
|||||||
|
|
||||||
var userProfile: UserProfileProxy?
|
var userProfile: UserProfileProxy?
|
||||||
|
|
||||||
var staticLocationMarkerUserProfile: UserProfileProxy? {
|
var locationMarkerUserProfile: UserProfileProxy? {
|
||||||
switch interactionMode {
|
switch interactionMode {
|
||||||
case .picker:
|
case .picker:
|
||||||
isSharingUserLocation ? userProfile : nil
|
isSharingUserLocation ? userProfile : nil
|
||||||
@@ -159,10 +160,3 @@ extension AlertInfo where T == LocationSharingViewError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct StaticLocationData: Hashable {
|
|
||||||
let sender: TimelineItemSender
|
|
||||||
let geoURI: GeoURI
|
|
||||||
let kind: StaticLocationKind
|
|
||||||
let timestamp: Date
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -132,7 +132,9 @@ extension LocationSharingScreenViewModel {
|
|||||||
case staticPinLocation
|
case staticPinLocation
|
||||||
}
|
}
|
||||||
|
|
||||||
static func mock(type: MockType, senderID: String = "@dan:matrix.org") -> LocationSharingScreenViewModel {
|
static func mock(type: MockType,
|
||||||
|
senderID: String = "@dan:matrix.org",
|
||||||
|
liveLocationSharingEnabled: Bool = true) -> LocationSharingScreenViewModel {
|
||||||
let interactionMode: LocationSharingInteractionMode = switch type {
|
let interactionMode: LocationSharingInteractionMode = switch type {
|
||||||
case .picker:
|
case .picker:
|
||||||
.picker
|
.picker
|
||||||
@@ -152,7 +154,7 @@ extension LocationSharingScreenViewModel {
|
|||||||
|
|
||||||
return LocationSharingScreenViewModel(interactionMode: interactionMode,
|
return LocationSharingScreenViewModel(interactionMode: interactionMode,
|
||||||
mapURLBuilder: ServiceLocator.shared.settings.mapTilerConfiguration,
|
mapURLBuilder: ServiceLocator.shared.settings.mapTilerConfiguration,
|
||||||
liveLocationSharingEnabled: true,
|
liveLocationSharingEnabled: liveLocationSharingEnabled,
|
||||||
roomProxy: JoinedRoomProxyMock(.init()),
|
roomProxy: JoinedRoomProxyMock(.init()),
|
||||||
timelineController: MockTimelineController(),
|
timelineController: MockTimelineController(),
|
||||||
analytics: ServiceLocator.shared.analytics,
|
analytics: ServiceLocator.shared.analytics,
|
||||||
|
|||||||
@@ -12,8 +12,20 @@ struct LocationPickerSheet: View {
|
|||||||
@Bindable var context: LocationSharingScreenViewModel.Context
|
@Bindable var context: LocationSharingScreenViewModel.Context
|
||||||
@State private var height: CGFloat = .zero
|
@State private var height: CGFloat = .zero
|
||||||
|
|
||||||
|
/// Fixes an iOS 26 sheet issue
|
||||||
|
/// if the content doesn't meet a certain size
|
||||||
|
/// additional insets are added.
|
||||||
|
private var additionalHeight: CGFloat {
|
||||||
|
context.viewState.showLiveLocationSharingButton ? 0 : 28
|
||||||
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
|
Text(L10n.screenSharingLocationOptionSheetTitle)
|
||||||
|
.foregroundStyle(.compound.textPrimary)
|
||||||
|
.font(.compound.bodyLGSemibold)
|
||||||
|
.padding(.top, 29)
|
||||||
|
.padding(.bottom, 25)
|
||||||
Button {
|
Button {
|
||||||
context.send(viewAction: .selectLocation)
|
context.send(viewAction: .selectLocation)
|
||||||
} label: {
|
} label: {
|
||||||
@@ -35,15 +47,12 @@ struct LocationPickerSheet: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.font(.compound.bodyLG)
|
|
||||||
.foregroundStyle(.compound.textPrimary)
|
|
||||||
.padding(.top, 38)
|
|
||||||
.readHeight($height)
|
.readHeight($height)
|
||||||
.interactiveDismissDisabled()
|
.interactiveDismissDisabled()
|
||||||
.presentationBackground(.compound.bgCanvasDefault)
|
.presentationBackground(.compound.bgCanvasDefault)
|
||||||
.presentationBackgroundInteraction(.enabled)
|
.presentationBackgroundInteraction(.enabled)
|
||||||
.presentationDragIndicator(.hidden)
|
.presentationDragIndicator(.hidden)
|
||||||
.presentationDetents([.height(height)])
|
.presentationDetents([.height(height + additionalHeight)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,6 +68,8 @@ private struct LocationPickerLabel: View {
|
|||||||
.padding(.vertical, 14)
|
.padding(.vertical, 14)
|
||||||
.rowDivider(alignment: .top)
|
.rowDivider(alignment: .top)
|
||||||
.padding(.trailing, 16)
|
.padding(.trailing, 16)
|
||||||
|
.font(.compound.bodyLG)
|
||||||
|
.foregroundStyle(.compound.textPrimary)
|
||||||
} icon: {
|
} icon: {
|
||||||
CompoundIcon(icon)
|
CompoundIcon(icon)
|
||||||
.foregroundStyle(iconColor)
|
.foregroundStyle(iconColor)
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ struct LocationSharingScreen: View {
|
|||||||
.ignoresSafeArea(.all, edges: mapSafeAreaEdges)
|
.ignoresSafeArea(.all, edges: mapSafeAreaEdges)
|
||||||
|
|
||||||
if context.viewState.isLocationPickerMode {
|
if context.viewState.isLocationPickerMode {
|
||||||
LocationMarkerView(userProfile: context.viewState.staticLocationMarkerUserProfile, mediaProvider: context.mediaProvider)
|
LocationMarkerView(userProfile: context.viewState.locationMarkerUserProfile, mediaProvider: context.mediaProvider)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.overlay(alignment: .topTrailing) {
|
.overlay(alignment: .topTrailing) {
|
||||||
@@ -76,11 +76,11 @@ struct LocationSharingScreen: View {
|
|||||||
private var mapOptions: MapLibreMapView.Options {
|
private var mapOptions: MapLibreMapView.Options {
|
||||||
var annotations: [String: LocationAnnotation] = [:]
|
var annotations: [String: LocationAnnotation] = [:]
|
||||||
if !context.viewState.isLocationPickerMode {
|
if !context.viewState.isLocationPickerMode {
|
||||||
let id = context.viewState.staticLocationMarkerUserProfile?.userID ?? UUID().uuidString
|
let id = context.viewState.locationMarkerUserProfile?.userID ?? UUID().uuidString
|
||||||
let annotation = LocationAnnotation(id: id,
|
let annotation = LocationAnnotation(id: id,
|
||||||
coordinate: context.viewState.initialMapCenter,
|
coordinate: context.viewState.initialMapCenter,
|
||||||
anchorPoint: .bottomCenter) {
|
anchorPoint: .bottomCenter) {
|
||||||
LocationMarkerView(userProfile: context.viewState.staticLocationMarkerUserProfile, mediaProvider: context.mediaProvider)
|
LocationMarkerView(userProfile: context.viewState.locationMarkerUserProfile, mediaProvider: context.mediaProvider)
|
||||||
}
|
}
|
||||||
annotations[id] = annotation
|
annotations[id] = annotation
|
||||||
}
|
}
|
||||||
@@ -129,10 +129,10 @@ struct LocationSharingScreen: View {
|
|||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var shareSheet: some View {
|
private var shareSheet: some View {
|
||||||
let location = context.viewState.initialMapCenter
|
let location = context.viewState.initialMapCenter
|
||||||
let senderName = context.viewState.staticLocationMarkerUserProfile?.displayName ?? context.viewState.staticLocationMarkerUserProfile?.userID
|
let senderName = context.viewState.locationMarkerUserProfile?.displayName ?? context.viewState.locationMarkerUserProfile?.userID
|
||||||
AppActivityView(activityItems: [ShareToMapsAppActivity.MapsAppType.apple.activityURL(for: location, senderName: senderName)],
|
AppActivityView(activityItems: [ShareToMapsAppActivity.MapsAppType.apple.activityURL(for: location, senderName: senderName)],
|
||||||
applicationActivities: ShareToMapsAppActivity.MapsAppType.allCases.map { ShareToMapsAppActivity(type: $0, location: location, senderName: senderName) })
|
applicationActivities: ShareToMapsAppActivity.MapsAppType.allCases.map { ShareToMapsAppActivity(type: $0, location: location, senderName: senderName) })
|
||||||
.edgesIgnoringSafeArea(.bottom)
|
.ignoresSafeArea(edges: .bottom)
|
||||||
.presentationDetents([.medium, .large])
|
.presentationDetents([.medium, .large])
|
||||||
.presentationCompactAdaptation(shareSheetCompactPresentation)
|
.presentationCompactAdaptation(shareSheetCompactPresentation)
|
||||||
.presentationDragIndicator(.hidden)
|
.presentationDragIndicator(.hidden)
|
||||||
@@ -152,6 +152,8 @@ struct LocationSharingScreen: View {
|
|||||||
struct LocationSharingScreen_Previews: PreviewProvider, TestablePreview {
|
struct LocationSharingScreen_Previews: PreviewProvider, TestablePreview {
|
||||||
static let viewModel = LocationSharingScreenViewModel.mock(type: .staticSenderLocation)
|
static let viewModel = LocationSharingScreenViewModel.mock(type: .staticSenderLocation)
|
||||||
|
|
||||||
|
static let withoutLiveSharingViewModel = LocationSharingScreenViewModel.mock(type: .picker, liveLocationSharingEnabled: false)
|
||||||
|
|
||||||
static let pinViewModel = LocationSharingScreenViewModel.mock(type: .staticPinLocation)
|
static let pinViewModel = LocationSharingScreenViewModel.mock(type: .staticPinLocation)
|
||||||
|
|
||||||
static let pickerViewModel = LocationSharingScreenViewModel.mock(type: .picker)
|
static let pickerViewModel = LocationSharingScreenViewModel.mock(type: .picker)
|
||||||
@@ -162,6 +164,11 @@ struct LocationSharingScreen_Previews: PreviewProvider, TestablePreview {
|
|||||||
}
|
}
|
||||||
.previewDisplayName("Picker")
|
.previewDisplayName("Picker")
|
||||||
|
|
||||||
|
ElementNavigationStack {
|
||||||
|
LocationSharingScreen(context: withoutLiveSharingViewModel.context)
|
||||||
|
}
|
||||||
|
.previewDisplayName("Picker without live location sharing")
|
||||||
|
|
||||||
ElementNavigationStack {
|
ElementNavigationStack {
|
||||||
LocationSharingScreen(context: viewModel.context)
|
LocationSharingScreen(context: viewModel.context)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,11 @@ struct StaticLocationSheet: View {
|
|||||||
@Bindable var context: LocationSharingScreenViewModel.Context
|
@Bindable var context: LocationSharingScreenViewModel.Context
|
||||||
@State private var height = CGFloat.zero
|
@State private var height = CGFloat.zero
|
||||||
|
|
||||||
|
/// Fixes an iOS 26 sheet issue
|
||||||
|
/// if the content doesn't meet a certain size
|
||||||
|
/// additional insets are added.
|
||||||
|
private let additionalHeight: CGFloat = 14
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
mainContent
|
mainContent
|
||||||
.readHeight($height)
|
.readHeight($height)
|
||||||
@@ -19,19 +24,18 @@ struct StaticLocationSheet: View {
|
|||||||
.presentationBackground(.compound.bgCanvasDefault)
|
.presentationBackground(.compound.bgCanvasDefault)
|
||||||
.presentationBackgroundInteraction(.enabled)
|
.presentationBackgroundInteraction(.enabled)
|
||||||
.presentationDragIndicator(.hidden)
|
.presentationDragIndicator(.hidden)
|
||||||
.presentationDetents([.height(height)])
|
.presentationDetents([.height(height + additionalHeight)])
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
|
||||||
private var mainContent: some View {
|
private var mainContent: some View {
|
||||||
if case let .viewStatic(location) = context.viewState.interactionMode,
|
VStack(spacing: 0) {
|
||||||
let userProfile = context.viewState.userProfile {
|
Text(L10n.screenStaticLocationSheetTitle)
|
||||||
VStack(spacing: 0) {
|
.foregroundStyle(.compound.textPrimary)
|
||||||
Text(L10n.screenStaticLocationSheetTitle)
|
.font(.compound.bodyLGSemibold)
|
||||||
.foregroundStyle(.compound.textPrimary)
|
.padding(.bottom, 25)
|
||||||
.font(.compound.bodyLGSemibold)
|
.padding(.top, 29)
|
||||||
.padding(.top, 29)
|
if case let .viewStatic(location) = context.viewState.interactionMode,
|
||||||
.padding(.bottom, 25)
|
let userProfile = context.viewState.userProfile {
|
||||||
Button {
|
Button {
|
||||||
context.showShareSheet = true
|
context.showShareSheet = true
|
||||||
} label: {
|
} label: {
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user