Unverified Commit e1785af7 authored by Hanwen Cheng's avatar Hanwen Cheng Committed by GitHub
Browse files

refactor: migrating to typescript (#521)

* init typescript settings

* change let to const

* use typescript strict

* update lint config for typescript

* update lint config for typescript

* upgrade to react-navigation v4 and use typed navigator

* add required dependency for react navigation

* update with eslint and App.tsx

* following merging

* refactor buttons

* refactor

* stash

* add types for networks specs

* fix add legacy account error

* update typescript configs

* refactor identity and account stores

* hoc.js to typescript

* refactor main landing page

* complete identity utils and account store

* renaming files

* refactor components and payloads component

* refactor all the components and scanner store

* fix typescript compiler errors

* rename alls screens

* refactor screens

* refactor all the screens

* fix typescript compiler errors

* fixed compiler and lint error

* reorder files and use path alias

* reoder imports

* ignore jest caches

* integrate typescript with jest

* integrate e2e test

* update travis config and readme

* remove logs and comments

* delete redundant line

* fix scanner name

* multi signing fix

* add default catch

* use await to avoid async problem and remove one warning with source.uri

* use path alias of e2e and utils

* imporve sign button display in small screen

* hide path derivation option for ethereum account

* fix path display error

* fix ethereum delete problem

* imporve navigation

* upgrade react navigation to resolve bug

* add react hooks lint

* fix missing icon bug
parent e5f959a9
Pipeline #81282 failed with stages
in 2 minutes and 17 seconds
const commonRules = {
"no-bitwise": "off",
"comma-dangle": ["error", "never"],
"object-curly-spacing": ["error", "always"],
"quotes": ["error", "single", { "avoidEscape": true }],
"no-unused-vars": ["error", { "args": "none" }],
"react-native/no-inline-styles": "off",
"sort-keys": ["error", "asc", {"caseSensitive": true, "natural": false, "minKeys": 2}],
"import/order": ["error", {
"newlines-between": "always"
}]
};
module.exports = {
extends: ["@react-native-community", "plugin:prettier/recommended", "plugin:import/errors", "plugin:import/warnings"],
extends: [
"@react-native-community",
"plugin:prettier/recommended",
"plugin:import/errors",
"plugin:import/warnings",
"plugin:import/typescript"
],
globals: { inTest: "writable" },
overrides: [
{
"files": ["e2e/*.spec.js", "e2e/init.js", "e2e/e2eUtils.js"],
"rules": {
files: ["e2e/*.spec.js", "e2e/init.js", "e2e/e2eUtils.js"],
rules: {
"no-undef": "off"
}
},
{
files: ["**/*.ts", "**/*.tsx"],
env: { "browser": true, "es6": true, "node": true },
extends: [
"@react-native-community",
"plugin:prettier/recommended",
"plugin:import/errors",
"plugin:import/warnings",
"plugin:import/typescript",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaFeatures: { "jsx": true },
ecmaVersion: 2018,
sourceType: "module",
project: "./tsconfig.json"
},
plugins: ["@typescript-eslint", "react-hooks"],
rules: {
...commonRules,
"@typescript-eslint/no-explicit-any": 0,
"@typescript-eslint/semi": ["error"],
"@typescript-eslint/no-use-before-define": ["error", { "variables": false }], // enable defining variables after react component;
"@typescript-eslint/no-non-null-assertion": 0,
'@typescript-eslint/camelcase': 0,
"no-void": "off",
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
"semi": "off"
}
}
],
parserOptions: {
......@@ -16,18 +69,19 @@ module.exports = {
},
},
settings: {
"import/resolver": {
"node": {
"extensions": [".js", ".jsx", ".ts", ".tsx"]
},
"typescript": {
"alwaysTryTypes": true // always try to resolve types under `<roo/>@types` directory even it doesn't contain any source code, like `@types/unist`
},
},
"import/ignore": "react-navigation",
react: {
"pragma": "React", // Pragma to use, default to "React"
"version": "16.9.0", // React version, default to the latest React stable release
},
},
rules: {
"no-bitwise": "off",
"comma-dangle": ["error", "never"],
"object-curly-spacing": ["error", "always"],
"quotes": ["error", "single", { "avoidEscape": true }],
"no-unused-vars": ["error", { "args": "none" }],
"react-native/no-inline-styles": "off",
"sort-keys": ["error", "asc", {"caseSensitive": true, "natural": false, "minKeys": 2}]
}
rules: commonRules
};
[ignore]
; We fork some components by platform
.*/*[.]android.js
; Ignore "BUCK" generated dirs
<PROJECT_ROOT>/\.buckd/
; Ignore unexpected extra "@providesModule"
.*/node_modules/.*/node_modules/fbjs/.*
; Ignore duplicate module providers
; For RN Apps installed via npm, "Libraries" folder is inside
; "node_modules/react-native" but in the source repo it is in the root
node_modules/react-native/Libraries/react-native/React.js
; Ignore polyfills
node_modules/react-native/Libraries/polyfills/.*
; These should not be required directly
; require from fbjs/lib instead: require('fbjs/lib/warning')
node_modules/warning/.*
; Flow doesn't support platforms
.*/Libraries/Utilities/HMRLoadingView.js
[untyped]
.*/node_modules/@react-native-community/cli/.*/.*
[include]
[libs]
node_modules/react-native/Libraries/react-native/react-native-interface.js
node_modules/react-native/flow/
[options]
emoji=true
esproposal.optional_chaining=enable
esproposal.nullish_coalescing=enable
module.file_ext=.js
module.file_ext=.json
module.file_ext=.ios.js
module.system=haste
module.system.haste.use_name_reducers=true
# get basename
module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1'
module.system.haste.paths.blacklist=.*/__tests__/.*
module.system.haste.paths.blacklist=.*/__mocks__/.*
module.system.haste.paths.whitelist=<PROJECT_ROOT>/node_modules/react-native/Libraries/.*
module.system.haste.paths.whitelist=<PROJECT_ROOT>/node_modules/react-native/RNTester/.*
module.system.haste.paths.whitelist=<PROJECT_ROOT>/node_modules/react-native/IntegrationTests/.*
module.system.haste.paths.blacklist=<PROJECT_ROOT>/node_modules/react-native/Libraries/react-native/react-native-implementation.js
module.system.haste.paths.blacklist=<PROJECT_ROOT>/node_modules/react-native/Libraries/Animated/src/polyfills/.*
munge_underscores=true
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FlowFixMeProps
suppress_type=$FlowFixMeState
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
[lints]
sketchy-null-number=warn
sketchy-null-mixed=warn
sketchy-number=warn
untyped-type-import=warn
nonstrict-import=warn
deprecated-type=warn
unsafe-getters-setters=warn
inexact-spread=warn
unnecessary-invariant=warn
signature-verification-failure=warn
deprecated-utility=error
[strict]
deprecated-type
nonstrict-import
sketchy-null
unclear-type
unsafe-getters-setters
untyped-import
untyped-type-import
[version]
^0.109.0
yarn-error.log
package-lock.json
# typescript output directory
dist/
# jest cache
.jest/cache
# NDK
NDK/
rust/.cargo
......
{
"printWidth": 80,
"parser": "flow",
"parser": "typescript",
"singleQuote": true,
"useTabs": true,
"tabWidth": 2
......
---
language: node_js
node_js: 8
node_js: 10
cache:
directories:
......
......@@ -35,7 +35,7 @@ Parity Signer was built to be used offline. The mobile device used to run the ap
## Build it
### Requirements
- `node.js` (tested on `v8.4.0`)
- `node.js` ( `>=10`)
- `yarn` (tested on `1.6.0`)
- `rustup` (tested on `rustup 1.16.0`)
- `rustc` (tested on `rustc 1.32.0 (9fda7c223 2019-01-16)`)
......
......@@ -169,6 +169,7 @@ android {
}
dependencies {
implementation project(':react-native-safe-area-context')
implementation project(':react-native-camera')
implementation project(':react-native-secure-storage')
implementation project(':react-native-gesture-handler')
......
......@@ -3,6 +3,7 @@ package io.parity.signer;
import android.app.Application;
import com.facebook.react.ReactApplication;
import com.th3rdwave.safeareacontext.SafeAreaContextPackage;
import com.reactlibrary.RNSecureStoragePackage;
import org.reactnative.camera.RNCameraPackage;
import com.swmansion.gesturehandler.react.RNGestureHandlerPackage;
......@@ -30,6 +31,7 @@ public class MainApplication extends Application implements ReactApplication {
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new SafeAreaContextPackage(),
new RNSecureStoragePackage(),
new RNCameraPackage(),
new SvgPackage(),
......
rootProject.name = 'Parity Signer'
include ':react-native-safe-area-context'
project(':react-native-safe-area-context').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-safe-area-context/android')
include ':react-native-secure-storage'
project(':react-native-secure-storage').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-secure-storage/android')
include ':react-native-gesture-handler'
......
......@@ -16,6 +16,23 @@ module.exports = {
vm: 'vm-browserify'
}
}
],
[
'module-resolver',
{
alias: {
components: './src/components',
constants: './src/constants',
e2e: './e2e',
res: './res',
screens: './src/screens',
stores: './src/stores',
styles: './src/styles',
types: './src/types',
utils: './src/utils'
},
root: ['.']
}
]
],
presets: ['module:metro-react-native-babel-preset']
......
{
"setupFilesAfterEnv": ["./init.js"],
"setupFilesAfterEnv": ["./init.ts"],
"testEnvironment": "node",
"reporters": ["detox/runners/jest/streamlineReporter"],
"verbose": true
......
......@@ -14,36 +14,43 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
'use strict';
import { expect, element, by } from 'detox';
import testIDs from './testIDs';
const { IdentityPin } = testIDs;
export const testTap = async buttonId => await element(by.id(buttonId)).tap();
export const testTap = async (buttonId: string): Promise<Detox.Actions<any>> =>
await element(by.id(buttonId)).tap();
export const testVisible = async componentId =>
export const testVisible = async (componentId: string): Promise<void> =>
await expect(element(by.id(componentId))).toBeVisible();
export const testExist = async componentId =>
export const testExist = async (componentId: string): Promise<void> =>
await expect(element(by.id(componentId))).toExist();
export const testNotExist = async componentId =>
export const testNotExist = async (componentId: string): Promise<void> =>
await expect(element(by.id(componentId))).toNotExist();
export const testNotVisible = async componentId =>
export const testNotVisible = async (componentId: string): Promise<void> =>
await expect(element(by.id(componentId))).toBeNotVisible();
export const tapBack = async () =>
export const tapBack = async (): Promise<Detox.Actions<any>> =>
await element(by.id(testIDs.Header.headerBackButton))
.atIndex(0)
.tap();
export const testInput = async (inputId, inputText) => {
export const testInput = async (
inputId: string,
inputText: string
): Promise<void> => {
await element(by.id(inputId)).typeText(inputText);
await element(by.id(inputId)).tapReturnKey();
};
export const testInputWithDone = async (inputId, inputText) => {
export const testInputWithDone = async (
inputId: string,
inputText: string
): Promise<void> => {
await element(by.id(inputId)).typeText(inputText);
if (device.getPlatform() === 'ios') {
await element(by.label('Done'))
......@@ -54,7 +61,10 @@ export const testInputWithDone = async (inputId, inputText) => {
}
};
export const testScrollAndTap = async (buttonId, screenId) => {
export const testScrollAndTap = async (
buttonId: string,
screenId: string
): Promise<void> => {
await waitFor(element(by.id(buttonId)))
.toBeVisible()
.whileElement(by.id(screenId))
......@@ -62,6 +72,6 @@ export const testScrollAndTap = async (buttonId, screenId) => {
await testTap(buttonId);
};
export const testUnlockPin = async pinCode => {
export const testUnlockPin = async (pinCode: string): Promise<void> => {
await testInputWithDone(IdentityPin.unlockPinInput, pinCode);
};
......@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
'use strict';
import { by, device, element } from 'detox';
import testIDs from './testIDs';
import {
......@@ -54,7 +54,7 @@ const defaultPath = '//default',
const mockSeedPhrase =
'split cradle example drum veteran swear cruel pizza guilt surface mansion film grant benefit educate marble cargo ignore bind include advance grunt exile grow';
const testSetUpDefaultPath = async () => {
const testSetUpDefaultPath = async (): Promise<void> => {
await testInput(IdentityPin.setPin, pinCode);
await testInputWithDone(IdentityPin.confirmPin, pinCode);
await testVisible(AccountNetworkChooser.chooserScreen);
......
......@@ -14,12 +14,11 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
'use strict';
import { init, cleanup } from 'detox';
import adapter from 'detox/runners/jest/adapter';
import specReporter from 'detox/runners/jest/specReporter';
const detox = require('detox');
const config = require('../package.json').detox;
const adapter = require('detox/runners/jest/adapter');
const specReporter = require('detox/runners/jest/specReporter');
import { detox as config } from '../package.json';
// Set the default timeout
jest.setTimeout(120000);
......@@ -30,7 +29,7 @@ jasmine.getEnv().addReporter(adapter);
jasmine.getEnv().addReporter(specReporter);
beforeAll(async () => {
await detox.init(config, { launchApp: false });
await init(config, { launchApp: false });
});
beforeEach(async () => {
......@@ -39,5 +38,5 @@ beforeEach(async () => {
afterAll(async () => {
await adapter.afterAll();
await detox.cleanup();
await cleanup();
});
......@@ -14,23 +14,30 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
'use strict';
import {
SUBSTRATE_NETWORK_LIST,
SubstrateNetworkKeys
} from 'constants/networkSpecs';
import { TxRequestData } from 'types/scannerTypes';
import { NETWORK_LIST, SubstrateNetworkKeys } from '../src/constants';
export const signingTestIdentityPath = `//${NETWORK_LIST[SubstrateNetworkKeys.KUSAMA].pathID}//default`;
export const signingTestIdentityPath = `//${
SUBSTRATE_NETWORK_LIST[SubstrateNetworkKeys.KUSAMA].pathId
}//default`;
const setRemarkExtrinsicKusama =
'47900000100005301021e169bcc4cdb062f1c85f971be770b6aea1bd32ac1bf7877aa54ccd73309014a20180000010c11111145030000fe030000b0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafeaf2df518f7017e0442a1d01b0f175e0fa5d427470014c1c3ab2131e6250072a70ec';
export const createMockSignRequest = () => ({
export const createMockSignRequest = (): TxRequestData => ({
bounds: {
bounds: [
{ x: '50', y: '50' },
{ x: '100', y: '100' }
],
height: 1440,
origin: [],
width: 1920
},
data: '',
rawData: setRemarkExtrinsicKusama,
target: 319,
type: 'QR_CODE'
type: 'qr'
});
......@@ -14,8 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
'use strict';
const testIDs = {
AccountListScreen: {
accountList: 'accountList'
......
......@@ -21,6 +21,7 @@
*/
import { AppRegistry, YellowBox } from 'react-native';
import App from './src/App';
YellowBox.ignoreWarnings([
'Warning: isMounted(...) is deprecated',
......
......@@ -21,6 +21,7 @@
*/
import { AppRegistry, YellowBox } from 'react-native';
import App from './src/App';
YellowBox.ignoreWarnings([
'Warning: isMounted(...) is deprecated',
......
......@@ -21,6 +21,7 @@
*/
import { AppRegistry, YellowBox } from 'react-native';
import App from './src/App';
YellowBox.ignoreWarnings([
'Warning: isMounted(...) is deprecated',
......
......@@ -5,6 +5,7 @@
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; };
00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; };
......@@ -29,6 +30,7 @@
1F426F9C208D358500CA43DB /* EthkeyBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F426F99208D358500CA43DB /* EthkeyBridge.swift */; };
1F426F9D208D358500CA43DB /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F426F9A208D358500CA43DB /* String.swift */; };
1F73EE2721777A1D00706E91 /* libsigner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F426F39208B7CC000CA43DB /* libsigner.a */; };
38FFF5E61C1F405DB01B8860 /* libRNCSafeAreaContext.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 76B16A4320094BA392D8B407 /* libRNCSafeAreaContext.a */; };
391AD32122F9BF6F005136A0 /* libRNCamera.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 39D36A8722F4A07200EDA4F1 /* libRNCamera.a */; };
391AD3F022F9D848005136A0 /* libRNCNetInfo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 39D36A0622F4588C00EDA4F1 /* libRNCNetInfo.a */; };
3946D2A52364A7E700BAC371 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
......@@ -380,6 +382,13 @@
remoteGlobalIDString = 2D2A28201D9B03D100D4039D;
remoteInfo = "RCTAnimation-tvOS";
};
6715DAFF23E6E499008EB7F6 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = C05C62985CF24E24AC3645F1 /* SafeAreaView.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RNCSafeAreaContext;
};
78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
......@@ -480,6 +489,7 @@
67E3BEA2237C17A6007882FA /* RobotoMono-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "RobotoMono-Regular.ttf"; sourceTree = "<group>"; };
6A7AB3BD3C1A4E0EB3C4B3B6 /* Entypo.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Entypo.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Entypo.ttf"; sourceTree = "<group>"; };
6C53A63D96B24FDD95AF1C97 /* Fontisto.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Fontisto.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Fontisto.ttf"; sourceTree = "<group>"; };
76B16A4320094BA392D8B407 /* libRNCSafeAreaContext.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNCSafeAreaContext.a; sourceTree = "<group>"; };
7733AB637FF54DE5B174F42C /* Zocial.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Zocial.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Zocial.ttf"; sourceTree = "<group>"; };
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
7F019AE07E4148359A2FBCAB /* RNCNetInfo.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNCNetInfo.xcodeproj; path = "../node_modules/@react-native-community/netinfo/ios/RNCNetInfo.xcodeproj"; sourceTree = "<group>"; };
......@@ -493,6 +503,7 @@
AB66C405057A41298E1FC8BB /* libRNSVG.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNSVG.a; sourceTree = "<group>"; };
BB0882DC34AE448DAA1E2320 /* RNCNetInfo.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNCNetInfo.xcodeproj; path = "../node_modules/@react-native-community/netinfo/ios/RNCNetInfo.xcodeproj"; sourceTree = "<group>"; };
C0205550495341279B513024 /* RNSVG.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNSVG.xcodeproj; path = "../node_modules/react-native-svg/ios/RNSVG.xcodeproj"; sourceTree = "<group>"; };
C05C62985CF24E24AC3645F1 /* SafeAreaView.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = SafeAreaView.xcodeproj; path = "../node_modules/react-native-safe-area-context/ios/SafeAreaView.xcodeproj"; sourceTree = "<group>"; };
CB5C4A7F0E8B4E4E98E06EFD /* MaterialCommunityIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = MaterialCommunityIcons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf"; sourceTree = "<group>"; };
D44E3C511D404074AF5AFDB9 /* libRNSVG.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNSVG.a; sourceTree = "<group>"; };
D592A5F1000548E09C637958 /* Roboto-Bold.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Roboto-Bold.ttf"; path = "../res/fonts/Roboto-Bold.ttf"; sourceTree = "<group>"; };
......@@ -538,6 +549,7 @@
139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */,
9CE53E9B76FD4CE88D0778EC /* libRNRandomBytes.a in Frameworks */,
D6EED2987CEF454F865C09E0 /* libRNSVG.a in Frameworks */,
38FFF5E61C1F405DB01B8860 /* libRNCSafeAreaContext.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -671,6 +683,7 @@
9AFB9B36F67549FE85C83E49 /* libRNSecureStorage.a */,
170C0768897F45A7A496F2BE /* libRNRandomBytes.a */,
D44E3C511D404074AF5AFDB9 /* libRNSVG.a */,
76B16A4320094BA392D8B407 /* libRNCSafeAreaContext.a */,
);
name = "Recovered References";
sourceTree = "<group>";
......@@ -755,6 +768,14 @@
name = Products;
sourceTree = "<group>";
};
6715DAFC23E6E499008EB7F6 /* Products */ = {
isa = PBXGroup;
children = (
6715DB0023E6E499008EB7F6 /* libRNCSafeAreaContext.a */,
);
name = Products;
sourceTree = "<group>";
};
6D14AF58F6CE45DDBA2DE41C /* Resources */ = {
isa = PBXGroup;
children = (
......@@ -825,6 +846,7 @@
C0205550495341279B513024 /* RNSVG.xcodeproj */,
7F019AE07E4148359A2FBCAB /* RNCNetInfo.xcodeproj */,
23407C2347C34F7D9EF80F09 /* RNSecureStorage.xcodeproj */,
C05C62985CF24E24AC3645F1 /* SafeAreaView.xcodeproj */,
);
name = Libraries;
sourceTree = "<group>";
......@@ -1035,6 +1057,10 @@
ProductGroup = 88043C742301BD2B00340AB7 /* Products */;
ProjectRef = C0205550495341279B513024 /* RNSVG.xcodeproj */;
},
{
ProductGroup = 6715DAFC23E6E499008EB7F6 /* Products */;
ProjectRef = C05C62985CF24E24AC3645F1 /* SafeAreaView.xcodeproj */;
},
);
projectRoot = "";
targets = (
......@@ -1346,6 +1372,13 @@
remoteRef = 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
6715DB0023E6E499008EB7F6 /* libRNCSafeAreaContext.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRNCSafeAreaContext.a;
remoteRef = 6715DAFF23E6E499008EB7F6 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
......@@ -1527,6 +1560,7 @@
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",