Knock Polishing part 4 (#3779)

* added decline and block and inviter redesign

* improved testing

* improved testing

* code improvement

* code improvement

* improved the code
This commit is contained in:
Mauro
2025-02-10 18:31:12 +01:00
committed by GitHub
parent 34d8adcf09
commit 22d0fae423
43 changed files with 231 additions and 91 deletions
@@ -90,6 +90,7 @@ struct JoinRoomScreenViewStateBindings {
enum JoinRoomScreenAlertType {
case declineInvite
case declineInviteAndBlock
case cancelKnock
case loadingError
}
@@ -100,6 +101,7 @@ enum JoinRoomScreenViewAction {
case join
case acceptInvite
case declineInvite
case declineInviteAndBlock(userID: String)
case forget
case dismiss
}
@@ -66,6 +66,8 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
showCancelKnockConfirmationAlert()
case .dismiss:
actionsSubject.send(.dismiss)
case .declineInviteAndBlock(let userID):
showDeclineAndBlockConfirmationAlert(userID: userID)
}
}
@@ -302,7 +304,27 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
secondaryButton: .init(title: L10n.screenJoinRoomCancelKnockAlertConfirmation, role: .destructive) { Task { await self.cancelKnock() } })
}
private func declineInvite() async {
private func showDeclineAndBlockConfirmationAlert(userID: String) {
state.bindings.alertInfo = .init(id: .declineInviteAndBlock,
title: L10n.screenJoinRoomDeclineAndBlockAlertTitle,
message: L10n.screenJoinRoomDeclineAndBlockAlertMessage(userID),
primaryButton: .init(title: L10n.actionCancel, role: .cancel, action: nil),
secondaryButton: .init(title: L10n.screenJoinRoomDeclineAndBlockAlertConfirmation, role: .destructive) { Task { await self.declineAndBlock(userID: userID) } })
}
private func declineAndBlock(userID: String) async {
guard await declineInvite() else {
return
}
// The decline alert and the view are already dismissed at this point so we can dispatch this separately as a best effort
// but only if the decline invite was succesfull
Task {
await clientProxy.ignoreUser(userID)
}
}
@discardableResult
private func declineInvite() async -> Bool {
defer {
userIndicatorController.retractIndicatorWithId(roomID)
}
@@ -311,16 +333,18 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
guard case let .invited(roomProxy) = room else {
userIndicatorController.submitIndicator(.init(title: L10n.errorUnknown))
return
return false
}
let result = await roomProxy.rejectInvitation()
if case .failure = result {
userIndicatorController.submitIndicator(.init(title: L10n.errorUnknown))
} else {
actionsSubject.send(.dismiss)
return false
}
actionsSubject.send(.dismiss)
return true
}
private func cancelKnock() async {
@@ -18,9 +18,16 @@ struct JoinRoomScreen: View {
private enum Focus {
case knockMessage
}
private var topPadding: CGFloat {
if context.viewState.roomDetails?.inviter != nil {
return 32
}
return context.viewState.mode == .knocked ? 151 : 44
}
var body: some View {
FullscreenDialog(topPadding: context.viewState.mode == .knocked ? 151 : 35) {
FullscreenDialog(topPadding: topPadding) {
if context.viewState.mode == .loading {
EmptyView()
} else {
@@ -50,6 +57,14 @@ struct JoinRoomScreen: View {
@ViewBuilder
private var defaultView: some View {
VStack(spacing: 16) {
if let inviter = context.viewState.roomDetails?.inviter {
RoomInviterLabel(inviter: inviter, mediaProvider: context.mediaProvider)
.multilineTextAlignment(.center)
.font(.compound.bodyMD)
.foregroundStyle(.compound.textSecondary)
.padding(.bottom, 44)
}
if let avatar = context.viewState.avatar {
RoomAvatarImage(avatar: avatar,
avatarSize: .room(on: .joinRoom),
@@ -80,12 +95,6 @@ struct JoinRoomScreen: View {
BadgeLabel(title: "\(memberCount)", icon: \.userProfile, isHighlighted: false)
}
if let inviter = context.viewState.roomDetails?.inviter {
RoomInviterLabel(inviter: inviter, mediaProvider: context.mediaProvider)
.font(.compound.bodyMD)
.foregroundStyle(.compound.textSecondary)
}
if let topic = context.viewState.roomDetails?.topic {
Text(topic)
.font(.compound.bodyMD)
@@ -178,8 +187,17 @@ struct JoinRoomScreen: View {
bottomNoticeMessage(L10n.screenJoinRoomInviteRequiredMessage)
case .invited:
ViewThatFits {
HStack(spacing: 8) { inviteButtons }
VStack(spacing: 16) { inviteButtons }
VStack(spacing: 24) {
HStack(spacing: 16) {
inviteButtons
}
declineAndBlockButton
}
VStack(spacing: 16) {
inviteButtons
declineAndBlockButton
}
}
case .banned(let sender, let reason):
VStack(spacing: 24) {
@@ -253,6 +271,19 @@ struct JoinRoomScreen: View {
.buttonStyle(.compound(.primary))
}
@ViewBuilder
var declineAndBlockButton: some View {
if let inviter = context.viewState.roomDetails?.inviter {
Button(role: .destructive) {
context.send(viewAction: .declineInviteAndBlock(userID: inviter.id))
} label: {
Text(L10n.screenJoinRoomDeclineAndBlockButtonTitle)
.padding(.vertical, 14)
}
.buttonStyle(.compound(.plain))
}
}
var joinButton: some View {
Button(L10n.screenJoinRoomJoinAction) { context.send(viewAction: .join) }
.buttonStyle(.compound(.super))