Skip to content
Snippets Groups Projects
Commit 1f170097 authored by Dariusz Rybicki's avatar Dariusz Rybicki
Browse files

Present MyIdentityView from SessionView

parent c506cef2
No related branches found
No related tags found
1 merge request!14[Example App] Make identity & contact
...@@ -62,6 +62,7 @@ let package = Package( ...@@ -62,6 +62,7 @@ let package = Package(
dependencies: [ dependencies: [
.target(name: "ErrorFeature"), .target(name: "ErrorFeature"),
.target(name: "LandingFeature"), .target(name: "LandingFeature"),
.target(name: "MyIdentityFeature"),
.target(name: "SessionFeature"), .target(name: "SessionFeature"),
.product( .product(
name: "ElixxirDAppsSDK", name: "ElixxirDAppsSDK",
...@@ -157,6 +158,7 @@ let package = Package( ...@@ -157,6 +158,7 @@ let package = Package(
name: "SessionFeature", name: "SessionFeature",
dependencies: [ dependencies: [
.target(name: "ErrorFeature"), .target(name: "ErrorFeature"),
.target(name: "MyIdentityFeature"),
.product( .product(
name: "ComposableArchitecture", name: "ComposableArchitecture",
package: "swift-composable-architecture" package: "swift-composable-architecture"
......
...@@ -3,6 +3,7 @@ import ComposableArchitecture ...@@ -3,6 +3,7 @@ import ComposableArchitecture
import ElixxirDAppsSDK import ElixxirDAppsSDK
import ErrorFeature import ErrorFeature
import LandingFeature import LandingFeature
import MyIdentityFeature
import SessionFeature import SessionFeature
import SwiftUI import SwiftUI
...@@ -44,7 +45,9 @@ extension AppEnvironment { ...@@ -44,7 +45,9 @@ extension AppEnvironment {
session: SessionEnvironment( session: SessionEnvironment(
getClient: { clientSubject.value }, getClient: { clientSubject.value },
bgScheduler: bgScheduler, bgScheduler: bgScheduler,
mainScheduler: mainScheduler mainScheduler: mainScheduler,
makeId: UUID.init,
myIdentity: MyIdentityEnvironment()
) )
) )
} }
......
import ComposableArchitecture import ComposableArchitecture
public struct MyIdentityState: Equatable { public struct MyIdentityState: Equatable {
public init() {} public init(
id: UUID
) {
self.id = id
}
public var id: UUID
} }
public enum MyIdentityAction: Equatable {} public enum MyIdentityAction: Equatable {}
......
...@@ -24,7 +24,7 @@ public struct MyIdentityView_Previews: PreviewProvider { ...@@ -24,7 +24,7 @@ public struct MyIdentityView_Previews: PreviewProvider {
public static var previews: some View { public static var previews: some View {
NavigationView { NavigationView {
MyIdentityView(store: .init( MyIdentityView(store: .init(
initialState: .init(), initialState: .init(id: UUID()),
reducer: .empty, reducer: .empty,
environment: () environment: ()
)) ))
......
...@@ -2,24 +2,28 @@ import Combine ...@@ -2,24 +2,28 @@ import Combine
import ComposableArchitecture import ComposableArchitecture
import ElixxirDAppsSDK import ElixxirDAppsSDK
import ErrorFeature import ErrorFeature
import MyIdentityFeature
public struct SessionState: Equatable { public struct SessionState: Equatable {
public init( public init(
id: UUID, id: UUID,
networkFollowerStatus: NetworkFollowerStatus? = nil, networkFollowerStatus: NetworkFollowerStatus? = nil,
isNetworkHealthy: Bool? = nil, isNetworkHealthy: Bool? = nil,
error: ErrorState? = nil error: ErrorState? = nil,
myIdentity: MyIdentityState? = nil
) { ) {
self.id = id self.id = id
self.networkFollowerStatus = networkFollowerStatus self.networkFollowerStatus = networkFollowerStatus
self.isNetworkHealthy = isNetworkHealthy self.isNetworkHealthy = isNetworkHealthy
self.error = error self.error = error
self.myIdentity = myIdentity
} }
public var id: UUID public var id: UUID
public var networkFollowerStatus: NetworkFollowerStatus? public var networkFollowerStatus: NetworkFollowerStatus?
public var isNetworkHealthy: Bool? public var isNetworkHealthy: Bool?
public var error: ErrorState? public var error: ErrorState?
public var myIdentity: MyIdentityState?
} }
public enum SessionAction: Equatable { public enum SessionAction: Equatable {
...@@ -31,23 +35,32 @@ public enum SessionAction: Equatable { ...@@ -31,23 +35,32 @@ public enum SessionAction: Equatable {
case monitorNetworkHealth(Bool) case monitorNetworkHealth(Bool)
case didUpdateNetworkHealth(Bool?) case didUpdateNetworkHealth(Bool?)
case didDismissError case didDismissError
case presentMyIdentity
case didDismissMyIdentity
case error(ErrorAction) case error(ErrorAction)
case myIdentity(MyIdentityAction)
} }
public struct SessionEnvironment { public struct SessionEnvironment {
public init( public init(
getClient: @escaping () -> Client?, getClient: @escaping () -> Client?,
bgScheduler: AnySchedulerOf<DispatchQueue>, bgScheduler: AnySchedulerOf<DispatchQueue>,
mainScheduler: AnySchedulerOf<DispatchQueue> mainScheduler: AnySchedulerOf<DispatchQueue>,
makeId: @escaping () -> UUID,
myIdentity: MyIdentityEnvironment
) { ) {
self.getClient = getClient self.getClient = getClient
self.bgScheduler = bgScheduler self.bgScheduler = bgScheduler
self.mainScheduler = mainScheduler self.mainScheduler = mainScheduler
self.makeId = makeId
self.myIdentity = myIdentity
} }
public var getClient: () -> Client? public var getClient: () -> Client?
public var bgScheduler: AnySchedulerOf<DispatchQueue> public var bgScheduler: AnySchedulerOf<DispatchQueue>
public var mainScheduler: AnySchedulerOf<DispatchQueue> public var mainScheduler: AnySchedulerOf<DispatchQueue>
public var makeId: () -> UUID
public var myIdentity: MyIdentityEnvironment
} }
public let sessionReducer = Reducer<SessionState, SessionAction, SessionEnvironment> public let sessionReducer = Reducer<SessionState, SessionAction, SessionEnvironment>
...@@ -129,17 +142,36 @@ public let sessionReducer = Reducer<SessionState, SessionAction, SessionEnvironm ...@@ -129,17 +142,36 @@ public let sessionReducer = Reducer<SessionState, SessionAction, SessionEnvironm
state.error = nil state.error = nil
return .none return .none
case .error(_): case .presentMyIdentity:
if state.myIdentity == nil {
state.myIdentity = MyIdentityState(id: env.makeId())
}
return .none
case .didDismissMyIdentity:
state.myIdentity = nil
return .none
case .error(_), .myIdentity(_):
return .none return .none
} }
} }
.presenting(
myIdentityReducer,
state: .keyPath(\.myIdentity),
id: .keyPath(\.?.id),
action: /SessionAction.myIdentity,
environment: \.myIdentity
)
#if DEBUG #if DEBUG
extension SessionEnvironment { extension SessionEnvironment {
public static let failing = SessionEnvironment( public static let failing = SessionEnvironment(
getClient: { .failing }, getClient: { .failing },
bgScheduler: .failing, bgScheduler: .failing,
mainScheduler: .failing mainScheduler: .failing,
makeId: { fatalError() },
myIdentity: .failing
) )
} }
#endif #endif
...@@ -2,6 +2,7 @@ import ComposableArchitecture ...@@ -2,6 +2,7 @@ import ComposableArchitecture
import ComposablePresentation import ComposablePresentation
import ElixxirDAppsSDK import ElixxirDAppsSDK
import ErrorFeature import ErrorFeature
import MyIdentityFeature
import SwiftUI import SwiftUI
public struct SessionView: View { public struct SessionView: View {
...@@ -49,6 +50,18 @@ public struct SessionView: View { ...@@ -49,6 +50,18 @@ public struct SessionView: View {
} header: { } header: {
Text("Network health") Text("Network health")
} }
Section {
Button {
viewStore.send(.presentMyIdentity)
} label: {
HStack {
Text("My identity")
Spacer()
Image(systemName: "chevron.forward")
}
}
}
} }
.navigationTitle("Session") .navigationTitle("Session")
.task { .task {
...@@ -64,6 +77,18 @@ public struct SessionView: View { ...@@ -64,6 +77,18 @@ public struct SessionView: View {
}, },
content: ErrorView.init(store:) content: ErrorView.init(store:)
) )
.background(
NavigationLinkWithStore(
store.scope(
state: \.myIdentity,
action: SessionAction.myIdentity
),
onDeactivate: {
viewStore.send(.didDismissMyIdentity)
},
destination: MyIdentityView.init(store:)
)
)
} }
} }
} }
......
import ComposableArchitecture import ComposableArchitecture
import ElixxirDAppsSDK import ElixxirDAppsSDK
import ErrorFeature import ErrorFeature
import MyIdentityFeature
import XCTest import XCTest
@testable import SessionFeature @testable import SessionFeature
...@@ -155,4 +156,25 @@ final class SessionFeatureTests: XCTestCase { ...@@ -155,4 +156,25 @@ final class SessionFeatureTests: XCTestCase {
$0.error = nil $0.error = nil
} }
} }
func testPresentingMyIdentity() {
let newId = UUID()
var env = SessionEnvironment.failing
env.makeId = { newId }
let store = TestStore(
initialState: SessionState(id: UUID()),
reducer: sessionReducer,
environment: env
)
store.send(.presentMyIdentity) {
$0.myIdentity = MyIdentityState(id: newId)
}
store.send(.didDismissMyIdentity) {
$0.myIdentity = nil
}
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment