mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-05 11:58:32 +00:00
Create room redesign and refactor (#4942)
This commit is contained in:
@@ -9855,7 +9855,7 @@
|
|||||||
repositoryURL = "https://github.com/pointfreeco/swift-snapshot-testing";
|
repositoryURL = "https://github.com/pointfreeco/swift-snapshot-testing";
|
||||||
requirement = {
|
requirement = {
|
||||||
kind = upToNextMinorVersion;
|
kind = upToNextMinorVersion;
|
||||||
minimumVersion = 1.18.3;
|
minimumVersion = 1.18.7;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
EC6D0C817B1C21D9D096505A /* XCRemoteSwiftPackageReference "Version" */ = {
|
EC6D0C817B1C21D9D096505A /* XCRemoteSwiftPackageReference "Version" */ = {
|
||||||
|
|||||||
@@ -532,18 +532,21 @@
|
|||||||
"screen_create_poll_remove_accessibility_label" = "Remove %1$@";
|
"screen_create_poll_remove_accessibility_label" = "Remove %1$@";
|
||||||
"screen_create_poll_settings_section_title" = "Settings";
|
"screen_create_poll_settings_section_title" = "Settings";
|
||||||
"screen_create_room_error_creating_space" = "The space could not be created because of an unknown error. Try again later.";
|
"screen_create_room_error_creating_space" = "The space could not be created because of an unknown error. Try again later.";
|
||||||
|
"screen_create_room_name_placeholder" = "Add name…";
|
||||||
|
"screen_create_room_new_room_title" = "New room";
|
||||||
"screen_create_room_new_space_title" = "New space";
|
"screen_create_room_new_space_title" = "New space";
|
||||||
"screen_create_room_public_option_short_description" = "Anyone can join.";
|
"screen_create_room_public_option_short_description" = "Anyone can join.";
|
||||||
"screen_create_room_room_access_section_anyone_option_description" = "Anyone can join.";
|
|
||||||
"screen_create_room_room_access_section_anyone_option_title" = "Anyone";
|
|
||||||
"screen_create_room_room_access_section_header" = "Room Access";
|
|
||||||
"screen_create_room_room_access_section_knocking_option_description" = "Anyone can ask to join but an administrator or a moderator must accept the request.";
|
"screen_create_room_room_access_section_knocking_option_description" = "Anyone can ask to join but an administrator or a moderator must accept the request.";
|
||||||
"screen_create_room_room_access_section_knocking_option_title" = "Ask to join";
|
"screen_create_room_room_access_section_knocking_option_title" = "Allow ask to join";
|
||||||
|
"screen_create_room_room_access_section_private_option_description" = "Only people invited can join.";
|
||||||
|
"screen_create_room_room_access_section_private_option_title" = "Private";
|
||||||
|
"screen_create_room_room_access_section_public_option_description" = "Anyone can join.";
|
||||||
|
"screen_create_room_room_access_section_public_option_title" = "Public";
|
||||||
"screen_create_room_room_access_section_title" = "Who has access";
|
"screen_create_room_room_access_section_title" = "Who has access";
|
||||||
"screen_create_room_room_address_section_footer" = "In order for this room to be visible in the public room directory, you will need a room address.";
|
"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" = "Room address";
|
"screen_create_room_room_address_section_title" = "Address";
|
||||||
"screen_create_room_room_visibility_section_title" = "Room visibility";
|
"screen_create_room_room_visibility_section_title" = "Room visibility";
|
||||||
"screen_create_room_title_new_space" = "New 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_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.";
|
"screen_decline_and_block_report_user_option_description" = "Report this room to your account provider.";
|
||||||
"screen_edit_room_address_room_address_section_footer" = "You’ll need an address in order to make it visible in the public directory.";
|
"screen_edit_room_address_room_address_section_footer" = "You’ll need an address in order to make it visible in the public directory.";
|
||||||
@@ -681,6 +684,7 @@
|
|||||||
"screen_security_and_privacy_add_room_address_action" = "Add address";
|
"screen_security_and_privacy_add_room_address_action" = "Add address";
|
||||||
"screen_security_and_privacy_ask_to_join_multiple_spaces_members_option_description" = "Anyone in authorized spaces can join, but everyone else must request access.";
|
"screen_security_and_privacy_ask_to_join_multiple_spaces_members_option_description" = "Anyone in authorized spaces can join, but everyone else must request access.";
|
||||||
"screen_security_and_privacy_ask_to_join_option_description" = "Everyone must request access.";
|
"screen_security_and_privacy_ask_to_join_option_description" = "Everyone must request access.";
|
||||||
|
"screen_security_and_privacy_ask_to_join_option_title" = "Ask to join";
|
||||||
"screen_security_and_privacy_ask_to_join_single_space_members_option_description" = "Anyone in %1$@ can join, but everyone else must request access.";
|
"screen_security_and_privacy_ask_to_join_single_space_members_option_description" = "Anyone in %1$@ can join, but everyone else must request access.";
|
||||||
"screen_security_and_privacy_enable_encryption_alert_confirm_button_title" = "Yes, enable encryption";
|
"screen_security_and_privacy_enable_encryption_alert_confirm_button_title" = "Yes, enable encryption";
|
||||||
"screen_security_and_privacy_enable_encryption_alert_description" = "Once enabled, encryption for a room cannot be disabled, Message history will only be visible for room members since they were invited or since they joined the room.\nNo one besides the room members will be able to read messages. This may prevent bots and bridges to work correctly.\nWe do not recommend enabling encryption for rooms that anyone can find and join.";
|
"screen_security_and_privacy_enable_encryption_alert_description" = "Once enabled, encryption for a room cannot be disabled, Message history will only be visible for room members since they were invited or since they joined the room.\nNo one besides the room members will be able to read messages. This may prevent bots and bridges to work correctly.\nWe do not recommend enabling encryption for rooms that anyone can find and join.";
|
||||||
@@ -688,6 +692,7 @@
|
|||||||
"screen_security_and_privacy_encryption_section_footer" = "Once enabled, encryption cannot be disabled.";
|
"screen_security_and_privacy_encryption_section_footer" = "Once enabled, encryption cannot be disabled.";
|
||||||
"screen_security_and_privacy_encryption_toggle_title" = "Enable end-to-end encryption";
|
"screen_security_and_privacy_encryption_toggle_title" = "Enable end-to-end encryption";
|
||||||
"screen_security_and_privacy_room_access_anyone_option_description" = "Anyone can join.";
|
"screen_security_and_privacy_room_access_anyone_option_description" = "Anyone can join.";
|
||||||
|
"screen_security_and_privacy_room_access_anyone_option_title" = "Anyone";
|
||||||
"screen_security_and_privacy_room_access_footer" = "Choose which spaces’ members can join this room without an invitation. %1$@";
|
"screen_security_and_privacy_room_access_footer" = "Choose which spaces’ members can join this room without an invitation. %1$@";
|
||||||
"screen_security_and_privacy_room_access_invite_only_option_description" = "Only invited people can join.";
|
"screen_security_and_privacy_room_access_invite_only_option_description" = "Only invited people can join.";
|
||||||
"screen_security_and_privacy_room_access_invite_only_option_title" = "Invite only";
|
"screen_security_and_privacy_room_access_invite_only_option_title" = "Invite only";
|
||||||
@@ -1424,9 +1429,7 @@
|
|||||||
"screen_room_details_profile_row_title" = "Profile";
|
"screen_room_details_profile_row_title" = "Profile";
|
||||||
"screen_room_details_security_and_privacy_title" = "Security & privacy";
|
"screen_room_details_security_and_privacy_title" = "Security & privacy";
|
||||||
"screen_roomlist_knock_event_sent_description" = "Request to join sent";
|
"screen_roomlist_knock_event_sent_description" = "Request to join sent";
|
||||||
"screen_security_and_privacy_ask_to_join_option_title" = "Ask to join";
|
|
||||||
"screen_security_and_privacy_encryption_section_header" = "Encryption";
|
"screen_security_and_privacy_encryption_section_header" = "Encryption";
|
||||||
"screen_security_and_privacy_room_access_anyone_option_title" = "Anyone";
|
|
||||||
"screen_security_and_privacy_room_access_footer_manage_spaces_action" = "Manage spaces";
|
"screen_security_and_privacy_room_access_footer_manage_spaces_action" = "Manage spaces";
|
||||||
"screen_security_and_privacy_room_address_section_footer" = "You’ll need an address in order to make it visible in the public directory.";
|
"screen_security_and_privacy_room_address_section_footer" = "You’ll need an address in order to make it visible in the public directory.";
|
||||||
"screen_space_settings_leave_space" = "Leave space";
|
"screen_space_settings_leave_space" = "Leave space";
|
||||||
@@ -1447,8 +1450,6 @@
|
|||||||
"screen_create_account_title" = "Create account";
|
"screen_create_account_title" = "Create account";
|
||||||
"screen_create_poll_cancel_confirmation_content_ios" = "Your changes won’t be saved";
|
"screen_create_poll_cancel_confirmation_content_ios" = "Your changes won’t be saved";
|
||||||
"screen_create_room_add_people_title" = "Invite people";
|
"screen_create_room_add_people_title" = "Invite people";
|
||||||
"screen_create_room_room_name_label" = "Room name";
|
|
||||||
"screen_create_room_title" = "Create a room";
|
|
||||||
"screen_deactivate_account_title" = "Deactivate account";
|
"screen_deactivate_account_title" = "Deactivate account";
|
||||||
"screen_dm_details_block_alert_action" = "Block";
|
"screen_dm_details_block_alert_action" = "Block";
|
||||||
"screen_dm_details_block_alert_description" = "Blocked users won't be able to send you messages and all their messages will be hidden. You can unblock them anytime.";
|
"screen_dm_details_block_alert_description" = "Blocked users won't be able to send you messages and all their messages will be hidden. You can unblock them anytime.";
|
||||||
|
|||||||
@@ -532,18 +532,21 @@
|
|||||||
"screen_create_poll_remove_accessibility_label" = "Remove %1$@";
|
"screen_create_poll_remove_accessibility_label" = "Remove %1$@";
|
||||||
"screen_create_poll_settings_section_title" = "Settings";
|
"screen_create_poll_settings_section_title" = "Settings";
|
||||||
"screen_create_room_error_creating_space" = "The space could not be created because of an unknown error. Try again later.";
|
"screen_create_room_error_creating_space" = "The space could not be created because of an unknown error. Try again later.";
|
||||||
|
"screen_create_room_name_placeholder" = "Add name…";
|
||||||
|
"screen_create_room_new_room_title" = "New room";
|
||||||
"screen_create_room_new_space_title" = "New space";
|
"screen_create_room_new_space_title" = "New space";
|
||||||
"screen_create_room_public_option_short_description" = "Anyone can join.";
|
"screen_create_room_public_option_short_description" = "Anyone can join.";
|
||||||
"screen_create_room_room_access_section_anyone_option_description" = "Anyone can join.";
|
|
||||||
"screen_create_room_room_access_section_anyone_option_title" = "Anyone";
|
|
||||||
"screen_create_room_room_access_section_header" = "Room Access";
|
|
||||||
"screen_create_room_room_access_section_knocking_option_description" = "Anyone can ask to join but an administrator or a moderator must accept the request.";
|
"screen_create_room_room_access_section_knocking_option_description" = "Anyone can ask to join but an administrator or a moderator must accept the request.";
|
||||||
"screen_create_room_room_access_section_knocking_option_title" = "Ask to join";
|
"screen_create_room_room_access_section_knocking_option_title" = "Allow ask to join";
|
||||||
|
"screen_create_room_room_access_section_private_option_description" = "Only people invited can join.";
|
||||||
|
"screen_create_room_room_access_section_private_option_title" = "Private";
|
||||||
|
"screen_create_room_room_access_section_public_option_description" = "Anyone can join.";
|
||||||
|
"screen_create_room_room_access_section_public_option_title" = "Public";
|
||||||
"screen_create_room_room_access_section_title" = "Who has access";
|
"screen_create_room_room_access_section_title" = "Who has access";
|
||||||
"screen_create_room_room_address_section_footer" = "In order for this room to be visible in the public room directory, you will need a room address.";
|
"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" = "Room address";
|
"screen_create_room_room_address_section_title" = "Address";
|
||||||
"screen_create_room_room_visibility_section_title" = "Room visibility";
|
"screen_create_room_room_visibility_section_title" = "Room visibility";
|
||||||
"screen_create_room_title_new_space" = "New 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_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.";
|
"screen_decline_and_block_report_user_option_description" = "Report this room to your account provider.";
|
||||||
"screen_edit_room_address_room_address_section_footer" = "You’ll need an address in order to make it visible in the public directory.";
|
"screen_edit_room_address_room_address_section_footer" = "You’ll need an address in order to make it visible in the public directory.";
|
||||||
@@ -681,6 +684,7 @@
|
|||||||
"screen_security_and_privacy_add_room_address_action" = "Add address";
|
"screen_security_and_privacy_add_room_address_action" = "Add address";
|
||||||
"screen_security_and_privacy_ask_to_join_multiple_spaces_members_option_description" = "Anyone in authorised spaces can join, but everyone else must request access.";
|
"screen_security_and_privacy_ask_to_join_multiple_spaces_members_option_description" = "Anyone in authorised spaces can join, but everyone else must request access.";
|
||||||
"screen_security_and_privacy_ask_to_join_option_description" = "Everyone must request access.";
|
"screen_security_and_privacy_ask_to_join_option_description" = "Everyone must request access.";
|
||||||
|
"screen_security_and_privacy_ask_to_join_option_title" = "Ask to join";
|
||||||
"screen_security_and_privacy_ask_to_join_single_space_members_option_description" = "Anyone in %1$@ can join, but everyone else must request access.";
|
"screen_security_and_privacy_ask_to_join_single_space_members_option_description" = "Anyone in %1$@ can join, but everyone else must request access.";
|
||||||
"screen_security_and_privacy_enable_encryption_alert_confirm_button_title" = "Yes, enable encryption";
|
"screen_security_and_privacy_enable_encryption_alert_confirm_button_title" = "Yes, enable encryption";
|
||||||
"screen_security_and_privacy_enable_encryption_alert_description" = "Once enabled, encryption for a room cannot be disabled, Message history will only be visible for room members since they were invited or since they joined the room.\nNo one besides the room members will be able to read messages. This may prevent bots and bridges to work correctly.\nWe do not recommend enabling encryption for rooms that anyone can find and join.";
|
"screen_security_and_privacy_enable_encryption_alert_description" = "Once enabled, encryption for a room cannot be disabled, Message history will only be visible for room members since they were invited or since they joined the room.\nNo one besides the room members will be able to read messages. This may prevent bots and bridges to work correctly.\nWe do not recommend enabling encryption for rooms that anyone can find and join.";
|
||||||
@@ -688,6 +692,7 @@
|
|||||||
"screen_security_and_privacy_encryption_section_footer" = "Once enabled, encryption cannot be disabled.";
|
"screen_security_and_privacy_encryption_section_footer" = "Once enabled, encryption cannot be disabled.";
|
||||||
"screen_security_and_privacy_encryption_toggle_title" = "Enable end-to-end encryption";
|
"screen_security_and_privacy_encryption_toggle_title" = "Enable end-to-end encryption";
|
||||||
"screen_security_and_privacy_room_access_anyone_option_description" = "Anyone can join.";
|
"screen_security_and_privacy_room_access_anyone_option_description" = "Anyone can join.";
|
||||||
|
"screen_security_and_privacy_room_access_anyone_option_title" = "Anyone";
|
||||||
"screen_security_and_privacy_room_access_footer" = "Choose which spaces’ members can join this room without an invitation. %1$@";
|
"screen_security_and_privacy_room_access_footer" = "Choose which spaces’ members can join this room without an invitation. %1$@";
|
||||||
"screen_security_and_privacy_room_access_invite_only_option_description" = "Only invited people can join.";
|
"screen_security_and_privacy_room_access_invite_only_option_description" = "Only invited people can join.";
|
||||||
"screen_security_and_privacy_room_access_invite_only_option_title" = "Invite only";
|
"screen_security_and_privacy_room_access_invite_only_option_title" = "Invite only";
|
||||||
@@ -1424,9 +1429,7 @@
|
|||||||
"screen_room_details_profile_row_title" = "Profile";
|
"screen_room_details_profile_row_title" = "Profile";
|
||||||
"screen_room_details_security_and_privacy_title" = "Security & privacy";
|
"screen_room_details_security_and_privacy_title" = "Security & privacy";
|
||||||
"screen_roomlist_knock_event_sent_description" = "Request to join sent";
|
"screen_roomlist_knock_event_sent_description" = "Request to join sent";
|
||||||
"screen_security_and_privacy_ask_to_join_option_title" = "Ask to join";
|
|
||||||
"screen_security_and_privacy_encryption_section_header" = "Encryption";
|
"screen_security_and_privacy_encryption_section_header" = "Encryption";
|
||||||
"screen_security_and_privacy_room_access_anyone_option_title" = "Anyone";
|
|
||||||
"screen_security_and_privacy_room_access_footer_manage_spaces_action" = "Manage spaces";
|
"screen_security_and_privacy_room_access_footer_manage_spaces_action" = "Manage spaces";
|
||||||
"screen_security_and_privacy_room_address_section_footer" = "You’ll need an address in order to make it visible in the public directory.";
|
"screen_security_and_privacy_room_address_section_footer" = "You’ll need an address in order to make it visible in the public directory.";
|
||||||
"screen_space_settings_leave_space" = "Leave space";
|
"screen_space_settings_leave_space" = "Leave space";
|
||||||
@@ -1447,8 +1450,6 @@
|
|||||||
"screen_create_account_title" = "Create account";
|
"screen_create_account_title" = "Create account";
|
||||||
"screen_create_poll_cancel_confirmation_content_ios" = "Your changes won’t be saved";
|
"screen_create_poll_cancel_confirmation_content_ios" = "Your changes won’t be saved";
|
||||||
"screen_create_room_add_people_title" = "Invite people";
|
"screen_create_room_add_people_title" = "Invite people";
|
||||||
"screen_create_room_room_name_label" = "Room name";
|
|
||||||
"screen_create_room_title" = "Create a room";
|
|
||||||
"screen_deactivate_account_title" = "Deactivate account";
|
"screen_deactivate_account_title" = "Deactivate account";
|
||||||
"screen_dm_details_block_alert_action" = "Block";
|
"screen_dm_details_block_alert_action" = "Block";
|
||||||
"screen_dm_details_block_alert_description" = "Blocked users won't be able to send you messages and all their messages will be hidden. You can unblock them anytime.";
|
"screen_dm_details_block_alert_description" = "Blocked users won't be able to send you messages and all their messages will be hidden. You can unblock them anytime.";
|
||||||
|
|||||||
@@ -567,7 +567,8 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
|
|
||||||
private func startStartChatFlow(animated: Bool) {
|
private func startStartChatFlow(animated: Bool) {
|
||||||
let navigationStackCoordinator = NavigationStackCoordinator()
|
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||||
let coordinator = StartChatFlowCoordinator(userDiscoveryService: UserDiscoveryService(clientProxy: userSession.clientProxy),
|
let coordinator = StartChatFlowCoordinator(isSpace: false,
|
||||||
|
userDiscoveryService: UserDiscoveryService(clientProxy: userSession.clientProxy),
|
||||||
navigationStackCoordinator: navigationStackCoordinator,
|
navigationStackCoordinator: navigationStackCoordinator,
|
||||||
flowParameters: flowParameters)
|
flowParameters: flowParameters)
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ enum StartChatFlowCoordinatorAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class StartChatFlowCoordinator: FlowCoordinatorProtocol {
|
class StartChatFlowCoordinator: FlowCoordinatorProtocol {
|
||||||
|
private let isSpace: Bool
|
||||||
private let userDiscoveryService: UserDiscoveryServiceProtocol
|
private let userDiscoveryService: UserDiscoveryServiceProtocol
|
||||||
private let navigationStackCoordinator: NavigationStackCoordinator
|
private let navigationStackCoordinator: NavigationStackCoordinator
|
||||||
|
|
||||||
@@ -63,9 +64,11 @@ class StartChatFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
actionsSubject.eraseToAnyPublisher()
|
actionsSubject.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
init(userDiscoveryService: UserDiscoveryServiceProtocol,
|
init(isSpace: Bool,
|
||||||
|
userDiscoveryService: UserDiscoveryServiceProtocol,
|
||||||
navigationStackCoordinator: NavigationStackCoordinator,
|
navigationStackCoordinator: NavigationStackCoordinator,
|
||||||
flowParameters: CommonFlowParameters) {
|
flowParameters: CommonFlowParameters) {
|
||||||
|
self.isSpace = isSpace
|
||||||
self.userDiscoveryService = userDiscoveryService
|
self.userDiscoveryService = userDiscoveryService
|
||||||
self.navigationStackCoordinator = navigationStackCoordinator
|
self.navigationStackCoordinator = navigationStackCoordinator
|
||||||
|
|
||||||
@@ -168,7 +171,8 @@ class StartChatFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func presentCreateRoomScreen() {
|
private func presentCreateRoomScreen() {
|
||||||
let createParameters = CreateRoomScreenCoordinatorParameters(userSession: flowParameters.userSession,
|
let createParameters = CreateRoomScreenCoordinatorParameters(isSpace: isSpace,
|
||||||
|
userSession: flowParameters.userSession,
|
||||||
userIndicatorController: flowParameters.userIndicatorController,
|
userIndicatorController: flowParameters.userIndicatorController,
|
||||||
appSettings: flowParameters.appSettings,
|
appSettings: flowParameters.appSettings,
|
||||||
analytics: flowParameters.analytics)
|
analytics: flowParameters.analytics)
|
||||||
|
|||||||
@@ -1571,6 +1571,10 @@ internal enum L10n {
|
|||||||
internal static var screenCreateRoomErrorCreatingRoom: String { return L10n.tr("Localizable", "screen_create_room_error_creating_room") }
|
internal static var screenCreateRoomErrorCreatingRoom: String { return L10n.tr("Localizable", "screen_create_room_error_creating_room") }
|
||||||
/// The space could not be created because of an unknown error. Try again later.
|
/// The space could not be created because of an unknown error. Try again later.
|
||||||
internal static var screenCreateRoomErrorCreatingSpace: String { return L10n.tr("Localizable", "screen_create_room_error_creating_space") }
|
internal static var screenCreateRoomErrorCreatingSpace: String { return L10n.tr("Localizable", "screen_create_room_error_creating_space") }
|
||||||
|
/// Add name…
|
||||||
|
internal static var screenCreateRoomNamePlaceholder: String { return L10n.tr("Localizable", "screen_create_room_name_placeholder") }
|
||||||
|
/// New room
|
||||||
|
internal static var screenCreateRoomNewRoomTitle: String { return L10n.tr("Localizable", "screen_create_room_new_room_title") }
|
||||||
/// New space
|
/// New space
|
||||||
internal static var screenCreateRoomNewSpaceTitle: String { return L10n.tr("Localizable", "screen_create_room_new_space_title") }
|
internal static var screenCreateRoomNewSpaceTitle: String { return L10n.tr("Localizable", "screen_create_room_new_space_title") }
|
||||||
/// Only people invited can join.
|
/// Only people invited can join.
|
||||||
@@ -1584,32 +1588,30 @@ internal enum L10n {
|
|||||||
internal static var screenCreateRoomPublicOptionShortDescription: String { return L10n.tr("Localizable", "screen_create_room_public_option_short_description") }
|
internal static var screenCreateRoomPublicOptionShortDescription: String { return L10n.tr("Localizable", "screen_create_room_public_option_short_description") }
|
||||||
/// Public
|
/// Public
|
||||||
internal static var screenCreateRoomPublicOptionTitle: String { return L10n.tr("Localizable", "screen_create_room_public_option_title") }
|
internal static var screenCreateRoomPublicOptionTitle: String { return L10n.tr("Localizable", "screen_create_room_public_option_title") }
|
||||||
/// Anyone can join.
|
|
||||||
internal static var screenCreateRoomRoomAccessSectionAnyoneOptionDescription: String { return L10n.tr("Localizable", "screen_create_room_room_access_section_anyone_option_description") }
|
|
||||||
/// Anyone
|
|
||||||
internal static var screenCreateRoomRoomAccessSectionAnyoneOptionTitle: String { return L10n.tr("Localizable", "screen_create_room_room_access_section_anyone_option_title") }
|
|
||||||
/// Room Access
|
|
||||||
internal static var screenCreateRoomRoomAccessSectionHeader: String { return L10n.tr("Localizable", "screen_create_room_room_access_section_header") }
|
|
||||||
/// Anyone can ask to join but an administrator or a moderator must accept the request.
|
/// Anyone can ask to join but an administrator or a moderator must accept the request.
|
||||||
internal static var screenCreateRoomRoomAccessSectionKnockingOptionDescription: String { return L10n.tr("Localizable", "screen_create_room_room_access_section_knocking_option_description") }
|
internal static var screenCreateRoomRoomAccessSectionKnockingOptionDescription: String { return L10n.tr("Localizable", "screen_create_room_room_access_section_knocking_option_description") }
|
||||||
/// Ask to join
|
/// Allow ask to join
|
||||||
internal static var screenCreateRoomRoomAccessSectionKnockingOptionTitle: String { return L10n.tr("Localizable", "screen_create_room_room_access_section_knocking_option_title") }
|
internal static var screenCreateRoomRoomAccessSectionKnockingOptionTitle: String { return L10n.tr("Localizable", "screen_create_room_room_access_section_knocking_option_title") }
|
||||||
|
/// Only people invited can join.
|
||||||
|
internal static var screenCreateRoomRoomAccessSectionPrivateOptionDescription: String { return L10n.tr("Localizable", "screen_create_room_room_access_section_private_option_description") }
|
||||||
|
/// Private
|
||||||
|
internal static var screenCreateRoomRoomAccessSectionPrivateOptionTitle: String { return L10n.tr("Localizable", "screen_create_room_room_access_section_private_option_title") }
|
||||||
|
/// Anyone can join.
|
||||||
|
internal static var screenCreateRoomRoomAccessSectionPublicOptionDescription: String { return L10n.tr("Localizable", "screen_create_room_room_access_section_public_option_description") }
|
||||||
|
/// Public
|
||||||
|
internal static var screenCreateRoomRoomAccessSectionPublicOptionTitle: String { return L10n.tr("Localizable", "screen_create_room_room_access_section_public_option_title") }
|
||||||
/// Who has access
|
/// Who has access
|
||||||
internal static var screenCreateRoomRoomAccessSectionTitle: String { return L10n.tr("Localizable", "screen_create_room_room_access_section_title") }
|
internal static var screenCreateRoomRoomAccessSectionTitle: String { return L10n.tr("Localizable", "screen_create_room_room_access_section_title") }
|
||||||
/// In order for this room to be visible in the public room directory, you will need a room address.
|
/// You’ll need an address in order to make it visible in the public directory.
|
||||||
internal static var screenCreateRoomRoomAddressSectionFooter: String { return L10n.tr("Localizable", "screen_create_room_room_address_section_footer") }
|
internal static var screenCreateRoomRoomAddressSectionFooter: String { return L10n.tr("Localizable", "screen_create_room_room_address_section_footer") }
|
||||||
/// Room address
|
/// Address
|
||||||
internal static var screenCreateRoomRoomAddressSectionTitle: String { return L10n.tr("Localizable", "screen_create_room_room_address_section_title") }
|
internal static var screenCreateRoomRoomAddressSectionTitle: String { return L10n.tr("Localizable", "screen_create_room_room_address_section_title") }
|
||||||
/// Room name
|
|
||||||
internal static var screenCreateRoomRoomNameLabel: String { return L10n.tr("Localizable", "screen_create_room_room_name_label") }
|
|
||||||
/// Room visibility
|
/// Room visibility
|
||||||
internal static var screenCreateRoomRoomVisibilitySectionTitle: String { return L10n.tr("Localizable", "screen_create_room_room_visibility_section_title") }
|
internal static var screenCreateRoomRoomVisibilitySectionTitle: String { return L10n.tr("Localizable", "screen_create_room_room_visibility_section_title") }
|
||||||
/// Create a room
|
|
||||||
internal static var screenCreateRoomTitle: String { return L10n.tr("Localizable", "screen_create_room_title") }
|
|
||||||
/// New space
|
|
||||||
internal static var screenCreateRoomTitleNewSpace: String { return L10n.tr("Localizable", "screen_create_room_title_new_space") }
|
|
||||||
/// Topic (optional)
|
/// Topic (optional)
|
||||||
internal static var screenCreateRoomTopicLabel: String { return L10n.tr("Localizable", "screen_create_room_topic_label") }
|
internal static var screenCreateRoomTopicLabel: String { return L10n.tr("Localizable", "screen_create_room_topic_label") }
|
||||||
|
/// Add description…
|
||||||
|
internal static var screenCreateRoomTopicPlaceholder: String { return L10n.tr("Localizable", "screen_create_room_topic_placeholder") }
|
||||||
/// Please confirm that you want to deactivate your account. This action cannot be undone.
|
/// Please confirm that you want to deactivate your account. This action cannot be undone.
|
||||||
internal static var screenDeactivateAccountConfirmationDialogContent: String { return L10n.tr("Localizable", "screen_deactivate_account_confirmation_dialog_content") }
|
internal static var screenDeactivateAccountConfirmationDialogContent: String { return L10n.tr("Localizable", "screen_deactivate_account_confirmation_dialog_content") }
|
||||||
/// Delete all my messages
|
/// Delete all my messages
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ extension ClientProxyMock {
|
|||||||
canDeactivateAccount = false
|
canDeactivateAccount = false
|
||||||
directRoomForUserIDReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
directRoomForUserIDReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||||
createDirectRoomWithExpectedRoomNameReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
createDirectRoomWithExpectedRoomNameReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||||
createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||||
canJoinRoomWithReturnValue = true
|
canJoinRoomWithReturnValue = true
|
||||||
joinRoomViaClosure = { roomID, _ in
|
joinRoomViaClosure = { roomID, _ in
|
||||||
configuration.overrides.joinedRoomIDs.insert(roomID)
|
configuration.overrides.joinedRoomIDs.insert(roomID)
|
||||||
|
|||||||
@@ -2847,15 +2847,15 @@ class ClientProxyMock: ClientProxyProtocol, @unchecked Sendable {
|
|||||||
}
|
}
|
||||||
//MARK: - createRoom
|
//MARK: - createRoom
|
||||||
|
|
||||||
var createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartUnderlyingCallsCount = 0
|
var createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartUnderlyingCallsCount = 0
|
||||||
var createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartCallsCount: Int {
|
var createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartCallsCount: Int {
|
||||||
get {
|
get {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
return createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartUnderlyingCallsCount
|
return createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartUnderlyingCallsCount
|
||||||
} else {
|
} else {
|
||||||
var returnValue: Int? = nil
|
var returnValue: Int? = nil
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
returnValue = createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartUnderlyingCallsCount
|
returnValue = createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartUnderlyingCallsCount
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnValue!
|
return returnValue!
|
||||||
@@ -2863,29 +2863,29 @@ class ClientProxyMock: ClientProxyProtocol, @unchecked Sendable {
|
|||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartUnderlyingCallsCount = newValue
|
createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartUnderlyingCallsCount = newValue
|
||||||
} else {
|
} else {
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartUnderlyingCallsCount = newValue
|
createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartUnderlyingCallsCount = newValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartCalled: Bool {
|
var createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartCalled: Bool {
|
||||||
return createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartCallsCount > 0
|
return createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartCallsCount > 0
|
||||||
}
|
}
|
||||||
var createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartReceivedArguments: (name: String, topic: String?, isRoomPrivate: Bool, isKnockingOnly: Bool, userIDs: [String], avatarURL: URL?, aliasLocalPart: String?)?
|
var createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments: (name: String, topic: String?, accessType: CreateRoomAccessType, isSpace: Bool, userIDs: [String], avatarURL: URL?, aliasLocalPart: String?)?
|
||||||
var createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartReceivedInvocations: [(name: String, topic: String?, isRoomPrivate: Bool, isKnockingOnly: Bool, userIDs: [String], avatarURL: URL?, aliasLocalPart: String?)] = []
|
var createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedInvocations: [(name: String, topic: String?, accessType: CreateRoomAccessType, isSpace: Bool, userIDs: [String], avatarURL: URL?, aliasLocalPart: String?)] = []
|
||||||
|
|
||||||
var createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartUnderlyingReturnValue: Result<String, ClientProxyError>!
|
var createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartUnderlyingReturnValue: Result<String, ClientProxyError>!
|
||||||
var createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartReturnValue: Result<String, ClientProxyError>! {
|
var createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReturnValue: Result<String, ClientProxyError>! {
|
||||||
get {
|
get {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
return createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartUnderlyingReturnValue
|
return createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartUnderlyingReturnValue
|
||||||
} else {
|
} else {
|
||||||
var returnValue: Result<String, ClientProxyError>? = nil
|
var returnValue: Result<String, ClientProxyError>? = nil
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
returnValue = createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartUnderlyingReturnValue
|
returnValue = createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartUnderlyingReturnValue
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnValue!
|
return returnValue!
|
||||||
@@ -2893,26 +2893,26 @@ class ClientProxyMock: ClientProxyProtocol, @unchecked Sendable {
|
|||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartUnderlyingReturnValue = newValue
|
createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartUnderlyingReturnValue = newValue
|
||||||
} else {
|
} else {
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartUnderlyingReturnValue = newValue
|
createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartUnderlyingReturnValue = newValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartClosure: ((String, String?, Bool, Bool, [String], URL?, String?) async -> Result<String, ClientProxyError>)?
|
var createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartClosure: ((String, String?, CreateRoomAccessType, Bool, [String], URL?, String?) async -> Result<String, ClientProxyError>)?
|
||||||
|
|
||||||
func createRoom(name: String, topic: String?, isRoomPrivate: Bool, isKnockingOnly: Bool, userIDs: [String], avatarURL: URL?, aliasLocalPart: String?) async -> Result<String, ClientProxyError> {
|
func createRoom(name: String, topic: String?, accessType: CreateRoomAccessType, isSpace: Bool, userIDs: [String], avatarURL: URL?, aliasLocalPart: String?) async -> Result<String, ClientProxyError> {
|
||||||
createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartCallsCount += 1
|
createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartCallsCount += 1
|
||||||
createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartReceivedArguments = (name: name, topic: topic, isRoomPrivate: isRoomPrivate, isKnockingOnly: isKnockingOnly, userIDs: userIDs, avatarURL: avatarURL, aliasLocalPart: aliasLocalPart)
|
createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments = (name: name, topic: topic, accessType: accessType, isSpace: isSpace, userIDs: userIDs, avatarURL: avatarURL, aliasLocalPart: aliasLocalPart)
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartReceivedInvocations.append((name: name, topic: topic, isRoomPrivate: isRoomPrivate, isKnockingOnly: isKnockingOnly, userIDs: userIDs, avatarURL: avatarURL, aliasLocalPart: aliasLocalPart))
|
self.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedInvocations.append((name: name, topic: topic, accessType: accessType, isSpace: isSpace, userIDs: userIDs, avatarURL: avatarURL, aliasLocalPart: aliasLocalPart))
|
||||||
}
|
}
|
||||||
if let createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartClosure = createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartClosure {
|
if let createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartClosure = createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartClosure {
|
||||||
return await createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartClosure(name, topic, isRoomPrivate, isKnockingOnly, userIDs, avatarURL, aliasLocalPart)
|
return await createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartClosure(name, topic, accessType, isSpace, userIDs, avatarURL, aliasLocalPart)
|
||||||
} else {
|
} else {
|
||||||
return createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartReturnValue
|
return createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReturnValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//MARK: - joinRoom
|
//MARK: - joinRoom
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import Combine
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct CreateRoomScreenCoordinatorParameters {
|
struct CreateRoomScreenCoordinatorParameters {
|
||||||
|
let isSpace: Bool
|
||||||
let userSession: UserSessionProtocol
|
let userSession: UserSessionProtocol
|
||||||
let userIndicatorController: UserIndicatorControllerProtocol
|
let userIndicatorController: UserIndicatorControllerProtocol
|
||||||
let appSettings: AppSettings
|
let appSettings: AppSettings
|
||||||
@@ -31,7 +32,8 @@ final class CreateRoomScreenCoordinator: CoordinatorProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init(parameters: CreateRoomScreenCoordinatorParameters) {
|
init(parameters: CreateRoomScreenCoordinatorParameters) {
|
||||||
viewModel = CreateRoomScreenViewModel(userSession: parameters.userSession,
|
viewModel = CreateRoomScreenViewModel(isSpace: parameters.isSpace,
|
||||||
|
userSession: parameters.userSession,
|
||||||
analytics: parameters.analytics,
|
analytics: parameters.analytics,
|
||||||
userIndicatorController: parameters.userIndicatorController,
|
userIndicatorController: parameters.userIndicatorController,
|
||||||
appSettings: parameters.appSettings)
|
appSettings: parameters.appSettings)
|
||||||
|
|||||||
@@ -23,12 +23,13 @@ enum CreateRoomScreenViewModelAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct CreateRoomScreenViewState: BindableState {
|
struct CreateRoomScreenViewState: BindableState {
|
||||||
|
let isSpace: Bool
|
||||||
var roomName: String
|
var roomName: String
|
||||||
let serverName: String
|
let serverName: String
|
||||||
let isKnockingFeatureEnabled: Bool
|
let isKnockingFeatureEnabled: Bool
|
||||||
var aliasLocalPart: String
|
var aliasLocalPart: String
|
||||||
var bindings: CreateRoomScreenViewStateBindings
|
var bindings: CreateRoomScreenViewStateBindings
|
||||||
var avatarURL: URL?
|
var avatarMediaInfo: MediaInfo?
|
||||||
var canCreateRoom: Bool {
|
var canCreateRoom: Bool {
|
||||||
!roomName.isEmpty && aliasErrors.isEmpty
|
!roomName.isEmpty && aliasErrors.isEmpty
|
||||||
}
|
}
|
||||||
@@ -43,12 +44,19 @@ struct CreateRoomScreenViewState: BindableState {
|
|||||||
nil
|
nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var availableAccessTypes: [CreateRoomAccessType] {
|
||||||
|
var availableTypes = CreateRoomAccessType.allCases
|
||||||
|
if !isKnockingFeatureEnabled {
|
||||||
|
availableTypes.removeAll { $0 == .askToJoin }
|
||||||
|
}
|
||||||
|
return availableTypes
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CreateRoomScreenViewStateBindings {
|
struct CreateRoomScreenViewStateBindings {
|
||||||
var roomTopic: String
|
var roomTopic: String
|
||||||
var isRoomPrivate: Bool
|
var selectedAccessType: CreateRoomAccessType
|
||||||
var isKnockingOnly: Bool
|
|
||||||
var showAttachmentConfirmationDialog = false
|
var showAttachmentConfirmationDialog = false
|
||||||
|
|
||||||
/// Information describing the currently displayed alert.
|
/// Information describing the currently displayed alert.
|
||||||
|
|||||||
@@ -13,17 +13,7 @@ import SwiftUI
|
|||||||
typealias CreateRoomScreenViewModelType = StateStoreViewModel<CreateRoomScreenViewState, CreateRoomScreenViewAction>
|
typealias CreateRoomScreenViewModelType = StateStoreViewModel<CreateRoomScreenViewState, CreateRoomScreenViewAction>
|
||||||
|
|
||||||
class CreateRoomScreenViewModel: CreateRoomScreenViewModelType, CreateRoomScreenViewModelProtocol {
|
class CreateRoomScreenViewModel: CreateRoomScreenViewModelType, CreateRoomScreenViewModelProtocol {
|
||||||
struct Parameters {
|
|
||||||
var name = ""
|
|
||||||
var topic = ""
|
|
||||||
var isRoomPrivate = true
|
|
||||||
var isKnockingOnly = false
|
|
||||||
var avatarImageMedia: MediaInfo?
|
|
||||||
var aliasLocalPart: String?
|
|
||||||
}
|
|
||||||
|
|
||||||
private let userSession: UserSessionProtocol
|
private let userSession: UserSessionProtocol
|
||||||
private var parameters: Parameters
|
|
||||||
private let mediaUploadingPreprocessor: MediaUploadingPreprocessor
|
private let mediaUploadingPreprocessor: MediaUploadingPreprocessor
|
||||||
private let analytics: AnalyticsService
|
private let analytics: AnalyticsService
|
||||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||||
@@ -36,25 +26,24 @@ class CreateRoomScreenViewModel: CreateRoomScreenViewModelType, CreateRoomScreen
|
|||||||
actionsSubject.eraseToAnyPublisher()
|
actionsSubject.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
init(userSession: UserSessionProtocol,
|
init(isSpace: Bool,
|
||||||
initialParameters: Parameters = .init(),
|
userSession: UserSessionProtocol,
|
||||||
analytics: AnalyticsService,
|
analytics: AnalyticsService,
|
||||||
userIndicatorController: UserIndicatorControllerProtocol,
|
userIndicatorController: UserIndicatorControllerProtocol,
|
||||||
appSettings: AppSettings) {
|
appSettings: AppSettings) {
|
||||||
self.userSession = userSession
|
self.userSession = userSession
|
||||||
parameters = initialParameters
|
|
||||||
mediaUploadingPreprocessor = MediaUploadingPreprocessor(appSettings: appSettings)
|
mediaUploadingPreprocessor = MediaUploadingPreprocessor(appSettings: appSettings)
|
||||||
self.analytics = analytics
|
self.analytics = analytics
|
||||||
self.userIndicatorController = userIndicatorController
|
self.userIndicatorController = userIndicatorController
|
||||||
|
|
||||||
let bindings = CreateRoomScreenViewStateBindings(roomTopic: parameters.topic,
|
let bindings = CreateRoomScreenViewStateBindings(roomTopic: "",
|
||||||
isRoomPrivate: parameters.isRoomPrivate,
|
selectedAccessType: .private)
|
||||||
isKnockingOnly: appSettings.knockingEnabled ? parameters.isKnockingOnly : false)
|
|
||||||
|
|
||||||
super.init(initialViewState: CreateRoomScreenViewState(roomName: parameters.name,
|
super.init(initialViewState: CreateRoomScreenViewState(isSpace: isSpace,
|
||||||
|
roomName: "",
|
||||||
serverName: userSession.clientProxy.userIDServerName ?? "",
|
serverName: userSession.clientProxy.userIDServerName ?? "",
|
||||||
isKnockingFeatureEnabled: appSettings.knockingEnabled,
|
isKnockingFeatureEnabled: appSettings.knockingEnabled,
|
||||||
aliasLocalPart: parameters.aliasLocalPart ?? roomAliasNameFromRoomDisplayName(roomName: parameters.name),
|
aliasLocalPart: roomAliasNameFromRoomDisplayName(roomName: ""),
|
||||||
bindings: bindings),
|
bindings: bindings),
|
||||||
mediaProvider: userSession.mediaProvider)
|
mediaProvider: userSession.mediaProvider)
|
||||||
|
|
||||||
@@ -72,8 +61,7 @@ class CreateRoomScreenViewModel: CreateRoomScreenViewModelType, CreateRoomScreen
|
|||||||
case .displayMediaPicker:
|
case .displayMediaPicker:
|
||||||
actionsSubject.send(.displayMediaPicker)
|
actionsSubject.send(.displayMediaPicker)
|
||||||
case .removeImage:
|
case .removeImage:
|
||||||
parameters.avatarImageMedia = nil
|
state.avatarMediaInfo = nil
|
||||||
state.avatarURL = nil
|
|
||||||
case .updateAliasLocalPart(let aliasLocalPart):
|
case .updateAliasLocalPart(let aliasLocalPart):
|
||||||
state.aliasLocalPart = aliasLocalPart.lowercased()
|
state.aliasLocalPart = aliasLocalPart.lowercased()
|
||||||
// If this has been called this means that the user wants a custom address not necessarily reflecting the name
|
// If this has been called this means that the user wants a custom address not necessarily reflecting the name
|
||||||
@@ -104,9 +92,8 @@ class CreateRoomScreenViewModel: CreateRoomScreenViewModelType, CreateRoomScreen
|
|||||||
let mediaInfo = try await mediaUploadingPreprocessor.processMedia(at: fileURL, maxUploadSize: maxUploadSize).get()
|
let mediaInfo = try await mediaUploadingPreprocessor.processMedia(at: fileURL, maxUploadSize: maxUploadSize).get()
|
||||||
|
|
||||||
switch mediaInfo {
|
switch mediaInfo {
|
||||||
case .image(_, let thumbnailURL, _):
|
case .image:
|
||||||
parameters.avatarImageMedia = mediaInfo
|
state.avatarMediaInfo = mediaInfo
|
||||||
state.avatarURL = thumbnailURL
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -123,34 +110,18 @@ class CreateRoomScreenViewModel: CreateRoomScreenViewModelType, CreateRoomScreen
|
|||||||
// Reset the state related to public rooms if the user choses the room to be empty
|
// Reset the state related to public rooms if the user choses the room to be empty
|
||||||
context.$viewState
|
context.$viewState
|
||||||
.dropFirst()
|
.dropFirst()
|
||||||
.map(\.bindings.isRoomPrivate)
|
.map(\.bindings.selectedAccessType)
|
||||||
.removeDuplicates()
|
.removeDuplicates()
|
||||||
.filter { $0 }
|
.filter(\.isPrivate)
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
.sink { [weak self] _ in
|
.sink { [weak self] _ in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
state.bindings.isKnockingOnly = false
|
|
||||||
state.aliasErrors = []
|
state.aliasErrors = []
|
||||||
state.aliasLocalPart = roomAliasNameFromRoomDisplayName(roomName: state.roomName)
|
state.aliasLocalPart = roomAliasNameFromRoomDisplayName(roomName: state.roomName)
|
||||||
syncNameAndAlias = true
|
syncNameAndAlias = true
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
context.$viewState
|
|
||||||
.throttle(for: 0.5, scheduler: DispatchQueue.main, latest: true)
|
|
||||||
.removeDuplicates { old, new in
|
|
||||||
old.roomName == new.roomName &&
|
|
||||||
old.bindings.roomTopic == new.bindings.roomTopic &&
|
|
||||||
old.bindings.isRoomPrivate == new.bindings.isRoomPrivate &&
|
|
||||||
old.bindings.isKnockingOnly == new.bindings.isKnockingOnly &&
|
|
||||||
old.aliasLocalPart == new.aliasLocalPart
|
|
||||||
}
|
|
||||||
.sink { [weak self] state in
|
|
||||||
guard let self else { return }
|
|
||||||
updateParameters(state: state)
|
|
||||||
}
|
|
||||||
.store(in: &cancellables)
|
|
||||||
|
|
||||||
context.$viewState
|
context.$viewState
|
||||||
.map(\.aliasLocalPart)
|
.map(\.aliasLocalPart)
|
||||||
.removeDuplicates()
|
.removeDuplicates()
|
||||||
@@ -160,8 +131,7 @@ class CreateRoomScreenViewModel: CreateRoomScreenViewModelType, CreateRoomScreen
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
guard state.isKnockingFeatureEnabled,
|
guard !state.bindings.selectedAccessType.isPrivate,
|
||||||
!state.bindings.isRoomPrivate,
|
|
||||||
let canonicalAlias = String.makeCanonicalAlias(aliasLocalPart: aliasLocalPart,
|
let canonicalAlias = String.makeCanonicalAlias(aliasLocalPart: aliasLocalPart,
|
||||||
serverName: state.serverName) else {
|
serverName: state.serverName) else {
|
||||||
// While is empty or private room we don't change or display the error
|
// While is empty or private room we don't change or display the error
|
||||||
@@ -195,30 +165,15 @@ class CreateRoomScreenViewModel: CreateRoomScreenViewModelType, CreateRoomScreen
|
|||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateParameters(state: CreateRoomScreenViewState) {
|
|
||||||
parameters.name = state.roomName
|
|
||||||
parameters.topic = state.bindings.roomTopic
|
|
||||||
parameters.isRoomPrivate = state.bindings.isRoomPrivate
|
|
||||||
parameters.isKnockingOnly = state.bindings.isKnockingOnly
|
|
||||||
if state.isKnockingFeatureEnabled, !state.aliasLocalPart.isEmpty {
|
|
||||||
parameters.aliasLocalPart = state.aliasLocalPart
|
|
||||||
} else {
|
|
||||||
parameters.aliasLocalPart = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func createRoom() async {
|
private func createRoom() async {
|
||||||
defer {
|
defer {
|
||||||
hideLoadingIndicator()
|
hideLoadingIndicator()
|
||||||
}
|
}
|
||||||
showLoadingIndicator()
|
showLoadingIndicator()
|
||||||
|
|
||||||
// Since the parameters are throttled, we need to make sure that the latest values are used
|
|
||||||
updateParameters(state: state)
|
|
||||||
|
|
||||||
// Better to double check the errors also when trying to create the room
|
// Better to double check the errors also when trying to create the room
|
||||||
if state.isKnockingFeatureEnabled, !parameters.isRoomPrivate {
|
if !state.bindings.selectedAccessType.isPrivate {
|
||||||
guard let canonicalAlias = String.makeCanonicalAlias(aliasLocalPart: parameters.aliasLocalPart,
|
guard let canonicalAlias = String.makeCanonicalAlias(aliasLocalPart: state.aliasLocalPart,
|
||||||
serverName: state.serverName),
|
serverName: state.serverName),
|
||||||
isRoomAliasFormatValid(alias: canonicalAlias) else {
|
isRoomAliasFormatValid(alias: canonicalAlias) else {
|
||||||
state.aliasErrors = [.invalidSymbols]
|
state.aliasErrors = [.invalidSymbols]
|
||||||
@@ -238,7 +193,7 @@ class CreateRoomScreenViewModel: CreateRoomScreenViewModelType, CreateRoomScreen
|
|||||||
}
|
}
|
||||||
|
|
||||||
let avatarURL: URL?
|
let avatarURL: URL?
|
||||||
if let media = parameters.avatarImageMedia {
|
if let media = state.avatarMediaInfo {
|
||||||
switch await userSession.clientProxy.uploadMedia(media) {
|
switch await userSession.clientProxy.uploadMedia(media) {
|
||||||
case .success(let url):
|
case .success(let url):
|
||||||
avatarURL = URL(string: url)
|
avatarURL = URL(string: url)
|
||||||
@@ -263,14 +218,13 @@ class CreateRoomScreenViewModel: CreateRoomScreenViewModelType, CreateRoomScreen
|
|||||||
avatarURL = nil
|
avatarURL = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
switch await userSession.clientProxy.createRoom(name: parameters.name,
|
switch await userSession.clientProxy.createRoom(name: state.roomName,
|
||||||
topic: parameters.topic.isBlank ? nil : parameters.topic,
|
topic: state.bindings.roomTopic.isBlank ? nil : state.bindings.roomTopic,
|
||||||
isRoomPrivate: parameters.isRoomPrivate,
|
accessType: state.bindings.selectedAccessType,
|
||||||
// As of right now we don't want to make private rooms with the knock rule
|
isSpace: state.isSpace,
|
||||||
isKnockingOnly: parameters.isRoomPrivate ? false : parameters.isKnockingOnly,
|
|
||||||
userIDs: [], // The invite users screen is shown next so we don't need to invite anyone right now.
|
userIDs: [], // The invite users screen is shown next so we don't need to invite anyone right now.
|
||||||
avatarURL: avatarURL,
|
avatarURL: avatarURL,
|
||||||
aliasLocalPart: parameters.isRoomPrivate ? nil : parameters.aliasLocalPart) {
|
aliasLocalPart: state.bindings.selectedAccessType.isPrivate ? nil : state.aliasLocalPart) {
|
||||||
case .success(let roomID):
|
case .success(let roomID):
|
||||||
guard case let .joined(roomProxy) = await userSession.clientProxy.roomForIdentifier(roomID) else {
|
guard case let .joined(roomProxy) = await userSession.clientProxy.roomForIdentifier(roomID) else {
|
||||||
state.bindings.alertInfo = AlertInfo(id: .failedCreatingRoom,
|
state.bindings.alertInfo = AlertInfo(id: .failedCreatingRoom,
|
||||||
|
|||||||
@@ -39,17 +39,15 @@ struct CreateRoomScreen: View {
|
|||||||
Form {
|
Form {
|
||||||
roomSection
|
roomSection
|
||||||
topicSection
|
topicSection
|
||||||
securitySection
|
roomAccessSection
|
||||||
if context.viewState.isKnockingFeatureEnabled,
|
if !context.selectedAccessType.isPrivate {
|
||||||
!context.isRoomPrivate {
|
|
||||||
roomAccessSection
|
|
||||||
roomAliasSection
|
roomAliasSection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.compoundList()
|
.compoundList()
|
||||||
.track(screen: .CreateRoom)
|
.track(screen: .CreateRoom)
|
||||||
.scrollDismissesKeyboard(.immediately)
|
.scrollDismissesKeyboard(.immediately)
|
||||||
.navigationTitle(L10n.screenCreateRoomTitle)
|
.navigationTitle(context.viewState.isSpace ? L10n.screenCreateRoomNewSpaceTitle : L10n.screenCreateRoomNewRoomTitle)
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
.toolbar { toolbar }
|
.toolbar { toolbar }
|
||||||
.alert(item: $context.alertInfo)
|
.alert(item: $context.alertInfo)
|
||||||
@@ -60,15 +58,20 @@ struct CreateRoomScreen: View {
|
|||||||
Section {
|
Section {
|
||||||
HStack(alignment: .center, spacing: 16) {
|
HStack(alignment: .center, spacing: 16) {
|
||||||
roomAvatarButton
|
roomAvatarButton
|
||||||
|
let nameLabel = if #available(iOS 26, *) {
|
||||||
|
L10n.commonName
|
||||||
|
} else {
|
||||||
|
L10n.commonName.uppercased()
|
||||||
|
}
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 8) {
|
VStack(alignment: .leading, spacing: 8) {
|
||||||
Text(L10n.screenCreateRoomRoomNameLabel.uppercased())
|
Text(nameLabel)
|
||||||
.padding(.leading, ListRowPadding.horizontal)
|
.padding(.leading, ListRowPadding.horizontal)
|
||||||
.compoundListSectionHeader()
|
.compoundListSectionHeader()
|
||||||
|
|
||||||
TextField(L10n.screenCreateRoomRoomNameLabel,
|
TextField(L10n.commonName,
|
||||||
text: roomNameBinding,
|
text: roomNameBinding,
|
||||||
prompt: Text(L10n.commonRoomNamePlaceholder).foregroundColor(.compound.textSecondary),
|
prompt: Text(L10n.screenCreateRoomNamePlaceholder).foregroundColor(.compound.textSecondary),
|
||||||
axis: .horizontal)
|
axis: .horizontal)
|
||||||
.font(.compound.bodyLG)
|
.font(.compound.bodyLG)
|
||||||
.foregroundStyle(.compound.textPrimary)
|
.foregroundStyle(.compound.textPrimary)
|
||||||
@@ -90,7 +93,7 @@ struct CreateRoomScreen: View {
|
|||||||
focus = nil
|
focus = nil
|
||||||
context.showAttachmentConfirmationDialog = true
|
context.showAttachmentConfirmationDialog = true
|
||||||
} label: {
|
} label: {
|
||||||
if let url = context.viewState.avatarURL {
|
if let url = context.viewState.avatarMediaInfo?.thumbnailURL {
|
||||||
AsyncImage(url: url) { image in
|
AsyncImage(url: url) { image in
|
||||||
image
|
image
|
||||||
.resizable()
|
.resizable()
|
||||||
@@ -118,7 +121,7 @@ struct CreateRoomScreen: View {
|
|||||||
}
|
}
|
||||||
.accessibilityIdentifier(A11yIdentifiers.createRoomScreen.mediaPicker)
|
.accessibilityIdentifier(A11yIdentifiers.createRoomScreen.mediaPicker)
|
||||||
|
|
||||||
if context.viewState.avatarURL != nil {
|
if context.viewState.avatarMediaInfo?.thumbnailURL != nil {
|
||||||
Button(L10n.actionRemove, role: .destructive) {
|
Button(L10n.actionRemove, role: .destructive) {
|
||||||
context.send(viewAction: .removeImage)
|
context.send(viewAction: .removeImage)
|
||||||
}
|
}
|
||||||
@@ -128,7 +131,7 @@ struct CreateRoomScreen: View {
|
|||||||
|
|
||||||
private var topicSection: some View {
|
private var topicSection: some View {
|
||||||
Section {
|
Section {
|
||||||
ListRow(label: .plain(title: L10n.commonTopicPlaceholder),
|
ListRow(label: .plain(title: L10n.screenCreateRoomTopicPlaceholder),
|
||||||
kind: .textField(text: $context.roomTopic, axis: .vertical))
|
kind: .textField(text: $context.roomTopic, axis: .vertical))
|
||||||
.lineLimit(3, reservesSpace: false)
|
.lineLimit(3, reservesSpace: false)
|
||||||
.focused($focus, equals: .topic)
|
.focused($focus, equals: .topic)
|
||||||
@@ -139,34 +142,16 @@ struct CreateRoomScreen: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var securitySection: some View {
|
|
||||||
Section {
|
|
||||||
ListRow(label: .default(title: L10n.screenCreateRoomPrivateOptionTitle,
|
|
||||||
description: L10n.screenCreateRoomPrivateOptionDescription,
|
|
||||||
icon: \.lock,
|
|
||||||
iconAlignment: .top),
|
|
||||||
kind: .selection(isSelected: context.isRoomPrivate) { context.isRoomPrivate = true })
|
|
||||||
ListRow(label: .default(title: L10n.screenCreateRoomPublicOptionTitle,
|
|
||||||
description: L10n.screenCreateRoomPublicOptionDescription,
|
|
||||||
icon: \.public,
|
|
||||||
iconAlignment: .top),
|
|
||||||
kind: .selection(isSelected: !context.isRoomPrivate) { context.isRoomPrivate = false })
|
|
||||||
} header: {
|
|
||||||
Text(L10n.screenCreateRoomRoomVisibilitySectionTitle)
|
|
||||||
.compoundListSectionHeader()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private var roomAccessSection: some View {
|
private var roomAccessSection: some View {
|
||||||
Section {
|
Section {
|
||||||
ListRow(label: .plain(title: L10n.screenCreateRoomRoomAccessSectionAnyoneOptionTitle,
|
ForEach(context.viewState.availableAccessTypes, id: \.self) { accessType in
|
||||||
description: L10n.screenCreateRoomRoomAccessSectionAnyoneOptionDescription),
|
CreateRoomAccessRow(access: accessType,
|
||||||
kind: .selection(isSelected: !context.isKnockingOnly) { context.isKnockingOnly = false })
|
isSelected: context.selectedAccessType == accessType) {
|
||||||
ListRow(label: .plain(title: L10n.screenCreateRoomRoomAccessSectionKnockingOptionTitle,
|
context.selectedAccessType = accessType
|
||||||
description: L10n.screenCreateRoomRoomAccessSectionKnockingOptionDescription),
|
}
|
||||||
kind: .selection(isSelected: context.isKnockingOnly) { context.isKnockingOnly = true })
|
}
|
||||||
} header: {
|
} header: {
|
||||||
Text(L10n.screenCreateRoomRoomAccessSectionHeader)
|
Text(L10n.screenCreateRoomRoomAccessSectionTitle)
|
||||||
.compoundListSectionHeader()
|
.compoundListSectionHeader()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -207,48 +192,129 @@ struct CreateRoomScreen: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private struct CreateRoomAccessRow: View {
|
||||||
|
let access: CreateRoomAccessType
|
||||||
|
let isSelected: Bool
|
||||||
|
let onSelection: () -> Void
|
||||||
|
|
||||||
|
var title: String {
|
||||||
|
switch access {
|
||||||
|
case .public:
|
||||||
|
L10n.screenCreateRoomRoomAccessSectionPublicOptionTitle
|
||||||
|
case .askToJoin:
|
||||||
|
L10n.screenCreateRoomRoomAccessSectionKnockingOptionTitle
|
||||||
|
case .private:
|
||||||
|
L10n.screenCreateRoomRoomAccessSectionPrivateOptionTitle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var description: String {
|
||||||
|
switch access {
|
||||||
|
case .public:
|
||||||
|
L10n.screenCreateRoomRoomAccessSectionPublicOptionDescription
|
||||||
|
case .askToJoin:
|
||||||
|
L10n.screenCreateRoomRoomAccessSectionKnockingOptionDescription
|
||||||
|
case .private:
|
||||||
|
L10n.screenCreateRoomRoomAccessSectionPrivateOptionDescription
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var icon: KeyPath<CompoundIcons, Image> {
|
||||||
|
switch access {
|
||||||
|
case .public:
|
||||||
|
\.public
|
||||||
|
case .askToJoin:
|
||||||
|
\.userAdd
|
||||||
|
case .private:
|
||||||
|
\.lock
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ListRow(label: .default(title: title,
|
||||||
|
description: description,
|
||||||
|
icon: icon,
|
||||||
|
iconAlignment: .top),
|
||||||
|
kind: .selection(isSelected: isSelected,
|
||||||
|
action: onSelection))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Previews
|
// MARK: - Previews
|
||||||
|
|
||||||
struct CreateRoom_Previews: PreviewProvider, TestablePreview {
|
struct CreateRoom_Previews: PreviewProvider, TestablePreview {
|
||||||
static let viewModel = {
|
static let viewModel = {
|
||||||
|
AppSettings.resetAllSettings()
|
||||||
let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userID: "@userid:example.com"))))
|
let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userID: "@userid:example.com"))))
|
||||||
return CreateRoomScreenViewModel(userSession: userSession,
|
return CreateRoomScreenViewModel(isSpace: false,
|
||||||
initialParameters: .init(),
|
userSession: userSession,
|
||||||
|
analytics: ServiceLocator.shared.analytics,
|
||||||
|
userIndicatorController: UserIndicatorControllerMock(),
|
||||||
|
appSettings: ServiceLocator.shared.settings)
|
||||||
|
}()
|
||||||
|
|
||||||
|
static let spaceViewModel = {
|
||||||
|
AppSettings.resetAllSettings()
|
||||||
|
let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userID: "@userid:example.com"))))
|
||||||
|
return CreateRoomScreenViewModel(isSpace: true,
|
||||||
|
userSession: userSession,
|
||||||
analytics: ServiceLocator.shared.analytics,
|
analytics: ServiceLocator.shared.analytics,
|
||||||
userIndicatorController: UserIndicatorControllerMock(),
|
userIndicatorController: UserIndicatorControllerMock(),
|
||||||
appSettings: ServiceLocator.shared.settings)
|
appSettings: ServiceLocator.shared.settings)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
static let publicRoomViewModel = {
|
static let publicRoomViewModel = {
|
||||||
|
AppSettings.resetAllSettings()
|
||||||
let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userIDServerName: "example.org", userID: "@userid:example.com"))))
|
let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userIDServerName: "example.org", userID: "@userid:example.com"))))
|
||||||
ServiceLocator.shared.settings.knockingEnabled = true
|
let viewModel = CreateRoomScreenViewModel(isSpace: false,
|
||||||
return CreateRoomScreenViewModel(userSession: userSession,
|
userSession: userSession,
|
||||||
initialParameters: .init(isRoomPrivate: false),
|
analytics: ServiceLocator.shared.analytics,
|
||||||
analytics: ServiceLocator.shared.analytics,
|
userIndicatorController: UserIndicatorControllerMock(),
|
||||||
userIndicatorController: UserIndicatorControllerMock(),
|
appSettings: ServiceLocator.shared.settings)
|
||||||
appSettings: ServiceLocator.shared.settings)
|
viewModel.context.selectedAccessType = .public
|
||||||
|
return viewModel
|
||||||
|
}()
|
||||||
|
|
||||||
|
static let askToJoinViewModel = {
|
||||||
|
AppSettings.resetAllSettings()
|
||||||
|
let appSettings = AppSettings()
|
||||||
|
appSettings.knockingEnabled = true
|
||||||
|
let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userIDServerName: "example.org", userID: "@userid:example.com"))))
|
||||||
|
let viewModel = CreateRoomScreenViewModel(isSpace: false,
|
||||||
|
userSession: userSession,
|
||||||
|
analytics: ServiceLocator.shared.analytics,
|
||||||
|
userIndicatorController: UserIndicatorControllerMock(),
|
||||||
|
appSettings: appSettings)
|
||||||
|
viewModel.context.selectedAccessType = .askToJoin
|
||||||
|
return viewModel
|
||||||
}()
|
}()
|
||||||
|
|
||||||
static let publicRoomInvalidAliasViewModel = {
|
static let publicRoomInvalidAliasViewModel = {
|
||||||
|
AppSettings.resetAllSettings()
|
||||||
let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userIDServerName: "example.org", userID: "@userid:example.com"))))
|
let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userIDServerName: "example.org", userID: "@userid:example.com"))))
|
||||||
ServiceLocator.shared.settings.knockingEnabled = true
|
let viewModel = CreateRoomScreenViewModel(isSpace: false,
|
||||||
return CreateRoomScreenViewModel(userSession: userSession,
|
userSession: userSession,
|
||||||
initialParameters: .init(isRoomPrivate: false, aliasLocalPart: "#:"),
|
analytics: ServiceLocator.shared.analytics,
|
||||||
analytics: ServiceLocator.shared.analytics,
|
userIndicatorController: UserIndicatorControllerMock(),
|
||||||
userIndicatorController: UserIndicatorControllerMock(),
|
appSettings: ServiceLocator.shared.settings)
|
||||||
appSettings: ServiceLocator.shared.settings)
|
viewModel.context.selectedAccessType = .public
|
||||||
|
viewModel.context.send(viewAction: .updateAliasLocalPart("#:"))
|
||||||
|
return viewModel
|
||||||
}()
|
}()
|
||||||
|
|
||||||
static let publicRoomExistingAliasViewModel = {
|
static let publicRoomExistingAliasViewModel = {
|
||||||
|
AppSettings.resetAllSettings()
|
||||||
let clientProxy = ClientProxyMock(.init(userIDServerName: "example.org", userID: "@userid:example.com"))
|
let clientProxy = ClientProxyMock(.init(userIDServerName: "example.org", userID: "@userid:example.com"))
|
||||||
clientProxy.isAliasAvailableReturnValue = .success(false)
|
clientProxy.isAliasAvailableReturnValue = .success(false)
|
||||||
let userSession = UserSessionMock(.init(clientProxy: clientProxy))
|
let userSession = UserSessionMock(.init(clientProxy: clientProxy))
|
||||||
ServiceLocator.shared.settings.knockingEnabled = true
|
let viewModel = CreateRoomScreenViewModel(isSpace: false,
|
||||||
return CreateRoomScreenViewModel(userSession: userSession,
|
userSession: userSession,
|
||||||
initialParameters: .init(isRoomPrivate: false, aliasLocalPart: "existing"),
|
analytics: ServiceLocator.shared.analytics,
|
||||||
analytics: ServiceLocator.shared.analytics,
|
userIndicatorController: UserIndicatorControllerMock(),
|
||||||
userIndicatorController: UserIndicatorControllerMock(),
|
appSettings: ServiceLocator.shared.settings)
|
||||||
appSettings: ServiceLocator.shared.settings)
|
viewModel.context.selectedAccessType = .public
|
||||||
|
viewModel.context.send(viewAction: .updateAliasLocalPart("existing"))
|
||||||
|
return viewModel
|
||||||
}()
|
}()
|
||||||
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
@@ -257,11 +323,21 @@ struct CreateRoom_Previews: PreviewProvider, TestablePreview {
|
|||||||
}
|
}
|
||||||
.previewDisplayName("Create Room")
|
.previewDisplayName("Create Room")
|
||||||
|
|
||||||
|
NavigationStack {
|
||||||
|
CreateRoomScreen(context: spaceViewModel.context)
|
||||||
|
}
|
||||||
|
.previewDisplayName("Create Space")
|
||||||
|
|
||||||
NavigationStack {
|
NavigationStack {
|
||||||
CreateRoomScreen(context: publicRoomViewModel.context)
|
CreateRoomScreen(context: publicRoomViewModel.context)
|
||||||
}
|
}
|
||||||
.previewDisplayName("Create Public Room")
|
.previewDisplayName("Create Public Room")
|
||||||
|
|
||||||
|
NavigationStack {
|
||||||
|
CreateRoomScreen(context: askToJoinViewModel.context)
|
||||||
|
}
|
||||||
|
.previewDisplayName("Create Knockable Room")
|
||||||
|
|
||||||
NavigationStack {
|
NavigationStack {
|
||||||
CreateRoomScreen(context: publicRoomInvalidAliasViewModel.context)
|
CreateRoomScreen(context: publicRoomInvalidAliasViewModel.context)
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-5
@@ -48,13 +48,15 @@ struct SecurityAndPrivacyScreen: View {
|
|||||||
Section {
|
Section {
|
||||||
ListRow(label: .default(title: L10n.screenSecurityAndPrivacyRoomAccessAnyoneOptionTitle,
|
ListRow(label: .default(title: L10n.screenSecurityAndPrivacyRoomAccessAnyoneOptionTitle,
|
||||||
description: L10n.screenSecurityAndPrivacyRoomAccessAnyoneOptionDescription,
|
description: L10n.screenSecurityAndPrivacyRoomAccessAnyoneOptionDescription,
|
||||||
icon: \.public),
|
icon: \.public,
|
||||||
|
iconAlignment: .top),
|
||||||
kind: .selection(isSelected: context.desiredSettings.accessType == .anyone) { context.desiredSettings.accessType = .anyone })
|
kind: .selection(isSelected: context.desiredSettings.accessType == .anyone) { context.desiredSettings.accessType = .anyone })
|
||||||
|
|
||||||
if context.viewState.isSpaceMembersOptionAvailable {
|
if context.viewState.isSpaceMembersOptionAvailable {
|
||||||
ListRow(label: .default(title: L10n.screenSecurityAndPrivacyRoomAccessSpaceMembersOptionTitle,
|
ListRow(label: .default(title: L10n.screenSecurityAndPrivacyRoomAccessSpaceMembersOptionTitle,
|
||||||
description: context.viewState.spaceMembersDescription,
|
description: context.viewState.spaceMembersDescription,
|
||||||
icon: \.space),
|
icon: \.space,
|
||||||
|
iconAlignment: .top),
|
||||||
kind: .selection(isSelected: context.desiredSettings.accessType.isSpaceMembers) {
|
kind: .selection(isSelected: context.desiredSettings.accessType.isSpaceMembers) {
|
||||||
context.send(viewAction: .selectedSpaceMembersAccess)
|
context.send(viewAction: .selectedSpaceMembersAccess)
|
||||||
})
|
})
|
||||||
@@ -74,7 +76,8 @@ struct SecurityAndPrivacyScreen: View {
|
|||||||
|
|
||||||
ListRow(label: .default(title: L10n.screenSecurityAndPrivacyRoomAccessInviteOnlyOptionTitle,
|
ListRow(label: .default(title: L10n.screenSecurityAndPrivacyRoomAccessInviteOnlyOptionTitle,
|
||||||
description: L10n.screenSecurityAndPrivacyRoomAccessInviteOnlyOptionDescription,
|
description: L10n.screenSecurityAndPrivacyRoomAccessInviteOnlyOptionDescription,
|
||||||
icon: \.lock),
|
icon: \.lock,
|
||||||
|
iconAlignment: .top),
|
||||||
kind: .selection(isSelected: context.desiredSettings.accessType == .inviteOnly) { context.desiredSettings.accessType = .inviteOnly })
|
kind: .selection(isSelected: context.desiredSettings.accessType == .inviteOnly) { context.desiredSettings.accessType = .inviteOnly })
|
||||||
} header: {
|
} header: {
|
||||||
Text(L10n.screenSecurityAndPrivacyRoomAccessSectionHeader)
|
Text(L10n.screenSecurityAndPrivacyRoomAccessSectionHeader)
|
||||||
@@ -94,7 +97,8 @@ struct SecurityAndPrivacyScreen: View {
|
|||||||
private var askToJoinOption: some View {
|
private var askToJoinOption: some View {
|
||||||
ListRow(label: .default(title: L10n.screenSecurityAndPrivacyAskToJoinOptionTitle,
|
ListRow(label: .default(title: L10n.screenSecurityAndPrivacyAskToJoinOptionTitle,
|
||||||
description: L10n.screenSecurityAndPrivacyAskToJoinOptionDescription,
|
description: L10n.screenSecurityAndPrivacyAskToJoinOptionDescription,
|
||||||
icon: \.userAdd),
|
icon: \.userAdd,
|
||||||
|
iconAlignment: .top),
|
||||||
kind: .selection(isSelected: context.desiredSettings.accessType == .askToJoin) { context.desiredSettings.accessType = .askToJoin })
|
kind: .selection(isSelected: context.desiredSettings.accessType == .askToJoin) { context.desiredSettings.accessType = .askToJoin })
|
||||||
.disabled(!context.viewState.isKnockingEnabled)
|
.disabled(!context.viewState.isKnockingEnabled)
|
||||||
}
|
}
|
||||||
@@ -102,7 +106,8 @@ struct SecurityAndPrivacyScreen: View {
|
|||||||
private var askToJoinWithSpaceMembersOption: some View {
|
private var askToJoinWithSpaceMembersOption: some View {
|
||||||
ListRow(label: .default(title: L10n.screenSecurityAndPrivacyAskToJoinOptionTitle,
|
ListRow(label: .default(title: L10n.screenSecurityAndPrivacyAskToJoinOptionTitle,
|
||||||
description: context.viewState.askToJoinWithSpaceMembersDescription,
|
description: context.viewState.askToJoinWithSpaceMembersDescription,
|
||||||
icon: \.userAdd),
|
icon: \.userAdd,
|
||||||
|
iconAlignment: .top),
|
||||||
kind: .selection(isSelected: context.desiredSettings.accessType.isAskToJoinWithSpaceMembers) { context.send(viewAction: .selectedAskToJoinWithSpaceMembersAccess) })
|
kind: .selection(isSelected: context.desiredSettings.accessType.isAskToJoinWithSpaceMembers) { context.send(viewAction: .selectedAskToJoinWithSpaceMembersAccess) })
|
||||||
.disabled(!context.viewState.isAskToJoinWithSpaceMembersOptionSelectable)
|
.disabled(!context.viewState.isAskToJoinWithSpaceMembersOptionSelectable)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -474,25 +474,26 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
|
|
||||||
func createRoom(name: String,
|
func createRoom(name: String,
|
||||||
topic: String?,
|
topic: String?,
|
||||||
isRoomPrivate: Bool,
|
accessType: CreateRoomAccessType,
|
||||||
isKnockingOnly: Bool,
|
isSpace: Bool,
|
||||||
userIDs: [String],
|
userIDs: [String],
|
||||||
avatarURL: URL?,
|
avatarURL: URL?,
|
||||||
aliasLocalPart: String?) async -> Result<String, ClientProxyError> {
|
aliasLocalPart: String?) async -> Result<String, ClientProxyError> {
|
||||||
do {
|
do {
|
||||||
let parameters = CreateRoomParameters(name: name,
|
let parameters = CreateRoomParameters(name: name,
|
||||||
topic: topic,
|
topic: topic,
|
||||||
isEncrypted: isRoomPrivate,
|
isEncrypted: accessType.isEncrypted,
|
||||||
isDirect: false,
|
isDirect: false,
|
||||||
visibility: isRoomPrivate ? .private : .public,
|
visibility: accessType.visibility,
|
||||||
preset: isRoomPrivate ? .privateChat : .publicChat,
|
preset: accessType.preset,
|
||||||
invite: userIDs,
|
invite: userIDs,
|
||||||
avatar: avatarURL?.absoluteString,
|
avatar: avatarURL?.absoluteString,
|
||||||
powerLevelContentOverride: isKnockingOnly ? Self.knockingRoomCreationPowerLevelOverrides : Self.roomCreationPowerLevelOverrides,
|
powerLevelContentOverride: accessType == .askToJoin ? Self.knockingRoomCreationPowerLevelOverrides : Self.roomCreationPowerLevelOverrides,
|
||||||
joinRuleOverride: isKnockingOnly ? .knock : nil,
|
joinRuleOverride: accessType.joinRuleOverride,
|
||||||
historyVisibilityOverride: isRoomPrivate ? .invited : nil,
|
historyVisibilityOverride: accessType.historyVisibilityOverride,
|
||||||
// This is an FFI naming mistake, what is required is the `aliasLocalPart` not the whole alias
|
// This is an FFI naming mistake, what is required is the `aliasLocalPart` not the whole alias
|
||||||
canonicalAlias: aliasLocalPart)
|
canonicalAlias: aliasLocalPart,
|
||||||
|
isSpace: isSpace)
|
||||||
let roomID = try await client.createRoom(request: parameters)
|
let roomID = try await client.createRoom(request: parameters)
|
||||||
|
|
||||||
await waitForRoomToSync(roomID: roomID)
|
await waitForRoomToSync(roomID: roomID)
|
||||||
@@ -1300,3 +1301,35 @@ private extension TimelineMediaVisibility {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private extension CreateRoomAccessType {
|
||||||
|
var isEncrypted: Bool {
|
||||||
|
switch self {
|
||||||
|
case .public:
|
||||||
|
false
|
||||||
|
case .askToJoin, .private:
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var visibility: RoomVisibility {
|
||||||
|
isPrivate ? .private : .public
|
||||||
|
}
|
||||||
|
|
||||||
|
var preset: RoomPreset {
|
||||||
|
isPrivate ? .privateChat : .publicChat
|
||||||
|
}
|
||||||
|
|
||||||
|
var historyVisibilityOverride: RoomHistoryVisibility? {
|
||||||
|
isPrivate ? .invited : nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var joinRuleOverride: JoinRule? {
|
||||||
|
switch self {
|
||||||
|
case .askToJoin:
|
||||||
|
.knock
|
||||||
|
case .private, .public:
|
||||||
|
nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -48,6 +48,21 @@ enum SlidingSyncConstants {
|
|||||||
static let maximumVisibleRangeSize = 30
|
static let maximumVisibleRangeSize = 30
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum CreateRoomAccessType: CaseIterable {
|
||||||
|
case `public`
|
||||||
|
case askToJoin
|
||||||
|
case `private`
|
||||||
|
|
||||||
|
var isPrivate: Bool {
|
||||||
|
switch self {
|
||||||
|
case .private:
|
||||||
|
true
|
||||||
|
case .public, .askToJoin:
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This struct represents the configuration that we are using to register the application through Pusher to Sygnal
|
/// This struct represents the configuration that we are using to register the application through Pusher to Sygnal
|
||||||
/// using the Matrix Rust SDK, more info here:
|
/// using the Matrix Rust SDK, more info here:
|
||||||
/// https://github.com/matrix-org/sygnal
|
/// https://github.com/matrix-org/sygnal
|
||||||
@@ -156,8 +171,8 @@ protocol ClientProxyProtocol: AnyObject {
|
|||||||
|
|
||||||
func createRoom(name: String,
|
func createRoom(name: String,
|
||||||
topic: String?,
|
topic: String?,
|
||||||
isRoomPrivate: Bool,
|
accessType: CreateRoomAccessType,
|
||||||
isKnockingOnly: Bool,
|
isSpace: Bool,
|
||||||
userIDs: [String],
|
userIDs: [String],
|
||||||
avatarURL: URL?,
|
avatarURL: URL?,
|
||||||
aliasLocalPart: String?) async -> Result<String, ClientProxyError>
|
aliasLocalPart: String?) async -> Result<String, ClientProxyError>
|
||||||
|
|||||||
@@ -651,14 +651,16 @@ class MockScreen: Identifiable {
|
|||||||
return navigationStackCoordinator
|
return navigationStackCoordinator
|
||||||
case .startChatFlow:
|
case .startChatFlow:
|
||||||
let clientProxy = ClientProxyMock(.init(userID: "@mock:client.com"))
|
let clientProxy = ClientProxyMock(.init(userID: "@mock:client.com"))
|
||||||
clientProxy.createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartReturnValue = .success("!new-room:client.com")
|
clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReturnValue =
|
||||||
|
.success("!new-room:client.com")
|
||||||
clientProxy.roomForIdentifierClosure = { roomID in .joined(JoinedRoomProxyMock(.init(id: roomID, members: []))) }
|
clientProxy.roomForIdentifierClosure = { roomID in .joined(JoinedRoomProxyMock(.init(id: roomID, members: []))) }
|
||||||
|
|
||||||
let userDiscoveryService = UserDiscoveryServiceMock()
|
let userDiscoveryService = UserDiscoveryServiceMock()
|
||||||
userDiscoveryService.searchProfilesWithReturnValue = .success([.mockBob, .mockBobby])
|
userDiscoveryService.searchProfilesWithReturnValue = .success([.mockBob, .mockBobby])
|
||||||
|
|
||||||
let navigationStackCoordinator = NavigationStackCoordinator()
|
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||||
let flowCoordinator = StartChatFlowCoordinator(userDiscoveryService: userDiscoveryService,
|
let flowCoordinator = StartChatFlowCoordinator(isSpace: false,
|
||||||
|
userDiscoveryService: userDiscoveryService,
|
||||||
navigationStackCoordinator: navigationStackCoordinator,
|
navigationStackCoordinator: navigationStackCoordinator,
|
||||||
flowParameters: CommonFlowParameters(userSession: UserSessionMock(.init(clientProxy: clientProxy)),
|
flowParameters: CommonFlowParameters(userSession: UserSessionMock(.init(clientProxy: clientProxy)),
|
||||||
bugReportService: BugReportServiceMock(.init()),
|
bugReportService: BugReportServiceMock(.init()),
|
||||||
|
|||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:f513aac79644e109b9cd0be2cf88e47362a70bdd39e92688fecbeab9d49e6414
|
||||||
|
size 157858
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:f4dcf0f103278fa02af6c0d97f54791e14f25d1f5ec0e31eba5b080e21ce6858
|
||||||
|
size 187550
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:e6e0f7572a47ad8fbc35bbe862e8d0634dd1357f4559bd54d6cb57d481485763
|
||||||
|
size 105733
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:abcffb042721e323327f3c70f4cdca89ff56654887293b2f9b2215cc486d465c
|
||||||
|
size 142332
|
||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:0f8d601c193367fe6e2fcbcafeea76da0481328d4c63d6c6f3a5106f9869cc0f
|
oid sha256:c744f0ddc6f0e2cb2e2063cc0135d18a07f18d3a58314ee33651962295199225
|
||||||
size 186260
|
size 158006
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:fc25f9648a4c81cf21d0d420fb08825f96d6a54fc1eedc589c673866a67af784
|
oid sha256:301081a176b706092f008e01c9a195dd58c7dc28adc7a42d38ee5e4c168cd1a2
|
||||||
size 224957
|
size 189421
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:98c9a9ee2f1c0d78a24a5e096c11f72f2467ee22c66f9fa26b84272732eb339c
|
oid sha256:7128f0417b2479525d2b35bfb4a501ac24690694f34841bc7ecf0d922741654d
|
||||||
size 121268
|
size 109846
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:33ac15d63ca2d46ba68e087e712442761bc40feecba310825e661b97b59cfba2
|
oid sha256:2a656ea4051f6a84282fca5f94978b199ec10df51dac04a7ad01c4ec55b6ae1f
|
||||||
size 144352
|
size 146993
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:9df32336b119eb58e4aa3a66280b944c6b54714509fab4d843fd16304d5292ab
|
oid sha256:2c110232459827a0f641057ed1bfc6bfdb714134f3a658fa5acee9a9395bf62a
|
||||||
size 180274
|
size 142457
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:21fc629bec2b888ab69f895fbb724c862383c67e5c8bfc3702f2a82ed046b5c3
|
oid sha256:729a6515bc93eb02be4d04a60c07f3854875ab2404a282a5de8bd11ae9e86a89
|
||||||
size 219688
|
size 165595
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:f5b29aa43bf4f260ca92827715079a66a2a721329510bdadb6e732ad6bbc067b
|
oid sha256:9d4b216831eb0595f1b3adbf0fade0d3db2e621d7922dbc647b62fc31ddc854f
|
||||||
size 114041
|
size 88801
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:5e00046d8a037d82931c163483cb96238476af973db9c36b66f6253b2dc94459
|
oid sha256:c3cfa55a1a89d1905c5c21d5aeadce37d8554487054c2abe6c7d39323e7359c4
|
||||||
size 141659
|
size 115037
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:4c67f6b214cc6d321d3566b5c02f3f8a226bfd0745cd5092f45c7c3e1a73fb32
|
oid sha256:ea061eb260fdeebd3d38a6f32c209345f45dfe3188bff5ebb4e5fefa26bd73e3
|
||||||
size 189590
|
size 161310
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:0018ab26fdd70f668853b04b10575aa018cb8dcb7cc3863350108354e0735121
|
oid sha256:cc8f86bff3d1377c3ca9cca775c998a736a90211d7bb4d03439aa788bdc60160
|
||||||
size 227012
|
size 197756
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:55dff7dd30c3bbe8ba5a4791ecd30bad37947f6209daf4ef2c8d0dcc154dc4b0
|
oid sha256:c58d9126bdf00d7b64ac59b740645d456ad06fe66ff67f0e805eb4b140f0adc1
|
||||||
size 119611
|
size 111712
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:33ac15d63ca2d46ba68e087e712442761bc40feecba310825e661b97b59cfba2
|
oid sha256:3cc77ead9f512f919377e076cf95cba2678a0eb3d7c79395dfcdd33a82d32d3f
|
||||||
size 144352
|
size 152160
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:fdc1e9766a4dde854f05b4b42c3fe6d9faf451813a0230b10dfc241b20038ad7
|
oid sha256:26726c399334387ad4f4f9603af729dd998d8aa40e31175def2b1719e3fe27ec
|
||||||
size 138315
|
size 124557
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:6f5c3ffd80810d57d9dceb6f64189b30cf5e60628b48e6968896dacfc53a0e17
|
oid sha256:6f0b7534290fc773b98633250f05b434ef83c5f8243dd891de5bc58902941e28
|
||||||
size 161485
|
size 142357
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:572a0649d2ba4efa3056ce34a822d4b1237891fc15a538f80ac51ff6948952cc
|
oid sha256:37a460ee15e802c3a165053bba730a911518682570d0692c2f1228913936cb95
|
||||||
size 86254
|
size 72654
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:968186dc96ec4e01fe52ff68ef441f85f48ad2d776ade28d983e650ec4b585c8
|
oid sha256:8b1447dc8d94468cbb42821eea9bc4431ad6c26682a3ef3901d11d80bddaed9a
|
||||||
size 106420
|
size 89114
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:0152d34aba8e7c97fd38b48433a83dee21ceaea96aacbb070782d65a75bfc4ce
|
||||||
|
size 125037
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:5e9b590ea56f6498031583f2eceda6c1269a697b532006d8226a5c0fb152ca41
|
||||||
|
size 142802
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:c672bfb3589592b0cdcd373ce02e47ebcdaf695d8f1e009381f2c527f326aed2
|
||||||
|
size 73155
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:b61ca92955968e5905967c5a62da3de062a561f608d6da3f7e200776a76ebfda
|
||||||
|
size 89771
|
||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:4a2874e02e5bae080c7f422b1359199f70f208d60735825416419882e8161b80
|
oid sha256:f3a736a4d1805184d597e7e8209d72208cdb942015ca7f5b119b9be551a2d13a
|
||||||
size 195179
|
size 195381
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:c90113d2a9b105c70446f58fa0e766b1cfdb83d4dae9b4c34efbb575b2cc5d3e
|
oid sha256:29a5425aee883225d39030768f821cf098084beb7f084998ffb25f914254d793
|
||||||
size 233537
|
size 233810
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:f7aa48ef3727c3fcc42a3b85a55417c217e50a4e50546b1fcb5bf92bb76152e3
|
oid sha256:c6a7aff5bc662c961cef7b941387ee8fd55b382496d0225d63a7baf2a85b3f2b
|
||||||
size 132863
|
size 133082
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:c56c5e6bf983dfbcc5aba2b9474be0c2f6da8c8fd94ec37cf72d4d02e24e227e
|
oid sha256:8ddfbe02c83239f4ea3c8b95eec2c6f508d835da6191ccd5170092eee12f630e
|
||||||
size 164583
|
size 164847
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:ca2c5743874b7c404c06b23bf133fb77d5f61812b1d55c2d5170b968915694ac
|
oid sha256:ddfbaeef5378191153110b43f9f48f21182159a8c75fb9234de6f8c9257bdcdf
|
||||||
size 211272
|
size 211601
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:7ebf814a7cb3d144e7c5172fc889114d41929dacf8068458b62152f832ff426d
|
oid sha256:36b336fb2119ba7753703704fc6ec507c429a389a820548e0c131e4b81c49fa6
|
||||||
size 260403
|
size 260759
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:58da8eeaec2f85afc1ecf3e762c79d94008b5fe725ae72e00aaf965858ef6b7c
|
oid sha256:44eee6824cf09e831336f8032fdbadbe023e47167edd16ca4332aab9a1e56887
|
||||||
size 147164
|
size 147504
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:b877cc4e12ac4afefb2ef0793f09919e9b81127a9eaa8cb221ebe2138b6b5a3f
|
oid sha256:407dc0929ce569c6cc4f5f5163ab8c1eaa79f35784e6949f96010a6f761067d0
|
||||||
size 179833
|
size 180458
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:bf83cc61198e77aa658cc17d57dbc1019569b2552bb341b90034f7345939e588
|
oid sha256:2b2cd165d6aa5fced734eb4207aa7dd252e47fce6f240f50b9434c5984e8e5a2
|
||||||
size 198334
|
size 198692
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:afd52028661858843b63bc99f715bd91fc10d5fb22b8eee3117875afee29722b
|
oid sha256:8da0db3f1929d2cdedb348146e751e5e2b29bb2a251e3777ecf227b06cbab0a5
|
||||||
size 248058
|
size 248426
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:cf7256d898a8329af1c1153250d1492e377021de91aacd23544fe83cbf16edb2
|
oid sha256:2aa7d0bef7669c074cc9167e681a5e16fe29103f948d7e0959261f3ad1c0bb1b
|
||||||
size 136320
|
size 136685
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:1a48162c23078a6eac6e3afdbe16b8045bb558247ce956a18f8b8a84eb73ad9e
|
oid sha256:bd5ff993dde6c617ef07b96e9d5841b13707f8d875c4a4c08f027359e65e7f0d
|
||||||
size 170604
|
size 171197
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:200ee11a5dd56886be8381f1a129b67c250d47a6eaefaedf82127973bb4f8a16
|
oid sha256:40718c83b3c6ae61aba5871cd179673684f38d516bf22070d2d19d920be5c228
|
||||||
size 173112
|
size 173334
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:7d348350791ed25e7e5db970a8128dda7f94c41216fb0f46f70f6c8b13540c78
|
oid sha256:711acf1affdf3fb3ec7f80776d78669e7e6652aef359e2285645af4b73c4a851
|
||||||
size 213524
|
size 213700
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:614305ed71ccea6133304c2b4caa9130437eb6ca55c7f01aba34cd78e678cca2
|
oid sha256:c5fcdfd6cfb12d365e13d42d101da721104f8b92ac4c26750fc60edd4a11c4d7
|
||||||
size 118448
|
size 118619
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:40bfe29281241156f291ebe633b913768441de7fa93d45e9cc98017373fcc842
|
oid sha256:a6debe0c740afde8f727afdc6e84294fb6e5c793559924c2107c1b629894a2b4
|
||||||
size 176498
|
size 176819
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:19ee4c8b01d1b18b962971ae0b1b950279863d12e832b572e2635837ace8f569
|
oid sha256:3466617944665b46015917c82d4dc84b420e5c54b53403f55d9fe78962f61d56
|
||||||
size 148707
|
size 148793
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:801c65df001931f413d10652a0934564b750cb7f2888760fe3ac8dd69461f649
|
oid sha256:8d016464d8f6cd7017e84465531dc9622fb865e61b6dc6cd7f9a9538a76befb5
|
||||||
size 177970
|
size 178171
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:108fa3154405e527b4f83dfb15f2d7720b375c349c8d9de50c4984192839ef26
|
oid sha256:3914a0e0ed46c0d88bb1fc368239c518ae2cc5687a836d16b5dd4bc1d76faf3d
|
||||||
size 93016
|
size 93124
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:e23e9b6268efabf0082f700393f080c7ff520af0a77a5c59d526800fb8b0e1b7
|
oid sha256:7f9eb7cc54ffed0a534a71b9ab2538fe3706c5d44a241429fffe05a5d7c1b197
|
||||||
size 132768
|
size 132874
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:9af7a48f714bec7db946bdf6762507aca1cd5609eadcb025857f7f3a7bd33179
|
oid sha256:c448b9630b608cd0bc4ddae356b31d6b5983339ef001f86e25b33fd14dbe4853
|
||||||
size 198158
|
size 198214
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:15dd87267271389ad687a635154757aba54788a2d47a1a89857495b7ceb3e093
|
oid sha256:7a0a36c9c6c4e1d671a2d6b076b8eee9317ced03b3f42ce08e7e650b4fb34ff0
|
||||||
size 250229
|
size 250367
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:5ea2f6d3dfa555f7be8886086f8f9885e8a537599e5e130d8019e870b5018b2a
|
oid sha256:a1713eacee2906eb96f6cca8e1f44eba015a28e4d83d074287d9509ebd958ba8
|
||||||
size 134575
|
size 134682
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:1ddc6ad69921913ef2f085c0cba06f5e731e727b36a8e9533825ee636315252a
|
oid sha256:5a186f342d0fb66171e821d425f3c946abded3d27ec8a26f69c992f28f898ed1
|
||||||
size 169254
|
size 169406
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:c324010c3328fa225c4477f1bb27be733072e5d8cd3ce888db6220a6d3bda0e6
|
oid sha256:0d1035d5d115c21eda179a45a159aa41590ec6234042323db1aa979982dddab2
|
||||||
size 170487
|
size 170541
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:3aaeb4185e78b1e6c4417bb7d76afac8421589f70fac6c486841b9974e386f09
|
oid sha256:9857f9df82cf5938e55cd02442a0ecf781eca44623fe32e3735127410b2f652d
|
||||||
size 215913
|
size 216055
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:bbc7316079d963ff3b8bc1680ba8bdc8212985668552de2fca39a6c51d004ab0
|
oid sha256:4e05ee29eca1bb23ad9238b8fdc1bd73a84901d12b234aaa2f7175f15dca22ef
|
||||||
size 115669
|
size 115798
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:23fddbb25038c9fdc0bfa53d48e0093cd22f4bc02453d0c4e436a64d531eb388
|
oid sha256:8184ca500b01f72d8fb86e034a4b0c2acfc9bcb884570f4ca3e266b7bce79542
|
||||||
size 153794
|
size 153899
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:41045c5701b59ed3164a4999189cff0f74772e420e511fc4339f2c4b2933762b
|
oid sha256:56168eb647c611eb0c214d3598e5d2518fa2933ed08f83d4ccd6c27be94ce1d1
|
||||||
size 151773
|
size 151831
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:8ce1a903be20de8485976cfcf5ad0f02458f8d1e95975bd83e05f946c5643200
|
oid sha256:bec22e56da539e1350b33f5b8dd229b57358750c6604b84471ec954a2165ec12
|
||||||
size 182075
|
size 182216
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:e78110e0a62ad1e0f83afb2a7f0d4d0212393dddb3c69fbf986387b0d02335d9
|
oid sha256:de97c82bf7ea565a982bc15425a77870152b7d048014751bf0850e9a416fec33
|
||||||
size 104721
|
size 104828
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:77754ddf31e79f7366b80ddd8a80b64ba17d1ca158930cdc74a0f97efc567264
|
oid sha256:81df879269cc8b8daa6dd7f174f290ed23e8f3d64a3e26fb4612b61db77a5907
|
||||||
size 147104
|
size 147256
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:b05a474e324855ae6a103ba650d11789b18ad5aabbf2690d5597302e58f1949b
|
oid sha256:e971940a1cc8bec0e7485e3d320edc679bbb8ccb7968082809fabb4016c194d9
|
||||||
size 160311
|
size 160528
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:d697c4216ba4330a2a91ac058c2c96380b5f192496a1be2a33a652a922365977
|
oid sha256:3c8ec3fe11e9bb64c153efb74debe250acc64e2935e500bcf04cae882cf0105b
|
||||||
size 195262
|
size 195540
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:1709e4b6fa0940284e48c4b8725c79361b5618fcdc3e49db8b87ccc5b0d874d9
|
oid sha256:3f937fb0b3982bdea1697fa4059c94d729704cc1a31abd8c4e332e98cbe7d996
|
||||||
size 105070
|
size 105278
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:aeb53763be78d707668492260db9328a5eb570fcb4ac02a00aa661406c729447
|
oid sha256:dd46ac2966599153dbeca05d90ef59e1d9fe3cfbebea3726e3cbec97b89f50e2
|
||||||
size 152085
|
size 152428
|
||||||
|
|||||||
@@ -28,15 +28,20 @@ class CreateRoomScreenViewModelTests: XCTestCase {
|
|||||||
clientProxy.roomForIdentifierClosure = { roomID in .joined(JoinedRoomProxyMock(.init(id: roomID))) }
|
clientProxy.roomForIdentifierClosure = { roomID in .joined(JoinedRoomProxyMock(.init(id: roomID))) }
|
||||||
userSession = UserSessionMock(.init(clientProxy: clientProxy))
|
userSession = UserSessionMock(.init(clientProxy: clientProxy))
|
||||||
ServiceLocator.shared.settings.knockingEnabled = true
|
ServiceLocator.shared.settings.knockingEnabled = true
|
||||||
let viewModel = CreateRoomScreenViewModel(userSession: userSession,
|
let viewModel = CreateRoomScreenViewModel(isSpace: false,
|
||||||
|
userSession: userSession,
|
||||||
analytics: ServiceLocator.shared.analytics,
|
analytics: ServiceLocator.shared.analytics,
|
||||||
userIndicatorController: UserIndicatorControllerMock(),
|
userIndicatorController: UserIndicatorControllerMock(),
|
||||||
appSettings: ServiceLocator.shared.settings)
|
appSettings: ServiceLocator.shared.settings)
|
||||||
self.viewModel = viewModel
|
self.viewModel = viewModel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func tearDown() {
|
||||||
|
AppSettings.resetAllSettings()
|
||||||
|
}
|
||||||
|
|
||||||
func testDefaultSecurity() {
|
func testDefaultSecurity() {
|
||||||
XCTAssertTrue(context.viewState.bindings.isRoomPrivate)
|
XCTAssertEqual(context.viewState.bindings.selectedAccessType, .private)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCreateRoomRequirements() {
|
func testCreateRoomRequirements() {
|
||||||
@@ -49,11 +54,11 @@ class CreateRoomScreenViewModelTests: XCTestCase {
|
|||||||
// Given a form with a blank topic.
|
// Given a form with a blank topic.
|
||||||
context.send(viewAction: .updateRoomName("A"))
|
context.send(viewAction: .updateRoomName("A"))
|
||||||
context.roomTopic = ""
|
context.roomTopic = ""
|
||||||
context.isRoomPrivate = false
|
context.selectedAccessType = .private
|
||||||
XCTAssertTrue(context.viewState.canCreateRoom)
|
XCTAssertTrue(context.viewState.canCreateRoom)
|
||||||
|
|
||||||
// When creating the room.
|
// When creating the room.
|
||||||
clientProxy.createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartReturnValue = .success("1")
|
clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReturnValue = .success("1")
|
||||||
let deferred = deferFulfillment(viewModel.actions) { action in
|
let deferred = deferFulfillment(viewModel.actions) { action in
|
||||||
guard case .createdRoom(let roomProxy) = action, roomProxy.id == "1" else { return false }
|
guard case .createdRoom(let roomProxy) = action, roomProxy.id == "1" else { return false }
|
||||||
return true
|
return true
|
||||||
@@ -62,26 +67,24 @@ class CreateRoomScreenViewModelTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
|
|
||||||
// Then the room should be created and a topic should not be set.
|
// Then the room should be created and a topic should not be set.
|
||||||
XCTAssertTrue(clientProxy.createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartCalled)
|
XCTAssertTrue(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartCalled)
|
||||||
XCTAssertEqual(clientProxy.createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartReceivedArguments?.name, "A")
|
XCTAssertEqual(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments?.name, "A")
|
||||||
XCTAssertNil(clientProxy.createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartReceivedArguments?.topic,
|
XCTAssertNil(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments?.topic,
|
||||||
"The topic should be sent as nil when it is empty.")
|
"The topic should be sent as nil when it is empty.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCreateKnockingRoom() async {
|
func testCreateKnockingRoom() async {
|
||||||
context.send(viewAction: .updateRoomName("A"))
|
context.send(viewAction: .updateRoomName("A"))
|
||||||
context.roomTopic = "B"
|
context.roomTopic = "B"
|
||||||
context.isRoomPrivate = false
|
context.selectedAccessType = .askToJoin
|
||||||
// When setting the room as private we always reset the knocking state to the default value of false
|
// When setting the room as private we always reset the knocking state to the default value of false
|
||||||
// so we need to wait a main actor cycle to ensure the view state is updated
|
// so we need to wait a main actor cycle to ensure the view state is updated
|
||||||
await Task.yield()
|
await Task.yield()
|
||||||
context.isKnockingOnly = true
|
|
||||||
XCTAssertTrue(context.viewState.canCreateRoom)
|
XCTAssertTrue(context.viewState.canCreateRoom)
|
||||||
|
|
||||||
let expectation = expectation(description: "Wait for the room to be created")
|
let expectation = expectation(description: "Wait for the room to be created")
|
||||||
clientProxy.createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartClosure = { _, _, isPrivate, isKnockingOnly, _, _, localAliasPart in
|
clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartClosure = { _, _, accessType, _, _, _, localAliasPart in
|
||||||
XCTAssertTrue(isKnockingOnly)
|
XCTAssertEqual(accessType, .askToJoin)
|
||||||
XCTAssertFalse(isPrivate)
|
|
||||||
XCTAssertEqual(localAliasPart, "a")
|
XCTAssertEqual(localAliasPart, "a")
|
||||||
defer { expectation.fulfill() }
|
defer { expectation.fulfill() }
|
||||||
return .success("")
|
return .success("")
|
||||||
@@ -93,7 +96,7 @@ class CreateRoomScreenViewModelTests: XCTestCase {
|
|||||||
func testCreatePublicRoomFailsForInvalidAlias() async throws {
|
func testCreatePublicRoomFailsForInvalidAlias() async throws {
|
||||||
context.send(viewAction: .updateRoomName("A"))
|
context.send(viewAction: .updateRoomName("A"))
|
||||||
context.roomTopic = "B"
|
context.roomTopic = "B"
|
||||||
context.isRoomPrivate = false
|
context.selectedAccessType = .public
|
||||||
// When setting the room as private we always reset the alias
|
// When setting the room as private we always reset the alias
|
||||||
// so we need to wait a main actor cycle to ensure the view state is updated
|
// so we need to wait a main actor cycle to ensure the view state is updated
|
||||||
await Task.yield()
|
await Task.yield()
|
||||||
@@ -109,14 +112,14 @@ class CreateRoomScreenViewModelTests: XCTestCase {
|
|||||||
// blocked it
|
// blocked it
|
||||||
context.send(viewAction: .createRoom)
|
context.send(viewAction: .createRoom)
|
||||||
await Task.yield()
|
await Task.yield()
|
||||||
XCTAssertFalse(clientProxy.createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartCalled)
|
XCTAssertFalse(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartCalled)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCreatePublicRoomFailsForExistingAlias() async throws {
|
func testCreatePublicRoomFailsForExistingAlias() async throws {
|
||||||
clientProxy.isAliasAvailableReturnValue = .success(false)
|
clientProxy.isAliasAvailableReturnValue = .success(false)
|
||||||
context.send(viewAction: .updateRoomName("A"))
|
context.send(viewAction: .updateRoomName("A"))
|
||||||
context.roomTopic = "B"
|
context.roomTopic = "B"
|
||||||
context.isRoomPrivate = false
|
context.selectedAccessType = .public
|
||||||
// When setting the room as private we always reset the alias
|
// When setting the room as private we always reset the alias
|
||||||
// so we need to wait a main actor cycle to ensure the view state is updated
|
// so we need to wait a main actor cycle to ensure the view state is updated
|
||||||
await Task.yield()
|
await Task.yield()
|
||||||
@@ -140,27 +143,11 @@ class CreateRoomScreenViewModelTests: XCTestCase {
|
|||||||
context.send(viewAction: .createRoom)
|
context.send(viewAction: .createRoom)
|
||||||
await fulfillment(of: [expectation])
|
await fulfillment(of: [expectation])
|
||||||
XCTAssertEqual(clientProxy.isAliasAvailableCallsCount, 2)
|
XCTAssertEqual(clientProxy.isAliasAvailableCallsCount, 2)
|
||||||
XCTAssertFalse(clientProxy.createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartCalled)
|
XCTAssertFalse(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartCalled)
|
||||||
}
|
|
||||||
|
|
||||||
func testCreatePrivateRoomCantHaveKnockRule() async {
|
|
||||||
context.send(viewAction: .updateRoomName("A"))
|
|
||||||
context.roomTopic = "B"
|
|
||||||
context.isRoomPrivate = true
|
|
||||||
context.isKnockingOnly = true
|
|
||||||
context.send(viewAction: .createRoom)
|
|
||||||
let expectation = expectation(description: "Wait for the room to be created")
|
|
||||||
clientProxy.createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartClosure = { _, _, isPrivate, isKnockingOnly, _, _, _ in
|
|
||||||
XCTAssertFalse(isKnockingOnly)
|
|
||||||
XCTAssertTrue(isPrivate)
|
|
||||||
expectation.fulfill()
|
|
||||||
return .success("")
|
|
||||||
}
|
|
||||||
await fulfillment(of: [expectation])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testNameAndAddressSync() async {
|
func testNameAndAddressSync() async {
|
||||||
context.isRoomPrivate = true
|
context.selectedAccessType = .private
|
||||||
await Task.yield()
|
await Task.yield()
|
||||||
context.send(viewAction: .updateRoomName("abc"))
|
context.send(viewAction: .updateRoomName("abc"))
|
||||||
XCTAssertEqual(context.viewState.aliasLocalPart, "abc")
|
XCTAssertEqual(context.viewState.aliasLocalPart, "abc")
|
||||||
|
|||||||
Reference in New Issue
Block a user