generated from rafaelesantos/swift-readme-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
de6aaf5
commit 1e49f6b
Showing
6 changed files
with
156 additions
and
0 deletions.
There are no files selected for viewing
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import SwiftUI | ||
import RefdsRedux | ||
|
||
public protocol RefdsRoutableRedux: Hashable, Identifiable { | ||
associatedtype State: RefdsReduxState | ||
associatedtype ViewType: View | ||
var navigationType: RefdsNavigationType { get } | ||
|
||
func view( | ||
router: RefdsRouterRedux<Self>, | ||
state: Binding<State>, | ||
action: (RefdsReduxAction) -> Void | ||
) -> ViewType | ||
} | ||
|
||
extension RefdsRoutableRedux { | ||
public var id: Self { self } | ||
|
||
func hash(into hasher: inout Hasher) { | ||
hasher.combine(id) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import SwiftUI | ||
import RefdsRedux | ||
|
||
public class RefdsRouterRedux< | ||
Destination: RefdsRoutableRedux | ||
>: ObservableObject { | ||
@Published public var path: NavigationPath = NavigationPath() | ||
@Published public var presentingSheet: Destination? | ||
@Published public var presentingFullScreenCover: Destination? | ||
@Published public var isPresented: Binding<Destination?> | ||
|
||
public var isPresenting: Bool { | ||
presentingSheet != nil || presentingFullScreenCover != nil | ||
} | ||
|
||
public init(isPresented: Binding<Destination?>) { | ||
self.isPresented = isPresented | ||
} | ||
|
||
@ViewBuilder | ||
public func view( | ||
for route: Destination, | ||
state: Binding<Destination.State>, | ||
action: (RefdsReduxAction) -> Void | ||
) -> some View { | ||
let router = router(type: route.navigationType) | ||
route.view(router: router, state: state, action: action) | ||
} | ||
|
||
public func route(to destination: Destination) { | ||
switch destination.navigationType { | ||
case .push: push(destination) | ||
case .sheet: presentSheet(destination) | ||
case .fullScreenCover: presentFullScreen(destination) | ||
} | ||
} | ||
|
||
public func popToRoot() { | ||
path.removeLast(path.count) | ||
} | ||
|
||
public func dismiss() { | ||
if !path.isEmpty { | ||
path.removeLast() | ||
} else if presentingSheet != nil { | ||
presentingSheet = nil | ||
} else if presentingFullScreenCover != nil { | ||
presentingFullScreenCover = nil | ||
} else { | ||
isPresented.wrappedValue = nil | ||
} | ||
} | ||
|
||
private func push(_ appRoute: Destination) { | ||
path.append(appRoute) | ||
} | ||
|
||
private func presentSheet(_ route: Destination) { | ||
self.presentingSheet = route | ||
} | ||
|
||
private func presentFullScreen(_ route: Destination) { | ||
self.presentingFullScreenCover = route | ||
} | ||
|
||
private func router(type: RefdsNavigationType) -> RefdsRouterRedux { | ||
switch type { | ||
case .push: | ||
return self | ||
case .sheet: | ||
return RefdsRouterRedux( | ||
isPresented: Binding( | ||
get: { self.presentingSheet }, | ||
set: { self.presentingSheet = $0 } | ||
) | ||
) | ||
case .fullScreenCover: | ||
return RefdsRouterRedux( | ||
isPresented: Binding( | ||
get: { self.presentingFullScreenCover }, | ||
set: { self.presentingFullScreenCover = $0 } | ||
) | ||
) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import SwiftUI | ||
import RefdsRedux | ||
|
||
public struct RefdsRoutingReduxView< | ||
Content: View, | ||
Destination: RefdsRoutableRedux | ||
>: View { | ||
@Binding var router: RefdsRouterRedux<Destination> | ||
@Binding var store: RefdsReduxStore<Destination.State> | ||
private let content: (RefdsRouterRedux<Destination>) -> Content | ||
|
||
public init( | ||
router: Binding<RefdsRouterRedux<Destination>>, | ||
store: Binding<RefdsReduxStore<Destination.State>>, | ||
@ViewBuilder content: @escaping (RefdsRouterRedux<Destination>) -> Content | ||
) { | ||
self._router = router | ||
self._store = store | ||
self.content = content | ||
} | ||
|
||
public var body: some View { | ||
NavigationStack(path: $router.path) { | ||
content(router) | ||
.navigationDestination(for: Destination.self) { | ||
router.view( | ||
for: $0, | ||
state: $store.state, | ||
action: store.dispatch(action:) | ||
) | ||
} | ||
} | ||
.sheet(item: $router.presentingSheet) { | ||
router.view( | ||
for: $0, | ||
state: $store.state, | ||
action: store.dispatch(action:) | ||
) | ||
} | ||
.refdsFullScreenCover(item: $router.presentingFullScreenCover) { | ||
router.view( | ||
for: $0, | ||
state: $store.state, | ||
action: store.dispatch(action:) | ||
) | ||
} | ||
} | ||
} |