Introduced MemberDetailsProvider, caching user avatar urls and images. Various other tweaks and improvements.

This commit is contained in:
Stefan Ceriu
2022-03-18 13:40:25 +02:00
parent 120bcaf012
commit 2eae0f0573
22 changed files with 346 additions and 203 deletions
@@ -13,6 +13,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
private let timelineProvider: RoomTimelineProvider
private let timelineItemFactory: RoomTimelineItemFactory
private let mediaProvider: MediaProviderProtocol
private let memberDetailsProvider: MemberDetailsProvider
private var cancellables = Set<AnyCancellable>()
@@ -22,10 +23,12 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
init(timelineProvider: RoomTimelineProvider,
timelineItemFactory: RoomTimelineItemFactory,
mediaProvider: MediaProviderProtocol) {
mediaProvider: MediaProviderProtocol,
memberDetailsProvider: MemberDetailsProvider) {
self.timelineProvider = timelineProvider
self.timelineItemFactory = timelineItemFactory
self.mediaProvider = mediaProvider
self.memberDetailsProvider = memberDetailsProvider
self.timelineProvider.callbacks.sink { [weak self] callback in
guard let self = self else { return }
@@ -54,33 +57,13 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
return
}
loadAvatarIfNeededForTimelineItem(timelineItem)
switch timelineItem {
case var item as ImageRoomTimelineItem:
if item.image != nil {
return
}
guard let url = item.url else {
return
}
mediaProvider.loadImageFromURL(url) { [weak self] result in
guard let self = self else {
return
}
if let item = timelineItem as? EventBasedTimelineItemProtocol {
loadAvatarForTimelineItem(item)
}
if case let .success(image) = result {
guard let index = self.timelineItems.firstIndex(where: { $0.id == itemId }) else {
return
}
item.image = image
self.timelineItems[index] = item
self.callbacks.send(.updatedTimelineItem(itemId))
}
}
switch timelineItem {
case let item as ImageRoomTimelineItem:
loadImageForTimelineItem(item)
default:
break
}
@@ -126,42 +109,56 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
return Calendar.current.isDate(lhs.originServerTs, inSameDayAs: rhs.originServerTs)
}
private func loadAvatarIfNeededForTimelineItem(_ timelineItem: RoomTimelineItemProtocol) {
switch timelineItem {
case var item as BaseRoomTimelineItemProtocol:
if item.shouldShowSenderDetails == false {
break
private func loadImageForTimelineItem(_ timelineItem: ImageRoomTimelineItem) {
var item = timelineItem
if item.image != nil {
return
}
guard let url = item.url else {
return
}
mediaProvider.loadImageFromURL(url) { [weak self] result in
guard let self = self else {
return
}
timelineProvider.avatarURLForUserId(item.sender) { [weak self] result in
guard let self = self else {
if case let .success(image) = result {
guard let index = self.timelineItems.firstIndex(where: { $0.id == timelineItem.id }) else {
return
}
switch result {
case .success(let userAvatarURL):
guard let avatarURL = userAvatarURL else {
return
}
self.mediaProvider.loadImageFromURL(avatarURL) { result in
if case let .success(image) = result {
guard let index = self.timelineItems.firstIndex(where: { $0.id == timelineItem.id }) else {
return
}
item.senderAvatar = image
self.timelineItems[index] = item
self.callbacks.send(.updatedTimelineItem(timelineItem.id))
item.image = image
self.timelineItems[index] = item
self.callbacks.send(.updatedTimelineItem(timelineItem.id))
}
}
}
private func loadAvatarForTimelineItem(_ timelineItem: EventBasedTimelineItemProtocol) {
var item = timelineItem
if item.shouldShowSenderDetails == false {
return
}
memberDetailsProvider.avatarURLForUserId(timelineItem.sender) { result in
if case let .success(avatarURL) = result,
let avatarURL = avatarURL {
self.mediaProvider.loadImageFromURL(avatarURL) { result in
if case let .success(image) = result {
guard let index = self.timelineItems.firstIndex(where: { $0.id == timelineItem.id }) else {
return
}
item.senderAvatar = image
self.timelineItems[index] = item
self.callbacks.send(.updatedTimelineItem(timelineItem.id))
}
case .failure:
MXLog.error("Failed retrieving user avatar")
}
}
default:
break
}
}
}