Onboarding flow coordinator and FTUE changes (#2578)

Fixes #2595, fixes #2594, fixes #2593, fixes #2592, fixes #2591
This commit is contained in:
Stefan Ceriu
2024-03-21 14:01:23 +02:00
committed by GitHub
parent 9e6b6ba60a
commit a62c96f1c5
176 changed files with 1886 additions and 912 deletions
@@ -18,8 +18,7 @@ import Foundation
struct MockRoomTimelineControllerFactory: RoomTimelineControllerFactoryProtocol {
func buildRoomTimelineController(roomProxy: RoomProxyProtocol,
timelineItemFactory: RoomTimelineItemFactoryProtocol,
secureBackupController: SecureBackupControllerProtocol) -> RoomTimelineControllerProtocol {
timelineItemFactory: RoomTimelineItemFactoryProtocol) -> RoomTimelineControllerProtocol {
let timelineController = MockRoomTimelineController()
timelineController.timelineItems = RoomTimelineItemFixtures.largeChunk
return timelineController
@@ -24,7 +24,6 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
private let timelineProvider: RoomTimelineProviderProtocol
private let timelineItemFactory: RoomTimelineItemFactoryProtocol
private let appSettings: AppSettings
private let secureBackupController: SecureBackupControllerProtocol
private let serialDispatchQueue: DispatchQueue
private var cancellables = Set<AnyCancellable>()
@@ -39,13 +38,11 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
init(roomProxy: RoomProxyProtocol,
timelineItemFactory: RoomTimelineItemFactoryProtocol,
appSettings: AppSettings,
secureBackupController: SecureBackupControllerProtocol) {
appSettings: AppSettings) {
self.roomProxy = roomProxy
timelineProvider = roomProxy.timeline.timelineProvider
self.timelineItemFactory = timelineItemFactory
self.appSettings = appSettings
self.secureBackupController = secureBackupController
serialDispatchQueue = DispatchQueue(label: "io.element.elementx.roomtimelineprovider", qos: .utility)
timelineProvider
@@ -253,7 +250,6 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
var newTimelineItems = [RoomTimelineItemProtocol]()
var canBackPaginate = !roomProxy.timeline.timelineStartReached
var isBackPaginating = false
var lastEncryptedHistoryItemIndex: Int?
let collapsibleChunks = timelineProvider.itemProxies.groupBy { isItemCollapsible($0) }
@@ -264,10 +260,6 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
let timelineItem = buildTimelineItem(for: itemProxy)
if timelineItem is EncryptedHistoryRoomTimelineItem {
canBackPaginate = false
}
return timelineItem
}
@@ -282,35 +274,25 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
continue
}
if timelineItem is EncryptedHistoryRoomTimelineItem {
lastEncryptedHistoryItemIndex = newTimelineItems.endIndex
}
newTimelineItems.append(timelineItem)
} else {
newTimelineItems.append(CollapsibleTimelineItem(items: items))
}
}
if let lastEncryptedHistoryItemIndex {
// Remove everything up to the last encrypted history item.
// It only contains encrypted messages, state changes and date separators.
newTimelineItems.removeFirst(lastEncryptedHistoryItemIndex)
} else {
// Otherwise check if we need to add anything to the top of the timeline.
switch timelineProvider.backPaginationState {
case .timelineStartReached:
if !roomProxy.isEncryptedOneToOneRoom {
let timelineStart = TimelineStartRoomTimelineItem(name: roomProxy.name)
newTimelineItems.insert(timelineStart, at: 0)
}
canBackPaginate = false
case .paginating:
newTimelineItems.insert(PaginationIndicatorRoomTimelineItem(), at: 0)
isBackPaginating = true
case .idle:
break
// Check if we need to add anything to the top of the timeline.
switch timelineProvider.backPaginationState {
case .timelineStartReached:
if !roomProxy.isEncryptedOneToOneRoom {
let timelineStart = TimelineStartRoomTimelineItem(name: roomProxy.name)
newTimelineItems.insert(timelineStart, at: 0)
}
canBackPaginate = false
case .paginating:
newTimelineItems.insert(PaginationIndicatorRoomTimelineItem(), at: 0)
isBackPaginating = true
case .idle:
break
}
DispatchQueue.main.sync {
@@ -326,17 +308,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
switch itemProxy {
case .event(let eventTimelineItem):
let timelineItem = timelineItemFactory.buildTimelineItem(for: eventTimelineItem, isDM: roomProxy.isEncryptedOneToOneRoom)
// When backup is enabled just show the timeline items, they will most likely
// resolve eventually. If we don't know the backup state then we assume the session is not verified yet,
// otherwise we just treat it as fully disabled.
if secureBackupController.keyBackupState.value != .enabled {
if timelineItem is EncryptedRoomTimelineItem, isItemInEncryptionHistory(eventTimelineItem) {
return EncryptedHistoryRoomTimelineItem(id: eventTimelineItem.id,
isSessionVerified: secureBackupController.keyBackupState.value != .unknown)
}
}
if let messageTimelineItem = timelineItem as? EventBasedMessageTimelineItemProtocol {
// Avoid fetching this over and over again as it changes states if it keeps failing to load
// Errors will be handled again on appearance
@@ -358,14 +330,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
return nil
}
}
/// Whether or not a specific item is part of the room's history that can't be decrypted due
/// to the lack of key-backup. This is handled differently so we only show a single item.
private func isItemInEncryptionHistory(_ itemProxy: EventTimelineItemProxy) -> Bool {
guard roomProxy.isEncrypted, let lastLoginDate = appSettings.lastLoginDate else { return false }
return itemProxy.timestamp < lastLoginDate
}
private func isItemCollapsible(_ item: TimelineItemProxy) -> Bool {
if !appSettings.shouldCollapseRoomStateEvents {
return false
@@ -18,11 +18,9 @@ import Foundation
struct RoomTimelineControllerFactory: RoomTimelineControllerFactoryProtocol {
func buildRoomTimelineController(roomProxy: RoomProxyProtocol,
timelineItemFactory: RoomTimelineItemFactoryProtocol,
secureBackupController: SecureBackupControllerProtocol) -> RoomTimelineControllerProtocol {
timelineItemFactory: RoomTimelineItemFactoryProtocol) -> RoomTimelineControllerProtocol {
RoomTimelineController(roomProxy: roomProxy,
timelineItemFactory: timelineItemFactory,
appSettings: ServiceLocator.shared.settings,
secureBackupController: secureBackupController)
appSettings: ServiceLocator.shared.settings)
}
}
@@ -19,6 +19,5 @@ import Foundation
@MainActor
protocol RoomTimelineControllerFactoryProtocol {
func buildRoomTimelineController(roomProxy: RoomProxyProtocol,
timelineItemFactory: RoomTimelineItemFactoryProtocol,
secureBackupController: SecureBackupControllerProtocol) -> RoomTimelineControllerProtocol
timelineItemFactory: RoomTimelineItemFactoryProtocol) -> RoomTimelineControllerProtocol
}
@@ -1,22 +0,0 @@
//
// Copyright 2023 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Foundation
struct EncryptedHistoryRoomTimelineItem: DecorationTimelineItemProtocol, Equatable {
let id: TimelineItemIdentifier
let isSessionVerified: Bool
}
@@ -64,8 +64,6 @@ struct RoomTimelineItemView: View {
UnsupportedRoomTimelineView(timelineItem: item)
case .timelineStart(let item):
TimelineStartRoomTimelineView(timelineItem: item)
case .encryptedHistory(let item):
EncryptedHistoryRoomTimelineView(timelineItem: item)
case .state(let item):
StateRoomTimelineView(timelineItem: item)
case .group(let item):
@@ -60,7 +60,6 @@ enum RoomTimelineItemType: Equatable {
case sticker(StickerRoomTimelineItem)
case unsupported(UnsupportedRoomTimelineItem)
case timelineStart(TimelineStartRoomTimelineItem)
case encryptedHistory(EncryptedHistoryRoomTimelineItem)
case state(StateRoomTimelineItem)
case group(CollapsibleTimelineItem)
case location(LocationRoomTimelineItem)
@@ -100,8 +99,6 @@ enum RoomTimelineItemType: Equatable {
self = .unsupported(item)
case let item as TimelineStartRoomTimelineItem:
self = .timelineStart(item)
case let item as EncryptedHistoryRoomTimelineItem:
self = .encryptedHistory(item)
case let item as StateRoomTimelineItem:
self = .state(item)
case let item as CollapsibleTimelineItem:
@@ -136,7 +133,6 @@ enum RoomTimelineItemType: Equatable {
.sticker(let item as RoomTimelineItemProtocol),
.unsupported(let item as RoomTimelineItemProtocol),
.timelineStart(let item as RoomTimelineItemProtocol),
.encryptedHistory(let item as RoomTimelineItemProtocol),
.state(let item as RoomTimelineItemProtocol),
.group(let item as RoomTimelineItemProtocol),
.location(let item as RoomTimelineItemProtocol),