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
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.expensify.reactnativehybridapp
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.module.annotations.ReactModule
import android.util.Log
import com.facebook.react.bridge.Promise

@ReactModule(name = NativeReactNativeHybridAppSpec.NAME)
class ReactNativeHybridApp(reactContext: ReactApplicationContext) :
Expand Down Expand Up @@ -36,4 +37,9 @@ class ReactNativeHybridApp(reactContext: ReactApplicationContext) :
override fun sendAuthToken(authToken: String?) {
Log.d(NAME, "`sendAuthToken` should never be called in standalone `New Expensify` app")
}

override fun getHybridAppSettings(promise: Promise) {
Log.d(NAME, "`getHybridAppSettings` should never be called in standalone `New Expensify` app")
promise.reject("NOT_IMPLEMENTED", "getHybridAppSettings is not implemented in standalone New Expensify app")
}
}
6 changes: 6 additions & 0 deletions modules/hybrid-app/ios/ReactNativeHybridApp.mm
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ - (void)sendAuthToken:(NSString *)authToken {
NSLog(@"[ReactNativeHybridApp] `sendAuthToken` should never be called in standalone `New Expensify` app");
}

- (void)getHybridAppSettings:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject {
NSLog(@"[ReactNativeHybridApp] `getHybridAppSettings` should never be called in standalone `New Expensify` app");
reject(@"NOT_IMPLEMENTED", @"This method is not available in standalone New Expensify app", nil);
}

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
(const facebook::react::ObjCTurboModule::InitParams &)params
{
Expand Down
1 change: 1 addition & 0 deletions modules/hybrid-app/src/NativeReactNativeHybridApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface Spec extends TurboModule {
completeOnboarding: (status: boolean) => void;
switchAccount: (newDotCurrentAccountEmail: string, authToken: string, policyID: string, accountID: string) => void;
sendAuthToken: (authToken: string) => void;
getHybridAppSettings: () => Promise<string | null>;
}

export default TurboModuleRegistry.getEnforcing<Spec>('ReactNativeHybridApp');
3 changes: 3 additions & 0 deletions modules/hybrid-app/src/index.native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ const HybridAppModule: HybridAppModuleType = {
sendAuthToken({authToken}) {
ReactNativeHybridApp.sendAuthToken(authToken);
},
getHybridAppSettings() {
return ReactNativeHybridApp.getHybridAppSettings();
},
};

export default HybridAppModule;
5 changes: 5 additions & 0 deletions modules/hybrid-app/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ const HybridAppModule: HybridAppModuleType = {
// eslint-disable-next-line no-console
console.warn('HybridAppModule: `sendAuthToken` should never be called on web');
},
getHybridAppSettings() {
// eslint-disable-next-line no-console
console.warn('HybridAppModule: `getHybridAppSettings` should never be called on web');
return Promise.resolve(null);
},
};

export default HybridAppModule;
1 change: 1 addition & 0 deletions modules/hybrid-app/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ type HybridAppModuleType = {
completeOnboarding: (args: {status: boolean}) => void;
switchAccount: (args: {newDotCurrentAccountEmail: string; authToken: string; policyID: string; accountID: string}) => void;
sendAuthToken: (args: {authToken: string}) => void;
getHybridAppSettings: () => Promise<string | null>;
};

export default HybridAppModuleType;
6 changes: 2 additions & 4 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ import {SplashScreenStateContextProvider} from './SplashScreenStateContext';
type AppProps = {
/** The URL specifying the initial navigation destination when the app opens */
url?: Route;
/** Serialized configuration data required to initialize the React Native app (e.g. authentication details) */
hybridAppSettings?: string;
};

LogBox.ignoreLogs([
Expand All @@ -71,15 +69,15 @@ const fill = {flex: 1};

const StrictModeWrapper = CONFIG.USE_REACT_STRICT_MODE_IN_DEV ? React.StrictMode : ({children}: {children: React.ReactElement}) => children;

function App({url, hybridAppSettings}: AppProps) {
function App({url}: AppProps) {
useDefaultDragAndDrop();
OnyxUpdateManager();

return (
<StrictModeWrapper>
<SplashScreenStateContextProvider>
<InitialURLContextProvider url={url}>
<HybridAppHandler hybridAppSettings={hybridAppSettings} />
<HybridAppHandler />
<GestureHandlerRootView style={fill}>
<ComposeProviders
components={[
Expand Down
31 changes: 20 additions & 11 deletions src/HybridAppHandler.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
import {useContext, useState} from 'react';
import type {AppProps} from './App';
import HybridAppModule from '@expensify/react-native-hybrid-app';
import {useContext, useEffect} from 'react';
import CONFIG from './CONFIG';
import CONST from './CONST';
import {signInAfterTransitionFromOldDot} from './libs/actions/Session';
import Log from './libs/Log';
import SplashScreenStateContext from './SplashScreenStateContext';

function HybridAppHandler({hybridAppSettings}: AppProps) {
const [signInHandled, setSignInHandled] = useState(false);
function HybridAppHandler() {
const {setSplashScreenState} = useContext(SplashScreenStateContext);

if (!CONFIG.IS_HYBRID_APP || !hybridAppSettings || signInHandled) {
return null;
}
useEffect(() => {
if (!CONFIG.IS_HYBRID_APP) {
return;
}

signInAfterTransitionFromOldDot(hybridAppSettings).then(() => {
setSplashScreenState(CONST.BOOT_SPLASH_STATE.READY_TO_BE_HIDDEN);
setSignInHandled(true);
});
HybridAppModule.getHybridAppSettings().then((hybridAppSettings: string | null) => {
if (!hybridAppSettings) {
// Native method can send non-null value only once per NewDot lifecycle. It prevents issues with multiple initializations during reloads on debug builds.
Log.info('[HybridApp] `getHybridAppSettings` called more than once during single NewDot lifecycle. Skipping initialization.');
return;
}

signInAfterTransitionFromOldDot(hybridAppSettings).then(() => {
setSplashScreenState(CONST.BOOT_SPLASH_STATE.READY_TO_BE_HIDDEN);
});
});
}, [setSplashScreenState]);

return null;
}
Expand Down
Loading