Skip to content
Open
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
5 changes: 2 additions & 3 deletions apps/src/shared/gamma/containers/stack/StackContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react';
import {
Stack,
StackScreenLifecycleState,
} from 'react-native-screens/experimental';
import type { StackScreenProps } from 'react-native-screens/experimental';

Expand Down Expand Up @@ -88,7 +87,7 @@ export function StackContainer({ pathConfigs }: StackContainerProps) {
...currentStack,
{
screenKey: getId().toString(),
maxLifecycleState: StackScreenLifecycleState.ATTACHED,
activityMode: 'attached',
...requestedPath,
},
]);
Expand Down Expand Up @@ -126,7 +125,7 @@ export function StackContainer({ pathConfigs }: StackContainerProps) {
...currentStack, // This is mutated through pop()
{
...lastElement,
maxLifecycleState: StackScreenLifecycleState.DETACHED,
activityMode: 'detached',
},
];
});
Expand Down
21 changes: 21 additions & 0 deletions ios/conversion/RNSConversions-Stack.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#if RCT_NEW_ARCH_ENABLED && RNS_GAMMA_ENABLED

#import <react/renderer/components/rnscreens/Props.h>
#import "RNSStackScreenComponentView.h"

namespace rnscreens::conversion {

template <typename TargetType, typename InputType>
TargetType convert(InputType) {
static_assert(
false, "[RNScreens] Missing template specialisation for demanded types!");
}

template <>
RNSStackScreenActivityMode convert(react::RNSStackScreenActivityMode mode);

}; // namespace rnscreens::conversion

#endif // RCT_NEW_ARCH_ENABLED && RNS_GAMMA_ENABLED
17 changes: 17 additions & 0 deletions ios/conversion/RNSConversions-Stack.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#import "RNSConversions-Stack.h"

#if RCT_NEW_ARCH_ENABLED && RNS_GAMMA_ENABLED

namespace rnscreens::conversion {

namespace react = facebook::react;

template <>
RNSStackScreenActivityMode convert(react::RNSStackScreenActivityMode mode)
{
return static_cast<RNSStackScreenActivityMode>(mode);
};

}; // namespace rnscreens::conversion

#endif // RCT_NEW_ARCH_ENABLED && RNS_GAMMA_ENABLED
6 changes: 6 additions & 0 deletions ios/conversion/RNSConversions.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,10 @@ RNSSplitViewScreenColumnType RNSSplitViewScreenColumnTypeFromScreenProp(react::R

}; // namespace rnscreens::conversion

#if RCT_NEW_ARCH_ENABLED

#import "RNSConversions-Stack.h"

#endif // RCT_NEW_ARCH_ENABLED

#endif
2 changes: 1 addition & 1 deletion ios/gamma/stack/host/RNSStackController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public class RNSStackController: UINavigationController, ReactMountingTransactio
"[RNScreens] Child view controller must be invalidated when update is forced!")

let activeControllers = sourceAllViewControllers()
.filter { screenCtrl in screenCtrl.screen.maxLifecycleState == .attached }
.filter { screenCtrl in screenCtrl.screen.activityMode == .attached }

setViewControllers(activeControllers, animated: true)

Expand Down
15 changes: 10 additions & 5 deletions ios/gamma/stack/screen/RNSStackScreenComponentView.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,24 @@ NS_ASSUME_NONNULL_BEGIN
@class RNSStackScreenController;
@class RNSStackHostComponentView;

typedef NS_ENUM(int, RNSStackScreenLifecycleState) {
RNSStackScreenLifecycleInitial = 0,
RNSStackScreenLifecycleDetached = 1,
RNSStackScreenLifecycleAttached = 2,
typedef NS_ENUM(int, RNSStackScreenActivityMode) {
RNSStackScreenActivityModeDetached = 0,
RNSStackScreenActivityModeAttached = 1,
};

@interface RNSStackScreenComponentView : RNSReactBaseView

@property (nonatomic, weak, readwrite, nullable) RNSStackHostComponentView *stackHost;
@property (nonatomic, strong, readonly, nonnull) RNSStackScreenController *controller;

@end

#pragma mark - Props

@interface RNSStackScreenComponentView ()

@property (nonatomic, strong, readonly, nullable) NSString *screenKey;
@property (nonatomic, readonly) RNSStackScreenLifecycleState maxLifecycleState;
@property (nonatomic, readonly) RNSStackScreenActivityMode activityMode;

@end

Expand Down
20 changes: 11 additions & 9 deletions ios/gamma/stack/screen/RNSStackScreenComponentView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#import <react/renderer/components/rnscreens/Props.h>
#import <react/renderer/components/rnscreens/RCTComponentViewHelpers.h>

#import "RNSConversions-Stack.h"

#import "Swift-Bridging.h"

namespace react = facebook::react;
Expand All @@ -20,7 +22,7 @@ @implementation RNSStackScreenComponentView {
RNSStackScreenComponentEventEmitter *_Nonnull _reactEventEmitter;

// Flags
BOOL _needsLifecycleStateUpdate;
BOOL _hasUpdatedActivityMode;
}

- (instancetype)initWithFrame:(CGRect)frame
Expand All @@ -39,7 +41,7 @@ - (void)initState

_reactEventEmitter = [RNSStackScreenComponentEventEmitter new];

_needsLifecycleStateUpdate = NO;
_hasUpdatedActivityMode = NO;
}

- (void)resetProps
Expand All @@ -49,7 +51,7 @@ - (void)resetProps

