Report room and decline & block screens tweaks (#4044)

* report rom and decline and block screens tweaks

- Use the copies: "Leave room" and "Report room" everywhere, also in DMs
- Report reason in report room is now mandatory.
- Report reason in decline and block is now mandatory if the report action is set to on.
- Generic alert for failure of main API in both report room and decline and block has been added

* report room and decline and block screen previews
This commit is contained in:
Mauro
2025-04-22 11:44:20 +02:00
committed by GitHub
parent cffcb5c7b9
commit 7183b0fe19
19 changed files with 64 additions and 36 deletions
@@ -15,7 +15,10 @@ struct DeclineAndBlockScreenViewState: BindableState {
var bindings = DeclineAndBlockScreenViewStateBindings()
var isDeclineDisabled: Bool {
!bindings.shouldBlockUser && !bindings.shouldReport
if bindings.shouldReport {
return bindings.reportReason.isEmpty
}
return !bindings.shouldBlockUser && !bindings.shouldReport
}
}
@@ -23,9 +26,15 @@ struct DeclineAndBlockScreenViewStateBindings {
var shouldBlockUser = true
var shouldReport = false
var reportReason = ""
var alert: AlertInfo<DeclineAndBlockAlertType>?
}
enum DeclineAndBlockScreenViewAction {
case decline
case dismiss
}
enum DeclineAndBlockAlertType {
case declineFailed
}
@@ -50,7 +50,7 @@ class DeclineAndBlockScreenViewModel: DeclineAndBlockScreenViewModelType, Declin
guard case let .invited(roomProxy) = await clientProxy.roomForIdentifier(roomID) else {
MXLog.error("DeclineAndBlockScreenViewModel: Unable to find an invited room for identifier \(roomID)")
hideLoadingIndicator()
showError()
showTryAgainAlert { [weak self] in Task { await self?.decline() } }
return
}
@@ -58,7 +58,7 @@ class DeclineAndBlockScreenViewModel: DeclineAndBlockScreenViewModelType, Declin
case .success:
var shouldShowFailure = false
if state.bindings.shouldReport {
shouldShowFailure = await clientProxy.reportRoomForIdentifier(roomID, reason: state.bindings.reportReason.isBlank ? nil : state.bindings.reportReason).isFailure
shouldShowFailure = await clientProxy.reportRoomForIdentifier(roomID, reason: state.bindings.reportReason.isEmpty ? nil : state.bindings.reportReason).isFailure
}
if state.bindings.shouldBlockUser {
@@ -74,7 +74,7 @@ class DeclineAndBlockScreenViewModel: DeclineAndBlockScreenViewModelType, Declin
actionsSubject.send(.dismiss(hasDeclined: true))
case .failure:
hideLoadingIndicator()
showError()
showTryAgainAlert { [weak self] in Task { await self?.decline() } }
}
}
@@ -97,6 +97,14 @@ class DeclineAndBlockScreenViewModel: DeclineAndBlockScreenViewModelType, Declin
userIndicatorController.submitIndicator(.init(title: L10n.errorUnknown))
}
private func showTryAgainAlert(retryAction: @escaping () -> Void) {
state.bindings.alert = .init(id: .declineFailed,
title: L10n.commonSomethingWentWrong,
message: L10n.commonSomethingWentWrongMessage,
primaryButton: .init(title: L10n.actionDismiss, role: .cancel, action: nil),
secondaryButton: .init(title: L10n.actionTryAgain, action: retryAction))
}
private func showSuccess() {
userIndicatorController.submitIndicator(.init(title: L10n.commonSuccess, iconName: "checkmark"))
}
@@ -24,6 +24,7 @@ struct DeclineAndBlockScreen: View {
.navigationBarTitleDisplayMode(.inline)
.toolbar { toolbar }
.animation(.elementDefault, value: context.shouldReport)
.alert(item: $context.alert)
}
private var blockUserSection: some View {
@@ -73,7 +73,7 @@ struct HomeScreenRoomList: View {
Button(role: .destructive) {
context.send(viewAction: .reportRoom(roomIdentifier: room.id))
} label: {
Label(room.isDirect ? L10n.actionReportDm : L10n.actionReportRoom, icon: \.chatProblem)
Label(L10n.actionReportRoom, icon: \.chatProblem)
}
}
@@ -13,6 +13,10 @@ enum ReportRoomScreenViewModelAction: Equatable {
struct ReportRoomScreenViewState: BindableState {
var bindings = ReportRoomScreenViewStateBindings()
var canReport: Bool {
!bindings.reason.isEmpty
}
}
struct ReportRoomScreenViewStateBindings {
@@ -27,5 +31,6 @@ enum ReportRoomScreenViewAction {
}
enum ReportRoomScreenAlertType {
case reportRoomFailed
case leaveRoomFailed
}
@@ -38,7 +38,7 @@ class ReportRoomScreenViewModel: ReportRoomScreenViewModelType, ReportRoomScreen
private func report() async {
showLoadingIndicator()
let result = await roomProxy.reportRoom(reason: state.bindings.reason.isBlank ? nil : state.bindings.reason)
let result = await roomProxy.reportRoom(reason: state.bindings.reason.isEmpty ? nil : state.bindings.reason)
switch result {
case .success:
@@ -51,7 +51,11 @@ class ReportRoomScreenViewModel: ReportRoomScreenViewModelType, ReportRoomScreen
}
case .failure:
hideLoadingIndicator()
userIndicatorController.submitIndicator(.init(title: L10n.errorUnknown))
state.bindings.alert = .init(id: .reportRoomFailed,
title: L10n.commonSomethingWentWrong,
message: L10n.commonSomethingWentWrongMessage,
primaryButton: .init(title: L10n.actionDismiss, role: .cancel, action: nil),
secondaryButton: .init(title: L10n.actionTryAgain) { [weak self] in Task { await self?.report() } })
}
}
@@ -72,7 +76,7 @@ class ReportRoomScreenViewModel: ReportRoomScreenViewModelType, ReportRoomScreen
title: L10n.screenReportRoomLeaveFailedAlertTitle,
message: L10n.screenReportRoomLeaveFailedAlertMessage,
primaryButton: .init(title: L10n.actionDismiss, role: .cancel) { [weak self] in self?.actionsSubject.send(.dismiss(shouldLeaveRoom: false)) },
secondaryButton: .init(title: L10n.actionRetry) { [weak self] in Task { await self?.leaveRoom(showLoading: true) } })
secondaryButton: .init(title: L10n.actionTryAgain) { [weak self] in Task { await self?.leaveRoom(showLoading: true) } })
}
}
@@ -53,6 +53,7 @@ struct ReportRoomScreen: View {
Button(L10n.actionReport) {
context.send(viewAction: .report)
}
.disabled(!context.viewState.canReport)
}
}
}
@@ -272,23 +272,15 @@ struct RoomDetailsScreen: View {
}
}
private var leaveRoomTitle: String {
context.viewState.dmRecipientInfo == nil ? L10n.screenRoomDetailsLeaveRoomTitle : L10n.screenRoomDetailsLeaveConversationTitle
}
private var reportRoomTitle: String {
context.viewState.dmRecipientInfo == nil ? L10n.actionReportRoom : L10n.actionReportDm
}
private var leaveRoomSection: some View {
Section {
if context.viewState.reportRoomEnabled {
ListRow(label: .action(title: reportRoomTitle,
ListRow(label: .action(title: L10n.actionReportRoom,
icon: \.chatProblem,
role: .destructive),
kind: .button { context.send(viewAction: .processTapReport) })
}
ListRow(label: .action(title: leaveRoomTitle,
ListRow(label: .action(title: L10n.screenRoomDetailsLeaveRoomTitle,
icon: \.leave,
role: .destructive),
kind: .button { context.send(viewAction: .processTapLeave) })