mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 21:39:12 +00:00
Knock Requests navigation flows (#3555)
* implemented navigations * better naming for the enum * removed list to banned users navigation * polished the code * avatarURL
This commit is contained in:
parent
03aaf849ee
commit
fe984a1301
@ -370,7 +370,16 @@
|
|||||||
"screen_join_room_knock_message_description" = "Message (optional)";
|
"screen_join_room_knock_message_description" = "Message (optional)";
|
||||||
"screen_join_room_knock_sent_description" = "You will receive an invite to join the room if your request is accepted.";
|
"screen_join_room_knock_sent_description" = "You will receive an invite to join the room if your request is accepted.";
|
||||||
"screen_join_room_knock_sent_title" = "Request to join sent";
|
"screen_join_room_knock_sent_title" = "Request to join sent";
|
||||||
|
"screen_knock_requests_list_accept_all_alert_confirm_button_title" = "Yes, accept all";
|
||||||
|
"screen_knock_requests_list_accept_all_alert_description" = "Are you sure you want to accept all requests to join?";
|
||||||
|
"screen_knock_requests_list_accept_all_alert_title" = "Accept all requests";
|
||||||
"screen_knock_requests_list_accept_all_button_title" = "Accept all";
|
"screen_knock_requests_list_accept_all_button_title" = "Accept all";
|
||||||
|
"screen_knock_requests_list_ban_alert_confirm_button_title" = "Yes, decline and ban";
|
||||||
|
"screen_knock_requests_list_ban_alert_description" = "Are you sure you want to decline and ban %1$@? This user won’t be able to request access to join this room again.";
|
||||||
|
"screen_knock_requests_list_ban_alert_title" = "Decline and ban from accessing";
|
||||||
|
"screen_knock_requests_list_decline_alert_confirm_button_title" = "Yes, decline";
|
||||||
|
"screen_knock_requests_list_decline_alert_description" = "Are you sure you want to decline %1$@ request to join this room?";
|
||||||
|
"screen_knock_requests_list_decline_alert_title" = "Decline access";
|
||||||
"screen_knock_requests_list_decline_and_ban_action_title" = "Decline and ban";
|
"screen_knock_requests_list_decline_and_ban_action_title" = "Decline and ban";
|
||||||
"screen_knock_requests_list_empty_state_description" = "When somebody will ask to join the room, you’ll be able to see their request here.";
|
"screen_knock_requests_list_empty_state_description" = "When somebody will ask to join the room, you’ll be able to see their request here.";
|
||||||
"screen_knock_requests_list_empty_state_title" = "No pending request to join";
|
"screen_knock_requests_list_empty_state_title" = "No pending request to join";
|
||||||
|
@ -316,10 +316,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
case (.roomMembersList, .dismissRoomMembersList):
|
case (.roomMembersList, .dismissRoomMembersList):
|
||||||
return .roomDetails(isRoot: false)
|
return .roomDetails(isRoot: false)
|
||||||
|
|
||||||
case (.room, .presentRoomMemberDetails(userID: let userID)):
|
case (_, .presentRoomMemberDetails(userID: let userID)):
|
||||||
return .roomMemberDetails(userID: userID, previousState: .room)
|
return .roomMemberDetails(userID: userID, previousState: fromState)
|
||||||
case (.roomMembersList, .presentRoomMemberDetails(userID: let userID)):
|
|
||||||
return .roomMemberDetails(userID: userID, previousState: .roomMembersList)
|
|
||||||
case (.roomMemberDetails(_, let previousState), .dismissRoomMemberDetails):
|
case (.roomMemberDetails(_, let previousState), .dismissRoomMemberDetails):
|
||||||
return previousState
|
return previousState
|
||||||
|
|
||||||
@ -328,12 +326,10 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
case (.userProfile(_, let previousState), .dismissUserProfile):
|
case (.userProfile(_, let previousState), .dismissUserProfile):
|
||||||
return previousState
|
return previousState
|
||||||
|
|
||||||
case (.roomDetails, .presentInviteUsersScreen):
|
case (_, .presentInviteUsersScreen):
|
||||||
return .inviteUsersScreen(fromRoomMembersList: false)
|
return .inviteUsersScreen(previousState: fromState)
|
||||||
case (.roomMembersList, .presentInviteUsersScreen):
|
case (.inviteUsersScreen(let previousState), .dismissInviteUsersScreen):
|
||||||
return .inviteUsersScreen(fromRoomMembersList: true)
|
return previousState
|
||||||
case (.inviteUsersScreen(let fromRoomMembersList), .dismissInviteUsersScreen):
|
|
||||||
return fromRoomMembersList ? .roomMembersList : .roomDetails(isRoot: false)
|
|
||||||
|
|
||||||
case (.room, .presentReportContent(let itemID, let senderID)):
|
case (.room, .presentReportContent(let itemID, let senderID)):
|
||||||
return .reportContent(itemID: itemID, senderID: senderID)
|
return .reportContent(itemID: itemID, senderID: senderID)
|
||||||
@ -398,9 +394,6 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
return .rolesAndPermissions
|
return .rolesAndPermissions
|
||||||
case (.rolesAndPermissions, .dismissRolesAndPermissionsScreen):
|
case (.rolesAndPermissions, .dismissRolesAndPermissionsScreen):
|
||||||
return .roomDetails(isRoot: false)
|
return .roomDetails(isRoot: false)
|
||||||
|
|
||||||
case (.roomDetails, .presentRoomMemberDetails(let userID)):
|
|
||||||
return .roomMemberDetails(userID: userID, previousState: fromState)
|
|
||||||
|
|
||||||
case (.room, .presentResolveSendFailure):
|
case (.room, .presentResolveSendFailure):
|
||||||
return .resolveSendFailure
|
return .resolveSendFailure
|
||||||
@ -414,10 +407,10 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
case (.presentingChild(_, let previousState), .dismissChildFlow):
|
case (.presentingChild(_, let previousState), .dismissChildFlow):
|
||||||
return previousState
|
return previousState
|
||||||
|
|
||||||
case (.roomDetails, .presentKnockRequestsListScreen):
|
case (_, .presentKnockRequestsListScreen):
|
||||||
return .knockRequestsList
|
return .knockRequestsList(previousState: fromState)
|
||||||
case (.knockRequestsList, .dismissKnockRequestsListScreen):
|
case (.knockRequestsList(let previousState), .dismissKnockRequestsListScreen):
|
||||||
return .roomDetails(isRoot: false)
|
return previousState
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
@ -575,6 +568,10 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
presentKnockRequestsList()
|
presentKnockRequestsList()
|
||||||
case (.knockRequestsList, .dismissKnockRequestsListScreen, .roomDetails):
|
case (.knockRequestsList, .dismissKnockRequestsListScreen, .roomDetails):
|
||||||
break
|
break
|
||||||
|
case (.room, .presentKnockRequestsListScreen, .knockRequestsList):
|
||||||
|
presentKnockRequestsList()
|
||||||
|
case (.knockRequestsList, .dismissKnockRequestsListScreen, .room):
|
||||||
|
break
|
||||||
|
|
||||||
// Child flow
|
// Child flow
|
||||||
case (_, .startChildFlow(let roomID, let via, let entryPoint), .presentingChild):
|
case (_, .startChildFlow(let roomID, let via, let entryPoint), .presentingChild):
|
||||||
@ -735,6 +732,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
stateMachine.tryEvent(.presentPinnedEventsTimeline)
|
stateMachine.tryEvent(.presentPinnedEventsTimeline)
|
||||||
case .presentResolveSendFailure(failure: let failure, sendHandle: let sendHandle):
|
case .presentResolveSendFailure(failure: let failure, sendHandle: let sendHandle):
|
||||||
stateMachine.tryEvent(.presentResolveSendFailure(failure: failure, sendHandle: sendHandle))
|
stateMachine.tryEvent(.presentResolveSendFailure(failure: failure, sendHandle: sendHandle))
|
||||||
|
case .presentKnockRequestsList:
|
||||||
|
stateMachine.tryEvent(.presentKnockRequestsListScreen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
@ -899,11 +898,6 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
let parameters = KnockRequestsListScreenCoordinatorParameters(roomProxy: roomProxy, mediaProvider: userSession.mediaProvider)
|
let parameters = KnockRequestsListScreenCoordinatorParameters(roomProxy: roomProxy, mediaProvider: userSession.mediaProvider)
|
||||||
let coordinator = KnockRequestsListScreenCoordinator(parameters: parameters)
|
let coordinator = KnockRequestsListScreenCoordinator(parameters: parameters)
|
||||||
|
|
||||||
coordinator.actionsPublisher
|
|
||||||
.sink { [weak self] _ in
|
|
||||||
}
|
|
||||||
.store(in: &cancellables)
|
|
||||||
|
|
||||||
navigationStackCoordinator.push(coordinator) { [weak self] in
|
navigationStackCoordinator.push(coordinator) { [weak self] in
|
||||||
self?.stateMachine.tryEvent(.dismissKnockRequestsListScreen)
|
self?.stateMachine.tryEvent(.dismissKnockRequestsListScreen)
|
||||||
}
|
}
|
||||||
@ -1559,7 +1553,7 @@ private extension RoomFlowCoordinator {
|
|||||||
case roomMembersList
|
case roomMembersList
|
||||||
case roomMemberDetails(userID: String, previousState: State)
|
case roomMemberDetails(userID: String, previousState: State)
|
||||||
case userProfile(userID: String, previousState: State)
|
case userProfile(userID: String, previousState: State)
|
||||||
case inviteUsersScreen(fromRoomMembersList: Bool)
|
case inviteUsersScreen(previousState: State)
|
||||||
case mediaUploadPicker(source: MediaPickerScreenSource)
|
case mediaUploadPicker(source: MediaPickerScreenSource)
|
||||||
case mediaUploadPreview(fileURL: URL)
|
case mediaUploadPreview(fileURL: URL)
|
||||||
case emojiPicker(itemID: TimelineItemIdentifier, selectedEmojis: Set<String>)
|
case emojiPicker(itemID: TimelineItemIdentifier, selectedEmojis: Set<String>)
|
||||||
@ -1572,7 +1566,7 @@ private extension RoomFlowCoordinator {
|
|||||||
case rolesAndPermissions
|
case rolesAndPermissions
|
||||||
case pinnedEventsTimeline(previousState: PinnedEventsTimelineSource)
|
case pinnedEventsTimeline(previousState: PinnedEventsTimelineSource)
|
||||||
case resolveSendFailure
|
case resolveSendFailure
|
||||||
case knockRequestsList
|
case knockRequestsList(previousState: State)
|
||||||
|
|
||||||
/// A child flow is in progress.
|
/// A child flow is in progress.
|
||||||
case presentingChild(childRoomID: String, previousState: State)
|
case presentingChild(childRoomID: String, previousState: State)
|
||||||
|
@ -1298,8 +1298,30 @@ internal enum L10n {
|
|||||||
}
|
}
|
||||||
/// Are you sure you want to turn off key storage and delete it?
|
/// Are you sure you want to turn off key storage and delete it?
|
||||||
internal static var screenKeyBackupDisableTitle: String { return L10n.tr("Localizable", "screen_key_backup_disable_title") }
|
internal static var screenKeyBackupDisableTitle: String { return L10n.tr("Localizable", "screen_key_backup_disable_title") }
|
||||||
|
/// Yes, accept all
|
||||||
|
internal static var screenKnockRequestsListAcceptAllAlertConfirmButtonTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_accept_all_alert_confirm_button_title") }
|
||||||
|
/// Are you sure you want to accept all requests to join?
|
||||||
|
internal static var screenKnockRequestsListAcceptAllAlertDescription: String { return L10n.tr("Localizable", "screen_knock_requests_list_accept_all_alert_description") }
|
||||||
|
/// Accept all requests
|
||||||
|
internal static var screenKnockRequestsListAcceptAllAlertTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_accept_all_alert_title") }
|
||||||
/// Accept all
|
/// Accept all
|
||||||
internal static var screenKnockRequestsListAcceptAllButtonTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_accept_all_button_title") }
|
internal static var screenKnockRequestsListAcceptAllButtonTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_accept_all_button_title") }
|
||||||
|
/// Yes, decline and ban
|
||||||
|
internal static var screenKnockRequestsListBanAlertConfirmButtonTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_ban_alert_confirm_button_title") }
|
||||||
|
/// Are you sure you want to decline and ban %1$@? This user won’t be able to request access to join this room again.
|
||||||
|
internal static func screenKnockRequestsListBanAlertDescription(_ p1: Any) -> String {
|
||||||
|
return L10n.tr("Localizable", "screen_knock_requests_list_ban_alert_description", String(describing: p1))
|
||||||
|
}
|
||||||
|
/// Decline and ban from accessing
|
||||||
|
internal static var screenKnockRequestsListBanAlertTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_ban_alert_title") }
|
||||||
|
/// Yes, decline
|
||||||
|
internal static var screenKnockRequestsListDeclineAlertConfirmButtonTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_decline_alert_confirm_button_title") }
|
||||||
|
/// Are you sure you want to decline %1$@ request to join this room?
|
||||||
|
internal static func screenKnockRequestsListDeclineAlertDescription(_ p1: Any) -> String {
|
||||||
|
return L10n.tr("Localizable", "screen_knock_requests_list_decline_alert_description", String(describing: p1))
|
||||||
|
}
|
||||||
|
/// Decline access
|
||||||
|
internal static var screenKnockRequestsListDeclineAlertTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_decline_alert_title") }
|
||||||
/// Decline and ban
|
/// Decline and ban
|
||||||
internal static var screenKnockRequestsListDeclineAndBanActionTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_decline_and_ban_action_title") }
|
internal static var screenKnockRequestsListDeclineAndBanActionTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_decline_and_ban_action_title") }
|
||||||
/// When somebody will ask to join the room, you’ll be able to see their request here.
|
/// When somebody will ask to join the room, you’ll be able to see their request here.
|
||||||
|
@ -32,12 +32,7 @@ final class KnockRequestsListScreenCoordinator: CoordinatorProtocol {
|
|||||||
mediaProvider: parameters.mediaProvider)
|
mediaProvider: parameters.mediaProvider)
|
||||||
}
|
}
|
||||||
|
|
||||||
func start() {
|
func start() { }
|
||||||
viewModel.actionsPublisher.sink { [weak self] action in
|
|
||||||
MXLog.info("Coordinator: received view model action: \(action)")
|
|
||||||
}
|
|
||||||
.store(in: &cancellables)
|
|
||||||
}
|
|
||||||
|
|
||||||
func toPresentable() -> AnyView {
|
func toPresentable() -> AnyView {
|
||||||
AnyView(KnockRequestsListScreen(context: viewModel.context))
|
AnyView(KnockRequestsListScreen(context: viewModel.context))
|
||||||
|
@ -10,7 +10,8 @@ import Foundation
|
|||||||
enum KnockRequestsListScreenViewModelAction { }
|
enum KnockRequestsListScreenViewModelAction { }
|
||||||
|
|
||||||
struct KnockRequestsListScreenViewState: BindableState {
|
struct KnockRequestsListScreenViewState: BindableState {
|
||||||
var requests: [KnockRequestCellInfo] = []
|
// TODO: Not sure yet how we will fetch this, this is just for testing purposes
|
||||||
|
var requests: [KnockRequestCellInfo] = [.init(id: "@alice:matrix.org", displayName: "Alice", avatarURL: nil, timestamp: "Now", reason: "Hello")]
|
||||||
// If you are in this view one of these must have been true so by default we assume all of them to be true
|
// If you are in this view one of these must have been true so by default we assume all of them to be true
|
||||||
var canAccept = true
|
var canAccept = true
|
||||||
var canDecline = true
|
var canDecline = true
|
||||||
@ -22,6 +23,18 @@ struct KnockRequestsListScreenViewState: BindableState {
|
|||||||
var shouldDisplayRequests: Bool {
|
var shouldDisplayRequests: Bool {
|
||||||
!requests.isEmpty && isKnockableRoom && (canAccept || canDecline || canBan)
|
!requests.isEmpty && isKnockableRoom && (canAccept || canDecline || canBan)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var bindings = KnockRequestsListStateBindings()
|
||||||
|
}
|
||||||
|
|
||||||
|
struct KnockRequestsListStateBindings {
|
||||||
|
var alertInfo: AlertInfo<KnockRequestsListAlertType>?
|
||||||
|
}
|
||||||
|
|
||||||
|
enum KnockRequestsListAlertType {
|
||||||
|
case acceptAllRequests
|
||||||
|
case declineRequest
|
||||||
|
case declineAndBan
|
||||||
}
|
}
|
||||||
|
|
||||||
enum KnockRequestsListScreenViewAction {
|
enum KnockRequestsListScreenViewAction {
|
||||||
|
@ -35,13 +35,34 @@ class KnockRequestsListScreenViewModel: KnockRequestsListScreenViewModelType, Kn
|
|||||||
override func process(viewAction: KnockRequestsListScreenViewAction) {
|
override func process(viewAction: KnockRequestsListScreenViewAction) {
|
||||||
switch viewAction {
|
switch viewAction {
|
||||||
case .acceptAllRequests:
|
case .acceptAllRequests:
|
||||||
break
|
state.bindings.alertInfo = .init(id: .acceptAllRequests,
|
||||||
|
title: L10n.screenKnockRequestsListAcceptAllAlertTitle,
|
||||||
|
message: L10n.screenKnockRequestsListAcceptAllAlertDescription,
|
||||||
|
primaryButton: .init(title: L10n.screenKnockRequestsListAcceptAllAlertConfirmButtonTitle,
|
||||||
|
// TODO: Implement action
|
||||||
|
action: nil),
|
||||||
|
secondaryButton: .init(title: L10n.actionCancel, role: .cancel, action: nil))
|
||||||
case .acceptRequest(let userID):
|
case .acceptRequest(let userID):
|
||||||
|
// TODO: Implement
|
||||||
break
|
break
|
||||||
case .declineRequest(let userID):
|
case .declineRequest(let userID):
|
||||||
break
|
state.bindings.alertInfo = .init(id: .declineRequest,
|
||||||
|
title: L10n.screenKnockRequestsListDeclineAlertTitle,
|
||||||
|
message: L10n.screenKnockRequestsListDeclineAlertDescription(userID),
|
||||||
|
primaryButton: .init(title: L10n.screenKnockRequestsListDeclineAlertConfirmButtonTitle,
|
||||||
|
role: .destructive,
|
||||||
|
// TODO: Implement action
|
||||||
|
action: nil),
|
||||||
|
secondaryButton: .init(title: L10n.actionCancel, role: .cancel, action: nil))
|
||||||
case .ban(let userID):
|
case .ban(let userID):
|
||||||
break
|
state.bindings.alertInfo = .init(id: .declineAndBan,
|
||||||
|
title: L10n.screenKnockRequestsListBanAlertTitle,
|
||||||
|
message: L10n.screenKnockRequestsListBanAlertDescription(userID),
|
||||||
|
// TODO: Implement action
|
||||||
|
primaryButton: .init(title: L10n.screenKnockRequestsListBanAlertConfirmButtonTitle,
|
||||||
|
role: .destructive,
|
||||||
|
action: nil),
|
||||||
|
secondaryButton: .init(title: L10n.actionCancel, role: .cancel, action: nil))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ struct KnockRequestCellInfo: Identifiable {
|
|||||||
/// user identifier of the usee that sent the request
|
/// user identifier of the usee that sent the request
|
||||||
let id: String
|
let id: String
|
||||||
let displayName: String?
|
let displayName: String?
|
||||||
let avatarUrl: URL?
|
let avatarURL: URL?
|
||||||
let timestamp: String?
|
let timestamp: String?
|
||||||
let reason: String?
|
let reason: String?
|
||||||
}
|
}
|
||||||
@ -33,7 +33,7 @@ struct KnockRequestCell: View {
|
|||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
HStack(alignment: .top, spacing: 16) {
|
HStack(alignment: .top, spacing: 16) {
|
||||||
LoadableAvatarImage(url: cellInfo.avatarUrl,
|
LoadableAvatarImage(url: cellInfo.avatarURL,
|
||||||
name: cellInfo.displayName,
|
name: cellInfo.displayName,
|
||||||
contentID: cellInfo.id,
|
contentID: cellInfo.id,
|
||||||
avatarSize: .user(on: .knockingUserList),
|
avatarSize: .user(on: .knockingUserList),
|
||||||
@ -168,13 +168,13 @@ private struct DisclosableText: View {
|
|||||||
|
|
||||||
struct KnockRequestCell_Previews: PreviewProvider, TestablePreview {
|
struct KnockRequestCell_Previews: PreviewProvider, TestablePreview {
|
||||||
// swiftlint:disable:next line_length
|
// swiftlint:disable:next line_length
|
||||||
static let aliceWithLongReason = KnockRequestCellInfo(id: "@alice:matrix.org", displayName: "Alice", avatarUrl: nil, timestamp: "20 Nov 2024", reason: "Hello would like to join this room, also this is a very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very long reason")
|
static let aliceWithLongReason = KnockRequestCellInfo(id: "@alice:matrix.org", displayName: "Alice", avatarURL: nil, timestamp: "20 Nov 2024", reason: "Hello would like to join this room, also this is a very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very long reason")
|
||||||
|
|
||||||
static let aliceWithShortReason = KnockRequestCellInfo(id: "@alice:matrix.org", displayName: "Alice", avatarUrl: nil, timestamp: "20 Nov 2024", reason: "Hello, I am Alice and would like to join this room, please")
|
static let aliceWithShortReason = KnockRequestCellInfo(id: "@alice:matrix.org", displayName: "Alice", avatarURL: nil, timestamp: "20 Nov 2024", reason: "Hello, I am Alice and would like to join this room, please")
|
||||||
|
|
||||||
static let aliceWithNoReason = KnockRequestCellInfo(id: "@alice:matrix.org", displayName: "Alice", avatarUrl: nil, timestamp: "20 Nov 2024", reason: nil)
|
static let aliceWithNoReason = KnockRequestCellInfo(id: "@alice:matrix.org", displayName: "Alice", avatarURL: nil, timestamp: "20 Nov 2024", reason: nil)
|
||||||
|
|
||||||
static let aliceWithNoName = KnockRequestCellInfo(id: "@alice:matrix.org", displayName: nil, avatarUrl: nil, timestamp: "20 Nov 2024", reason: nil)
|
static let aliceWithNoName = KnockRequestCellInfo(id: "@alice:matrix.org", displayName: nil, avatarURL: nil, timestamp: "20 Nov 2024", reason: nil)
|
||||||
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
KnockRequestCell(cellInfo: aliceWithLongReason, onAccept: { _ in }, onDecline: { _ in }, onDeclineAndBan: { _ in })
|
KnockRequestCell(cellInfo: aliceWithLongReason, onAccept: { _ in }, onDecline: { _ in }, onDeclineAndBan: { _ in })
|
||||||
|
@ -26,6 +26,7 @@ struct KnockRequestsListScreen: View {
|
|||||||
acceptAllButton
|
acceptAllButton
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.alert(item: $context.alertInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
@ -75,13 +76,13 @@ struct KnockRequestsListScreen: View {
|
|||||||
// MARK: - Previews
|
// MARK: - Previews
|
||||||
|
|
||||||
struct KnockRequestsListScreen_Previews: PreviewProvider, TestablePreview {
|
struct KnockRequestsListScreen_Previews: PreviewProvider, TestablePreview {
|
||||||
static let emptyViewModel = KnockRequestsListScreenViewModel.mockWithInitialState(.init())
|
static let emptyViewModel = KnockRequestsListScreenViewModel.mockWithInitialState(.init(requests: []))
|
||||||
|
|
||||||
static let viewModel = KnockRequestsListScreenViewModel.mockWithInitialState(.init(requests: [.init(id: "@alice:matrix.org", displayName: "Alice", avatarUrl: nil, timestamp: "Now", reason: "Hello"),
|
static let viewModel = KnockRequestsListScreenViewModel.mockWithInitialState(.init(requests: [.init(id: "@alice:matrix.org", displayName: "Alice", avatarURL: nil, timestamp: "Now", reason: "Hello"),
|
||||||
// swiftlint:disable:next line_length
|
// swiftlint:disable:next line_length
|
||||||
.init(id: "@bob:matrix.org", displayName: "Bob", avatarUrl: nil, timestamp: "Now", reason: "Hello this one is a very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very long reason"),
|
.init(id: "@bob:matrix.org", displayName: "Bob", avatarURL: nil, timestamp: "Now", reason: "Hello this one is a very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very long reason"),
|
||||||
.init(id: "@charlie:matrix.org", displayName: "Charlie", avatarUrl: nil, timestamp: "Now", reason: nil),
|
.init(id: "@charlie:matrix.org", displayName: "Charlie", avatarURL: nil, timestamp: "Now", reason: nil),
|
||||||
.init(id: "@dan:matrix.org", displayName: "Dan", avatarUrl: nil, timestamp: "Now", reason: "Hello! It's a me! Dan!")]))
|
.init(id: "@dan:matrix.org", displayName: "Dan", avatarURL: nil, timestamp: "Now", reason: "Hello! It's a me! Dan!")]))
|
||||||
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
NavigationStack {
|
NavigationStack {
|
||||||
|
@ -42,6 +42,7 @@ enum RoomScreenCoordinatorAction {
|
|||||||
case presentCallScreen
|
case presentCallScreen
|
||||||
case presentPinnedEventsTimeline
|
case presentPinnedEventsTimeline
|
||||||
case presentResolveSendFailure(failure: TimelineItemSendFailure.VerifiedUser, sendHandle: SendHandleProxy)
|
case presentResolveSendFailure(failure: TimelineItemSendFailure.VerifiedUser, sendHandle: SendHandleProxy)
|
||||||
|
case presentKnockRequestsList
|
||||||
}
|
}
|
||||||
|
|
||||||
final class RoomScreenCoordinator: CoordinatorProtocol {
|
final class RoomScreenCoordinator: CoordinatorProtocol {
|
||||||
@ -169,6 +170,8 @@ final class RoomScreenCoordinator: CoordinatorProtocol {
|
|||||||
actionsSubject.send(.presentCallScreen)
|
actionsSubject.send(.presentCallScreen)
|
||||||
case .removeComposerFocus:
|
case .removeComposerFocus:
|
||||||
composerViewModel.process(timelineAction: .removeFocus)
|
composerViewModel.process(timelineAction: .removeFocus)
|
||||||
|
case .displayKnockRequests:
|
||||||
|
actionsSubject.send(.presentKnockRequestsList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
@ -14,6 +14,7 @@ enum RoomScreenViewModelAction {
|
|||||||
case displayRoomDetails
|
case displayRoomDetails
|
||||||
case displayCall
|
case displayCall
|
||||||
case removeComposerFocus
|
case removeComposerFocus
|
||||||
|
case displayKnockRequests
|
||||||
}
|
}
|
||||||
|
|
||||||
enum RoomScreenViewAction {
|
enum RoomScreenViewAction {
|
||||||
@ -22,6 +23,9 @@ enum RoomScreenViewAction {
|
|||||||
case displayRoomDetails
|
case displayRoomDetails
|
||||||
case displayCall
|
case displayCall
|
||||||
case footerViewAction(RoomScreenFooterViewAction)
|
case footerViewAction(RoomScreenFooterViewAction)
|
||||||
|
case acceptKnock(userID: String)
|
||||||
|
case dismissKnockRequests
|
||||||
|
case viewKnockRequests
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RoomScreenViewState: BindableState {
|
struct RoomScreenViewState: BindableState {
|
||||||
|
@ -103,6 +103,14 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
|||||||
case .resolvePinViolation(let userID):
|
case .resolvePinViolation(let userID):
|
||||||
Task { await resolveIdentityPinningViolation(userID) }
|
Task { await resolveIdentityPinningViolation(userID) }
|
||||||
}
|
}
|
||||||
|
case .acceptKnock(userID: let userID):
|
||||||
|
// TODO: API to accept a knock required
|
||||||
|
break
|
||||||
|
case .dismissKnockRequests:
|
||||||
|
// TODO: API to mark knocks as seen required
|
||||||
|
break
|
||||||
|
case .viewKnockRequests:
|
||||||
|
actionsSubject.send(.displayKnockRequests)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,15 +148,15 @@ struct RoomScreen: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func dismissKnockRequestsBanner() {
|
private func dismissKnockRequestsBanner() {
|
||||||
// TODO: Implement
|
roomContext.send(viewAction: .dismissKnockRequests)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func acceptKnockRequest(userID: String) {
|
private func acceptKnockRequest(userID: String) {
|
||||||
// TODO: Implement
|
roomContext.send(viewAction: .acceptKnock(userID: userID))
|
||||||
}
|
}
|
||||||
|
|
||||||
private func onViewAllKnockRequests() {
|
private func onViewAllKnockRequests() {
|
||||||
// TODO: Implement
|
roomContext.send(viewAction: .viewKnockRequests)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var scrollToBottomButton: some View {
|
private var scrollToBottomButton: some View {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user