mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-24 10:32:46 +02:00
Glitchy room list header when scrolling
- fixed
This commit is contained in:
@@ -14,9 +14,18 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
// swiftlint:disable file_length
|
||||
|
||||
import UIKit
|
||||
import Reusable
|
||||
|
||||
protocol AllChatsViewControllerDelegate: AnyObject {
|
||||
func allChatsViewControllerDidCompleteAuthentication(_ allChatsViewController: AllChatsViewController)
|
||||
func allChatsViewController(_ allChatsViewController: AllChatsViewController, didSelectRoomWithParameters roomNavigationParameters: RoomNavigationParameters, completion: @escaping () -> Void)
|
||||
func allChatsViewController(_ allChatsViewController: AllChatsViewController, didSelectRoomPreviewWithParameters roomPreviewNavigationParameters: RoomPreviewNavigationParameters, completion: @escaping () -> Void)
|
||||
func allChatsViewController(_ allChatsViewController: AllChatsViewController, didSelectContact contact: MXKContact, with presentationParameters: ScreenPresentationParameters)
|
||||
}
|
||||
|
||||
class AllChatsViewController: HomeViewController {
|
||||
|
||||
// MARK: - Class methods
|
||||
@@ -33,6 +42,10 @@ class AllChatsViewController: HomeViewController {
|
||||
return viewController
|
||||
}
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
weak var allChatsDelegate: AllChatsViewControllerDelegate?
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private let searchController = UISearchController(searchResultsController: nil)
|
||||
@@ -45,6 +58,40 @@ class AllChatsViewController: HomeViewController {
|
||||
|
||||
private var childCoordinators: [Coordinator] = []
|
||||
|
||||
private let tableViewPaginationThrottler = MXThrottler(minimumDelay: 0.1)
|
||||
|
||||
private var reviewSessionAlertHasBeenDisplayed: Bool = false
|
||||
|
||||
private var bannerView: UIView? {
|
||||
didSet {
|
||||
bannerView?.translatesAutoresizingMaskIntoConstraints = false
|
||||
set(tableHeadeView: bannerView)
|
||||
}
|
||||
}
|
||||
|
||||
private var isOnboardingCoordinatorPreparing: Bool = false
|
||||
|
||||
private var allChatsOnboardingCoordinatorBridgePresenter: AllChatsOnboardingCoordinatorBridgePresenter?
|
||||
|
||||
private var currentAlert: UIAlertController?
|
||||
|
||||
// MARK: - MasterTabBarController
|
||||
|
||||
// References on the currently selected room
|
||||
@objc private(set) var selectedRoomId: String?
|
||||
@objc private(set) var selectedEventId: String?
|
||||
@objc private(set) var selectedRoomSession: MXSession?
|
||||
@objc private(set) var selectedRoomPreviewData: RoomPreviewData?
|
||||
|
||||
// References on the currently selected contact
|
||||
@objc private(set) var selectedContact: MXKContact?
|
||||
|
||||
// Reference to the current onboarding flow. It is always nil unless the flow is being presented.
|
||||
@objc private(set) var onboardingCoordinatorBridgePresenter: OnboardingCoordinatorBridgePresenter?
|
||||
|
||||
// Tell whether the onboarding screen is preparing.
|
||||
@objc private(set) var isOnboardingInProgress: Bool = false
|
||||
|
||||
// MARK: - Lifecycle
|
||||
|
||||
override func viewDidLoad() {
|
||||
@@ -57,9 +104,12 @@ class AllChatsViewController: HomeViewController {
|
||||
recentsTableView.clipsToBounds = false
|
||||
recentsTableView.register(RecentEmptySectionTableViewCell.nib, forCellReuseIdentifier: RecentEmptySectionTableViewCell.reuseIdentifier)
|
||||
recentsTableView.register(RecentsInvitesTableViewCell.nib, forCellReuseIdentifier: RecentsInvitesTableViewCell.reuseIdentifier)
|
||||
|
||||
recentsTableView.contentInsetAdjustmentBehavior = .automatic
|
||||
|
||||
updateUI()
|
||||
vc_setLargeTitleDisplayMode(.automatic)
|
||||
|
||||
navigationItem.largeTitleDisplayMode = .automatic
|
||||
navigationController?.navigationBar.prefersLargeTitles = true
|
||||
|
||||
searchController.obscuresBackgroundDuringPresentation = false
|
||||
searchController.searchResultsUpdater = self
|
||||
@@ -72,12 +122,44 @@ class AllChatsViewController: HomeViewController {
|
||||
|
||||
self.navigationController?.isToolbarHidden = false
|
||||
self.navigationController?.toolbar.tintColor = ThemeService.shared().theme.colors.accent
|
||||
if self.tabBarController?.navigationItem.searchController == nil {
|
||||
self.tabBarController?.navigationItem.searchController = searchController
|
||||
if self.navigationItem.searchController == nil {
|
||||
self.navigationItem.searchController = searchController
|
||||
}
|
||||
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(self.spaceListDidChange), name: MXSpaceService.didInitialise, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(self.spaceListDidChange), name: MXSpaceService.didBuildSpaceGraph, object: nil)
|
||||
|
||||
set(tableHeadeView: self.bannerView)
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
// Check whether we're not logged in
|
||||
let authIsShown: Bool
|
||||
if MXKAccountManager.shared().accounts.isEmpty {
|
||||
showOnboardingFlow()
|
||||
authIsShown = true
|
||||
} else {
|
||||
// Display a login screen if the account is soft logout
|
||||
// Note: We support only one account
|
||||
if let account = MXKAccountManager.shared().accounts.first, account.isSoftLogout {
|
||||
showSoftLogoutOnboardingFlow(credentials: account.mxCredentials)
|
||||
authIsShown = true
|
||||
} else {
|
||||
authIsShown = false
|
||||
}
|
||||
}
|
||||
|
||||
guard !authIsShown else {
|
||||
return
|
||||
}
|
||||
|
||||
AppDelegate.theDelegate().checkAppVersion()
|
||||
|
||||
if BuildSettings.isNewAppLayoutActivated && !RiotSettings.shared.allChatsOnboardingHasBeenDisplayed {
|
||||
self.showAllChatsOnboardingScreen()
|
||||
}
|
||||
}
|
||||
|
||||
override func viewWillDisappear(_ animated: Bool) {
|
||||
@@ -85,13 +167,60 @@ class AllChatsViewController: HomeViewController {
|
||||
|
||||
self.navigationController?.isToolbarHidden = true
|
||||
}
|
||||
|
||||
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
|
||||
super.viewWillTransition(to: size, with: coordinator)
|
||||
|
||||
coordinator.animate { context in
|
||||
self.recentsTableView?.tableHeaderView?.layoutIfNeeded()
|
||||
self.recentsTableView?.tableHeaderView = self.recentsTableView?.tableHeaderView
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - HomeViewController
|
||||
// MARK: - Public
|
||||
|
||||
func switchSpace(withId spaceId: String?) {
|
||||
searchController.isActive = false
|
||||
|
||||
guard let spaceId = spaceId else {
|
||||
self.dataSource?.currentSpace = nil
|
||||
updateUI()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
guard let space = self.mainSession.spaceService.getSpace(withId: spaceId) else {
|
||||
MXLog.warning("[AllChatsViewController] switchSpace: no space found with id \(spaceId)")
|
||||
return
|
||||
}
|
||||
|
||||
self.dataSource.currentSpace = space
|
||||
updateUI()
|
||||
|
||||
self.recentsTableView.setContentOffset(.zero, animated: true)
|
||||
}
|
||||
|
||||
override var recentsDataSourceMode: RecentsDataSourceMode {
|
||||
.allChats
|
||||
}
|
||||
|
||||
override func addMatrixSession(_ mxSession: MXSession!) {
|
||||
super.addMatrixSession(mxSession)
|
||||
initDataSource()
|
||||
}
|
||||
|
||||
private func initDataSource() {
|
||||
guard self.dataSource == nil, let mainSession = self.mxSessions.first as? MXSession else {
|
||||
return
|
||||
}
|
||||
|
||||
MXLog.debug("[AllChatsViewController] initDataSource")
|
||||
let recentsListService = RecentsListService(withSession: mainSession)
|
||||
let recentsDataSource = RecentsDataSource(matrixSession: mainSession, recentsListService: recentsListService)
|
||||
displayList(recentsDataSource)
|
||||
recentsDataSource?.setDelegate(self, andRecentsDataSourceMode: self.recentsDataSourceMode)
|
||||
}
|
||||
|
||||
@objc private func spaceListDidChange() {
|
||||
guard self.editActionProvider.shouldUpdate(with: self.mainSession, parentSpace: self.dataSource?.currentSpace) else {
|
||||
return
|
||||
@@ -118,6 +247,10 @@ class AllChatsViewController: HomeViewController {
|
||||
]
|
||||
}
|
||||
|
||||
override func startActivityIndicator() {
|
||||
super.startActivityIndicator()
|
||||
}
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
@objc private func showSpaceSelectorAction(sender: AnyObject) {
|
||||
@@ -174,6 +307,23 @@ class AllChatsViewController: HomeViewController {
|
||||
showRoomInviteList()
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
|
||||
super.tableView(tableView, willDisplay: cell, forRowAt: indexPath)
|
||||
|
||||
guard let recentsDataSource = dataSource as? RecentsDataSource else {
|
||||
return
|
||||
}
|
||||
|
||||
let sectionType = recentsDataSource.sections.sectionType(forSectionIndex: indexPath.section)
|
||||
guard sectionType == .allChats, let numberOfRowsInSection = recentsDataSource.recentsListService.allChatsRoomListData?.counts.numberOfRooms, indexPath.row == numberOfRowsInSection - 1 else {
|
||||
return
|
||||
}
|
||||
|
||||
tableViewPaginationThrottler.throttle {
|
||||
recentsDataSource.paginate(inSection: indexPath.section)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Toolbar animation
|
||||
|
||||
private var lastScrollPosition: Double = 0
|
||||
@@ -240,13 +390,11 @@ class AllChatsViewController: HomeViewController {
|
||||
let shouldShowEmptyView = super.shouldShowEmptyView()
|
||||
|
||||
if shouldShowEmptyView {
|
||||
self.tabBarController?.navigationItem.searchController = nil
|
||||
self.navigationItem.searchController = nil
|
||||
navigationItem.largeTitleDisplayMode = .never
|
||||
navigationController?.navigationBar.prefersLargeTitles = false
|
||||
} else {
|
||||
self.tabBarController?.navigationItem.searchController = searchController
|
||||
self.navigationItem.searchController = searchController
|
||||
navigationItem.largeTitleDisplayMode = .automatic
|
||||
navigationController?.navigationBar.prefersLargeTitles = true
|
||||
}
|
||||
|
||||
return shouldShowEmptyView
|
||||
@@ -258,7 +406,7 @@ class AllChatsViewController: HomeViewController {
|
||||
override func userInterfaceThemeDidChange() {
|
||||
super.userInterfaceThemeDidChange()
|
||||
|
||||
guard self.tabBarController?.toolbarItems != nil else {
|
||||
guard self.toolbarItems != nil else {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -271,6 +419,17 @@ class AllChatsViewController: HomeViewController {
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func set(tableHeadeView: UIView?) {
|
||||
guard let tableView = recentsTableView else {
|
||||
return
|
||||
}
|
||||
|
||||
tableView.tableHeaderView = tableHeadeView
|
||||
tableView.tableHeaderView?.widthAnchor.constraint(equalTo: tableView.widthAnchor).isActive = true
|
||||
tableView.tableHeaderView?.layoutIfNeeded()
|
||||
tableView.tableHeaderView = self.recentsTableView?.tableHeaderView
|
||||
}
|
||||
|
||||
@objc private func setupEditOptions() {
|
||||
guard let currentSpace = self.dataSource?.currentSpace else {
|
||||
updateRightNavigationItem(with: AllChatsActionProvider().menu)
|
||||
@@ -284,7 +443,7 @@ class AllChatsViewController: HomeViewController {
|
||||
|
||||
private func updateUI() {
|
||||
let currentSpace = self.dataSource?.currentSpace
|
||||
self.tabBarController?.title = currentSpace?.summary?.displayname ?? VectorL10n.allChatsTitle
|
||||
self.title = currentSpace?.summary?.displayname ?? VectorL10n.allChatsTitle
|
||||
|
||||
setupEditOptions()
|
||||
updateToolbar(with: editActionProvider.updateMenu(with: mainSession, parentSpace: currentSpace, completion: { [weak self] menu in
|
||||
@@ -294,13 +453,13 @@ class AllChatsViewController: HomeViewController {
|
||||
}
|
||||
|
||||
private func updateRightNavigationItem(with menu: UIMenu) {
|
||||
self.tabBarController?.navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(systemName: "ellipsis.circle"), menu: menu)
|
||||
self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(systemName: "ellipsis.circle"), menu: menu)
|
||||
}
|
||||
|
||||
private func updateToolbar(with menu: UIMenu) {
|
||||
self.navigationController?.isToolbarHidden = false
|
||||
self.update(with: ThemeService.shared().theme)
|
||||
self.tabBarController?.setToolbarItems([
|
||||
self.setToolbarItems([
|
||||
UIBarButtonItem(image: Asset.Images.allChatsSpacesIcon.image, style: .done, target: self, action: #selector(self.showSpaceSelectorAction(sender: ))),
|
||||
UIBarButtonItem.flexibleSpace(),
|
||||
UIBarButtonItem(image: Asset.Images.allChatsEditIcon.image, menu: menu)
|
||||
@@ -330,27 +489,6 @@ class AllChatsViewController: HomeViewController {
|
||||
coordinator.start()
|
||||
}
|
||||
|
||||
private func switchSpace(withId spaceId: String?) {
|
||||
searchController.isActive = false
|
||||
|
||||
guard let spaceId = spaceId else {
|
||||
self.dataSource.currentSpace = nil
|
||||
updateUI()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
guard let space = self.mainSession.spaceService.getSpace(withId: spaceId) else {
|
||||
MXLog.warning("[AllChatsViewController] switchSpace: no space found with id \(spaceId)")
|
||||
return
|
||||
}
|
||||
|
||||
self.dataSource.currentSpace = space
|
||||
updateUI()
|
||||
|
||||
self.recentsTableView.setContentOffset(.zero, animated: true)
|
||||
}
|
||||
|
||||
private func add(childCoordinator: Coordinator) {
|
||||
self.childCoordinators.append(childCoordinator)
|
||||
}
|
||||
@@ -444,6 +582,21 @@ class AllChatsViewController: HomeViewController {
|
||||
invitesViewController.displayList(recentsDataSource)
|
||||
self.navigationController?.pushViewController(invitesViewController, animated: true)
|
||||
}
|
||||
|
||||
private func showAllChatsOnboardingScreen() {
|
||||
let allChatsOnboardingCoordinatorBridgePresenter = AllChatsOnboardingCoordinatorBridgePresenter()
|
||||
allChatsOnboardingCoordinatorBridgePresenter.completion = { [weak self] in
|
||||
RiotSettings.shared.allChatsOnboardingHasBeenDisplayed = true
|
||||
|
||||
guard let self = self else { return }
|
||||
self.allChatsOnboardingCoordinatorBridgePresenter?.dismiss(animated: true, completion: {
|
||||
self.allChatsOnboardingCoordinatorBridgePresenter = nil
|
||||
})
|
||||
}
|
||||
|
||||
allChatsOnboardingCoordinatorBridgePresenter.present(from: self, animated: true)
|
||||
self.allChatsOnboardingCoordinatorBridgePresenter = allChatsOnboardingCoordinatorBridgePresenter
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - SpaceSelectorBottomSheetCoordinatorBridgePresenterDelegate
|
||||
@@ -565,3 +718,300 @@ extension AllChatsViewController: SpaceMembersCoordinatorDelegate {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - BannerPresentationProtocol
|
||||
extension AllChatsViewController: BannerPresentationProtocol {
|
||||
func presentBannerView(_ bannerView: UIView, animated: Bool) {
|
||||
self.bannerView = bannerView
|
||||
}
|
||||
|
||||
func dismissBannerView(animated: Bool) {
|
||||
self.bannerView = nil
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: The `MasterTabBarViewController` is called from the entire app through the `LegacyAppDelegate`. this part of the code should be moved into `AppCoordinator`
|
||||
// MARK: - MasterTabBarViewController
|
||||
extension AllChatsViewController {
|
||||
|
||||
/// Release the current selected item (if any).
|
||||
@objc func releaseSelectedItem() {
|
||||
selectedRoomId = nil
|
||||
selectedEventId = nil
|
||||
selectedRoomSession = nil
|
||||
selectedRoomPreviewData = nil
|
||||
selectedContact = nil
|
||||
}
|
||||
|
||||
/// Refresh the missed conversations badges on tab bar icon
|
||||
@objc func refreshTabBarBadges() {
|
||||
// Nothing to do here as we don't have tab bar
|
||||
}
|
||||
|
||||
/// Verify the current device if needed.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - session: the matrix session.
|
||||
@objc func presentVerifyCurrentSessionAlertIfNeeded(session: MXSession) {
|
||||
guard !RiotSettings.shared.hideVerifyThisSessionAlert, !reviewSessionAlertHasBeenDisplayed, !isOnboardingInProgress else {
|
||||
return
|
||||
}
|
||||
|
||||
reviewSessionAlertHasBeenDisplayed = true
|
||||
|
||||
// Force verification if required by the HS configuration
|
||||
guard !session.vc_homeserverConfiguration().encryption.isSecureBackupRequired else {
|
||||
MXLog.debug("[AllChatsViewController] presentVerifyCurrentSessionAlertIfNeededWithSession: Force verification of the device")
|
||||
AppDelegate.theDelegate().presentCompleteSecurity(for: session)
|
||||
return
|
||||
}
|
||||
|
||||
presentVerifyCurrentSessionAlert(with: session)
|
||||
}
|
||||
|
||||
/// Verify others device if needed.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - session: the matrix session.
|
||||
@objc func presentReviewUnverifiedSessionsAlertIfNeeded(session: MXSession) {
|
||||
guard !RiotSettings.shared.hideReviewSessionsAlert, !reviewSessionAlertHasBeenDisplayed else {
|
||||
return
|
||||
}
|
||||
|
||||
let devices = mainSession.crypto.devices(forUser: mainSession.myUserId).values
|
||||
var userHasOneUnverifiedDevice = false
|
||||
for device in devices {
|
||||
if !device.trustLevel.isCrossSigningVerified {
|
||||
userHasOneUnverifiedDevice = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if userHasOneUnverifiedDevice {
|
||||
reviewSessionAlertHasBeenDisplayed = true
|
||||
presentReviewUnverifiedSessionsAlert(with: session)
|
||||
}
|
||||
}
|
||||
|
||||
@objc func showOnboardingFlow() {
|
||||
MXLog.debug("[AllChatsViewController] showOnboardingFlow")
|
||||
self.showOnboardingFlowAndResetSessionFlags(true)
|
||||
}
|
||||
|
||||
/// Display the onboarding flow configured to log back into a soft logout session.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - credentials: the credentials of the soft logout session.
|
||||
@objc func showSoftLogoutOnboardingFlow(credentials: MXCredentials?) {
|
||||
// This method can be called after the user chooses to clear their data as the MXSession
|
||||
// is opened to call logout from. So we only set the credentials when authentication isn't
|
||||
// in progress to prevent a second soft logout screen being shown.
|
||||
guard self.onboardingCoordinatorBridgePresenter == nil && !self.isOnboardingCoordinatorPreparing else {
|
||||
return
|
||||
}
|
||||
|
||||
MXLog.debug("[AllChatsViewController] showAuthenticationScreenAfterSoftLogout")
|
||||
AuthenticationService.shared.softLogoutCredentials = credentials
|
||||
self.showOnboardingFlowAndResetSessionFlags(false)
|
||||
}
|
||||
|
||||
/// Open the room with the provided identifier in a specific matrix session.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - parameters: the presentation parameters that contains room information plus display information.
|
||||
/// - completion: the block to execute at the end of the operation.
|
||||
@objc func selectRoom(parameters: RoomNavigationParameters, completion: @escaping () -> Void) {
|
||||
releaseSelectedItem()
|
||||
|
||||
selectedRoomId = parameters.roomId
|
||||
selectedEventId = parameters.eventId
|
||||
selectedRoomSession = parameters.mxSession
|
||||
|
||||
allChatsDelegate?.allChatsViewController(self, didSelectRoomWithParameters: parameters, completion: completion)
|
||||
|
||||
refreshSelectedControllerSelectedCellIfNeeded()
|
||||
}
|
||||
|
||||
/// Open the RoomViewController to display the preview of a room that is unknown for the user.
|
||||
/// This room can come from an email invitation link or a simple link to a room.
|
||||
/// - Parameters:
|
||||
/// - parameters: the presentation parameters that contains room preview information plus display information.
|
||||
/// - completion: the block to execute at the end of the operation.
|
||||
@objc func selectRoomPreview(parameters: RoomPreviewNavigationParameters, completion: @escaping () -> Void) {
|
||||
releaseSelectedItem()
|
||||
|
||||
let roomPreviewData = parameters.previewData
|
||||
|
||||
selectedRoomPreviewData = roomPreviewData
|
||||
selectedRoomId = roomPreviewData.roomId
|
||||
selectedRoomSession = roomPreviewData.mxSession
|
||||
|
||||
allChatsDelegate?.allChatsViewController(self, didSelectRoomPreviewWithParameters: parameters, completion: completion)
|
||||
|
||||
refreshSelectedControllerSelectedCellIfNeeded()
|
||||
}
|
||||
|
||||
/// Open a ContactDetailsViewController to display the information of the provided contact.
|
||||
@objc func selectContact(_ contact: MXKContact) {
|
||||
let presentationParameters = ScreenPresentationParameters(restoreInitialDisplay: true, stackAboveVisibleViews: false)
|
||||
selectContact(contact, withPresentationParameters: presentationParameters)
|
||||
}
|
||||
|
||||
/// Open a ContactDetailsViewController to display the information of the provided contact.
|
||||
@objc func selectContact(_ contact: MXKContact, withPresentationParameters presentationParameters: ScreenPresentationParameters) {
|
||||
releaseSelectedItem()
|
||||
|
||||
selectedContact = contact
|
||||
|
||||
allChatsDelegate?.allChatsViewController(self, didSelectContact: contact, with: presentationParameters)
|
||||
|
||||
refreshSelectedControllerSelectedCellIfNeeded()
|
||||
}
|
||||
|
||||
/// The current number of rooms with missed notifications, including the invites.
|
||||
@objc func missedDiscussionsCount() -> UInt {
|
||||
guard let session = mxSessions as? [MXSession] else {
|
||||
return 0
|
||||
}
|
||||
|
||||
return session.reduce(0) { $0 + $1.vc_missedDiscussionsCount() }
|
||||
}
|
||||
|
||||
/// The current number of rooms with unread highlighted messages.
|
||||
@objc func missedHighlightDiscussionsCount() -> UInt {
|
||||
guard let session = mxSessions as? [MXSession] else {
|
||||
return 0
|
||||
}
|
||||
|
||||
return session.reduce(0) { $0 + $1.missedHighlightDiscussionsCount() }
|
||||
}
|
||||
|
||||
/// Emulated `UItabBarViewController.selectedViewController` member
|
||||
@objc var selectedViewController: UIViewController? {
|
||||
return self
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func presentVerifyCurrentSessionAlert(with session: MXSession) {
|
||||
MXLog.debug("[AllChatsViewController] presentVerifyCurrentSessionAlertWithSession")
|
||||
|
||||
currentAlert?.dismiss(animated: true, completion: nil)
|
||||
|
||||
let alert = UIAlertController(title: VectorL10n.keyVerificationSelfVerifyCurrentSessionAlertTitle,
|
||||
message: VectorL10n.keyVerificationSelfVerifyCurrentSessionAlertMessage,
|
||||
preferredStyle: .alert)
|
||||
|
||||
alert.addAction(UIAlertAction(title: VectorL10n.keyVerificationSelfVerifyCurrentSessionAlertValidateAction,
|
||||
style: .default,
|
||||
handler: { action in
|
||||
AppDelegate.theDelegate().presentCompleteSecurity(for: session)
|
||||
}))
|
||||
|
||||
alert.addAction(UIAlertAction(title: VectorL10n.later, style: .cancel))
|
||||
|
||||
alert.addAction(UIAlertAction(title: VectorL10n.doNotAskAgain,
|
||||
style: .destructive,
|
||||
handler: { action in
|
||||
RiotSettings.shared.hideVerifyThisSessionAlert = true
|
||||
}))
|
||||
|
||||
self.present(alert, animated: true)
|
||||
currentAlert = alert
|
||||
}
|
||||
|
||||
private func presentReviewUnverifiedSessionsAlert(with session: MXSession) {
|
||||
MXLog.debug("[AllChatsViewController] presentReviewUnverifiedSessionsAlert")
|
||||
|
||||
currentAlert?.dismiss(animated: true, completion: nil)
|
||||
|
||||
let alert = UIAlertController(title: VectorL10n.keyVerificationSelfVerifyUnverifiedSessionsAlertTitle,
|
||||
message: VectorL10n.keyVerificationSelfVerifyUnverifiedSessionsAlertMessage,
|
||||
preferredStyle: .alert)
|
||||
|
||||
alert.addAction(UIAlertAction(title: VectorL10n.keyVerificationSelfVerifyUnverifiedSessionsAlertValidateAction,
|
||||
style: .default,
|
||||
handler: { action in
|
||||
self.showSettingsSecurityScreen(with: session)
|
||||
}))
|
||||
|
||||
alert.addAction(UIAlertAction(title: VectorL10n.later, style: .cancel))
|
||||
|
||||
alert.addAction(UIAlertAction(title: VectorL10n.doNotAskAgain, style: .destructive, handler: { action in
|
||||
RiotSettings.shared.hideReviewSessionsAlert = true
|
||||
}))
|
||||
|
||||
present(alert, animated: true)
|
||||
currentAlert = alert
|
||||
}
|
||||
|
||||
private func showSettingsSecurityScreen(with session: MXSession) {
|
||||
guard let settingsViewController = SettingsViewController.instantiate() else {
|
||||
MXLog.warning("[AllChatsViewController] showSettingsSecurityScreen: cannot instantiate SettingsViewController")
|
||||
return
|
||||
}
|
||||
|
||||
guard let securityViewController = SecurityViewController.instantiate(withMatrixSession: session) else {
|
||||
MXLog.warning("[AllChatsViewController] showSettingsSecurityScreen: cannot instantiate SecurityViewController")
|
||||
return
|
||||
}
|
||||
|
||||
settingsViewController.loadViewIfNeeded()
|
||||
AppDelegate.theDelegate().restoreInitialDisplay {
|
||||
self.navigationController?.viewControllers = [self, settingsViewController, securityViewController]
|
||||
}
|
||||
}
|
||||
|
||||
private func showOnboardingFlowAndResetSessionFlags(_ resetSessionFlags: Bool) {
|
||||
// Check whether an authentication screen is not already shown or preparing
|
||||
guard self.onboardingCoordinatorBridgePresenter == nil && !self.isOnboardingCoordinatorPreparing else {
|
||||
return
|
||||
}
|
||||
|
||||
self.isOnboardingCoordinatorPreparing = true
|
||||
self.isOnboardingInProgress = true
|
||||
|
||||
if resetSessionFlags {
|
||||
resetReviewSessionsFlags()
|
||||
}
|
||||
|
||||
AppDelegate.theDelegate().restoreInitialDisplay {
|
||||
self.presentOnboardingFlow()
|
||||
}
|
||||
}
|
||||
|
||||
private func resetReviewSessionsFlags() {
|
||||
reviewSessionAlertHasBeenDisplayed = false
|
||||
RiotSettings.shared.hideVerifyThisSessionAlert = false
|
||||
RiotSettings.shared.hideReviewSessionsAlert = false
|
||||
}
|
||||
|
||||
private func presentOnboardingFlow() {
|
||||
MXLog.debug("[AllChatsViewController] presentOnboardingFlow")
|
||||
|
||||
let onboardingCoordinatorBridgePresenter = OnboardingCoordinatorBridgePresenter()
|
||||
onboardingCoordinatorBridgePresenter.completion = { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.onboardingCoordinatorBridgePresenter?.dismiss(animated: true, completion: {
|
||||
self.onboardingCoordinatorBridgePresenter = nil
|
||||
})
|
||||
|
||||
self.isOnboardingInProgress = false // Must be set before calling didCompleteAuthentication
|
||||
self.allChatsDelegate?.allChatsViewControllerDidCompleteAuthentication(self)
|
||||
}
|
||||
|
||||
onboardingCoordinatorBridgePresenter.present(from: self, animated: true)
|
||||
self.onboardingCoordinatorBridgePresenter = onboardingCoordinatorBridgePresenter
|
||||
self.isOnboardingCoordinatorPreparing = false
|
||||
}
|
||||
|
||||
private func refreshSelectedControllerSelectedCellIfNeeded() {
|
||||
guard splitViewController != nil else {
|
||||
return
|
||||
}
|
||||
|
||||
// Refresh selected cell without scrolling the selected cell (We suppose it's visible here)
|
||||
self.refreshCurrentSelectedCell(false)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user