Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions components/ios/base/PilotAccessibility.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,24 @@ extension View {
) -> some View {
modifier(AccessibilityViewModifier(infoFlow: infoFlow, traits: traits, childBehavior: childBehavior))
}

public func pilotAccessibility(
_ infoFlow: SkieSwiftOptionalFlow<PilotAccessibilityInfo>,
initialValue: PilotAccessibilityInfo? = nil,
traits: AccessibilityTraits = [],
childBehavior: AccessibilityChildBehavior = .ignore
) -> some View {
modifier(NullableAccessibilityViewModifier(infoFlow: infoFlow, initialValue: initialValue, traits: traits, childBehavior: childBehavior))
}

public func pilotAccessibility(
_ infoFlow: SkieSwiftFlow<PilotAccessibilityInfo>,
initialValue: PilotAccessibilityInfo,
traits: AccessibilityTraits = [],
childBehavior: AccessibilityChildBehavior = .ignore
) -> some View {
modifier(AccessibilityViewModifier(infoFlow: infoFlow, initialValue: initialValue, traits: traits, childBehavior: childBehavior))
}
}

private struct NullableAccessibilityViewModifier: ViewModifier {
Expand Down Expand Up @@ -52,6 +70,17 @@ private struct NullableAccessibilityViewModifier: ViewModifier {
self.childBehavior = childBehavior
}

init(
infoFlow: SkieSwiftOptionalFlow<PilotAccessibilityInfo>,
initialValue: PilotAccessibilityInfo?,
traits: AccessibilityTraits,
childBehavior: AccessibilityChildBehavior
) {
_accessibilityInfo = ObservedObject(wrappedValue: NullableStateObservable(infoFlow, initialValue: initialValue))
self.traits = traits
self.childBehavior = childBehavior
}

func body(content: Content) -> some View {
content
.configureAccessibility(
Expand All @@ -77,6 +106,17 @@ private struct AccessibilityViewModifier: ViewModifier {
self.childBehavior = childBehavior
}

init(
infoFlow: SkieSwiftFlow<PilotAccessibilityInfo>,
initialValue: PilotAccessibilityInfo,
traits: AccessibilityTraits,
childBehavior: AccessibilityChildBehavior
) {
_accessibilityInfo = ObservedObject(wrappedValue: StateObservable(infoFlow, initialValue: initialValue))
self.traits = traits
self.childBehavior = childBehavior
}

func body(content: Content) -> some View {
content
.configureAccessibility(
Expand Down
34 changes: 30 additions & 4 deletions viewmodel/ios/NullableStateObservable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ public class NullableStateObservable<State>: ObservableObject {
switch valueHolder {
case .const(let state):
state
case .flow(let stateFlow):
case .stateFlow(let stateFlow):
stateFlow.value
case .flow:
lastState
}
}

Expand All @@ -24,13 +26,36 @@ public class NullableStateObservable<State>: ObservableObject {
}

public init(_ stateFlow: SkieSwiftOptionalStateFlow<State>, animation: ((State?, State?) -> Animation?)? = nil) {
self.valueHolder = StateObservableValueHolder.flow(stateFlow)
self.valueHolder = StateObservableValueHolder.stateFlow(stateFlow)
self.animation = animation
self.lastState = stateFlow.value

task = Task { [weak self] in
for await newState in stateFlow.dropFirst() {
if let animation = self?.animation?(lastState, newState) {
if let animation = self?.animation?(self?.lastState, newState) {
DispatchQueue.main.async {
withAnimation(animation) {
self?.objectWillChange.send()
}
}
} else {
DispatchQueue.main.async {
self?.objectWillChange.send()
}
}
self?.lastState = newState
}
}
}

public init(_ flow: SkieSwiftOptionalFlow<State>, initialValue: State? = nil, animation: ((State?, State?) -> Animation?)? = nil) {
self.valueHolder = StateObservableValueHolder.flow(flow)
self.animation = animation
self.lastState = initialValue

task = Task { [weak self] in
for await newState in flow {
if let animation = self?.animation?(self?.lastState, newState) {
DispatchQueue.main.async {
withAnimation(animation) {
self?.objectWillChange.send()
Expand All @@ -53,5 +78,6 @@ public class NullableStateObservable<State>: ObservableObject {

private enum StateObservableValueHolder<State> {
case const(State?)
case flow(SkieSwiftOptionalStateFlow<State>)
case stateFlow(SkieSwiftOptionalStateFlow<State>)
case flow(SkieSwiftOptionalFlow<State>)
}
32 changes: 29 additions & 3 deletions viewmodel/ios/StateObservable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ public class StateObservable<State>: ObservableObject {
switch valueHolder {
case .const(let state):
state
case .flow(let stateFlow):
case .stateFlow(let stateFlow):
stateFlow.value
case .flow:
lastState
}
}

Expand All @@ -24,7 +26,7 @@ public class StateObservable<State>: ObservableObject {
}

public init(_ stateFlow: SkieSwiftStateFlow<State>, animation: ((State, State) -> Animation?)? = nil) {
self.valueHolder = StateObservableValueHolder.flow(stateFlow)
self.valueHolder = StateObservableValueHolder.stateFlow(stateFlow)
self.animation = animation
self.lastState = stateFlow.value

Expand All @@ -46,12 +48,36 @@ public class StateObservable<State>: ObservableObject {
}
}

public init(_ flow: SkieSwiftFlow<State>, initialValue: State, animation: ((State, State) -> Animation?)? = nil) {
self.valueHolder = StateObservableValueHolder.flow(flow)
self.animation = animation
self.lastState = initialValue

task = Task { [weak self] in
for await newState in flow {
if let lastState = self?.lastState, let animation = self?.animation?(lastState, newState) {
DispatchQueue.main.async {
withAnimation(animation) {
self?.objectWillChange.send()
}
}
} else {
DispatchQueue.main.async {
self?.objectWillChange.send()
}
}
self?.lastState = newState
}
}
}

deinit {
task?.cancel()
}
}

private enum StateObservableValueHolder<State> {
case const(State)
case flow(SkieSwiftStateFlow<State>)
case stateFlow(SkieSwiftStateFlow<State>)
case flow(SkieSwiftFlow<State>)
}
Loading