From 81cc5fc5ec2568fd4385315b78706e450552f768 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 20 Jan 2026 18:07:56 +0100 Subject: [PATCH] implemented the space selection list and the selection logic # Conflicts: # ElementX/Sources/Screens/CreateRoomScreen/View/CreateRoomScreen.swift --- .../en-US.lproj/Localizable.strings | 4 ++ .../en.lproj/Localizable.strings | 4 ++ ElementX/Sources/Generated/Strings.swift | 8 +++ .../View/CreateRoomScreen.swift | 5 +- .../View/CreateRoomSpaceSelectionSheet.swift | 66 ++++++++++++++++++- 5 files changed, 84 insertions(+), 3 deletions(-) diff --git a/ElementX/Resources/Localizations/en-US.lproj/Localizable.strings b/ElementX/Resources/Localizations/en-US.lproj/Localizable.strings index 89de5a15f..dab73e8ba 100644 --- a/ElementX/Resources/Localizations/en-US.lproj/Localizable.strings +++ b/ElementX/Resources/Localizations/en-US.lproj/Localizable.strings @@ -85,6 +85,7 @@ "action_enable" = "Enable"; "action_end_poll" = "End poll"; "action_enter_pin" = "Enter PIN"; +"action_explore_public_spaces" = "Explore public spaces"; "action_finish" = "Finish"; "action_forgot_password" = "Forgot password?"; "action_forward" = "Forward"; @@ -553,6 +554,9 @@ "screen_create_room_room_address_section_footer" = "You’ll need an address in order to make it visible in the public directory."; "screen_create_room_room_address_section_title" = "Address"; "screen_create_room_room_visibility_section_title" = "Room visibility"; +"screen_create_room_space_selection_no_space_description" = "(no space)"; +"screen_create_room_space_selection_no_space_title" = "Home"; +"screen_create_room_space_selection_sheet_title" = "Add to space"; "screen_create_room_topic_placeholder" = "Add description…"; "screen_decline_and_block_block_user_option_description" = "You will not see any messages or room invites from this user"; "screen_decline_and_block_report_user_option_description" = "Report this room to your account provider."; diff --git a/ElementX/Resources/Localizations/en.lproj/Localizable.strings b/ElementX/Resources/Localizations/en.lproj/Localizable.strings index 78b106ba4..71c924cd9 100644 --- a/ElementX/Resources/Localizations/en.lproj/Localizable.strings +++ b/ElementX/Resources/Localizations/en.lproj/Localizable.strings @@ -85,6 +85,7 @@ "action_enable" = "Enable"; "action_end_poll" = "End poll"; "action_enter_pin" = "Enter PIN"; +"action_explore_public_spaces" = "Explore public spaces"; "action_finish" = "Finish"; "action_forgot_password" = "Forgot password?"; "action_forward" = "Forward"; @@ -553,6 +554,9 @@ "screen_create_room_room_address_section_footer" = "You’ll need an address in order to make it visible in the public directory."; "screen_create_room_room_address_section_title" = "Address"; "screen_create_room_room_visibility_section_title" = "Room visibility"; +"screen_create_room_space_selection_no_space_description" = "(no space)"; +"screen_create_room_space_selection_no_space_title" = "Home"; +"screen_create_room_space_selection_sheet_title" = "Add to space"; "screen_create_room_topic_placeholder" = "Add description…"; "screen_decline_and_block_block_user_option_description" = "You will not see any messages or room invites from this user"; "screen_decline_and_block_report_user_option_description" = "Report this room to your account provider."; diff --git a/ElementX/Sources/Generated/Strings.swift b/ElementX/Sources/Generated/Strings.swift index cc5d4e524..76ff00fe8 100644 --- a/ElementX/Sources/Generated/Strings.swift +++ b/ElementX/Sources/Generated/Strings.swift @@ -204,6 +204,8 @@ internal enum L10n { internal static var actionEndPoll: String { return L10n.tr("Localizable", "action_end_poll") } /// Enter PIN internal static var actionEnterPin: String { return L10n.tr("Localizable", "action_enter_pin") } + /// Explore public spaces + internal static var actionExplorePublicSpaces: String { return L10n.tr("Localizable", "action_explore_public_spaces") } /// Finish internal static var actionFinish: String { return L10n.tr("Localizable", "action_finish") } /// Forgot password? @@ -1634,6 +1636,12 @@ internal enum L10n { internal static var screenCreateRoomRoomAddressSectionTitle: String { return L10n.tr("Localizable", "screen_create_room_room_address_section_title") } /// Room visibility internal static var screenCreateRoomRoomVisibilitySectionTitle: String { return L10n.tr("Localizable", "screen_create_room_room_visibility_section_title") } + /// (no space) + internal static var screenCreateRoomSpaceSelectionNoSpaceDescription: String { return L10n.tr("Localizable", "screen_create_room_space_selection_no_space_description") } + /// Home + internal static var screenCreateRoomSpaceSelectionNoSpaceTitle: String { return L10n.tr("Localizable", "screen_create_room_space_selection_no_space_title") } + /// Add to space + internal static var screenCreateRoomSpaceSelectionSheetTitle: String { return L10n.tr("Localizable", "screen_create_room_space_selection_sheet_title") } /// Topic (optional) internal static var screenCreateRoomTopicLabel: String { return L10n.tr("Localizable", "screen_create_room_topic_label") } /// Add description… diff --git a/ElementX/Sources/Screens/CreateRoomScreen/View/CreateRoomScreen.swift b/ElementX/Sources/Screens/CreateRoomScreen/View/CreateRoomScreen.swift index 27edb6dfe..c71cdd422 100644 --- a/ElementX/Sources/Screens/CreateRoomScreen/View/CreateRoomScreen.swift +++ b/ElementX/Sources/Screens/CreateRoomScreen/View/CreateRoomScreen.swift @@ -234,7 +234,10 @@ struct CreateRoomScreen: View { context.showSpaceSelectionSheet = true }) } else { - ListRow(label: .default(title: "Test", icon: \.home), + ListRow(label: .default(title: L10n.screenCreateRoomSpaceSelectionNoSpaceTitle, + description: L10n.screenCreateRoomSpaceSelectionNoSpaceDescription, + icon: \.home, + iconAlignment: .top), kind: .navigationLink { context.showSpaceSelectionSheet = true }) diff --git a/ElementX/Sources/Screens/CreateRoomScreen/View/CreateRoomSpaceSelectionSheet.swift b/ElementX/Sources/Screens/CreateRoomScreen/View/CreateRoomSpaceSelectionSheet.swift index 6b2d09ea5..2ad51faac 100644 --- a/ElementX/Sources/Screens/CreateRoomScreen/View/CreateRoomSpaceSelectionSheet.swift +++ b/ElementX/Sources/Screens/CreateRoomScreen/View/CreateRoomSpaceSelectionSheet.swift @@ -5,18 +5,80 @@ // Please see LICENSE files in the repository root for full details. // +import Compound import SwiftUI struct CreateRoomSpaceSelectionSheet: View { @ObservedObject var context: CreateRoomScreenViewModel.Context + @Environment(\.dismiss) private var dismiss + + private var dragIndicatorVisibilty: Visibility { + if #available(iOS 26, *) { + .hidden + } else { + .automatic + } + } var body: some View { - EmptyView() + NavigationStack { + List { + Section { + ListRow(label: .default(title: L10n.screenCreateRoomSpaceSelectionNoSpaceTitle, + description: L10n.screenCreateRoomSpaceSelectionNoSpaceDescription, + icon: \.home), + kind: .selection(isSelected: context.selectedSpace == nil) { + context.selectedSpace = nil + dismiss() + }) + ForEach(context.viewState.topLevelSpaces, id: \.id) { space in + ListRow(label: .avatar(title: space.name, + description: space.canonicalAlias, + icon: RoomAvatarImage(avatar: space.avatar, + avatarSize: .room(on: .createRoomSelectSpace), + mediaProvider: context.mediaProvider)), + kind: .selection(isSelected: context.selectedSpace?.id == space.id) { + context.selectedSpace = space + dismiss() + }) + } + } + } + .listStyle(.plain) + .environment(\.defaultMinListRowHeight, 66) + .scrollContentBackground(.hidden) + .background(Color.compound.bgCanvasDefault.ignoresSafeArea()) + .navigationTitle(L10n.screenCreateRoomSpaceSelectionSheetTitle) + .navigationBarTitleDisplayMode(.inline) + .toolbar { + ToolbarItem(placement: .topBarTrailing) { + ToolbarButton(role: .cancel) { + dismiss() + } + } + } + .presentationDetents([.medium, .large]) + .presentationDragIndicator(dragIndicatorVisibilty) + } } } struct CreateRoomSpaceSelectionSheet_Previews: PreviewProvider, TestablePreview { + static let viewModel = { + let clientProxy = ClientProxyMock(.init(userID: "@userid:example.com")) + clientProxy.spaceService = SpaceServiceProxyMock(.init(topLevelSpaces: .mockJoinedSpaces2)) + let userSession = UserSessionMock(.init(clientProxy: clientProxy)) + + return CreateRoomScreenViewModel(isSpace: false, + spaceSelectionMode: .list, + shouldShowCancelButton: false, + userSession: userSession, + analytics: ServiceLocator.shared.analytics, + userIndicatorController: UserIndicatorControllerMock(), + appSettings: ServiceLocator.shared.settings) + }() + static var previews: some View { - EmptyView() + CreateRoomSpaceSelectionSheet(context: viewModel.context) } }