mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 01:20:12 +00:00
vector-im/element-x-ios/issues/31 - Implement simple SaS sesson verification
* vector-im/element-x-ios/issues/31 - Session verification unit and UI tests * Fix ImageAnonymizer tests when running on Apple Silicon * Rename SessionVerification to SessionVerificationScreen
This commit is contained in:
@@ -26,6 +26,7 @@ struct HomeScreenCoordinatorParameters {
|
||||
enum HomeScreenCoordinatorAction {
|
||||
case presentRoom(roomIdentifier: String)
|
||||
case presentSettings
|
||||
case verifySession
|
||||
}
|
||||
|
||||
final class HomeScreenCoordinator: Coordinator, Presentable {
|
||||
@@ -66,19 +67,31 @@ final class HomeScreenCoordinator: Coordinator, Presentable {
|
||||
self.callback?(.presentRoom(roomIdentifier: roomIdentifier))
|
||||
case .tapUserAvatar:
|
||||
self.callback?(.presentSettings)
|
||||
case .verifySession:
|
||||
self.callback?(.verifySession)
|
||||
}
|
||||
}
|
||||
|
||||
parameters.userSession.clientProxy
|
||||
.callbacks
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak self] action in
|
||||
switch action {
|
||||
case .updatedRoomsList:
|
||||
.sink { [weak self] callback in
|
||||
if case .updatedRoomsList = callback {
|
||||
self?.updateRoomsList()
|
||||
}
|
||||
}.store(in: &cancellables)
|
||||
|
||||
parameters.userSession.callbacks
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak self] callback in
|
||||
switch callback {
|
||||
case .sessionVerificationNeeded:
|
||||
self?.viewModel.showSessionVerificationBanner()
|
||||
case .didVerifySession:
|
||||
self?.viewModel.hideSessionVerificationBanner()
|
||||
}
|
||||
}.store(in: &cancellables)
|
||||
|
||||
updateRoomsList()
|
||||
|
||||
Task {
|
||||
|
||||
@@ -20,18 +20,22 @@ import UIKit
|
||||
enum HomeScreenViewModelAction {
|
||||
case selectRoom(roomIdentifier: String)
|
||||
case tapUserAvatar
|
||||
case verifySession
|
||||
}
|
||||
|
||||
enum HomeScreenViewAction {
|
||||
case loadRoomData(roomIdentifier: String)
|
||||
case selectRoom(roomIdentifier: String)
|
||||
case tapUserAvatar
|
||||
case verifySession
|
||||
}
|
||||
|
||||
struct HomeScreenViewState: BindableState {
|
||||
var userDisplayName: String?
|
||||
var userAvatar: UIImage?
|
||||
|
||||
var showSessionVerificationBanner: Bool = false
|
||||
|
||||
var rooms: [HomeScreenRoom] = []
|
||||
|
||||
var isLoadingRooms: Bool = false
|
||||
|
||||
@@ -27,7 +27,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
|
||||
private var roomSummaries: [RoomSummaryProtocol]? {
|
||||
didSet {
|
||||
self.state.isLoadingRooms = (roomSummaries?.count ?? 0 == 0)
|
||||
state.isLoadingRooms = (roomSummaries?.count ?? 0 == 0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,8 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
callback?(.selectRoom(roomIdentifier: roomIdentifier))
|
||||
case .tapUserAvatar:
|
||||
callback?(.tapUserAvatar)
|
||||
case .verifySession:
|
||||
callback?(.verifySession)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,11 +86,19 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
}
|
||||
|
||||
func updateWithUserAvatar(_ avatar: UIImage) {
|
||||
self.state.userAvatar = avatar
|
||||
state.userAvatar = avatar
|
||||
}
|
||||
|
||||
func updateWithUserDisplayName(_ displayName: String) {
|
||||
self.state.userDisplayName = displayName
|
||||
state.userDisplayName = displayName
|
||||
}
|
||||
|
||||
func showSessionVerificationBanner() {
|
||||
state.showSessionVerificationBanner = true
|
||||
}
|
||||
|
||||
func hideSessionVerificationBanner() {
|
||||
state.showSessionVerificationBanner = false
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
@@ -105,7 +115,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
private func buildOrUpdateRoomFromSummary(_ roomSummary: RoomSummaryProtocol) -> HomeScreenRoom {
|
||||
let lastMessage = lastMessageFromEventBrief(roomSummary.lastMessage)
|
||||
|
||||
guard var room = self.state.rooms.first(where: { $0.id == roomSummary.id }) else {
|
||||
guard var room = state.rooms.first(where: { $0.id == roomSummary.id }) else {
|
||||
return HomeScreenRoom(id: roomSummary.id,
|
||||
displayName: roomSummary.displayName,
|
||||
topic: roomSummary.topic,
|
||||
|
||||
@@ -26,4 +26,7 @@ protocol HomeScreenViewModelProtocol {
|
||||
func updateWithUserAvatar(_ avatar: UIImage)
|
||||
func updateWithUserDisplayName(_ displayName: String)
|
||||
func updateWithRoomSummaries(_ roomSummaries: [RoomSummaryProtocol])
|
||||
|
||||
func showSessionVerificationBanner()
|
||||
func hideSessionVerificationBanner()
|
||||
}
|
||||
|
||||
@@ -23,13 +23,27 @@ struct HomeScreen: View {
|
||||
// MARK: Views
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 16.0) {
|
||||
VStack(spacing: 0.0) {
|
||||
if context.viewState.isLoadingRooms {
|
||||
VStack {
|
||||
Text(ElementL10n.loading)
|
||||
ProgressView()
|
||||
}
|
||||
} else {
|
||||
|
||||
if context.viewState.showSessionVerificationBanner {
|
||||
HStack {
|
||||
Text(ElementL10n.verificationVerifyDevice)
|
||||
Spacer()
|
||||
Button(ElementL10n.startVerification) {
|
||||
context.send(viewAction: .verifySession)
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
.background(Color.element.quaternaryContent)
|
||||
.padding(.top, 1)
|
||||
}
|
||||
|
||||
List {
|
||||
Section(ElementL10n.rooms) {
|
||||
ForEach(context.viewState.visibleRooms) { room in
|
||||
@@ -52,6 +66,8 @@ struct HomeScreen: View {
|
||||
Spacer()
|
||||
}
|
||||
.background(Color.element.background)
|
||||
.transition(.slide)
|
||||
.animation(.default, value: context.viewState.showSessionVerificationBanner)
|
||||
.ignoresSafeArea(.all, edges: .bottom)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar {
|
||||
@@ -100,6 +116,8 @@ struct HomeScreen: View {
|
||||
|
||||
struct RoomCell: View {
|
||||
|
||||
@ScaledMetric private var avatarSize = 32.0
|
||||
|
||||
let room: HomeScreenRoom
|
||||
let context: HomeScreenViewModel.Context
|
||||
|
||||
@@ -112,12 +130,12 @@ struct RoomCell: View {
|
||||
Image(uiImage: avatar)
|
||||
.resizable()
|
||||
.scaledToFill()
|
||||
.frame(width: 40, height: 40)
|
||||
.frame(width: avatarSize, height: avatarSize)
|
||||
.clipShape(Circle())
|
||||
} else {
|
||||
PlaceholderAvatarImage(text: room.displayName ?? room.id)
|
||||
.clipShape(Circle())
|
||||
.frame(width: 40, height: 40)
|
||||
.frame(width: avatarSize, height: avatarSize)
|
||||
}
|
||||
|
||||
VStack(alignment: .leading, spacing: 2.0) {
|
||||
@@ -182,6 +200,8 @@ struct HomeScreen_Previews: PreviewProvider {
|
||||
viewModel.updateWithUserAvatar(avatarImage)
|
||||
}
|
||||
|
||||
viewModel.showSessionVerificationBanner()
|
||||
|
||||
return NavigationView {
|
||||
HomeScreen(context: viewModel.context)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user