mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 21:33:26 +00:00
Further design updates to the timeline. (#524)
- Decryption banner on the timeline - Bubble colours - Background insets - Multiline composer corner radius - Read marker - GIF indicator - Reactions shape - Use RoomTimelineViewLabelStyle everywhere possible - Only set a line limit on reply quotes, allow all the lines for regular quotes. - Message label icons - Yes/No button casing - Make sender profiles immutable. - Enable copy link and invite buttons. - Fix layout loop detecting multiline composer text. - Add animation to the encryption banner.
This commit is contained in:
@@ -29,6 +29,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
private let timelineController: RoomTimelineControllerProtocol
|
||||
private let timelineViewFactory: RoomTimelineViewFactoryProtocol
|
||||
|
||||
// swiftlint:disable:next cyclomatic_complexity
|
||||
init(timelineController: RoomTimelineControllerProtocol,
|
||||
timelineViewFactory: RoomTimelineViewFactoryProtocol,
|
||||
mediaProvider: MediaProviderProtocol,
|
||||
@@ -66,6 +67,10 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
if self.state.isBackPaginating != isBackPaginating {
|
||||
self.state.isBackPaginating = isBackPaginating
|
||||
}
|
||||
case .hasEncryptedItems(let hasEncryptedItems):
|
||||
if self.state.showEncryptionBanner != hasEncryptedItems {
|
||||
self.state.showEncryptionBanner = hasEncryptedItems
|
||||
}
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
@@ -113,6 +118,8 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
state.bindings.composerText = ""
|
||||
case .markRoomAsRead:
|
||||
await markRoomAsRead()
|
||||
case .retryDecryption:
|
||||
retryDecryption()
|
||||
case .contextMenuAction(let itemID, let action):
|
||||
processContentMenuAction(action, itemID: itemID)
|
||||
}
|
||||
@@ -182,6 +189,19 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
}
|
||||
}
|
||||
|
||||
/// Retry decrypting any encrypted items in the timeline.
|
||||
private func retryDecryption() {
|
||||
Task {
|
||||
let firstEncryptedItem = state.items.first { $0.sessionID != nil }
|
||||
|
||||
if let sessionID = firstEncryptedItem?.sessionID {
|
||||
// Request for the first encrypted item to be decrypted as the SDK
|
||||
// will continue to decrypt any following items automatically.
|
||||
await timelineController.retryDecryption(for: sessionID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func displayError(_ type: RoomScreenErrorType) {
|
||||
switch type {
|
||||
case .alert(let message):
|
||||
@@ -224,12 +244,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
actions.append(.redact)
|
||||
}
|
||||
|
||||
var debugActions: [TimelineItemContextMenuAction] = [.viewSource]
|
||||
|
||||
if let item = timelineItem as? EncryptedRoomTimelineItem,
|
||||
case let .megolmV1AesSha2(sessionId) = item.encryptionType {
|
||||
debugActions.append(.retryDecryption(sessionId: sessionId))
|
||||
}
|
||||
let debugActions: [TimelineItemContextMenuAction] = [.viewSource]
|
||||
|
||||
return .init(actions: actions, debugActions: debugActions)
|
||||
}
|
||||
@@ -271,10 +286,6 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
let debugDescription = timelineController.debugDescription(for: item.id)
|
||||
MXLog.info(debugDescription)
|
||||
state.bindings.debugInfo = .init(title: "Timeline item", content: debugDescription)
|
||||
case .retryDecryption(let sessionId):
|
||||
Task {
|
||||
await timelineController.retryDecryption(for: sessionId)
|
||||
}
|
||||
}
|
||||
|
||||
if action.switchToDefaultComposer {
|
||||
@@ -291,3 +302,14 @@ extension RoomScreenViewModel {
|
||||
mediaProvider: MockMediaProvider(),
|
||||
roomName: "Preview room")
|
||||
}
|
||||
|
||||
private extension RoomTimelineViewProvider {
|
||||
/// The item's session ID if it was unable to decrypt and uses megolm.
|
||||
/// This will be nil for items that have already been decrypted.
|
||||
var sessionID: String? {
|
||||
guard case let .encrypted(item) = self,
|
||||
case let .megolmV1AesSha2(sessionID) = item.encryptionType
|
||||
else { return nil }
|
||||
return sessionID
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user