mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
Empty spaces list screen (#4936)
* Added an FF to create spaces + empty spaces list state * removed learn more button and improved spacing * updated toolbar for chats and spaces to match ios 26 designs
This commit is contained in:
@@ -67,6 +67,7 @@
|
||||
"action_copy_text" = "Copy text";
|
||||
"action_create" = "Create";
|
||||
"action_create_a_room" = "Create a room";
|
||||
"action_create_space" = "Create space";
|
||||
"action_deactivate" = "Deactivate";
|
||||
"action_deactivate_account" = "Deactivate account";
|
||||
"action_decline" = "Decline";
|
||||
@@ -188,6 +189,7 @@
|
||||
"common_copied_to_clipboard" = "Copied to clipboard";
|
||||
"common_copyright" = "Copyright";
|
||||
"common_creating_room" = "Creating room…";
|
||||
"common_creating_space" = "Creating space…";
|
||||
"common_current_user_canceled_knock" = "Request canceled";
|
||||
"common_current_user_left_room" = "Left room";
|
||||
"common_current_user_left_space" = "Left space";
|
||||
@@ -307,6 +309,7 @@
|
||||
"common_starting_chat" = "Starting chat…";
|
||||
"common_sticker" = "Sticker";
|
||||
"common_success" = "Success";
|
||||
"common_suggested" = "Suggested";
|
||||
"common_suggestions" = "Suggestions";
|
||||
"common_syncing" = "Syncing";
|
||||
"common_system" = "System";
|
||||
@@ -526,14 +529,19 @@
|
||||
"screen_create_poll_options_section_title" = "Options";
|
||||
"screen_create_poll_remove_accessibility_label" = "Remove %1$@";
|
||||
"screen_create_poll_settings_section_title" = "Settings";
|
||||
"screen_create_room_room_access_section_anyone_option_description" = "Anyone can join this room";
|
||||
"screen_create_room_error_creating_space" = "The space could not be created because of an unknown error. Try again later.";
|
||||
"screen_create_room_new_space_title" = "New space";
|
||||
"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 the room but an administrator or a moderator will have to 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_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_title" = "Room address";
|
||||
"screen_create_room_room_visibility_section_title" = "Room visibility";
|
||||
"screen_create_room_title_new_space" = "New space";
|
||||
"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_edit_room_address_room_address_section_footer" = "You’ll need an address in order to make it visible in the public directory.";
|
||||
@@ -679,7 +687,7 @@
|
||||
"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_room_access_anyone_option_description" = "Anyone can join.";
|
||||
"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_title" = "Invite only";
|
||||
"screen_security_and_privacy_room_access_section_header" = "Access";
|
||||
@@ -712,6 +720,7 @@
|
||||
"screen_space_announcement_title" = "Introducing Spaces";
|
||||
"screen_space_list_description" = "Spaces you have created or joined.";
|
||||
"screen_space_list_details" = "%1$@ • %2$@";
|
||||
"screen_space_list_empty_state_title" = "Create spaces to organize rooms";
|
||||
"screen_space_list_parent_space" = "%1$@ space";
|
||||
"screen_space_list_title" = "Spaces";
|
||||
"screen_start_chat_join_room_by_address_action" = "Join room by address";
|
||||
@@ -835,8 +844,10 @@
|
||||
"screen_create_poll_title" = "Create Poll";
|
||||
"screen_create_room_action_create_room" = "New room";
|
||||
"screen_create_room_error_creating_room" = "An error occurred when creating the room";
|
||||
"screen_create_room_private_option_description" = "Only people invited can access this room. All messages are end-to-end encrypted.";
|
||||
"screen_create_room_private_option_description" = "Only people invited can join.";
|
||||
"screen_create_room_private_option_title" = "Private";
|
||||
"screen_create_room_public_option_description" = "Anyone can find this room.\nYou can change this anytime in room settings.";
|
||||
"screen_create_room_public_option_title" = "Public";
|
||||
"screen_create_room_topic_label" = "Topic (optional)";
|
||||
"screen_deactivate_account_confirmation_dialog_content" = "Please confirm that you want to deactivate your account. This action cannot be undone.";
|
||||
"screen_deactivate_account_delete_all_messages" = "Delete all my messages";
|
||||
@@ -1434,8 +1445,6 @@
|
||||
"screen_create_account_title" = "Create account";
|
||||
"screen_create_poll_cancel_confirmation_content_ios" = "Your changes won’t be saved";
|
||||
"screen_create_room_add_people_title" = "Invite people";
|
||||
"screen_create_room_private_option_title" = "Private room";
|
||||
"screen_create_room_public_option_title" = "Public room";
|
||||
"screen_create_room_room_name_label" = "Room name";
|
||||
"screen_create_room_title" = "Create a room";
|
||||
"screen_deactivate_account_title" = "Deactivate account";
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
"action_copy_text" = "Copy text";
|
||||
"action_create" = "Create";
|
||||
"action_create_a_room" = "Create a room";
|
||||
"action_create_space" = "Create space";
|
||||
"action_deactivate" = "Deactivate";
|
||||
"action_deactivate_account" = "Deactivate account";
|
||||
"action_decline" = "Decline";
|
||||
@@ -188,6 +189,7 @@
|
||||
"common_copied_to_clipboard" = "Copied to clipboard";
|
||||
"common_copyright" = "Copyright";
|
||||
"common_creating_room" = "Creating room…";
|
||||
"common_creating_space" = "Creating space…";
|
||||
"common_current_user_canceled_knock" = "Request canceled";
|
||||
"common_current_user_left_room" = "Left room";
|
||||
"common_current_user_left_space" = "Left space";
|
||||
@@ -307,6 +309,7 @@
|
||||
"common_starting_chat" = "Starting chat…";
|
||||
"common_sticker" = "Sticker";
|
||||
"common_success" = "Success";
|
||||
"common_suggested" = "Suggested";
|
||||
"common_suggestions" = "Suggestions";
|
||||
"common_syncing" = "Syncing";
|
||||
"common_system" = "System";
|
||||
@@ -526,14 +529,19 @@
|
||||
"screen_create_poll_options_section_title" = "Options";
|
||||
"screen_create_poll_remove_accessibility_label" = "Remove %1$@";
|
||||
"screen_create_poll_settings_section_title" = "Settings";
|
||||
"screen_create_room_room_access_section_anyone_option_description" = "Anyone can join this room";
|
||||
"screen_create_room_error_creating_space" = "The space could not be created because of an unknown error. Try again later.";
|
||||
"screen_create_room_new_space_title" = "New space";
|
||||
"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 the room but an administrator or a moderator will have to 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_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_title" = "Room address";
|
||||
"screen_create_room_room_visibility_section_title" = "Room visibility";
|
||||
"screen_create_room_title_new_space" = "New space";
|
||||
"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_edit_room_address_room_address_section_footer" = "You’ll need an address in order to make it visible in the public directory.";
|
||||
@@ -679,7 +687,7 @@
|
||||
"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_room_access_anyone_option_description" = "Anyone can join.";
|
||||
"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_title" = "Invite only";
|
||||
"screen_security_and_privacy_room_access_section_header" = "Access";
|
||||
@@ -712,6 +720,7 @@
|
||||
"screen_space_announcement_title" = "Introducing Spaces";
|
||||
"screen_space_list_description" = "Spaces you have created or joined.";
|
||||
"screen_space_list_details" = "%1$@ • %2$@";
|
||||
"screen_space_list_empty_state_title" = "Create spaces to organize rooms";
|
||||
"screen_space_list_parent_space" = "%1$@ space";
|
||||
"screen_space_list_title" = "Spaces";
|
||||
"screen_start_chat_join_room_by_address_action" = "Join room by address";
|
||||
@@ -835,8 +844,10 @@
|
||||
"screen_create_poll_title" = "Create Poll";
|
||||
"screen_create_room_action_create_room" = "New room";
|
||||
"screen_create_room_error_creating_room" = "An error occurred when creating the room";
|
||||
"screen_create_room_private_option_description" = "Only people invited can access this room. All messages are end-to-end encrypted.";
|
||||
"screen_create_room_private_option_description" = "Only people invited can join.";
|
||||
"screen_create_room_private_option_title" = "Private";
|
||||
"screen_create_room_public_option_description" = "Anyone can find this room.\nYou can change this anytime in room settings.";
|
||||
"screen_create_room_public_option_title" = "Public";
|
||||
"screen_create_room_topic_label" = "Topic (optional)";
|
||||
"screen_deactivate_account_confirmation_dialog_content" = "Please confirm that you want to deactivate your account. This action cannot be undone.";
|
||||
"screen_deactivate_account_delete_all_messages" = "Delete all my messages";
|
||||
@@ -1434,8 +1445,6 @@
|
||||
"screen_create_account_title" = "Create account";
|
||||
"screen_create_poll_cancel_confirmation_content_ios" = "Your changes won’t be saved";
|
||||
"screen_create_room_add_people_title" = "Invite people";
|
||||
"screen_create_room_private_option_title" = "Private room";
|
||||
"screen_create_room_public_option_title" = "Public room";
|
||||
"screen_create_room_room_name_label" = "Room name";
|
||||
"screen_create_room_title" = "Create a room";
|
||||
"screen_deactivate_account_title" = "Deactivate account";
|
||||
|
||||
@@ -65,10 +65,13 @@ final class AppSettings {
|
||||
case threadsEnabled
|
||||
case developerOptionsEnabled
|
||||
case linkPreviewsEnabled
|
||||
case spaceSettingsEnabled
|
||||
case focusEventOnNotificationTap
|
||||
case linkNewDeviceEnabled
|
||||
|
||||
// Spaces
|
||||
case spaceSettingsEnabled
|
||||
case createSpaceEnabled
|
||||
|
||||
// Doug's tweaks 🔧
|
||||
case hideUnreadMessagesBadge
|
||||
case hideQuietNotificationAlerts
|
||||
@@ -377,6 +380,14 @@ final class AppSettings {
|
||||
|
||||
// MARK: - Feature Flags
|
||||
|
||||
// Spaces
|
||||
@UserPreference(key: UserDefaultsKeys.spaceSettingsEnabled, defaultValue: false, storageType: .userDefaults(store))
|
||||
var spaceSettingsEnabled
|
||||
|
||||
@UserPreference(key: UserDefaultsKeys.createSpaceEnabled, defaultValue: false, storageType: .userDefaults(store))
|
||||
var createSpaceEnabled
|
||||
|
||||
// Others
|
||||
@UserPreference(key: UserDefaultsKeys.publicSearchEnabled, defaultValue: false, storageType: .userDefaults(store))
|
||||
var publicSearchEnabled
|
||||
|
||||
@@ -402,9 +413,6 @@ final class AppSettings {
|
||||
|
||||
@UserPreference(key: UserDefaultsKeys.focusEventOnNotificationTap, defaultValue: false, storageType: .userDefaults(store))
|
||||
var focusEventOnNotificationTap
|
||||
|
||||
@UserPreference(key: UserDefaultsKeys.spaceSettingsEnabled, defaultValue: false, storageType: .userDefaults(store))
|
||||
var spaceSettingsEnabled
|
||||
|
||||
@UserPreference(key: UserDefaultsKeys.linkPreviewsEnabled, defaultValue: false, storageType: .userDefaults(store))
|
||||
var linkPreviewsEnabled
|
||||
|
||||
@@ -288,7 +288,10 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
.store(in: &cancellables)
|
||||
|
||||
userSession.clientProxy.spaceService.topLevelSpacesPublisher
|
||||
.map { $0.isEmpty ? .hidden : nil }
|
||||
.combineLatest(flowParameters.appSettings.$createSpaceEnabled)
|
||||
.map { topLevelSpaces, isCreateSpaceEnabled in
|
||||
!isCreateSpaceEnabled && topLevelSpaces.isEmpty ? .hidden : nil
|
||||
}
|
||||
.weakAssign(to: \.chatsTabDetails.barVisibilityOverride, on: self)
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
@@ -168,6 +168,8 @@ internal enum L10n {
|
||||
internal static var actionCreate: String { return L10n.tr("Localizable", "action_create") }
|
||||
/// Create a room
|
||||
internal static var actionCreateARoom: String { return L10n.tr("Localizable", "action_create_a_room") }
|
||||
/// Create space
|
||||
internal static var actionCreateSpace: String { return L10n.tr("Localizable", "action_create_space") }
|
||||
/// Deactivate
|
||||
internal static var actionDeactivate: String { return L10n.tr("Localizable", "action_deactivate") }
|
||||
/// Deactivate account
|
||||
@@ -420,6 +422,8 @@ internal enum L10n {
|
||||
internal static var commonCopyright: String { return L10n.tr("Localizable", "common_copyright") }
|
||||
/// Creating room…
|
||||
internal static var commonCreatingRoom: String { return L10n.tr("Localizable", "common_creating_room") }
|
||||
/// Creating space…
|
||||
internal static var commonCreatingSpace: String { return L10n.tr("Localizable", "common_creating_space") }
|
||||
/// Request canceled
|
||||
internal static var commonCurrentUserCanceledKnock: String { return L10n.tr("Localizable", "common_current_user_canceled_knock") }
|
||||
/// Left room
|
||||
@@ -696,6 +700,8 @@ internal enum L10n {
|
||||
internal static var commonSticker: String { return L10n.tr("Localizable", "common_sticker") }
|
||||
/// Success
|
||||
internal static var commonSuccess: String { return L10n.tr("Localizable", "common_success") }
|
||||
/// Suggested
|
||||
internal static var commonSuggested: String { return L10n.tr("Localizable", "common_suggested") }
|
||||
/// Suggestions
|
||||
internal static var commonSuggestions: String { return L10n.tr("Localizable", "common_suggestions") }
|
||||
/// Syncing
|
||||
@@ -1559,25 +1565,33 @@ internal enum L10n {
|
||||
internal static var screenCreateRoomAddPeopleTitle: String { return L10n.tr("Localizable", "screen_create_room_add_people_title") }
|
||||
/// An error occurred when creating the room
|
||||
internal static var screenCreateRoomErrorCreatingRoom: String { return L10n.tr("Localizable", "screen_create_room_error_creating_room") }
|
||||
/// Only people invited can access this room. All messages are end-to-end encrypted.
|
||||
/// 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") }
|
||||
/// New space
|
||||
internal static var screenCreateRoomNewSpaceTitle: String { return L10n.tr("Localizable", "screen_create_room_new_space_title") }
|
||||
/// Only people invited can join.
|
||||
internal static var screenCreateRoomPrivateOptionDescription: String { return L10n.tr("Localizable", "screen_create_room_private_option_description") }
|
||||
/// Private room
|
||||
/// Private
|
||||
internal static var screenCreateRoomPrivateOptionTitle: String { return L10n.tr("Localizable", "screen_create_room_private_option_title") }
|
||||
/// Anyone can find this room.
|
||||
/// You can change this anytime in room settings.
|
||||
internal static var screenCreateRoomPublicOptionDescription: String { return L10n.tr("Localizable", "screen_create_room_public_option_description") }
|
||||
/// Public room
|
||||
/// Anyone can join.
|
||||
internal static var screenCreateRoomPublicOptionShortDescription: String { return L10n.tr("Localizable", "screen_create_room_public_option_short_description") }
|
||||
/// Public
|
||||
internal static var screenCreateRoomPublicOptionTitle: String { return L10n.tr("Localizable", "screen_create_room_public_option_title") }
|
||||
/// Anyone can join this room
|
||||
/// 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 the room but an administrator or a moderator will have to 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") }
|
||||
/// Ask to join
|
||||
internal static var screenCreateRoomRoomAccessSectionKnockingOptionTitle: String { return L10n.tr("Localizable", "screen_create_room_room_access_section_knocking_option_title") }
|
||||
/// Who has access
|
||||
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.
|
||||
internal static var screenCreateRoomRoomAddressSectionFooter: String { return L10n.tr("Localizable", "screen_create_room_room_address_section_footer") }
|
||||
/// Room address
|
||||
@@ -1588,6 +1602,8 @@ internal enum L10n {
|
||||
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)
|
||||
internal static var screenCreateRoomTopicLabel: String { return L10n.tr("Localizable", "screen_create_room_topic_label") }
|
||||
/// Please confirm that you want to deactivate your account. This action cannot be undone.
|
||||
@@ -2882,7 +2898,7 @@ internal enum L10n {
|
||||
internal static var screenSecurityAndPrivacyRoomAccessAnyoneOptionDescription: String { return L10n.tr("Localizable", "screen_security_and_privacy_room_access_anyone_option_description") }
|
||||
/// Anyone
|
||||
internal static var screenSecurityAndPrivacyRoomAccessAnyoneOptionTitle: String { return L10n.tr("Localizable", "screen_security_and_privacy_room_access_anyone_option_title") }
|
||||
/// Choose which spaces’ members can join this room without an invitation. %1$@
|
||||
/// Choose which spaces’ members can join this room without an invitation. %1$@
|
||||
internal static func screenSecurityAndPrivacyRoomAccessFooter(_ p1: Any) -> String {
|
||||
return L10n.tr("Localizable", "screen_security_and_privacy_room_access_footer", String(describing: p1))
|
||||
}
|
||||
@@ -3113,6 +3129,8 @@ internal enum L10n {
|
||||
internal static func screenSpaceListDetails(_ p1: Any, _ p2: Any) -> String {
|
||||
return L10n.tr("Localizable", "screen_space_list_details", String(describing: p1), String(describing: p2))
|
||||
}
|
||||
/// Create spaces to organize rooms
|
||||
internal static var screenSpaceListEmptyStateTitle: String { return L10n.tr("Localizable", "screen_space_list_empty_state_title") }
|
||||
/// %1$@ space
|
||||
internal static func screenSpaceListParentSpace(_ p1: Any) -> String {
|
||||
return L10n.tr("Localizable", "screen_space_list_parent_space", String(describing: p1))
|
||||
|
||||
@@ -87,7 +87,11 @@ enum UserAvatarSizeOnScreen {
|
||||
var value: CGFloat {
|
||||
switch self {
|
||||
case .chats, .spaces:
|
||||
return 32
|
||||
if #available(iOS 26, *) {
|
||||
return 40
|
||||
} else {
|
||||
return 32
|
||||
}
|
||||
case .timeline:
|
||||
return 32
|
||||
case .readReceipt:
|
||||
|
||||
@@ -40,9 +40,13 @@ struct HomeScreen: View {
|
||||
.backportSharedBackgroundVisibility(.hidden)
|
||||
|
||||
ToolbarItem(placement: .primaryAction) {
|
||||
newRoomButton
|
||||
if #available(iOS 26, *) {
|
||||
newRoomButton
|
||||
} else {
|
||||
newRoomButton
|
||||
.buttonStyle(.compound(.super, size: .toolbarIcon))
|
||||
}
|
||||
}
|
||||
.backportSharedBackgroundVisibility(.hidden)
|
||||
}
|
||||
|
||||
private var settingsButton: some View {
|
||||
@@ -71,7 +75,6 @@ struct HomeScreen: View {
|
||||
} label: {
|
||||
CompoundIcon(\.plus)
|
||||
}
|
||||
.buttonStyle(.compound(.super, size: .toolbarIcon))
|
||||
.accessibilityLabel(L10n.actionStartChat)
|
||||
.accessibilityIdentifier(A11yIdentifiers.homeScreen.startChat)
|
||||
default:
|
||||
|
||||
+3
-1
@@ -66,8 +66,10 @@ protocol DeveloperOptionsProtocol: AnyObject {
|
||||
|
||||
var linkPreviewsEnabled: Bool { get set }
|
||||
|
||||
var spaceSettingsEnabled: Bool { get set }
|
||||
var linkNewDeviceEnabled: Bool { get set }
|
||||
|
||||
var spaceSettingsEnabled: Bool { get set }
|
||||
var createSpaceEnabled: Bool { get set }
|
||||
}
|
||||
|
||||
extension AppSettings: DeveloperOptionsProtocol { }
|
||||
|
||||
+10
-3
@@ -45,15 +45,22 @@ struct DeveloperOptionsScreen: View {
|
||||
Toggle(isOn: $context.linkNewDeviceEnabled) {
|
||||
Text("Link new device with QR code")
|
||||
}
|
||||
Toggle(isOn: $context.spaceSettingsEnabled) {
|
||||
Text("Space settings")
|
||||
}
|
||||
|
||||
context.viewState.appHooks
|
||||
.developerOptionsScreenHook
|
||||
.generalSectionRows()
|
||||
}
|
||||
|
||||
Section("Spaces") {
|
||||
Toggle(isOn: $context.spaceSettingsEnabled) {
|
||||
Text("Space settings")
|
||||
}
|
||||
|
||||
Toggle(isOn: $context.createSpaceEnabled) {
|
||||
Text("Create space")
|
||||
}
|
||||
}
|
||||
|
||||
Section("Room List") {
|
||||
Toggle(isOn: $context.publicSearchEnabled) {
|
||||
Text("Public search")
|
||||
|
||||
@@ -21,6 +21,8 @@ struct SpaceListScreenViewState: BindableState {
|
||||
var topLevelSpaces: [SpaceRoomProxyProtocol]
|
||||
var selectedSpaceID: String?
|
||||
|
||||
var isCreateSpaceEnabled: Bool
|
||||
|
||||
var bindings: SpaceListScreenViewStateBindings
|
||||
}
|
||||
|
||||
@@ -33,4 +35,5 @@ enum SpaceListScreenViewAction {
|
||||
case showSettings
|
||||
case screenAppeared
|
||||
case featureAnnouncementAppeared
|
||||
case createSpace
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ class SpaceListScreenViewModel: SpaceListScreenViewModelType, SpaceListScreenVie
|
||||
|
||||
super.init(initialViewState: SpaceListScreenViewState(userID: userSession.clientProxy.userID,
|
||||
topLevelSpaces: spaceServiceProxy.topLevelSpacesPublisher.value,
|
||||
isCreateSpaceEnabled: appSettings.createSpaceEnabled,
|
||||
bindings: .init()),
|
||||
mediaProvider: userSession.mediaProvider)
|
||||
|
||||
@@ -52,6 +53,10 @@ class SpaceListScreenViewModel: SpaceListScreenViewModelType, SpaceListScreenVie
|
||||
.receive(on: DispatchQueue.main)
|
||||
.weakAssign(to: \.state.userDisplayName, on: self)
|
||||
.store(in: &cancellables)
|
||||
|
||||
appSettings.$createSpaceEnabled
|
||||
.weakAssign(to: \.state.isCreateSpaceEnabled, on: self)
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
@@ -73,6 +78,9 @@ class SpaceListScreenViewModel: SpaceListScreenViewModelType, SpaceListScreenVie
|
||||
}
|
||||
case .featureAnnouncementAppeared:
|
||||
appSettings.hasSeenSpacesAnnouncement = true
|
||||
case .createSpace:
|
||||
// TODO: Implement
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,24 +13,46 @@ struct SpaceListScreen: View {
|
||||
@Bindable var context: SpaceListScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
LazyVStack(spacing: 0) {
|
||||
header
|
||||
spaces
|
||||
mainContent
|
||||
.navigationTitle(L10n.screenSpaceListTitle)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar { toolbar }
|
||||
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
|
||||
.toolbarBloom(hasSearchBar: false)
|
||||
.onAppear { context.send(viewAction: .screenAppeared) }
|
||||
.sheet(isPresented: $context.isPresentingFeatureAnnouncement) {
|
||||
SpacesAnnouncementSheetView(context: context)
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var mainContent: some View {
|
||||
if context.viewState.isCreateSpaceEnabled, context.viewState.topLevelSpaces.isEmpty {
|
||||
emptyState
|
||||
} else {
|
||||
ScrollView {
|
||||
LazyVStack(spacing: 0) {
|
||||
header
|
||||
spaces
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationTitle(L10n.screenSpaceListTitle)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar { toolbar }
|
||||
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
|
||||
.toolbarBloom(hasSearchBar: false)
|
||||
.onAppear { context.send(viewAction: .screenAppeared) }
|
||||
.sheet(isPresented: $context.isPresentingFeatureAnnouncement) {
|
||||
SpacesAnnouncementSheetView(context: context)
|
||||
}
|
||||
}
|
||||
|
||||
var header: some View {
|
||||
private var emptyState: some View {
|
||||
FullscreenDialog(horizontalPadding: 24) {
|
||||
TitleAndIcon(title: L10n.screenSpaceListEmptyStateTitle,
|
||||
icon: \.spaceSolid,
|
||||
iconStyle: .defaultSolid)
|
||||
} bottomContent: {
|
||||
Button(L10n.actionCreateSpace) {
|
||||
context.send(viewAction: .createSpace)
|
||||
}
|
||||
.buttonStyle(.compound(.primary))
|
||||
}
|
||||
}
|
||||
|
||||
private var header: some View {
|
||||
VStack(spacing: 16) {
|
||||
BigIcon(icon: \.spaceSolid)
|
||||
|
||||
@@ -62,7 +84,7 @@ struct SpaceListScreen: View {
|
||||
}
|
||||
}
|
||||
|
||||
var spaces: some View {
|
||||
private var spaces: some View {
|
||||
ForEach(context.viewState.topLevelSpaces, id: \.id) { spaceRoomProxy in
|
||||
SpaceRoomCell(spaceRoomProxy: spaceRoomProxy,
|
||||
isSelected: spaceRoomProxy.id == context.viewState.selectedSpaceID,
|
||||
@@ -73,7 +95,7 @@ struct SpaceListScreen: View {
|
||||
}
|
||||
|
||||
@ToolbarContentBuilder
|
||||
var toolbar: some ToolbarContent {
|
||||
private var toolbar: some ToolbarContent {
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
Button {
|
||||
context.send(viewAction: .showSettings)
|
||||
@@ -95,6 +117,18 @@ struct SpaceListScreen: View {
|
||||
Text("").accessibilityHidden(true)
|
||||
}
|
||||
.backportSharedBackgroundVisibility(.hidden)
|
||||
|
||||
if context.viewState.isCreateSpaceEnabled {
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
Button {
|
||||
context.send(viewAction: .createSpace)
|
||||
} label: {
|
||||
CompoundIcon(\.plus)
|
||||
.accessibilityHidden(true)
|
||||
}
|
||||
.accessibilityLabel(L10n.actionCreateSpace)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,20 +136,31 @@ struct SpaceListScreen: View {
|
||||
|
||||
struct SpaceListScreen_Previews: PreviewProvider, TestablePreview {
|
||||
static let viewModel = makeViewModel()
|
||||
static let emptyViewModel = makeViewModel(isEmpty: true)
|
||||
|
||||
static var previews: some View {
|
||||
NavigationStack {
|
||||
SpaceListScreen(context: viewModel.context)
|
||||
}
|
||||
|
||||
NavigationStack {
|
||||
SpaceListScreen(context: emptyViewModel.context)
|
||||
}
|
||||
.previewDisplayName("Empty")
|
||||
}
|
||||
|
||||
static func makeViewModel() -> SpaceListScreenViewModel {
|
||||
static func makeViewModel(isEmpty: Bool = false) -> SpaceListScreenViewModel {
|
||||
AppSettings.resetAllSettings()
|
||||
let appSettings = AppSettings()
|
||||
appSettings.createSpaceEnabled = true
|
||||
appSettings.hasSeenSpacesAnnouncement = true
|
||||
|
||||
let clientProxy = ClientProxyMock(.init())
|
||||
clientProxy.spaceService = SpaceServiceProxyMock(.init(topLevelSpaces: .mockJoinedSpaces))
|
||||
clientProxy.spaceService = SpaceServiceProxyMock(.init(topLevelSpaces: isEmpty ? [] : .mockJoinedSpaces))
|
||||
|
||||
let viewModel = SpaceListScreenViewModel(userSession: UserSessionMock(.init(clientProxy: clientProxy)),
|
||||
selectedSpacePublisher: .init(nil),
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
appSettings: appSettings,
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
|
||||
return viewModel
|
||||
|
||||
Reference in New Issue
Block a user