// container state
_screenKey = nil;
_maxLifecycleState = RNSStackScreenLifecycleInitial;
_activityMode = RNSStackScreenActivityModeDetached;
}

- (void)setupController
Expand Down Expand Up @@ -86,9 +88,9 @@ - (void)updateProps:(const facebook::react::Props::Shared &)props
const auto &oldComponentProps = *std::static_pointer_cast<const react::RNSStackScreenProps>(_props);
const auto &newComponentProps = *std::static_pointer_cast<const react::RNSStackScreenProps>(props);

if (oldComponentProps.maxLifecycleState != newComponentProps.maxLifecycleState) {
_maxLifecycleState = static_cast<RNSStackScreenLifecycleState>(newComponentProps.maxLifecycleState);
_needsLifecycleStateUpdate = YES;
if (oldComponentProps.activityMode != newComponentProps.activityMode) {
_activityMode = rnscreens::conversion::convert<RNSStackScreenActivityMode>(newComponentProps.activityMode);
_hasUpdatedActivityMode = YES;
}

if (oldComponentProps.screenKey != newComponentProps.screenKey) {
Expand All @@ -101,9 +103,9 @@ - (void)updateProps:(const facebook::react::Props::Shared &)props

- (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask
{
if (_needsLifecycleStateUpdate) {
_needsLifecycleStateUpdate = NO;
[_controller setNeedsLifecycleStateUpdate];
if (_hasUpdatedActivityMode) {
_hasUpdatedActivityMode = NO;
[_controller setActivityModeInvalidated];
}

[super finalizeUpdates:updateMask];
Expand Down
2 changes: 1 addition & 1 deletion ios/gamma/stack/screen/RNSStackScreenController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class RNSStackScreenController: UIViewController {
// MARK: Signals

@objc
public func setNeedsLifecycleStateUpdate() {
public func setActivityModeInvalidated() {
findStackController()?.setNeedsUpdateOfChildViewControllers()
}

Expand Down
10 changes: 2 additions & 8 deletions src/components/gamma/stack/StackScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,13 @@ import StackScreenNativeComponent from '../../../fabric/gamma/stack/StackScreenN
import type { NativeSyntheticEvent } from 'react-native';
import { StackScreenProps } from './StackScreen.types';

export const StackScreenLifecycleState = {
INITIAL: 0,
DETACHED: 1,
ATTACHED: 2,
} as const;

/**
* EXPERIMENTAL API, MIGHT CHANGE W/O ANY NOTICE
*/
function StackScreen({
children,
// Control
maxLifecycleState,
activityMode,
screenKey,
// Events
onWillAppear,
Expand All @@ -38,7 +32,7 @@ function StackScreen({
<StackScreenNativeComponent
style={StyleSheet.absoluteFill}
// Control
maxLifecycleState={maxLifecycleState}
activityMode={activityMode}
screenKey={screenKey}
// Events
onWillAppear={onWillAppear}
Expand Down
6 changes: 4 additions & 2 deletions src/components/gamma/stack/StackScreen.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ import { NativeSyntheticEvent, ViewProps } from 'react-native';

export type GenericEmptyEvent = Record<string, never>;

export type StackScreenActivityMode = 'detached' | 'attached';

export type StackScreenEventHandler = (
event: NativeSyntheticEvent<GenericEmptyEvent>,
) => void;

export type StackScreenProps = {
children?: ViewProps['children'];

maxLifecycleState: 0 | 1 | 2; // TODO: Figure out to type this w/o circular import

// Control
activityMode: StackScreenActivityMode;
screenKey: string;

// Events
Expand Down
6 changes: 0 additions & 6 deletions src/components/gamma/stack/StackScreen.web.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import { View } from 'react-native';

export const StackScreenLifecycleState = {
INITIAL: 0,
DETACHED: 1,
ATTACHED: 2,
} as const;

const StackScreen = View;

export default StackScreen;
2 changes: 0 additions & 2 deletions src/components/gamma/stack/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import StackHost from './StackHost';
import StackScreen from './StackScreen';

export { StackScreenLifecycleState } from './StackScreen';

export * from './StackHost.types';
export * from './StackScreen.types';

Expand Down
5 changes: 1 addition & 4 deletions src/experimental/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ export * from './types';

// Components

export {
default as Stack,
StackScreenLifecycleState,
} from '../components/gamma/stack';
export { default as Stack } from '../components/gamma/stack';

export { default as Split } from '../components/gamma/split';
export { default as SafeAreaView } from '../components/safe-area/SafeAreaView';
9 changes: 7 additions & 2 deletions src/fabric/gamma/stack/StackScreenNativeComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,19 @@ import type { CodegenTypes as CT, ViewProps } from 'react-native';
import { codegenNativeComponent } from 'react-native';

// eslint-disable-next-line @typescript-eslint/ban-types
export type GenericEmptyEvent = Readonly<{}>;
type GenericEmptyEvent = Readonly<{}>;

type ActivityMode = 'detached' | 'attached';

export interface NativeProps extends ViewProps {
// Control
maxLifecycleState: CT.Int32;

// Codegen does not currently support non-optional enum.
activityMode?: CT.WithDefault<ActivityMode, 'detached'>;
screenKey: string;

// Events

onWillAppear?: CT.DirectEventHandler<GenericEmptyEvent>;
onDidAppear?: CT.DirectEventHandler<GenericEmptyEvent>;
onWillDisappear?: CT.DirectEventHandler<GenericEmptyEvent>;
Expand Down
Loading