Files
letro-ios/ElementX/Sources/Screens/SessionVerification/SessionVerificationStateMachine.swift
Stefan Ceriu 2623b14dce Sliding Sync + New Timeline API (#189)
* Begin adopting new Timeline API.

* Add edited indicator and reactions.

* vector-im/element-x-ios/issues/65 - Sliding sync support
* Fix missing room display name, wrong placeholder avatar text color and various other warnings that would fail the build on the CI

* Various tweaks:
* using release version of the demo branch of the sdk
* enabled home screen last room messages
* switched debug mode rust logging to warn
* enabled redactions
* enabled new logout flows and soft logout
* enabled replies

* Fix room member display name and avatar crashes / race condition, fix unit tests
* Make the ClientProxy and the UserSession MainActors
* Remove unused MatrixRustSDK imports, we should strive to keep these only in top level services and proxies
* Don't start either of the syncs while in soft logout

* #181: Style the session verification banner to match Figma.
* #181: Update verification modal.
* #181: Update snapshot tests.

* Make session verification state machine less pedantic
* Remove unnecessary weak selfs
* Various tweaks following code review:
* add start and stop sync client proxy methods
* move ss proxy url the build settings
* made media provider load results discardable
* added publishers for the roomSummaryProvider's total number of rooms and state

* Fix when sender details are shown
* Disable sync v2, causes duplicates in the timeline (as expected)
* Move ClientProxy media loading off the main queue and into a detached task
* Another attempt at moving image loading off the main queue
* Moved home screen diffing and latest room fetching to the background
* Prevent the timeline composer from becoming the first responder when not needed

* Bump to a newer version of the RustSDK

* Fixes vector-im/element-x-ios/issues/107 - New home screen design
* Implement thumbnail loading instead of full image avatars.
* Revert "Disable sync v2, causes duplicates in the timeline (as expected)"
* Add support for local echoes, dispatching detached tasks to a concurrenc GCD queue
* Move the session verification banner to a List Section to avoid UI glitches
* Optimise room mapping after sliding sync updates and thumbnail fetching
* Replace home screen List with a LazyVStack in an attempt to fix performance. Moved move summary provider room updating to a background thread

* Fixes vector-im/element-x-ios/issues/177 - New Bubbles Design
* Define in group state for timeline items
* Add replies into the bubble
* Add timeline width environment value
* Add `RoundedCorner` shape with specific corners rounding
* Add in group state for previews
* Implement bubble grouping logic
* Timeline avatar layout changes
* Fix placeholder avatars for dark mode
* New bubbles design
* Update mock timeline items
* Update timeline separator design
* Update room screen reference screenshots
* Add changelog
* Formatting fixes
* Add some space before single or beginning outgoing items

* Redesign the message composer

* Handle the msgtype enum.

* Update room name label line limit and incoming bubble background. Disabled syncv2, ss withCommonExtensions and session verification controller checking

* Increase default back pagination limit.
* Stop parsing links and tidy up composer button.
* Also fix the frame of an image whilst loading.
* Bump SDK package version.

* Remove app states about settings
* Add strings
* Use colors on placeholder avatars
* Tiny changes for placeholder avatars
* Update settings screen design
* Provide a user display name from the mock client
* Settings screen presentation logic
* Add changelog
* Update reference screenshots

Co-authored-by: Doug <douglase@element.io>
Co-authored-by: ismailgulek <ismailgulek@users.noreply.github.com>
Co-authored-by: ismailgulek <ismailg@matrix.org>
2022-09-21 09:21:58 +01:00

122 lines
4.6 KiB
Swift

//
// Copyright 2022 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
import SwiftState
class SessionVerificationStateMachine {
/// States the SessionVerificationViewModel can find itself in
enum State: StateType {
/// The initial state, before verification started
case initial
/// Waiting for verification acceptance
case requestingVerification
/// Verification accepted and emojis received
case showingChallenge(emojis: [SessionVerificationEmoji])
/// Emojis match locally
case acceptingChallenge(emojis: [SessionVerificationEmoji])
/// Emojis do not match locally
case decliningChallenge(emojis: [SessionVerificationEmoji])
/// Verification successful
case verified
/// User requested verification cancellation
case cancelling
/// The verification has been cancelled, remotely or locally
case cancelled
}
/// Events that can be triggered on the SessionVerification state machine
enum Event: EventType {
/// Request verification
case requestVerification
/// Has received emojis
case didReceiveChallenge(emojis: [SessionVerificationEmoji])
/// Emojis match
case acceptChallenge
/// Emojis do not match
case declineChallenge
/// Remote accepted challenge
case didAcceptChallenge
/// Request cancellation
case cancel
/// Verification cancelled
case didCancel
/// Request failed
case didFail
/// Restart the verification flow
case restart
}
private let stateMachine: StateMachine<State, Event>
var state: State {
stateMachine.state
}
init() {
stateMachine = StateMachine(state: .initial) { machine in
machine.addRoutes(event: .requestVerification, transitions: [.initial => .requestingVerification])
machine.addRoutes(event: .didFail, transitions: [.requestingVerification => .initial])
machine.addRoutes(event: .restart, transitions: [.cancelled => .initial])
// Transitions with associated values need to be handled through `addRouteMapping`
machine.addRouteMapping { event, fromState, _ in
switch (event, fromState) {
case (.didReceiveChallenge(let emojis), .requestingVerification):
return .showingChallenge(emojis: emojis)
case (.acceptChallenge, .showingChallenge(let emojis)):
return .acceptingChallenge(emojis: emojis)
case (.didFail, .acceptingChallenge(let emojis)):
return .showingChallenge(emojis: emojis)
case (.didAcceptChallenge, .acceptingChallenge):
return .verified
case (.declineChallenge, .showingChallenge(let emojis)):
return .decliningChallenge(emojis: emojis)
case (.didFail, .decliningChallenge(let emojis)):
return .showingChallenge(emojis: emojis)
case (.cancel, _):
return .cancelling
case (.didCancel, _):
return .cancelled
default:
return nil
}
}
}
}
/// Attempt to move the state machine to another state through an event
/// It will either invoke the `transitionHandler` or the `errorHandler` depending on its current state
func processEvent(_ event: Event) {
stateMachine.tryEvent(event)
}
/// Registers a callback for processing state machine transitions
func addTransitionHandler(_ handler: @escaping StateMachine<State, Event>.Handler) {
stateMachine.addAnyHandler(.any => .any, handler: handler)
}
/// Registers a callback for processing state machine errors
func addErrorHandler(_ handler: @escaping StateMachine<State, Event>.Handler) {
stateMachine.addErrorHandler(handler: handler)
}
}