Implement Knock Logic (#3573)

* WIP RequestToJoin struct

* implemented the logic to display the cells

* knock request banner accept flow

* mark all knocks as seen implemented

* details logic

* implemented accept, decline and ban in the list

* added a loader and modified the stacked view

of the banner

* pr suggestions

* updated naming and loading strings

* added the initial loading state

improved code and the tests

* updated a string that has changed

* code improvement

* tests for the room screen view model

* room details tests

and improved the knock requests tests for the room screen

* knock requests list tests

* added error state alerts with retry

* struct has been renamed on the sdk

so I renamed it also on the app side

* update SDK
This commit is contained in:
Mauro
2024-12-16 15:32:45 +01:00
committed by GitHub
parent 016cdc687a
commit 45a630dd85
54 changed files with 1700 additions and 150 deletions
@@ -15,9 +15,9 @@
import Compound
import SwiftUI
struct KnockRequestCellInfo: Identifiable {
/// user identifier of the usee that sent the request
let id: String
struct KnockRequestCellInfo: Equatable {
let eventID: String
let userID: String
let displayName: String?
let avatarURL: URL?
let timestamp: String?
@@ -35,7 +35,7 @@ struct KnockRequestCell: View {
HStack(alignment: .top, spacing: 16) {
LoadableAvatarImage(url: cellInfo.avatarURL,
name: cellInfo.displayName,
contentID: cellInfo.id,
contentID: cellInfo.userID,
avatarSize: .user(on: .knockingUserList),
mediaProvider: mediaProvider)
VStack(alignment: .leading, spacing: 12) {
@@ -60,7 +60,7 @@ struct KnockRequestCell: View {
private var header: some View {
VStack(alignment: .leading, spacing: 0) {
HStack(alignment: .top, spacing: 0) {
Text(cellInfo.displayName ?? cellInfo.id)
Text(cellInfo.displayName ?? cellInfo.userID)
.font(.compound.bodyLGSemibold)
.foregroundStyle(.compound.textPrimary)
.frame(maxWidth: .infinity, alignment: .leading)
@@ -71,7 +71,7 @@ struct KnockRequestCell: View {
}
}
if cellInfo.displayName != nil {
Text(cellInfo.id)
Text(cellInfo.userID)
.font(.compound.bodyMD)
.foregroundStyle(.compound.textSecondary)
}
@@ -85,14 +85,14 @@ struct KnockRequestCell: View {
HStack(spacing: 16) {
if let onDecline {
Button(L10n.actionDecline) {
onDecline(cellInfo.id)
onDecline(cellInfo.eventID)
}
.buttonStyle(.compound(.secondary, size: .medium))
}
if let onAccept {
Button(L10n.actionAccept) {
onAccept(cellInfo.id)
onAccept(cellInfo.eventID)
}
.buttonStyle(.compound(.primary, size: .medium))
}
@@ -101,7 +101,7 @@ struct KnockRequestCell: View {
if let onDeclineAndBan {
Button(role: .destructive) {
onDeclineAndBan(cellInfo.id)
onDeclineAndBan(cellInfo.eventID)
} label: {
Text(L10n.screenKnockRequestsListDeclineAndBanActionTitle)
.padding(.top, 8)
@@ -166,15 +166,19 @@ private struct DisclosableText: View {
}
}
extension KnockRequestCellInfo: Identifiable {
var id: String { eventID }
}
struct KnockRequestCell_Previews: PreviewProvider, TestablePreview {
// 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(eventID: "1", userID: "@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(eventID: "1", userID: "@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(eventID: "1", userID: "@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(eventID: "1", userID: "@alice:matrix.org", displayName: nil, avatarURL: nil, timestamp: "20 Nov 2024", reason: nil)
static var previews: some View {
KnockRequestCell(cellInfo: aliceWithLongReason) { _ in } onDecline: { _ in } onDeclineAndBan: { _ in }