mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-05 20:09:04 +00:00
Start using the new (faster) RoomInfo record to populate the room and invite lists
This commit is contained in:
committed by
Stefan Ceriu
parent
8188fd2d2a
commit
fa78912027
@@ -21,10 +21,6 @@ enum InvitesScreenViewModelAction {
|
||||
struct InvitesScreenViewState: BindableState {
|
||||
var invites: [InvitesScreenRoomDetails] = []
|
||||
var bindings: InvitesScreenViewStateBindings = .init()
|
||||
|
||||
// ideally we wanted to derive this state from `invites` being `Optional.none`.
|
||||
// But we needed to make it a non optional array due to a strange crash in release builds (https://github.com/vector-im/element-x-ios/pull/1120)
|
||||
var isLoading = true
|
||||
}
|
||||
|
||||
struct InvitesScreenViewStateBindings {
|
||||
@@ -33,7 +29,6 @@ struct InvitesScreenViewStateBindings {
|
||||
|
||||
struct InvitesScreenRoomDetails: Identifiable {
|
||||
let roomDetails: RoomSummaryDetails
|
||||
var inviter: RoomMemberProxyProtocol?
|
||||
var isUnread: Bool
|
||||
|
||||
var isDirect: Bool {
|
||||
|
||||
@@ -28,7 +28,6 @@ class InvitesScreenViewModel: InvitesScreenViewModelType, InvitesScreenViewModel
|
||||
|
||||
private let previouslySeenInvites: Set<String>
|
||||
private let actionsSubject: PassthroughSubject<InvitesScreenViewModelAction, Never> = .init()
|
||||
@CancellableTask private var fetchInvitersTask: Task<Void, Never>?
|
||||
|
||||
var actions: AnyPublisher<InvitesScreenViewModelAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
@@ -83,58 +82,22 @@ class InvitesScreenViewModel: InvitesScreenViewModelType, InvitesScreenViewModel
|
||||
.removeDuplicates()
|
||||
.sink { [weak self] roomSummaries in
|
||||
guard let self else { return }
|
||||
|
||||
fetchInvitersTask = Task { [weak self] in
|
||||
guard let self else { return }
|
||||
let fullInvites = await self.buildInvites(from: roomSummaries)
|
||||
guard !Task.isCancelled else { return }
|
||||
self.state.invites = fullInvites
|
||||
self.state.isLoading = false
|
||||
self.appSettings.seenInvites = Set(fullInvites.map(\.roomDetails.id))
|
||||
|
||||
let invites: [InvitesScreenRoomDetails] = roomSummaries.compactMap { summary in
|
||||
guard case .filled(let details) = summary else {
|
||||
return nil
|
||||
}
|
||||
return InvitesScreenRoomDetails(roomDetails: details, isUnread: !self.previouslySeenInvites.contains(details.id))
|
||||
}
|
||||
|
||||
self.state.invites = invites
|
||||
self.appSettings.seenInvites = Set(invites.map(\.roomDetails.id))
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
private func buildInvites(from summaries: [RoomSummary]) async -> [InvitesScreenRoomDetails] {
|
||||
await Task.detached {
|
||||
let invites: [InvitesScreenRoomDetails] = summaries.compactMap { summary in
|
||||
guard case .filled(let details) = summary else {
|
||||
return nil
|
||||
}
|
||||
return InvitesScreenRoomDetails(roomDetails: details, isUnread: !self.previouslySeenInvites.contains(details.id))
|
||||
}
|
||||
|
||||
// fetch the inviters...
|
||||
return await withTaskGroup(of: (Int, RoomMemberProxyProtocol)?.self) { [clientProxy = self.clientProxy] group in
|
||||
var invitesWithInviters = invites
|
||||
|
||||
for inviteIndex in 0..<invites.count {
|
||||
group.addTask {
|
||||
let roomID = invites[inviteIndex].roomDetails.id
|
||||
guard let inviter = await clientProxy.roomForIdentifier(roomID)?.inviter() else {
|
||||
return nil
|
||||
}
|
||||
return (inviteIndex, inviter)
|
||||
}
|
||||
}
|
||||
|
||||
for await result in group {
|
||||
guard let (inviteIndex, inviter) = result else {
|
||||
continue
|
||||
}
|
||||
|
||||
invitesWithInviters[inviteIndex].inviter = inviter
|
||||
}
|
||||
|
||||
return invitesWithInviters
|
||||
}
|
||||
}
|
||||
.value
|
||||
}
|
||||
|
||||
private func startDeclineFlow(invite: InvitesScreenRoomDetails) {
|
||||
let roomPlaceholder = invite.isDirect ? (invite.inviter?.displayName ?? invite.roomDetails.name) : invite.roomDetails.name
|
||||
let roomPlaceholder = invite.isDirect ? (invite.roomDetails.inviter?.displayName ?? invite.roomDetails.name) : invite.roomDetails.name
|
||||
let title = invite.isDirect ? L10n.screenInvitesDeclineDirectChatTitle : L10n.screenInvitesDeclineChatTitle
|
||||
let message = invite.isDirect ? L10n.screenInvitesDeclineDirectChatMessage(roomPlaceholder) : L10n.screenInvitesDeclineChatMessage(roomPlaceholder)
|
||||
|
||||
|
||||
@@ -20,17 +20,11 @@ struct InvitesScreen: View {
|
||||
@ObservedObject var context: InvitesScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
Group {
|
||||
if context.viewState.isLoading {
|
||||
ProgressView()
|
||||
} else {
|
||||
mainContent
|
||||
}
|
||||
}
|
||||
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
|
||||
.navigationTitle(L10n.actionInvitesList)
|
||||
.alert(item: $context.alertInfo)
|
||||
.track(screen: .invites)
|
||||
mainContent
|
||||
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
|
||||
.navigationTitle(L10n.actionInvitesList)
|
||||
.alert(item: $context.alertInfo)
|
||||
.track(screen: .invites)
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
@@ -71,9 +71,9 @@ struct InvitesScreenCell: View {
|
||||
|
||||
@ViewBuilder
|
||||
private var inviterView: some View {
|
||||
if let invitedText = attributedInviteText, let name = invite.inviter?.displayName {
|
||||
if let invitedText = attributedInviteText, let name = invite.roomDetails.inviter?.displayName {
|
||||
HStack(alignment: .firstTextBaseline) {
|
||||
LoadableAvatarImage(url: invite.inviter?.avatarURL,
|
||||
LoadableAvatarImage(url: invite.roomDetails.inviter?.avatarURL,
|
||||
name: name,
|
||||
contentID: name,
|
||||
avatarSize: .custom(16),
|
||||
@@ -125,14 +125,14 @@ struct InvitesScreenCell: View {
|
||||
}
|
||||
|
||||
private var subtitle: String? {
|
||||
invite.isDirect ? invite.inviter?.userID : invite.roomDetails.canonicalAlias
|
||||
invite.isDirect ? invite.roomDetails.inviter?.userID : invite.roomDetails.canonicalAlias
|
||||
}
|
||||
|
||||
private var attributedInviteText: AttributedString? {
|
||||
guard
|
||||
invite.roomDetails.isDirect == false,
|
||||
let inviterName = invite.inviter?.displayName,
|
||||
let inviterID = invite.inviter?.userID
|
||||
let inviterName = invite.roomDetails.inviter?.displayName,
|
||||
let inviterID = invite.roomDetails.inviter?.userID
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
@@ -178,6 +178,10 @@ struct InvitesScreenCell_Previews: PreviewProvider {
|
||||
@MainActor
|
||||
private extension InvitesScreenRoomDetails {
|
||||
static var dm: InvitesScreenRoomDetails {
|
||||
let inviter = RoomMemberProxyMock()
|
||||
inviter.displayName = "Jack"
|
||||
inviter.userID = "@jack:somewhere.com"
|
||||
|
||||
let dmRoom = RoomSummaryDetails(id: "@someone:somewhere.com",
|
||||
name: "Some Guy",
|
||||
isDirect: true,
|
||||
@@ -185,15 +189,17 @@ private extension InvitesScreenRoomDetails {
|
||||
lastMessage: nil,
|
||||
lastMessageFormattedTimestamp: nil,
|
||||
unreadNotificationCount: 0,
|
||||
canonicalAlias: "#footest:somewhere.org")
|
||||
let inviter = RoomMemberProxyMock()
|
||||
inviter.displayName = "Jack"
|
||||
inviter.userID = "@jack:somewhere.com"
|
||||
|
||||
return .init(roomDetails: dmRoom, inviter: inviter, isUnread: false)
|
||||
canonicalAlias: "#footest:somewhere.org",
|
||||
inviter: inviter)
|
||||
return .init(roomDetails: dmRoom, isUnread: false)
|
||||
}
|
||||
|
||||
static func room(alias: String? = nil, avatarURL: URL? = nil, isUnread: Bool = true) -> InvitesScreenRoomDetails {
|
||||
let inviter = RoomMemberProxyMock()
|
||||
inviter.displayName = "Luca"
|
||||
inviter.userID = "@jack:somewhi.nl"
|
||||
inviter.avatarURL = avatarURL
|
||||
|
||||
let dmRoom = RoomSummaryDetails(id: "@someone:somewhere.com",
|
||||
name: "Awesome Room",
|
||||
isDirect: false,
|
||||
@@ -201,12 +207,8 @@ private extension InvitesScreenRoomDetails {
|
||||
lastMessage: nil,
|
||||
lastMessageFormattedTimestamp: nil,
|
||||
unreadNotificationCount: 0,
|
||||
canonicalAlias: alias)
|
||||
let inviter = RoomMemberProxyMock()
|
||||
inviter.displayName = "Luca"
|
||||
inviter.userID = "@jack:somewhi.nl"
|
||||
inviter.avatarURL = avatarURL
|
||||
|
||||
return .init(roomDetails: dmRoom, inviter: inviter, isUnread: isUnread)
|
||||
canonicalAlias: alias,
|
||||
inviter: inviter)
|
||||
return .init(roomDetails: dmRoom, isUnread: isUnread)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user