Unverified sessions screen

This commit is contained in:
Aleksandrs Proskurins
2022-10-05 16:01:17 +03:00
parent 145cce76f2
commit 21225b408f
15 changed files with 83 additions and 41 deletions
@@ -24,6 +24,7 @@ class UserSessionsOverviewService: UserSessionsOverviewServiceProtocol {
private let dataProvider: UserSessionsDataProviderProtocol
private(set) var overviewData: UserSessionsOverviewData
private(set) var sessionInfos: [UserSessionInfo]
init(dataProvider: UserSessionsDataProviderProtocol) {
self.dataProvider = dataProvider
@@ -32,7 +33,7 @@ class UserSessionsOverviewService: UserSessionsOverviewServiceProtocol {
unverifiedSessions: [],
inactiveSessions: [],
otherSessions: [])
sessionInfos = []
setupInitialOverviewData()
}
@@ -42,7 +43,8 @@ class UserSessionsOverviewService: UserSessionsOverviewServiceProtocol {
dataProvider.devices { response in
switch response {
case .success(let devices):
self.overviewData = self.sessionsOverviewData(from: devices)
self.sessionInfos = self.sortAndConvertDevices(devices: devices)
self.overviewData = self.sessionsOverviewData(from: self.sessionInfos)
completion(.success(self.overviewData))
case .failure(let error):
completion(.failure(error))
@@ -78,16 +80,18 @@ class UserSessionsOverviewService: UserSessionsOverviewServiceProtocol {
}
return sessionInfo(from: device, isCurrentSession: true)
}
private func sessionsOverviewData(from devices: [MXDevice]) -> UserSessionsOverviewData {
let allSessions = devices
private func sortAndConvertDevices(devices: [MXDevice]) -> [UserSessionInfo] {
devices
.sorted { $0.lastSeenTs > $1.lastSeenTs }
.map { sessionInfo(from: $0, isCurrentSession: $0.deviceId == dataProvider.myDeviceId) }
return UserSessionsOverviewData(currentSession: allSessions.filter(\.isCurrent).first,
unverifiedSessions: allSessions.filter { !$0.isVerified },
inactiveSessions: allSessions.filter { !$0.isActive },
otherSessions: allSessions.filter { !$0.isCurrent })
}
private func sessionsOverviewData(from allSessions: [UserSessionInfo]) -> UserSessionsOverviewData {
UserSessionsOverviewData(currentSession: allSessions.filter(\.isCurrent).first,
unverifiedSessions: allSessions.filter { !$0.isVerified },
inactiveSessions: allSessions.filter { !$0.isActive },
otherSessions: allSessions.filter { !$0.isCurrent })
}
private func sessionInfo(from device: MXDevice, isCurrentSession: Bool) -> UserSessionInfo {
@@ -17,6 +17,7 @@
import Foundation
class MockUserSessionsOverviewService: UserSessionsOverviewServiceProtocol {
enum Mode {
case currentSessionUnverified
case currentSessionVerified
@@ -28,6 +29,7 @@ class MockUserSessionsOverviewService: UserSessionsOverviewServiceProtocol {
private let mode: Mode
var overviewData: UserSessionsOverviewData
var sessionInfos = [UserSessionInfo]()
init(mode: Mode = .currentSessionUnverified) {
self.mode = mode
@@ -25,6 +25,7 @@ struct UserSessionsOverviewData {
protocol UserSessionsOverviewServiceProtocol {
var overviewData: UserSessionsOverviewData { get }
var sessionInfos: [UserSessionInfo] { get }
func updateOverviewData(completion: @escaping (Result<UserSessionsOverviewData, Error>) -> Void) -> Void
@@ -46,8 +46,7 @@ class UserSessionsOverviewViewModel: UserSessionsOverviewViewModelType, UserSess
}
completion?(.showCurrentSessionOverview(sessionInfo: currentSessionInfo))
case .viewAllUnverifiedSessions:
// TODO: showSessions(filteredBy: .unverified)
break
showSessions(filteredBy: .unverified)
case .viewAllInactiveSessions:
showSessions(filteredBy: .inactive)
case .viewAllOtherSessions:
@@ -95,7 +94,7 @@ class UserSessionsOverviewViewModel: UserSessionsOverviewViewModelType, UserSess
}
private func showSessions(filteredBy filter: OtherUserSessionsFilter) {
completion?(.showOtherSessions(sessionsInfo: userSessionsOverviewService.overviewData.otherSessions,
completion?(.showOtherSessions(sessionsInfo: userSessionsOverviewService.sessionInfos,
filter: filter))
}
}
@@ -49,7 +49,7 @@ struct UserSessionListItem: View {
}
Text(viewData.sessionDetails)
.font(theme.fonts.caption1)
.foregroundColor(theme.colors.secondaryContent)
.foregroundColor(viewData.highlightSessionDetails ? theme.colors.alert : theme.colors.secondaryContent)
.multilineTextAlignment(.leading)
}
}
@@ -29,6 +29,8 @@ struct UserSessionListItemViewData: Identifiable, Hashable {
let sessionDetails: String
let highlightSessionDetails: Bool
let deviceAvatarViewData: DeviceAvatarViewData
let sessionDetailsIcon: String?
@@ -18,49 +18,50 @@ import Foundation
struct UserSessionListItemViewDataFactory {
func create(from session: UserSessionInfo) -> UserSessionListItemViewData {
let sessionName = UserSessionNameFormatter.sessionName(deviceType: session.deviceType,
sessionDisplayName: session.name)
let sessionDetails = buildSessionDetails(isVerified: session.isVerified,
lastActivityDate: session.lastSeenTimestamp,
isActive: session.isActive)
let deviceAvatarViewData = DeviceAvatarViewData(deviceType: session.deviceType,
isVerified: session.isVerified)
return UserSessionListItemViewData(sessionId: session.id,
func create(from sessionInfo: UserSessionInfo) -> UserSessionListItemViewData {
let sessionName = UserSessionNameFormatter.sessionName(deviceType: sessionInfo.deviceType,
sessionDisplayName: sessionInfo.name)
let sessionDetails = buildSessionDetails(sessionInfo: sessionInfo)
let deviceAvatarViewData = DeviceAvatarViewData(deviceType: sessionInfo.deviceType,
isVerified: sessionInfo.isVerified)
return UserSessionListItemViewData(sessionId: sessionInfo.id,
sessionName: sessionName,
sessionDetails: sessionDetails,
highlightSessionDetails: sessionInfo.isCurrent,
deviceAvatarViewData: deviceAvatarViewData,
sessionDetailsIcon: getSessionDetailsIcon(isActive: session.isActive))
sessionDetailsIcon: getSessionDetailsIcon(isActive: sessionInfo.isActive))
}
private func buildSessionDetails(isVerified: Bool, lastActivityDate: TimeInterval?, isActive: Bool) -> String {
if isActive {
return activeSessionDetails(isVerified: isVerified, lastActivityDate: lastActivityDate)
private func buildSessionDetails(sessionInfo: UserSessionInfo) -> String {
if sessionInfo.isActive {
return activeSessionDetails(sessionInfo: sessionInfo)
} else {
return inactiveSessionDetails(lastActivityDate: lastActivityDate)
return inactiveSessionDetails(sessionInfo: sessionInfo)
}
}
private func inactiveSessionDetails(lastActivityDate: TimeInterval?) -> String {
if let lastActivityDate = lastActivityDate {
private func inactiveSessionDetails(sessionInfo: UserSessionInfo) -> String {
if let lastActivityDate = sessionInfo.lastSeenTimestamp {
let lastActivityDateString = InactiveUserSessionLastActivityFormatter.lastActivityDateString(from: lastActivityDate)
return VectorL10n.userInactiveSessionItemWithDate(lastActivityDateString)
}
return VectorL10n.userInactiveSessionItem
}
private func activeSessionDetails(isVerified: Bool, lastActivityDate: TimeInterval?) -> String {
private func activeSessionDetails(sessionInfo: UserSessionInfo) -> String {
let sessionDetailsString: String
let sessionStatusText = isVerified ? VectorL10n.userSessionVerifiedShort : VectorL10n.userSessionUnverifiedShort
let sessionStatusText = sessionInfo.isVerified ? VectorL10n.userSessionVerifiedShort : VectorL10n.userSessionUnverifiedShort
var lastActivityDateString: String?
if let lastActivityDate = lastActivityDate {
if let lastActivityDate = sessionInfo.lastSeenTimestamp {
lastActivityDateString = UserSessionLastActivityFormatter.lastActivityDateString(from: lastActivityDate)
}
if let lastActivityDateString = lastActivityDateString, lastActivityDateString.isEmpty == false {
if sessionInfo.isCurrent {
sessionDetailsString = VectorL10n.userOtherSessionUnverifiedCurrentSessionDetails(sessionStatusText)
} else if let lastActivityDateString = lastActivityDateString, lastActivityDateString.isEmpty == false {
sessionDetailsString = VectorL10n.userSessionItemDetails(sessionStatusText, lastActivityDateString)
} else {
sessionDetailsString = sessionStatusText