Knock Requests banner display logic (#3550)

* added the join rule to the info

* update SDK and added logic to display the banner

in the room screen

* added the logic to display the banner
This commit is contained in:
Mauro
2024-11-25 13:14:02 +01:00
committed by GitHub
parent 9180bac13c
commit 26e07f2457
16 changed files with 131 additions and 42 deletions
@@ -11,9 +11,17 @@ enum KnockRequestsListScreenViewModelAction { }
struct KnockRequestsListScreenViewState: BindableState {
var requests: [KnockRequestCellInfo] = []
var canAccept = false
var canDecline = false
var canBan = false
// 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 canDecline = true
var canBan = true
var isKnockableRoom = true
// If all the permissions are denied or the join rule changes while we are in the view
// we want to stop displaying any request
var shouldDisplayRequests: Bool {
!requests.isEmpty && isKnockableRoom && (canAccept || canDecline || canBan)
}
}
enum KnockRequestsListScreenViewAction {
@@ -22,6 +22,7 @@ class KnockRequestsListScreenViewModel: KnockRequestsListScreenViewModelType, Kn
self.roomProxy = roomProxy
super.init(initialViewState: KnockRequestsListScreenViewState(), mediaProvider: mediaProvider)
updateRoomInfo(roomInfo: roomProxy.infoPublisher.value)
Task {
await updatePermissions()
}
@@ -48,13 +49,23 @@ class KnockRequestsListScreenViewModel: KnockRequestsListScreenViewModelType, Kn
private func setupSubscriptions() {
roomProxy.infoPublisher
.throttle(for: .milliseconds(200), scheduler: DispatchQueue.main, latest: true)
.sink { [weak self] _ in
.receive(on: DispatchQueue.main)
.sink { [weak self] roomInfo in
self?.updateRoomInfo(roomInfo: roomInfo)
Task { await self?.updatePermissions() }
}
.store(in: &cancellables)
}
private func updateRoomInfo(roomInfo: RoomInfoProxy) {
switch roomInfo.joinRule {
case .knock, .knockRestricted:
state.isKnockableRoom = true
default:
state.isKnockableRoom = false
}
}
private func updatePermissions() async {
state.canAccept = await (try? roomProxy.canUserInvite(userID: roomProxy.ownUserID).get()) == true
state.canDecline = await (try? roomProxy.canUserKick(userID: roomProxy.ownUserID).get()) == true
@@ -17,12 +17,12 @@ struct KnockRequestsListScreen: View {
.navigationTitle(L10n.screenKnockRequestsListTitle)
.background(.compound.bgCanvasDefault)
.overlay {
if context.viewState.requests.isEmpty {
if !context.viewState.shouldDisplayRequests {
KnockRequestsListEmptyStateView()
}
}
.safeAreaInset(edge: .bottom) {
if !context.viewState.requests.isEmpty {
if context.viewState.shouldDisplayRequests {
acceptAllButton
}
}
@@ -32,14 +32,16 @@ struct KnockRequestsListScreen: View {
private var mainContent: some View {
ScrollView {
LazyVStack(spacing: 0) {
ForEach(context.viewState.requests) { requestInfo in
ListRow(kind: .custom {
KnockRequestCell(cellInfo: requestInfo,
mediaProvider: context.mediaProvider,
onAccept: context.viewState.canAccept ? onAccept : nil,
onDecline: context.viewState.canDecline ? onDecline : nil,
onDeclineAndBan: context.viewState.canBan ? onDeclineAndBan : nil)
})
if context.viewState.shouldDisplayRequests {
ForEach(context.viewState.requests) { requestInfo in
ListRow(kind: .custom {
KnockRequestCell(cellInfo: requestInfo,
mediaProvider: context.mediaProvider,
onAccept: context.viewState.canAccept ? onAccept : nil,
onDecline: context.viewState.canDecline ? onDecline : nil,
onDeclineAndBan: context.viewState.canBan ? onDeclineAndBan : nil)
})
}
}
}
.padding(.top, 40)
@@ -79,10 +81,7 @@ struct KnockRequestsListScreen_Previews: PreviewProvider, TestablePreview {
// 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: "@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!")],
canAccept: true,
canDecline: true,
canBan: true))
.init(id: "@dan:matrix.org", displayName: "Dan", avatarUrl: nil, timestamp: "Now", reason: "Hello! It's a me! Dan!")]))
static var previews: some View {
NavigationStack {