mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-06 04:18:31 +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
@@ -1029,6 +1029,7 @@
|
|||||||
47F29139BC2A804CE5E0757E /* MediaUploadPreviewScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadPreviewScreenViewModel.swift; sourceTree = "<group>"; };
|
47F29139BC2A804CE5E0757E /* MediaUploadPreviewScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadPreviewScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
4959CECEC984B3995616F427 /* DataProtectionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataProtectionManager.swift; sourceTree = "<group>"; };
|
4959CECEC984B3995616F427 /* DataProtectionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataProtectionManager.swift; sourceTree = "<group>"; };
|
||||||
49D2C8E66E83EA578A7F318A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
49D2C8E66E83EA578A7F318A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
||||||
|
49E6066092ED45E36BB306F7 /* zh-Hant-TW */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "zh-Hant-TW"; path = "zh-Hant-TW.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
|
||||||
49E751D7EDB6043238111D90 /* UNNotificationRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UNNotificationRequest.swift; sourceTree = "<group>"; };
|
49E751D7EDB6043238111D90 /* UNNotificationRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UNNotificationRequest.swift; sourceTree = "<group>"; };
|
||||||
4A4AD793D50748F8997E5B15 /* TimelineItemMacContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemMacContextMenu.swift; sourceTree = "<group>"; };
|
4A4AD793D50748F8997E5B15 /* TimelineItemMacContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemMacContextMenu.swift; sourceTree = "<group>"; };
|
||||||
4AB7D7DAAAF662DED9D02379 /* MockMediaLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockMediaLoader.swift; sourceTree = "<group>"; };
|
4AB7D7DAAAF662DED9D02379 /* MockMediaLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockMediaLoader.swift; sourceTree = "<group>"; };
|
||||||
@@ -1217,6 +1218,7 @@
|
|||||||
8FC803282F9268D49F4ABF14 /* AppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinator.swift; sourceTree = "<group>"; };
|
8FC803282F9268D49F4ABF14 /* AppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinator.swift; sourceTree = "<group>"; };
|
||||||
90A55430639712CFACA34F43 /* TextRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRoomTimelineItem.swift; sourceTree = "<group>"; };
|
90A55430639712CFACA34F43 /* TextRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||||
90F2F8998E5632668B0AD848 /* RoomTimelineItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemView.swift; sourceTree = "<group>"; };
|
90F2F8998E5632668B0AD848 /* RoomTimelineItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemView.swift; sourceTree = "<group>"; };
|
||||||
|
91CF6F7D08228D16BA69B63B /* zh-Hant-TW */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant-TW"; path = "zh-Hant-TW.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||||
923485F85E1D765EF9D20E88 /* UserProfileCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileCell.swift; sourceTree = "<group>"; };
|
923485F85E1D765EF9D20E88 /* UserProfileCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileCell.swift; sourceTree = "<group>"; };
|
||||||
92390F9FA98255440A6BF5F8 /* OIDCAuthenticationPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OIDCAuthenticationPresenter.swift; sourceTree = "<group>"; };
|
92390F9FA98255440A6BF5F8 /* OIDCAuthenticationPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OIDCAuthenticationPresenter.swift; sourceTree = "<group>"; };
|
||||||
92FCD9116ADDE820E4E30F92 /* UIKitBackgroundTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitBackgroundTask.swift; sourceTree = "<group>"; };
|
92FCD9116ADDE820E4E30F92 /* UIKitBackgroundTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitBackgroundTask.swift; sourceTree = "<group>"; };
|
||||||
@@ -3949,6 +3951,7 @@
|
|||||||
ro,
|
ro,
|
||||||
ru,
|
ru,
|
||||||
sk,
|
sk,
|
||||||
|
"zh-Hant-TW",
|
||||||
);
|
);
|
||||||
mainGroup = 405B00F139AEE3994601B36A;
|
mainGroup = 405B00F139AEE3994601B36A;
|
||||||
packageReferences = (
|
packageReferences = (
|
||||||
@@ -4906,6 +4909,7 @@
|
|||||||
E9D059BFE329BE09B6D96A9F /* ro */,
|
E9D059BFE329BE09B6D96A9F /* ro */,
|
||||||
E5F2B6443D1ED8602F328539 /* ru */,
|
E5F2B6443D1ED8602F328539 /* ru */,
|
||||||
667DD3A9D932D7D9EB380CAA /* sk */,
|
667DD3A9D932D7D9EB380CAA /* sk */,
|
||||||
|
49E6066092ED45E36BB306F7 /* zh-Hant-TW */,
|
||||||
);
|
);
|
||||||
name = Localizable.stringsdict;
|
name = Localizable.stringsdict;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -4922,6 +4926,7 @@
|
|||||||
33E49C5C6F802B4D94CA78D1 /* ro */,
|
33E49C5C6F802B4D94CA78D1 /* ro */,
|
||||||
E8294DB9E95C0C0630418466 /* ru */,
|
E8294DB9E95C0C0630418466 /* ru */,
|
||||||
AD378D580A41E42560C60E9C /* sk */,
|
AD378D580A41E42560C60E9C /* sk */,
|
||||||
|
91CF6F7D08228D16BA69B63B /* zh-Hant-TW */,
|
||||||
);
|
);
|
||||||
name = Localizable.strings;
|
name = Localizable.strings;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -5460,7 +5465,7 @@
|
|||||||
repositoryURL = "https://github.com/matrix-org/matrix-rust-components-swift";
|
repositoryURL = "https://github.com/matrix-org/matrix-rust-components-swift";
|
||||||
requirement = {
|
requirement = {
|
||||||
kind = exactVersion;
|
kind = exactVersion;
|
||||||
version = "1.0.107-alpha";
|
version = "1.0.108-alpha";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
821C67C9A7F8CC3FD41B28B4 /* XCRemoteSwiftPackageReference "emojibase-bindings" */ = {
|
821C67C9A7F8CC3FD41B28B4 /* XCRemoteSwiftPackageReference "emojibase-bindings" */ = {
|
||||||
|
|||||||
@@ -129,8 +129,8 @@
|
|||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/matrix-org/matrix-rust-components-swift",
|
"location" : "https://github.com/matrix-org/matrix-rust-components-swift",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "28211915a5a5ca926798d12bedc3bf1a352714fd",
|
"revision" : "3166b3e6d35779aa78025a0b9143def6a7ee1c51",
|
||||||
"version" : "1.0.107-alpha"
|
"version" : "1.0.108-alpha"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,10 +21,6 @@ enum InvitesScreenViewModelAction {
|
|||||||
struct InvitesScreenViewState: BindableState {
|
struct InvitesScreenViewState: BindableState {
|
||||||
var invites: [InvitesScreenRoomDetails] = []
|
var invites: [InvitesScreenRoomDetails] = []
|
||||||
var bindings: InvitesScreenViewStateBindings = .init()
|
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 {
|
struct InvitesScreenViewStateBindings {
|
||||||
@@ -33,7 +29,6 @@ struct InvitesScreenViewStateBindings {
|
|||||||
|
|
||||||
struct InvitesScreenRoomDetails: Identifiable {
|
struct InvitesScreenRoomDetails: Identifiable {
|
||||||
let roomDetails: RoomSummaryDetails
|
let roomDetails: RoomSummaryDetails
|
||||||
var inviter: RoomMemberProxyProtocol?
|
|
||||||
var isUnread: Bool
|
var isUnread: Bool
|
||||||
|
|
||||||
var isDirect: Bool {
|
var isDirect: Bool {
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ class InvitesScreenViewModel: InvitesScreenViewModelType, InvitesScreenViewModel
|
|||||||
|
|
||||||
private let previouslySeenInvites: Set<String>
|
private let previouslySeenInvites: Set<String>
|
||||||
private let actionsSubject: PassthroughSubject<InvitesScreenViewModelAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<InvitesScreenViewModelAction, Never> = .init()
|
||||||
@CancellableTask private var fetchInvitersTask: Task<Void, Never>?
|
|
||||||
|
|
||||||
var actions: AnyPublisher<InvitesScreenViewModelAction, Never> {
|
var actions: AnyPublisher<InvitesScreenViewModelAction, Never> {
|
||||||
actionsSubject.eraseToAnyPublisher()
|
actionsSubject.eraseToAnyPublisher()
|
||||||
@@ -84,57 +83,21 @@ class InvitesScreenViewModel: InvitesScreenViewModelType, InvitesScreenViewModel
|
|||||||
.sink { [weak self] roomSummaries in
|
.sink { [weak self] roomSummaries in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
|
|
||||||
fetchInvitersTask = Task { [weak self] in
|
let invites: [InvitesScreenRoomDetails] = roomSummaries.compactMap { summary in
|
||||||
guard let self else { return }
|
guard case .filled(let details) = summary else {
|
||||||
let fullInvites = await self.buildInvites(from: roomSummaries)
|
return nil
|
||||||
guard !Task.isCancelled else { return }
|
}
|
||||||
self.state.invites = fullInvites
|
return InvitesScreenRoomDetails(roomDetails: details, isUnread: !self.previouslySeenInvites.contains(details.id))
|
||||||
self.state.isLoading = false
|
|
||||||
self.appSettings.seenInvites = Set(fullInvites.map(\.roomDetails.id))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.state.invites = invites
|
||||||
|
self.appSettings.seenInvites = Set(invites.map(\.roomDetails.id))
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.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) {
|
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 title = invite.isDirect ? L10n.screenInvitesDeclineDirectChatTitle : L10n.screenInvitesDeclineChatTitle
|
||||||
let message = invite.isDirect ? L10n.screenInvitesDeclineDirectChatMessage(roomPlaceholder) : L10n.screenInvitesDeclineChatMessage(roomPlaceholder)
|
let message = invite.isDirect ? L10n.screenInvitesDeclineDirectChatMessage(roomPlaceholder) : L10n.screenInvitesDeclineChatMessage(roomPlaceholder)
|
||||||
|
|
||||||
|
|||||||
@@ -20,17 +20,11 @@ struct InvitesScreen: View {
|
|||||||
@ObservedObject var context: InvitesScreenViewModel.Context
|
@ObservedObject var context: InvitesScreenViewModel.Context
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Group {
|
mainContent
|
||||||
if context.viewState.isLoading {
|
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
|
||||||
ProgressView()
|
.navigationTitle(L10n.actionInvitesList)
|
||||||
} else {
|
.alert(item: $context.alertInfo)
|
||||||
mainContent
|
.track(screen: .invites)
|
||||||
}
|
|
||||||
}
|
|
||||||
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
|
|
||||||
.navigationTitle(L10n.actionInvitesList)
|
|
||||||
.alert(item: $context.alertInfo)
|
|
||||||
.track(screen: .invites)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|||||||
@@ -71,9 +71,9 @@ struct InvitesScreenCell: View {
|
|||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var inviterView: some View {
|
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) {
|
HStack(alignment: .firstTextBaseline) {
|
||||||
LoadableAvatarImage(url: invite.inviter?.avatarURL,
|
LoadableAvatarImage(url: invite.roomDetails.inviter?.avatarURL,
|
||||||
name: name,
|
name: name,
|
||||||
contentID: name,
|
contentID: name,
|
||||||
avatarSize: .custom(16),
|
avatarSize: .custom(16),
|
||||||
@@ -125,14 +125,14 @@ struct InvitesScreenCell: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var subtitle: String? {
|
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? {
|
private var attributedInviteText: AttributedString? {
|
||||||
guard
|
guard
|
||||||
invite.roomDetails.isDirect == false,
|
invite.roomDetails.isDirect == false,
|
||||||
let inviterName = invite.inviter?.displayName,
|
let inviterName = invite.roomDetails.inviter?.displayName,
|
||||||
let inviterID = invite.inviter?.userID
|
let inviterID = invite.roomDetails.inviter?.userID
|
||||||
else {
|
else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -178,6 +178,10 @@ struct InvitesScreenCell_Previews: PreviewProvider {
|
|||||||
@MainActor
|
@MainActor
|
||||||
private extension InvitesScreenRoomDetails {
|
private extension InvitesScreenRoomDetails {
|
||||||
static var dm: InvitesScreenRoomDetails {
|
static var dm: InvitesScreenRoomDetails {
|
||||||
|
let inviter = RoomMemberProxyMock()
|
||||||
|
inviter.displayName = "Jack"
|
||||||
|
inviter.userID = "@jack:somewhere.com"
|
||||||
|
|
||||||
let dmRoom = RoomSummaryDetails(id: "@someone:somewhere.com",
|
let dmRoom = RoomSummaryDetails(id: "@someone:somewhere.com",
|
||||||
name: "Some Guy",
|
name: "Some Guy",
|
||||||
isDirect: true,
|
isDirect: true,
|
||||||
@@ -185,15 +189,17 @@ private extension InvitesScreenRoomDetails {
|
|||||||
lastMessage: nil,
|
lastMessage: nil,
|
||||||
lastMessageFormattedTimestamp: nil,
|
lastMessageFormattedTimestamp: nil,
|
||||||
unreadNotificationCount: 0,
|
unreadNotificationCount: 0,
|
||||||
canonicalAlias: "#footest:somewhere.org")
|
canonicalAlias: "#footest:somewhere.org",
|
||||||
let inviter = RoomMemberProxyMock()
|
inviter: inviter)
|
||||||
inviter.displayName = "Jack"
|
return .init(roomDetails: dmRoom, isUnread: false)
|
||||||
inviter.userID = "@jack:somewhere.com"
|
|
||||||
|
|
||||||
return .init(roomDetails: dmRoom, inviter: inviter, isUnread: false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static func room(alias: String? = nil, avatarURL: URL? = nil, isUnread: Bool = true) -> InvitesScreenRoomDetails {
|
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",
|
let dmRoom = RoomSummaryDetails(id: "@someone:somewhere.com",
|
||||||
name: "Awesome Room",
|
name: "Awesome Room",
|
||||||
isDirect: false,
|
isDirect: false,
|
||||||
@@ -201,12 +207,8 @@ private extension InvitesScreenRoomDetails {
|
|||||||
lastMessage: nil,
|
lastMessage: nil,
|
||||||
lastMessageFormattedTimestamp: nil,
|
lastMessageFormattedTimestamp: nil,
|
||||||
unreadNotificationCount: 0,
|
unreadNotificationCount: 0,
|
||||||
canonicalAlias: alias)
|
canonicalAlias: alias,
|
||||||
let inviter = RoomMemberProxyMock()
|
inviter: inviter)
|
||||||
inviter.displayName = "Luca"
|
return .init(roomDetails: dmRoom, isUnread: isUnread)
|
||||||
inviter.userID = "@jack:somewhi.nl"
|
|
||||||
inviter.avatarURL = avatarURL
|
|
||||||
|
|
||||||
return .init(roomDetails: dmRoom, inviter: inviter, isUnread: isUnread)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -399,12 +399,14 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
roomSummaryProvider = RoomSummaryProvider(roomListService: roomListService,
|
roomSummaryProvider = RoomSummaryProvider(roomListService: roomListService,
|
||||||
eventStringBuilder: eventStringBuilder,
|
eventStringBuilder: eventStringBuilder,
|
||||||
name: "AllRooms",
|
name: "AllRooms",
|
||||||
appSettings: appSettings)
|
appSettings: appSettings,
|
||||||
|
backgroundTaskService: backgroundTaskService)
|
||||||
try await roomSummaryProvider?.setRoomList(roomListService.allRooms())
|
try await roomSummaryProvider?.setRoomList(roomListService.allRooms())
|
||||||
inviteSummaryProvider = RoomSummaryProvider(roomListService: roomListService,
|
inviteSummaryProvider = RoomSummaryProvider(roomListService: roomListService,
|
||||||
eventStringBuilder: eventStringBuilder,
|
eventStringBuilder: eventStringBuilder,
|
||||||
name: "Invites",
|
name: "Invites",
|
||||||
appSettings: appSettings)
|
appSettings: appSettings,
|
||||||
|
backgroundTaskService: backgroundTaskService)
|
||||||
|
|
||||||
self.syncService = syncService
|
self.syncService = syncService
|
||||||
self.roomListService = roomListService
|
self.roomListService = roomListService
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ extension Array where Element == RoomSummary {
|
|||||||
lastMessage: AttributedString("Prosciutto beef ribs pancetta filet mignon kevin hamburger, chuck ham venison picanha. Beef ribs chislic turkey biltong tenderloin."),
|
lastMessage: AttributedString("Prosciutto beef ribs pancetta filet mignon kevin hamburger, chuck ham venison picanha. Beef ribs chislic turkey biltong tenderloin."),
|
||||||
lastMessageFormattedTimestamp: "Now",
|
lastMessageFormattedTimestamp: "Now",
|
||||||
unreadNotificationCount: 4,
|
unreadNotificationCount: 4,
|
||||||
canonicalAlias: nil)),
|
canonicalAlias: nil,
|
||||||
|
inviter: nil)),
|
||||||
.filled(details: RoomSummaryDetails(id: "2",
|
.filled(details: RoomSummaryDetails(id: "2",
|
||||||
name: "Second room",
|
name: "Second room",
|
||||||
isDirect: true,
|
isDirect: true,
|
||||||
@@ -65,7 +66,8 @@ extension Array where Element == RoomSummary {
|
|||||||
lastMessage: nil,
|
lastMessage: nil,
|
||||||
lastMessageFormattedTimestamp: nil,
|
lastMessageFormattedTimestamp: nil,
|
||||||
unreadNotificationCount: 1,
|
unreadNotificationCount: 1,
|
||||||
canonicalAlias: nil)),
|
canonicalAlias: nil,
|
||||||
|
inviter: nil)),
|
||||||
.filled(details: RoomSummaryDetails(id: "3",
|
.filled(details: RoomSummaryDetails(id: "3",
|
||||||
name: "Third room",
|
name: "Third room",
|
||||||
isDirect: true,
|
isDirect: true,
|
||||||
@@ -73,7 +75,8 @@ extension Array where Element == RoomSummary {
|
|||||||
lastMessage: try? AttributedString(markdown: "**@mock:client.com**: T-bone beef ribs bacon"),
|
lastMessage: try? AttributedString(markdown: "**@mock:client.com**: T-bone beef ribs bacon"),
|
||||||
lastMessageFormattedTimestamp: "Later",
|
lastMessageFormattedTimestamp: "Later",
|
||||||
unreadNotificationCount: 0,
|
unreadNotificationCount: 0,
|
||||||
canonicalAlias: nil)),
|
canonicalAlias: nil,
|
||||||
|
inviter: nil)),
|
||||||
.empty
|
.empty
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -84,7 +87,8 @@ extension Array where Element == RoomSummary {
|
|||||||
lastMessage: nil,
|
lastMessage: nil,
|
||||||
lastMessageFormattedTimestamp: nil,
|
lastMessageFormattedTimestamp: nil,
|
||||||
unreadNotificationCount: 0,
|
unreadNotificationCount: 0,
|
||||||
canonicalAlias: "#footest:somewhere.org")),
|
canonicalAlias: "#footest:somewhere.org",
|
||||||
|
inviter: nil)),
|
||||||
.filled(details: RoomSummaryDetails(id: "someAwesomeRoomId2",
|
.filled(details: RoomSummaryDetails(id: "someAwesomeRoomId2",
|
||||||
name: "Second room",
|
name: "Second room",
|
||||||
isDirect: true,
|
isDirect: true,
|
||||||
@@ -92,6 +96,7 @@ extension Array where Element == RoomSummary {
|
|||||||
lastMessage: nil,
|
lastMessage: nil,
|
||||||
lastMessageFormattedTimestamp: nil,
|
lastMessageFormattedTimestamp: nil,
|
||||||
unreadNotificationCount: 0,
|
unreadNotificationCount: 0,
|
||||||
canonicalAlias: nil))
|
canonicalAlias: nil,
|
||||||
|
inviter: nil))
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import MatrixRustSDK
|
||||||
|
|
||||||
struct RoomSummaryDetails {
|
struct RoomSummaryDetails {
|
||||||
let id: String
|
let id: String
|
||||||
@@ -25,6 +26,7 @@ struct RoomSummaryDetails {
|
|||||||
let lastMessageFormattedTimestamp: String?
|
let lastMessageFormattedTimestamp: String?
|
||||||
let unreadNotificationCount: UInt
|
let unreadNotificationCount: UInt
|
||||||
let canonicalAlias: String?
|
let canonicalAlias: String?
|
||||||
|
let inviter: RoomMemberProxyProtocol?
|
||||||
}
|
}
|
||||||
|
|
||||||
extension RoomSummaryDetails: CustomStringConvertible {
|
extension RoomSummaryDetails: CustomStringConvertible {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
|
|||||||
private let eventStringBuilder: RoomEventStringBuilder
|
private let eventStringBuilder: RoomEventStringBuilder
|
||||||
private let name: String
|
private let name: String
|
||||||
private var appSettings: AppSettings
|
private var appSettings: AppSettings
|
||||||
|
private let backgroundTaskService: BackgroundTaskServiceProtocol
|
||||||
|
|
||||||
private let serialDispatchQueue: DispatchQueue
|
private let serialDispatchQueue: DispatchQueue
|
||||||
|
|
||||||
@@ -56,12 +57,14 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
|
|||||||
init(roomListService: RoomListServiceProtocol,
|
init(roomListService: RoomListServiceProtocol,
|
||||||
eventStringBuilder: RoomEventStringBuilder,
|
eventStringBuilder: RoomEventStringBuilder,
|
||||||
name: String,
|
name: String,
|
||||||
appSettings: AppSettings) {
|
appSettings: AppSettings,
|
||||||
|
backgroundTaskService: BackgroundTaskServiceProtocol) {
|
||||||
self.roomListService = roomListService
|
self.roomListService = roomListService
|
||||||
serialDispatchQueue = DispatchQueue(label: "io.element.elementx.roomsummaryprovider", qos: .utility)
|
serialDispatchQueue = DispatchQueue(label: "io.element.elementx.roomsummaryprovider", qos: .utility)
|
||||||
self.eventStringBuilder = eventStringBuilder
|
self.eventStringBuilder = eventStringBuilder
|
||||||
self.name = name
|
self.name = name
|
||||||
self.appSettings = appSettings
|
self.appSettings = appSettings
|
||||||
|
self.backgroundTaskService = backgroundTaskService
|
||||||
|
|
||||||
diffsPublisher
|
diffsPublisher
|
||||||
.receive(on: serialDispatchQueue)
|
.receive(on: serialDispatchQueue)
|
||||||
@@ -155,20 +158,24 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
|
|||||||
MXLog.info("\(name): Finished applying \(diffs.count) diffs, new room list \(rooms.compactMap { $0.id ?? "Empty" })")
|
MXLog.info("\(name): Finished applying \(diffs.count) diffs, new room list \(rooms.compactMap { $0.id ?? "Empty" })")
|
||||||
}
|
}
|
||||||
|
|
||||||
private func fetchLastMessage(roomListItem: RoomListItemProtocol) -> EventTimelineItem? {
|
private func fetchRoomInfo(roomListItem: RoomListItemProtocol) -> RoomInfo? {
|
||||||
class FetchResult {
|
class FetchResult {
|
||||||
var latestRoomEvent: EventTimelineItem?
|
var roomInfo: RoomInfo?
|
||||||
}
|
}
|
||||||
|
|
||||||
let semaphore = DispatchSemaphore(value: 0)
|
let semaphore = DispatchSemaphore(value: 0)
|
||||||
let result = FetchResult()
|
let result = FetchResult()
|
||||||
|
|
||||||
Task {
|
Task {
|
||||||
result.latestRoomEvent = await roomListItem.latestEvent()
|
do {
|
||||||
|
result.roomInfo = try await roomListItem.roomInfo()
|
||||||
|
} catch {
|
||||||
|
MXLog.error("Failed fetching room info with error: \(error)")
|
||||||
|
}
|
||||||
semaphore.signal()
|
semaphore.signal()
|
||||||
}
|
}
|
||||||
semaphore.wait()
|
semaphore.wait()
|
||||||
return result.latestRoomEvent
|
return result.roomInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
private func buildRoomSummaryForIdentifier(_ identifier: String, invalidated: Bool) -> RoomSummary {
|
private func buildRoomSummaryForIdentifier(_ identifier: String, invalidated: Bool) -> RoomSummary {
|
||||||
@@ -177,23 +184,33 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
|
|||||||
return .empty
|
return .empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
guard let roomInfo = fetchRoomInfo(roomListItem: roomListItem) else {
|
||||||
|
return .empty
|
||||||
|
}
|
||||||
|
|
||||||
var attributedLastMessage: AttributedString?
|
var attributedLastMessage: AttributedString?
|
||||||
var lastMessageFormattedTimestamp: String?
|
var lastMessageFormattedTimestamp: String?
|
||||||
|
|
||||||
if let latestRoomMessage = fetchLastMessage(roomListItem: roomListItem) {
|
if let latestRoomMessage = roomInfo.latestEvent {
|
||||||
let lastMessage = EventTimelineItemProxy(item: latestRoomMessage, id: 0)
|
let lastMessage = EventTimelineItemProxy(item: latestRoomMessage, id: 0)
|
||||||
lastMessageFormattedTimestamp = lastMessage.timestamp.formattedMinimal()
|
lastMessageFormattedTimestamp = lastMessage.timestamp.formattedMinimal()
|
||||||
attributedLastMessage = eventStringBuilder.buildAttributedString(for: lastMessage)
|
attributedLastMessage = eventStringBuilder.buildAttributedString(for: lastMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
let details = RoomSummaryDetails(id: roomListItem.id(),
|
var inviterProxy: RoomMemberProxyProtocol?
|
||||||
name: roomListItem.name() ?? roomListItem.id(),
|
if let inviter = roomInfo.inviter {
|
||||||
isDirect: roomListItem.isDirect(),
|
inviterProxy = RoomMemberProxy(member: inviter, backgroundTaskService: backgroundTaskService)
|
||||||
avatarURL: roomListItem.avatarUrl().flatMap(URL.init(string:)),
|
}
|
||||||
|
|
||||||
|
let details = RoomSummaryDetails(id: roomInfo.id,
|
||||||
|
name: roomInfo.name ?? roomInfo.id,
|
||||||
|
isDirect: roomInfo.isDirect,
|
||||||
|
avatarURL: roomInfo.avatarUrl.flatMap(URL.init(string:)),
|
||||||
lastMessage: attributedLastMessage,
|
lastMessage: attributedLastMessage,
|
||||||
lastMessageFormattedTimestamp: lastMessageFormattedTimestamp,
|
lastMessageFormattedTimestamp: lastMessageFormattedTimestamp,
|
||||||
unreadNotificationCount: UInt(roomListItem.unreadNotifications().notificationCount()),
|
unreadNotificationCount: UInt(roomInfo.notificationCount),
|
||||||
canonicalAlias: roomListItem.canonicalAlias())
|
canonicalAlias: roomInfo.canonicalAlias,
|
||||||
|
inviter: inviterProxy)
|
||||||
|
|
||||||
return invalidated ? .invalidated(details: details) : .filled(details: details)
|
return invalidated ? .invalidated(details: details) : .filled(details: details)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -45,7 +45,7 @@ packages:
|
|||||||
# Element/Matrix dependencies
|
# Element/Matrix dependencies
|
||||||
MatrixRustSDK:
|
MatrixRustSDK:
|
||||||
url: https://github.com/matrix-org/matrix-rust-components-swift
|
url: https://github.com/matrix-org/matrix-rust-components-swift
|
||||||
exactVersion: 1.0.107-alpha
|
exactVersion: 1.0.108-alpha
|
||||||
# path: ../matrix-rust-sdk
|
# path: ../matrix-rust-sdk
|
||||||
DesignKit:
|
DesignKit:
|
||||||
path: DesignKit
|
path: DesignKit
|
||||||
|
|||||||
Reference in New Issue
Block a user