diff --git a/App.js b/App.js index f81d1278..a21a87bc 100644 --- a/App.js +++ b/App.js @@ -1,6 +1,6 @@ console.disableYellowBox = true; import './shim.js'; -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useRef } from 'react'; import { AppState, StatusBar } from 'react-native'; import { Provider } from 'react-redux'; import { SafeAreaProvider } from 'react-native-safe-area-context'; @@ -9,6 +9,7 @@ import { PersistGate } from 'redux-persist/integration/react'; import configureStore from './src/store/configureStore'; import Navigator from './src/navigation/Root'; import NavigationService from './src/navigation/service'; +import LoadingScreen from './src/screens/LoadingScreen'; import { initWallet } from './src/actions/wallet'; import { oClient } from './src/lib/oCustom'; @@ -16,17 +17,21 @@ const App = () => { const [store, setStore] = useState(undefined); const [persistor, setPersistor] = useState(undefined); const [appState, setAppState] = useState('active'); + const [appReady, setAppReady] = useState(false); + const readynessIntervalRef = useRef(); useEffect(() => { const storeSetup = configureStore(); setStore(storeSetup.store); setPersistor(storeSetup.persistor); - }, [configureStore, initWallet]); + }, []); + useEffect(() => { if (!!store) { store.dispatch(initWallet()); } }, [store]); + useEffect(() => { AppState.addEventListener('change', nextAppState => setAppState(nextAppState), @@ -38,7 +43,23 @@ const App = () => { }; }, [setAppState]); - StatusBar.setBarStyle('dark-content'); + useEffect(() => { + if (!appReady) { + const id = setInterval(() => { + if (store?.getState && persistor) { + setAppReady(true); + } else { + setAppReady(false); + } + }, 4000); + readynessIntervalRef.current = id; + } + + return () => { + clearInterval(readynessIntervalRef.current); + }; + }, [appReady, store, persistor]); + // TODO: close and restart hub connection // useEffect(() => { // if (appState !== 'active') { @@ -46,14 +67,19 @@ const App = () => { // } // }, [appState]); - if (!store | !persistor) { - return null; + if (!appReady) { + return ( + + + + ); } return ( + { NavigationService.setTopLevelNavigator(navigatorRef); diff --git a/android/app/build.gradle b/android/app/build.gradle index a46f9be1..41cff934 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -134,6 +134,7 @@ android { targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1 versionName "1.0" + missingDimensionStrategy 'react-native-camera', 'general' } splits { abi { @@ -150,6 +151,14 @@ android { keyAlias 'androiddebugkey' keyPassword 'android' } + release { + if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) { + storeFile file(MYAPP_RELEASE_STORE_FILE) + storePassword MYAPP_RELEASE_STORE_PASSWORD + keyAlias MYAPP_RELEASE_KEY_ALIAS + keyPassword MYAPP_RELEASE_KEY_PASSWORD + } + } } buildTypes { debug { @@ -158,7 +167,7 @@ android { release { // Caution! In production, you need to generate your own keystore file. // see https://facebook.github.io/react-native/docs/signed-apk-android. - signingConfig signingConfigs.debug + signingConfig signingConfigs.release minifyEnabled enableProguardInReleaseBuilds proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" } @@ -182,8 +191,9 @@ android { dependencies { implementation project(':react-native-randombytes') implementation fileTree(dir: "libs", include: ["*.jar"]) - implementation "com.facebook.react:react-native:+" // From node_modules + implementation "com.facebook.react:react-native:0.61.5" // From node_modules addUnimodulesDependencies() + implementation project(':react-native-camera') if (enableHermes) { def hermesPath = "../../node_modules/hermes-engine/android/"; diff --git a/android/app/src/main/java/com/obby/MainActivity.java b/android/app/src/main/java/com/obby/MainActivity.java index 4be69243..106cb090 100644 --- a/android/app/src/main/java/com/obby/MainActivity.java +++ b/android/app/src/main/java/com/obby/MainActivity.java @@ -10,6 +10,6 @@ public class MainActivity extends ReactActivity { */ @Override protected String getMainComponentName() { - return "Obby"; + return "Obby chat"; } } diff --git a/android/app/src/main/java/com/obby/MainApplication.java b/android/app/src/main/java/com/obby/MainApplication.java index cd476145..ae0b9a3f 100644 --- a/android/app/src/main/java/com/obby/MainApplication.java +++ b/android/app/src/main/java/com/obby/MainApplication.java @@ -3,6 +3,7 @@ import android.app.Application; import android.content.Context; import com.facebook.react.PackageList; +import com.facebook.react.shell.MainReactPackage; import com.facebook.react.ReactApplication; import com.bitgo.randombytes.RandomBytesPackage; import com.facebook.react.ReactNativeHost; @@ -10,7 +11,9 @@ import com.facebook.soloader.SoLoader; import java.lang.reflect.InvocationTargetException; import java.util.List; -import com.myapp.generated.BasePackageList; +import java.util.Arrays; +import com.obby.generated.BasePackageList; +import org.reactnative.camera.RNCameraPackage; import org.unimodules.adapters.react.ModuleRegistryAdapter; import org.unimodules.adapters.react.ReactModuleRegistryProvider; import org.unimodules.core.interfaces.SingletonModule; @@ -29,10 +32,9 @@ public boolean getUseDeveloperSupport() { @Override protected List getPackages() { @SuppressWarnings("UnnecessaryLocalVariable") - List packages = new PackageList(this).getPackages() { - new MainReactPackage(), - new ModuleRegistryAdapter(mModuleRegistryProvider) - }; + List packages = new PackageList(this).getPackages(); + // packages.add(new MainReactPackage()); + packages.add(new ModuleRegistryAdapter(mModuleRegistryProvider)); // Packages that cannot be autolinked yet can be added manually here, for example: // packages.add(new MyReactNativePackage()); return packages; diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index a2f59082..00000000 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png deleted file mode 100644 index 1b523998..00000000 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-hdpi/obby_launcher.png b/android/app/src/main/res/mipmap-hdpi/obby_launcher.png new file mode 100644 index 00000000..a7ff1054 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/obby_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index ff10afd6..00000000 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png deleted file mode 100644 index 115a4c76..00000000 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-mdpi/obby_launcher.png b/android/app/src/main/res/mipmap-mdpi/obby_launcher.png new file mode 100644 index 00000000..2817cfc4 Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/obby_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index dcd3cd80..00000000 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png deleted file mode 100644 index 459ca609..00000000 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xhdpi/obby_launcher.png b/android/app/src/main/res/mipmap-xhdpi/obby_launcher.png new file mode 100644 index 00000000..6c8d1d72 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/obby_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 8ca12fe0..00000000 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index 8e19b410..00000000 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/obby_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/obby_launcher.png new file mode 100644 index 00000000..fc0e14cc Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/obby_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index b824ebdd..00000000 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index 4c19a13c..00000000 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/obby_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/obby_launcher.png new file mode 100644 index 00000000..699adeb5 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/obby_launcher.png differ diff --git a/android/app/src/main/res/mipmap/ic_launcher.png b/android/app/src/main/res/mipmap/ic_launcher.png new file mode 100644 index 00000000..699adeb5 Binary files /dev/null and b/android/app/src/main/res/mipmap/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap/ic_launcher_round.png b/android/app/src/main/res/mipmap/ic_launcher_round.png new file mode 100644 index 00000000..c34307c6 Binary files /dev/null and b/android/app/src/main/res/mipmap/ic_launcher_round.png differ diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 63412829..689c89ed 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -1,3 +1,3 @@ - Obby + Obby chat diff --git a/android/gradle.properties b/android/gradle.properties index 027ef9db..7f445340 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -19,3 +19,8 @@ android.useAndroidX=true android.enableJetifier=true + +MYAPP_RELEASE_STORE_FILE=my-release-key.keystore +MYAPP_RELEASE_KEY_ALIAS=my-key-alias +MYAPP_RELEASE_STORE_PASSWORD=ObbyMan +MYAPP_RELEASE_KEY_PASSWORD=ObbyMan \ No newline at end of file diff --git a/android/settings.gradle b/android/settings.gradle index d076af0d..659d02e1 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -5,3 +5,5 @@ include ':react-native-randombytes' project(':react-native-randombytes').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-randombytes/android') apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) include ':app' +include ':react-native-camera' +project(':react-native-camera').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-camera/android') \ No newline at end of file diff --git a/ios/Obby.xcodeproj/project.pbxproj b/ios/Obby Chat.xcodeproj/project.pbxproj similarity index 79% rename from ios/Obby.xcodeproj/project.pbxproj rename to ios/Obby Chat.xcodeproj/project.pbxproj index c6301e84..3c375ec5 100644 --- a/ios/Obby.xcodeproj/project.pbxproj +++ b/ios/Obby Chat.xcodeproj/project.pbxproj @@ -5,60 +5,60 @@ }; objectVersion = 46; objects = { + /* Begin PBXBuildFile section */ 00E356F31AD99517003FC87E /* ObbyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* ObbyTests.m */; }; 013226D0E85C4FDB99315164 /* AntDesign.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 1465EF17EEE64272B1596C60 /* AntDesign.ttf */; }; + 093D436A90624169807B9BCA /* Lato-BlackItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = E3DB28E8406D4F97A02BF853 /* Lato-BlackItalic.ttf */; }; 0F3D84D69A6D46049A487C9B /* MaterialCommunityIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 596CFCAAFA7041CBB8284A0A /* MaterialCommunityIcons.ttf */; }; 10D0A5A896A84E74A236CDC8 /* Roboto.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 2804A11EE6FD466387D3061C /* Roboto.ttf */; }; + 1250F0CB7E7F18BB7FD28C89 /* libPods-Obby Chat-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 741BBD822B8BE738FFE84D06 /* libPods-Obby Chat-tvOS.a */; }; 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; - 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; + 18455F6FE1A34F5DB8776EF4 /* Agenda-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 90B0E081BF704ABC87832FD8 /* Agenda-Bold.otf */; }; 1F83E6712FD14099A77271DB /* MaterialIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6CDAEB454F3242C99AFB5F2C /* MaterialIcons.ttf */; }; + 2748B43969B34A3B82D79317 /* Lato-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 564DF84948E04803AEB5F52B /* Lato-Bold.ttf */; }; 2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 2DCD954D1E0B4F2C00145EB5 /* ObbyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* ObbyTests.m */; }; 38D368D42CB643789397D374 /* Zocial.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 857C9C2A3CB149DF95D63132 /* Zocial.ttf */; }; + 3C26165CC66FE02D24D58DF5 /* libPods-Obby Chat-tvOSTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E65C8C104F477F42277D1D4 /* libPods-Obby Chat-tvOSTests.a */; }; + 4518B12B13F2440DBC622A59 /* Lato-LightItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 82242746F9C04BCBB1D6FCA5 /* Lato-LightItalic.ttf */; }; 4541757D6AE04B9DAC2DE412 /* rubicon-icon-font.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D298F4ECAE3746A7840B8848 /* rubicon-icon-font.ttf */; }; + 475B643F36434107A1B2C34C /* Lato-HeavyItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 85F812A3556541ADADF764A9 /* Lato-HeavyItalic.ttf */; }; 493E88EE332249FFBC0B6C14 /* Foundation.ttf in Resources */ = {isa = PBXBuildFile; fileRef = DDD652B30F074540991B4231 /* Foundation.ttf */; }; - 545F8167D6C42D337FED2F58 /* libPods-Obby-tvOSTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 815F6CC7DFECCA9F1947F6CE /* libPods-Obby-tvOSTests.a */; }; + 593554B31FDE4AB0A7823339 /* Lato-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 22F6AB7691244BA589CC13EC /* Lato-Light.ttf */; }; + 5BE8C1B2F27188690C6E9D66 /* libPods-Obby ChatTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C9BAE641C7E18E4D48450A64 /* libPods-Obby ChatTests.a */; }; 5D6F3101DF1149BCA191F81A /* Feather.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 001B73BD98B04DDEA68AB586 /* Feather.ttf */; }; + 5ED7729484C84C798B2AA313 /* Lato-ThinItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 45DD86BB963C43F7B33E3031 /* Lato-ThinItalic.ttf */; }; + 67149AAC06074C3DB5DAA69E /* Lato-BoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 624A99B98FDF46C98F1E0350 /* Lato-BoldItalic.ttf */; }; 6F0C02E046F2492B989F1331 /* Octicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 30FEE54C8F4C42FCAF453EF6 /* Octicons.ttf */; }; 7244A7A7E5FC4417A9576548 /* Fontisto.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6EF259CC9DBB4F3B87B5BBA9 /* Fontisto.ttf */; }; + 78FB2F45892D40BE9A68EFF2 /* Lato-MediumItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = BA655E0ACC844DAC85E98939 /* Lato-MediumItalic.ttf */; }; 7AA5D0FF612D46648975373C /* Roboto_medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 406A18A8AF294805BB275EF9 /* Roboto_medium.ttf */; }; + 7F718E7E614F415995160AD0 /* Agenda-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 38A317970F2E4C8188D4D5AE /* Agenda-Medium.otf */; }; + 807B9839138E4DF2AD9D8625 /* Lato-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 2B55B9A14F3D467F9D0ED3FF /* Lato-Medium.ttf */; }; 838812ADB3284196B14E91C6 /* FontAwesome5_Brands.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 3980BCB612594CB5863C881E /* FontAwesome5_Brands.ttf */; }; + 848431CB17E749679FEE3A72 /* Lato-Thin.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 7BD33D6683E240D586ABD4FB /* Lato-Thin.ttf */; }; + 86BE9593B7434B92AA3DDF76 /* Lato-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 65686229E02440AEBB05078C /* Lato-Regular.ttf */; }; + 93734053899747E38BE651A8 /* Lato-HairlineItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 75756DB8E204491CA0C91C22 /* Lato-HairlineItalic.ttf */; }; + 94A7867CD40E405B8FFDF218 /* Lato-Heavy.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 2F040A5B9DDB43D7BF06EE67 /* Lato-Heavy.ttf */; }; 9B75609A6740494A9CC454C1 /* Entypo.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 1A2D8D556F5B4F97B8E9C66A /* Entypo.ttf */; }; 9BD63194FBDD4EFEA692F552 /* FontAwesome5_Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A53AEFE151174268BC723051 /* FontAwesome5_Regular.ttf */; }; 9C9047D76DF7480784208341 /* EvilIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0F92F5AE7BC64325AD6014C9 /* EvilIcons.ttf */; }; - 9D46AE7B6E768B5B5BF9299A /* libPods-ObbyTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 682E95FDD1A6008E0E43513E /* libPods-ObbyTests.a */; }; - 9F85C44C37479BB47F14C00A /* libPods-Obby.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 33DB30998729BC1889DBEC35 /* libPods-Obby.a */; }; + AD3D8E626CD9440982086C96 /* Lato-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = F02668ECA9EA49D195782D5F /* Lato-Italic.ttf */; }; + AF601697F590449A825A23CC /* Lato-Black.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 2FD90C1225B84E9B9A4248ED /* Lato-Black.ttf */; }; + BC80E15F7729449899309641 /* Lato-SemiboldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B0472E829BFE40229570A3B6 /* Lato-SemiboldItalic.ttf */; }; C23187EEF5C240ABB67A58A1 /* SimpleLineIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B5CCCF430FB34F51AE589D93 /* SimpleLineIcons.ttf */; }; + C29B5A521B117F400D62D319 /* libPods-Obby Chat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 278966828955BBED7EAC29D9 /* libPods-Obby Chat.a */; }; CD2CECDDE7D246808496F0D5 /* Ionicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 4218EEA460334C16ABFEAE17 /* Ionicons.ttf */; }; - E4D5AD6FECB09C594CCB4060 /* libPods-Obby-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0F263115B387921B9CAAC573 /* libPods-Obby-tvOS.a */; }; + D72D6738A237494181DE8AAE /* Agenda-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = AECAA9509CEB46149D4AEB7B /* Agenda-Light.otf */; }; + E61B40A05DC14FA8858D1A90 /* Lato-Semibold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B4C4B9EFBFFC495BB868A159 /* Lato-Semibold.ttf */; }; + F2115F4E30E441578AFF1686 /* Lato-Hairline.ttf in Resources */ = {isa = PBXBuildFile; fileRef = CEED5EED1F6B4BE580F6980E /* Lato-Hairline.ttf */; }; F34CC1139CCF4031A3E4CC6E /* FontAwesome5_Solid.ttf in Resources */ = {isa = PBXBuildFile; fileRef = AFCCC573DEA64785A2093359 /* FontAwesome5_Solid.ttf */; }; FFD3021121D0449F96A569DF /* FontAwesome.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 864022EED1C1497E95314EA9 /* FontAwesome.ttf */; }; - AF601697F590449A825A23CC /* Lato-Black.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 2FD90C1225B84E9B9A4248ED /* Lato-Black.ttf */; }; - 093D436A90624169807B9BCA /* Lato-BlackItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = E3DB28E8406D4F97A02BF853 /* Lato-BlackItalic.ttf */; }; - 2748B43969B34A3B82D79317 /* Lato-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 564DF84948E04803AEB5F52B /* Lato-Bold.ttf */; }; - 67149AAC06074C3DB5DAA69E /* Lato-BoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 624A99B98FDF46C98F1E0350 /* Lato-BoldItalic.ttf */; }; - F2115F4E30E441578AFF1686 /* Lato-Hairline.ttf in Resources */ = {isa = PBXBuildFile; fileRef = CEED5EED1F6B4BE580F6980E /* Lato-Hairline.ttf */; }; - 93734053899747E38BE651A8 /* Lato-HairlineItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 75756DB8E204491CA0C91C22 /* Lato-HairlineItalic.ttf */; }; - 94A7867CD40E405B8FFDF218 /* Lato-Heavy.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 2F040A5B9DDB43D7BF06EE67 /* Lato-Heavy.ttf */; }; - 475B643F36434107A1B2C34C /* Lato-HeavyItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 85F812A3556541ADADF764A9 /* Lato-HeavyItalic.ttf */; }; - AD3D8E626CD9440982086C96 /* Lato-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = F02668ECA9EA49D195782D5F /* Lato-Italic.ttf */; }; - 593554B31FDE4AB0A7823339 /* Lato-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 22F6AB7691244BA589CC13EC /* Lato-Light.ttf */; }; - 4518B12B13F2440DBC622A59 /* Lato-LightItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 82242746F9C04BCBB1D6FCA5 /* Lato-LightItalic.ttf */; }; - 807B9839138E4DF2AD9D8625 /* Lato-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 2B55B9A14F3D467F9D0ED3FF /* Lato-Medium.ttf */; }; - 78FB2F45892D40BE9A68EFF2 /* Lato-MediumItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = BA655E0ACC844DAC85E98939 /* Lato-MediumItalic.ttf */; }; - 86BE9593B7434B92AA3DDF76 /* Lato-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 65686229E02440AEBB05078C /* Lato-Regular.ttf */; }; - E61B40A05DC14FA8858D1A90 /* Lato-Semibold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B4C4B9EFBFFC495BB868A159 /* Lato-Semibold.ttf */; }; - BC80E15F7729449899309641 /* Lato-SemiboldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B0472E829BFE40229570A3B6 /* Lato-SemiboldItalic.ttf */; }; - 848431CB17E749679FEE3A72 /* Lato-Thin.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 7BD33D6683E240D586ABD4FB /* Lato-Thin.ttf */; }; - 5ED7729484C84C798B2AA313 /* Lato-ThinItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 45DD86BB963C43F7B33E3031 /* Lato-ThinItalic.ttf */; }; - 18455F6FE1A34F5DB8776EF4 /* Agenda-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 90B0E081BF704ABC87832FD8 /* Agenda-Bold.otf */; }; - D72D6738A237494181DE8AAE /* Agenda-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = AECAA9509CEB46149D4AEB7B /* Agenda-Light.otf */; }; - 7F718E7E614F415995160AD0 /* Agenda-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 38A317970F2E4C8188D4D5AE /* Agenda-Medium.otf */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -81,71 +81,78 @@ /* Begin PBXFileReference section */ 001B73BD98B04DDEA68AB586 /* Feather.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Feather.ttf; path = "../node_modules/native-base/Fonts/Feather.ttf"; sourceTree = ""; }; 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; }; - 00E356EE1AD99517003FC87E /* ObbyTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ObbyTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 00E356EE1AD99517003FC87E /* Obby ChatTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Obby ChatTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 00E356F21AD99517003FC87E /* ObbyTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ObbyTests.m; sourceTree = ""; }; - 0F263115B387921B9CAAC573 /* libPods-Obby-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Obby-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 0F92F5AE7BC64325AD6014C9 /* EvilIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = EvilIcons.ttf; path = "../node_modules/native-base/Fonts/EvilIcons.ttf"; sourceTree = ""; }; - 13B07F961A680F5B00A75B9A /* Obby.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Obby.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 13B07F961A680F5B00A75B9A /* Obby Chat.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Obby Chat.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Obby/AppDelegate.h; sourceTree = ""; }; 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = Obby/AppDelegate.m; sourceTree = ""; }; - 13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = Obby/Images.xcassets; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Obby/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Obby/main.m; sourceTree = ""; }; 1465EF17EEE64272B1596C60 /* AntDesign.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = AntDesign.ttf; path = "../node_modules/native-base/Fonts/AntDesign.ttf"; sourceTree = ""; }; 1A2D8D556F5B4F97B8E9C66A /* Entypo.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Entypo.ttf; path = "../node_modules/native-base/Fonts/Entypo.ttf"; sourceTree = ""; }; + 1E65C8C104F477F42277D1D4 /* libPods-Obby Chat-tvOSTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Obby Chat-tvOSTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 22F6AB7691244BA589CC13EC /* Lato-Light.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Lato-Light.ttf"; path = "../src/assets/fonts/Lato-Light.ttf"; sourceTree = ""; }; + 278966828955BBED7EAC29D9 /* libPods-Obby Chat.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Obby Chat.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 2804A11EE6FD466387D3061C /* Roboto.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Roboto.ttf; path = "../node_modules/native-base/Fonts/Roboto.ttf"; sourceTree = ""; }; 2B2EA621760694CFE59AABDD /* Pods-Obby-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Obby-tvOS.release.xcconfig"; path = "Target Support Files/Pods-Obby-tvOS/Pods-Obby-tvOS.release.xcconfig"; sourceTree = ""; }; - 2D02E47B1E0B4A5D006451C7 /* Obby-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Obby-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - 2D02E4901E0B4A5D006451C7 /* Obby-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Obby-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 2B55B9A14F3D467F9D0ED3FF /* Lato-Medium.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Lato-Medium.ttf"; path = "../src/assets/fonts/Lato-Medium.ttf"; sourceTree = ""; }; + 2D02E47B1E0B4A5D006451C7 /* Obby Chat-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Obby Chat-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 2D02E4901E0B4A5D006451C7 /* Obby Chat-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Obby Chat-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 2F040A5B9DDB43D7BF06EE67 /* Lato-Heavy.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Lato-Heavy.ttf"; path = "../src/assets/fonts/Lato-Heavy.ttf"; sourceTree = ""; }; + 2FD90C1225B84E9B9A4248ED /* Lato-Black.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Lato-Black.ttf"; path = "../src/assets/fonts/Lato-Black.ttf"; sourceTree = ""; }; 30FEE54C8F4C42FCAF453EF6 /* Octicons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Octicons.ttf; path = "../node_modules/native-base/Fonts/Octicons.ttf"; sourceTree = ""; }; - 33DB30998729BC1889DBEC35 /* libPods-Obby.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Obby.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 38A317970F2E4C8188D4D5AE /* Agenda-Medium.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Agenda-Medium.otf"; path = "../src/assets/fonts/Agenda-Medium.otf"; sourceTree = ""; }; 3980BCB612594CB5863C881E /* FontAwesome5_Brands.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = FontAwesome5_Brands.ttf; path = "../node_modules/native-base/Fonts/FontAwesome5_Brands.ttf"; sourceTree = ""; }; + 3EA2462620867FC9703A65B5 /* Pods-Obby Chat-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Obby Chat-tvOS.debug.xcconfig"; path = "Target Support Files/Pods-Obby Chat-tvOS/Pods-Obby Chat-tvOS.debug.xcconfig"; sourceTree = ""; }; 406A18A8AF294805BB275EF9 /* Roboto_medium.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Roboto_medium.ttf; path = "../node_modules/native-base/Fonts/Roboto_medium.ttf"; sourceTree = ""; }; 4218EEA460334C16ABFEAE17 /* Ionicons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Ionicons.ttf; path = "../node_modules/native-base/Fonts/Ionicons.ttf"; sourceTree = ""; }; + 45DD86BB963C43F7B33E3031 /* Lato-ThinItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Lato-ThinItalic.ttf"; path = "../src/assets/fonts/Lato-ThinItalic.ttf"; sourceTree = ""; }; 4E561FB35AAE6BAF97EF1ACF /* Pods-ObbyTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ObbyTests.debug.xcconfig"; path = "Target Support Files/Pods-ObbyTests/Pods-ObbyTests.debug.xcconfig"; sourceTree = ""; }; 513644CB146F4CC30EEB5E61 /* Pods-Obby-tvOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Obby-tvOSTests.release.xcconfig"; path = "Target Support Files/Pods-Obby-tvOSTests/Pods-Obby-tvOSTests.release.xcconfig"; sourceTree = ""; }; + 564DF84948E04803AEB5F52B /* Lato-Bold.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Lato-Bold.ttf"; path = "../src/assets/fonts/Lato-Bold.ttf"; sourceTree = ""; }; 596CFCAAFA7041CBB8284A0A /* MaterialCommunityIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = MaterialCommunityIcons.ttf; path = "../node_modules/native-base/Fonts/MaterialCommunityIcons.ttf"; sourceTree = ""; }; + 624A99B98FDF46C98F1E0350 /* Lato-BoldItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Lato-BoldItalic.ttf"; path = "../src/assets/fonts/Lato-BoldItalic.ttf"; sourceTree = ""; }; 6334B3BC9590139F4183BBD1 /* Pods-Obby-tvOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Obby-tvOSTests.debug.xcconfig"; path = "Target Support Files/Pods-Obby-tvOSTests/Pods-Obby-tvOSTests.debug.xcconfig"; sourceTree = ""; }; - 682E95FDD1A6008E0E43513E /* libPods-ObbyTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ObbyTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 65686229E02440AEBB05078C /* Lato-Regular.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Lato-Regular.ttf"; path = "../src/assets/fonts/Lato-Regular.ttf"; sourceTree = ""; }; + 6CD7EFD87576BCD88D1E0781 /* Pods-Obby Chat.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Obby Chat.release.xcconfig"; path = "Target Support Files/Pods-Obby Chat/Pods-Obby Chat.release.xcconfig"; sourceTree = ""; }; 6CDAEB454F3242C99AFB5F2C /* MaterialIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = MaterialIcons.ttf; path = "../node_modules/native-base/Fonts/MaterialIcons.ttf"; sourceTree = ""; }; 6EF259CC9DBB4F3B87B5BBA9 /* Fontisto.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Fontisto.ttf; path = "../node_modules/native-base/Fonts/Fontisto.ttf"; sourceTree = ""; }; - 815F6CC7DFECCA9F1947F6CE /* libPods-Obby-tvOSTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Obby-tvOSTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6EFCC415540CF34C4B48D09F /* Pods-Obby Chat-tvOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Obby Chat-tvOSTests.debug.xcconfig"; path = "Target Support Files/Pods-Obby Chat-tvOSTests/Pods-Obby Chat-tvOSTests.debug.xcconfig"; sourceTree = ""; }; + 741BBD822B8BE738FFE84D06 /* libPods-Obby Chat-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Obby Chat-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 75756DB8E204491CA0C91C22 /* Lato-HairlineItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Lato-HairlineItalic.ttf"; path = "../src/assets/fonts/Lato-HairlineItalic.ttf"; sourceTree = ""; }; + 7BD33D6683E240D586ABD4FB /* Lato-Thin.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Lato-Thin.ttf"; path = "../src/assets/fonts/Lato-Thin.ttf"; sourceTree = ""; }; + 82242746F9C04BCBB1D6FCA5 /* Lato-LightItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Lato-LightItalic.ttf"; path = "../src/assets/fonts/Lato-LightItalic.ttf"; sourceTree = ""; }; 857C9C2A3CB149DF95D63132 /* Zocial.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Zocial.ttf; path = "../node_modules/native-base/Fonts/Zocial.ttf"; sourceTree = ""; }; + 85F812A3556541ADADF764A9 /* Lato-HeavyItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Lato-HeavyItalic.ttf"; path = "../src/assets/fonts/Lato-HeavyItalic.ttf"; sourceTree = ""; }; 864022EED1C1497E95314EA9 /* FontAwesome.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = FontAwesome.ttf; path = "../node_modules/native-base/Fonts/FontAwesome.ttf"; sourceTree = ""; }; + 90B0E081BF704ABC87832FD8 /* Agenda-Bold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Agenda-Bold.otf"; path = "../src/assets/fonts/Agenda-Bold.otf"; sourceTree = ""; }; + A17E62FCAA5148590E89BA8D /* Pods-Obby Chat-tvOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Obby Chat-tvOSTests.release.xcconfig"; path = "Target Support Files/Pods-Obby Chat-tvOSTests/Pods-Obby Chat-tvOSTests.release.xcconfig"; sourceTree = ""; }; A53AEFE151174268BC723051 /* FontAwesome5_Regular.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = FontAwesome5_Regular.ttf; path = "../node_modules/native-base/Fonts/FontAwesome5_Regular.ttf"; sourceTree = ""; }; ABC0F199E8C96DFC469A5469 /* Pods-Obby-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Obby-tvOS.debug.xcconfig"; path = "Target Support Files/Pods-Obby-tvOS/Pods-Obby-tvOS.debug.xcconfig"; sourceTree = ""; }; + AECAA9509CEB46149D4AEB7B /* Agenda-Light.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Agenda-Light.otf"; path = "../src/assets/fonts/Agenda-Light.otf"; sourceTree = ""; }; + AFB77DF034706CD351105B7B /* Pods-Obby Chat-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Obby Chat-tvOS.release.xcconfig"; path = "Target Support Files/Pods-Obby Chat-tvOS/Pods-Obby Chat-tvOS.release.xcconfig"; sourceTree = ""; }; AFCCC573DEA64785A2093359 /* FontAwesome5_Solid.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = FontAwesome5_Solid.ttf; path = "../node_modules/native-base/Fonts/FontAwesome5_Solid.ttf"; sourceTree = ""; }; + B0472E829BFE40229570A3B6 /* Lato-SemiboldItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Lato-SemiboldItalic.ttf"; path = "../src/assets/fonts/Lato-SemiboldItalic.ttf"; sourceTree = ""; }; + B3D2B2804355F88F79EDB224 /* Pods-Obby ChatTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Obby ChatTests.release.xcconfig"; path = "Target Support Files/Pods-Obby ChatTests/Pods-Obby ChatTests.release.xcconfig"; sourceTree = ""; }; + B4C4B9EFBFFC495BB868A159 /* Lato-Semibold.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Lato-Semibold.ttf"; path = "../src/assets/fonts/Lato-Semibold.ttf"; sourceTree = ""; }; B5CCCF430FB34F51AE589D93 /* SimpleLineIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = SimpleLineIcons.ttf; path = "../node_modules/native-base/Fonts/SimpleLineIcons.ttf"; sourceTree = ""; }; + BA655E0ACC844DAC85E98939 /* Lato-MediumItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Lato-MediumItalic.ttf"; path = "../src/assets/fonts/Lato-MediumItalic.ttf"; sourceTree = ""; }; + C9BAE641C7E18E4D48450A64 /* libPods-Obby ChatTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Obby ChatTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; CE4473240D7F414E62547621 /* Pods-Obby.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Obby.debug.xcconfig"; path = "Target Support Files/Pods-Obby/Pods-Obby.debug.xcconfig"; sourceTree = ""; }; + CE4783273AA8FA9DB42F9C39 /* Pods-Obby ChatTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Obby ChatTests.debug.xcconfig"; path = "Target Support Files/Pods-Obby ChatTests/Pods-Obby ChatTests.debug.xcconfig"; sourceTree = ""; }; + CEED5EED1F6B4BE580F6980E /* Lato-Hairline.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Lato-Hairline.ttf"; path = "../src/assets/fonts/Lato-Hairline.ttf"; sourceTree = ""; }; + CF82C327B7A63EF6A46CDC57 /* Pods-Obby Chat.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Obby Chat.debug.xcconfig"; path = "Target Support Files/Pods-Obby Chat/Pods-Obby Chat.debug.xcconfig"; sourceTree = ""; }; D298F4ECAE3746A7840B8848 /* rubicon-icon-font.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "rubicon-icon-font.ttf"; path = "../node_modules/native-base/Fonts/rubicon-icon-font.ttf"; sourceTree = ""; }; D69182206EC402ECB55C4706 /* Pods-ObbyTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ObbyTests.release.xcconfig"; path = "Target Support Files/Pods-ObbyTests/Pods-ObbyTests.release.xcconfig"; sourceTree = ""; }; DDD652B30F074540991B4231 /* Foundation.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Foundation.ttf; path = "../node_modules/native-base/Fonts/Foundation.ttf"; sourceTree = ""; }; + E3DB28E8406D4F97A02BF853 /* Lato-BlackItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Lato-BlackItalic.ttf"; path = "../src/assets/fonts/Lato-BlackItalic.ttf"; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; }; + F02668ECA9EA49D195782D5F /* Lato-Italic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Lato-Italic.ttf"; path = "../src/assets/fonts/Lato-Italic.ttf"; sourceTree = ""; }; FC8479CE079E8605B496F07E /* Pods-Obby.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Obby.release.xcconfig"; path = "Target Support Files/Pods-Obby/Pods-Obby.release.xcconfig"; sourceTree = ""; }; - 2FD90C1225B84E9B9A4248ED /* Lato-Black.ttf */ = {isa = PBXFileReference; name = "Lato-Black.ttf"; path = "../src/assets/fonts/Lato-Black.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - E3DB28E8406D4F97A02BF853 /* Lato-BlackItalic.ttf */ = {isa = PBXFileReference; name = "Lato-BlackItalic.ttf"; path = "../src/assets/fonts/Lato-BlackItalic.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 564DF84948E04803AEB5F52B /* Lato-Bold.ttf */ = {isa = PBXFileReference; name = "Lato-Bold.ttf"; path = "../src/assets/fonts/Lato-Bold.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 624A99B98FDF46C98F1E0350 /* Lato-BoldItalic.ttf */ = {isa = PBXFileReference; name = "Lato-BoldItalic.ttf"; path = "../src/assets/fonts/Lato-BoldItalic.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - CEED5EED1F6B4BE580F6980E /* Lato-Hairline.ttf */ = {isa = PBXFileReference; name = "Lato-Hairline.ttf"; path = "../src/assets/fonts/Lato-Hairline.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 75756DB8E204491CA0C91C22 /* Lato-HairlineItalic.ttf */ = {isa = PBXFileReference; name = "Lato-HairlineItalic.ttf"; path = "../src/assets/fonts/Lato-HairlineItalic.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 2F040A5B9DDB43D7BF06EE67 /* Lato-Heavy.ttf */ = {isa = PBXFileReference; name = "Lato-Heavy.ttf"; path = "../src/assets/fonts/Lato-Heavy.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 85F812A3556541ADADF764A9 /* Lato-HeavyItalic.ttf */ = {isa = PBXFileReference; name = "Lato-HeavyItalic.ttf"; path = "../src/assets/fonts/Lato-HeavyItalic.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - F02668ECA9EA49D195782D5F /* Lato-Italic.ttf */ = {isa = PBXFileReference; name = "Lato-Italic.ttf"; path = "../src/assets/fonts/Lato-Italic.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 22F6AB7691244BA589CC13EC /* Lato-Light.ttf */ = {isa = PBXFileReference; name = "Lato-Light.ttf"; path = "../src/assets/fonts/Lato-Light.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 82242746F9C04BCBB1D6FCA5 /* Lato-LightItalic.ttf */ = {isa = PBXFileReference; name = "Lato-LightItalic.ttf"; path = "../src/assets/fonts/Lato-LightItalic.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 2B55B9A14F3D467F9D0ED3FF /* Lato-Medium.ttf */ = {isa = PBXFileReference; name = "Lato-Medium.ttf"; path = "../src/assets/fonts/Lato-Medium.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - BA655E0ACC844DAC85E98939 /* Lato-MediumItalic.ttf */ = {isa = PBXFileReference; name = "Lato-MediumItalic.ttf"; path = "../src/assets/fonts/Lato-MediumItalic.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 65686229E02440AEBB05078C /* Lato-Regular.ttf */ = {isa = PBXFileReference; name = "Lato-Regular.ttf"; path = "../src/assets/fonts/Lato-Regular.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - B4C4B9EFBFFC495BB868A159 /* Lato-Semibold.ttf */ = {isa = PBXFileReference; name = "Lato-Semibold.ttf"; path = "../src/assets/fonts/Lato-Semibold.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - B0472E829BFE40229570A3B6 /* Lato-SemiboldItalic.ttf */ = {isa = PBXFileReference; name = "Lato-SemiboldItalic.ttf"; path = "../src/assets/fonts/Lato-SemiboldItalic.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 7BD33D6683E240D586ABD4FB /* Lato-Thin.ttf */ = {isa = PBXFileReference; name = "Lato-Thin.ttf"; path = "../src/assets/fonts/Lato-Thin.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 45DD86BB963C43F7B33E3031 /* Lato-ThinItalic.ttf */ = {isa = PBXFileReference; name = "Lato-ThinItalic.ttf"; path = "../src/assets/fonts/Lato-ThinItalic.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 90B0E081BF704ABC87832FD8 /* Agenda-Bold.otf */ = {isa = PBXFileReference; name = "Agenda-Bold.otf"; path = "../src/assets/fonts/Agenda-Bold.otf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - AECAA9509CEB46149D4AEB7B /* Agenda-Light.otf */ = {isa = PBXFileReference; name = "Agenda-Light.otf"; path = "../src/assets/fonts/Agenda-Light.otf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 38A317970F2E4C8188D4D5AE /* Agenda-Medium.otf */ = {isa = PBXFileReference; name = "Agenda-Medium.otf"; path = "../src/assets/fonts/Agenda-Medium.otf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -153,7 +160,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 9D46AE7B6E768B5B5BF9299A /* libPods-ObbyTests.a in Frameworks */, + 5BE8C1B2F27188690C6E9D66 /* libPods-Obby ChatTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -161,7 +168,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 9F85C44C37479BB47F14C00A /* libPods-Obby.a in Frameworks */, + C29B5A521B117F400D62D319 /* libPods-Obby Chat.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -169,7 +176,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - E4D5AD6FECB09C594CCB4060 /* libPods-Obby-tvOS.a in Frameworks */, + 1250F0CB7E7F18BB7FD28C89 /* libPods-Obby Chat-tvOS.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -177,7 +184,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 545F8167D6C42D337FED2F58 /* libPods-Obby-tvOSTests.a in Frameworks */, + 3C26165CC66FE02D24D58DF5 /* libPods-Obby Chat-tvOSTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -209,7 +216,6 @@ 13B07FB01A68108700A75B9A /* AppDelegate.m */, 13B07FB51A68108700A75B9A /* Images.xcassets */, 13B07FB61A68108700A75B9A /* Info.plist */, - 13B07FB11A68108700A75B9A /* LaunchScreen.xib */, 13B07FB71A68108700A75B9A /* main.m */, ); name = Obby; @@ -220,10 +226,10 @@ children = ( ED297162215061F000B7C4FE /* JavaScriptCore.framework */, ED2971642150620600B7C4FE /* JavaScriptCore.framework */, - 33DB30998729BC1889DBEC35 /* libPods-Obby.a */, - 0F263115B387921B9CAAC573 /* libPods-Obby-tvOS.a */, - 815F6CC7DFECCA9F1947F6CE /* libPods-Obby-tvOSTests.a */, - 682E95FDD1A6008E0E43513E /* libPods-ObbyTests.a */, + 278966828955BBED7EAC29D9 /* libPods-Obby Chat.a */, + 741BBD822B8BE738FFE84D06 /* libPods-Obby Chat-tvOS.a */, + 1E65C8C104F477F42277D1D4 /* libPods-Obby Chat-tvOSTests.a */, + C9BAE641C7E18E4D48450A64 /* libPods-Obby ChatTests.a */, ); name = Frameworks; sourceTree = ""; @@ -301,10 +307,10 @@ 83CBBA001A601CBA00E9B192 /* Products */ = { isa = PBXGroup; children = ( - 13B07F961A680F5B00A75B9A /* Obby.app */, - 00E356EE1AD99517003FC87E /* ObbyTests.xctest */, - 2D02E47B1E0B4A5D006451C7 /* Obby-tvOS.app */, - 2D02E4901E0B4A5D006451C7 /* Obby-tvOSTests.xctest */, + 13B07F961A680F5B00A75B9A /* Obby Chat.app */, + 00E356EE1AD99517003FC87E /* Obby ChatTests.xctest */, + 2D02E47B1E0B4A5D006451C7 /* Obby Chat-tvOS.app */, + 2D02E4901E0B4A5D006451C7 /* Obby Chat-tvOSTests.xctest */, ); name = Products; sourceTree = ""; @@ -320,6 +326,14 @@ 513644CB146F4CC30EEB5E61 /* Pods-Obby-tvOSTests.release.xcconfig */, 4E561FB35AAE6BAF97EF1ACF /* Pods-ObbyTests.debug.xcconfig */, D69182206EC402ECB55C4706 /* Pods-ObbyTests.release.xcconfig */, + CF82C327B7A63EF6A46CDC57 /* Pods-Obby Chat.debug.xcconfig */, + 6CD7EFD87576BCD88D1E0781 /* Pods-Obby Chat.release.xcconfig */, + 3EA2462620867FC9703A65B5 /* Pods-Obby Chat-tvOS.debug.xcconfig */, + AFB77DF034706CD351105B7B /* Pods-Obby Chat-tvOS.release.xcconfig */, + 6EFCC415540CF34C4B48D09F /* Pods-Obby Chat-tvOSTests.debug.xcconfig */, + A17E62FCAA5148590E89BA8D /* Pods-Obby Chat-tvOSTests.release.xcconfig */, + CE4783273AA8FA9DB42F9C39 /* Pods-Obby ChatTests.debug.xcconfig */, + B3D2B2804355F88F79EDB224 /* Pods-Obby ChatTests.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -327,9 +341,9 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 00E356ED1AD99517003FC87E /* ObbyTests */ = { + 00E356ED1AD99517003FC87E /* Obby ChatTests */ = { isa = PBXNativeTarget; - buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "ObbyTests" */; + buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "Obby ChatTests" */; buildPhases = ( E507547DE39DD4706D0DD900 /* [CP] Check Pods Manifest.lock */, 00E356EA1AD99517003FC87E /* Sources */, @@ -341,14 +355,14 @@ dependencies = ( 00E356F51AD99517003FC87E /* PBXTargetDependency */, ); - name = ObbyTests; + name = "Obby ChatTests"; productName = ObbyTests; - productReference = 00E356EE1AD99517003FC87E /* ObbyTests.xctest */; + productReference = 00E356EE1AD99517003FC87E /* Obby ChatTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - 13B07F861A680F5B00A75B9A /* Obby */ = { + 13B07F861A680F5B00A75B9A /* Obby Chat */ = { isa = PBXNativeTarget; - buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Obby" */; + buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Obby Chat" */; buildPhases = ( 9DDB7FE018CE87EBFD0C5521 /* [CP] Check Pods Manifest.lock */, FD10A7F022414F080027D42C /* Start Packager */, @@ -361,14 +375,14 @@ ); dependencies = ( ); - name = Obby; + name = "Obby Chat"; productName = Obby; - productReference = 13B07F961A680F5B00A75B9A /* Obby.app */; + productReference = 13B07F961A680F5B00A75B9A /* Obby Chat.app */; productType = "com.apple.product-type.application"; }; - 2D02E47A1E0B4A5D006451C7 /* Obby-tvOS */ = { + 2D02E47A1E0B4A5D006451C7 /* Obby Chat-tvOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "Obby-tvOS" */; + buildConfigurationList = 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "Obby Chat-tvOS" */; buildPhases = ( 939D7A7FEF02C4BCE12EB835 /* [CP] Check Pods Manifest.lock */, FD10A7F122414F3F0027D42C /* Start Packager */, @@ -381,14 +395,14 @@ ); dependencies = ( ); - name = "Obby-tvOS"; + name = "Obby Chat-tvOS"; productName = "Obby-tvOS"; - productReference = 2D02E47B1E0B4A5D006451C7 /* Obby-tvOS.app */; + productReference = 2D02E47B1E0B4A5D006451C7 /* Obby Chat-tvOS.app */; productType = "com.apple.product-type.application"; }; - 2D02E48F1E0B4A5D006451C7 /* Obby-tvOSTests */ = { + 2D02E48F1E0B4A5D006451C7 /* Obby Chat-tvOSTests */ = { isa = PBXNativeTarget; - buildConfigurationList = 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "Obby-tvOSTests" */; + buildConfigurationList = 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "Obby Chat-tvOSTests" */; buildPhases = ( 0A79DD99BE0DCC65EAD63D4C /* [CP] Check Pods Manifest.lock */, 2D02E48C1E0B4A5D006451C7 /* Sources */, @@ -400,9 +414,9 @@ dependencies = ( 2D02E4921E0B4A5D006451C7 /* PBXTargetDependency */, ); - name = "Obby-tvOSTests"; + name = "Obby Chat-tvOSTests"; productName = "Obby-tvOSTests"; - productReference = 2D02E4901E0B4A5D006451C7 /* Obby-tvOSTests.xctest */; + productReference = 2D02E4901E0B4A5D006451C7 /* Obby Chat-tvOSTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; /* End PBXNativeTarget section */ @@ -420,6 +434,7 @@ }; 13B07F861A680F5B00A75B9A = { DevelopmentTeam = NFLP3N867J; + ProvisioningStyle = Automatic; }; 2D02E47A1E0B4A5D006451C7 = { CreatedOnToolsVersion = 8.2.1; @@ -432,7 +447,7 @@ }; }; }; - buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Obby" */; + buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Obby Chat" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; @@ -446,10 +461,10 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 13B07F861A680F5B00A75B9A /* Obby */, - 00E356ED1AD99517003FC87E /* ObbyTests */, - 2D02E47A1E0B4A5D006451C7 /* Obby-tvOS */, - 2D02E48F1E0B4A5D006451C7 /* Obby-tvOSTests */, + 13B07F861A680F5B00A75B9A /* Obby Chat */, + 00E356ED1AD99517003FC87E /* Obby ChatTests */, + 2D02E47A1E0B4A5D006451C7 /* Obby Chat-tvOS */, + 2D02E48F1E0B4A5D006451C7 /* Obby Chat-tvOSTests */, ); }; /* End PBXProject section */ @@ -467,7 +482,6 @@ buildActionMask = 2147483647; files = ( 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, - 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */, 013226D0E85C4FDB99315164 /* AntDesign.ttf in Resources */, 9B75609A6740494A9CC454C1 /* Entypo.ttf in Resources */, 9C9047D76DF7480784208341 /* EvilIcons.ttf in Resources */, @@ -558,7 +572,7 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Obby-tvOSTests-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-Obby Chat-tvOSTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -594,7 +608,7 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Obby-tvOS-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-Obby Chat-tvOS-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -616,7 +630,7 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Obby-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-Obby Chat-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -638,7 +652,7 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-ObbyTests-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-Obby ChatTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -725,32 +739,20 @@ /* Begin PBXTargetDependency section */ 00E356F51AD99517003FC87E /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 13B07F861A680F5B00A75B9A /* Obby */; + target = 13B07F861A680F5B00A75B9A /* Obby Chat */; targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */; }; 2D02E4921E0B4A5D006451C7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 2D02E47A1E0B4A5D006451C7 /* Obby-tvOS */; + target = 2D02E47A1E0B4A5D006451C7 /* Obby Chat-tvOS */; targetProxy = 2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ -/* Begin PBXVariantGroup section */ - 13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 13B07FB21A68108700A75B9A /* Base */, - ); - name = LaunchScreen.xib; - path = Obby; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - /* Begin XCBuildConfiguration section */ 00E356F61AD99517003FC87E /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4E561FB35AAE6BAF97EF1ACF /* Pods-ObbyTests.debug.xcconfig */; + baseConfigurationReference = CE4783273AA8FA9DB42F9C39 /* Pods-Obby ChatTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -767,13 +769,13 @@ ); PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Obby.app/Obby"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Obby Chat.app/Obby Chat"; }; name = Debug; }; 00E356F71AD99517003FC87E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D69182206EC402ECB55C4706 /* Pods-ObbyTests.release.xcconfig */; + baseConfigurationReference = B3D2B2804355F88F79EDB224 /* Pods-Obby ChatTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; COPY_PHASE_STRIP = NO; @@ -787,17 +789,18 @@ ); PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Obby.app/Obby"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Obby Chat.app/Obby Chat"; }; name = Release; }; 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = CE4473240D7F414E62547621 /* Pods-Obby.debug.xcconfig */; + baseConfigurationReference = CF82C327B7A63EF6A46CDC57 /* Pods-Obby Chat.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 1; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 7; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = NFLP3N867J; INFOPLIST_FILE = Obby/Info.plist; @@ -807,8 +810,8 @@ "-ObjC", "-lc++", ); - PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = Obby; + PRODUCT_BUNDLE_IDENTIFIER = chat.obby; + PRODUCT_NAME = "Obby Chat"; PROVISIONING_PROFILE_SPECIFIER = ""; VERSIONING_SYSTEM = "apple-generic"; }; @@ -816,12 +819,13 @@ }; 13B07F951A680F5B00A75B9A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = FC8479CE079E8605B496F07E /* Pods-Obby.release.xcconfig */; + baseConfigurationReference = 6CD7EFD87576BCD88D1E0781 /* Pods-Obby Chat.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 1; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 7; DEVELOPMENT_TEAM = NFLP3N867J; INFOPLIST_FILE = Obby/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -830,8 +834,8 @@ "-ObjC", "-lc++", ); - PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = Obby; + PRODUCT_BUNDLE_IDENTIFIER = chat.obby; + PRODUCT_NAME = "Obby Chat"; PROVISIONING_PROFILE_SPECIFIER = ""; VERSIONING_SYSTEM = "apple-generic"; }; @@ -839,7 +843,7 @@ }; 2D02E4971E0B4A5E006451C7 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = ABC0F199E8C96DFC469A5469 /* Pods-Obby-tvOS.debug.xcconfig */; + baseConfigurationReference = 3EA2462620867FC9703A65B5 /* Pods-Obby Chat-tvOS.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; @@ -867,7 +871,7 @@ }; 2D02E4981E0B4A5E006451C7 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 2B2EA621760694CFE59AABDD /* Pods-Obby-tvOS.release.xcconfig */; + baseConfigurationReference = AFB77DF034706CD351105B7B /* Pods-Obby Chat-tvOS.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; @@ -895,7 +899,7 @@ }; 2D02E4991E0B4A5E006451C7 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6334B3BC9590139F4183BBD1 /* Pods-Obby-tvOSTests.debug.xcconfig */; + baseConfigurationReference = 6EFCC415540CF34C4B48D09F /* Pods-Obby Chat-tvOSTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NONNULL = YES; @@ -915,14 +919,14 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.Obby-tvOSTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Obby-tvOS.app/Obby-tvOS"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Obby Chat-tvOS.app/Obby Chat-tvOS"; TVOS_DEPLOYMENT_TARGET = 10.1; }; name = Debug; }; 2D02E49A1E0B4A5E006451C7 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 513644CB146F4CC30EEB5E61 /* Pods-Obby-tvOSTests.release.xcconfig */; + baseConfigurationReference = A17E62FCAA5148590E89BA8D /* Pods-Obby Chat-tvOSTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NONNULL = YES; @@ -942,7 +946,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.Obby-tvOSTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Obby-tvOS.app/Obby-tvOS"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Obby Chat-tvOS.app/Obby Chat-tvOS"; TVOS_DEPLOYMENT_TARGET = 10.1; }; name = Release; @@ -1049,7 +1053,7 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "ObbyTests" */ = { + 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "Obby ChatTests" */ = { isa = XCConfigurationList; buildConfigurations = ( 00E356F61AD99517003FC87E /* Debug */, @@ -1058,7 +1062,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Obby" */ = { + 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Obby Chat" */ = { isa = XCConfigurationList; buildConfigurations = ( 13B07F941A680F5B00A75B9A /* Debug */, @@ -1067,7 +1071,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "Obby-tvOS" */ = { + 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "Obby Chat-tvOS" */ = { isa = XCConfigurationList; buildConfigurations = ( 2D02E4971E0B4A5E006451C7 /* Debug */, @@ -1076,7 +1080,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "Obby-tvOSTests" */ = { + 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "Obby Chat-tvOSTests" */ = { isa = XCConfigurationList; buildConfigurations = ( 2D02E4991E0B4A5E006451C7 /* Debug */, @@ -1085,7 +1089,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Obby" */ = { + 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Obby Chat" */ = { isa = XCConfigurationList; buildConfigurations = ( 83CBBA201A601CBA00E9B192 /* Debug */, diff --git a/ios/Obby.xcodeproj/xcshareddata/xcschemes/Obby-tvOS.xcscheme b/ios/Obby Chat.xcodeproj/xcshareddata/xcschemes/Obby-tvOS.xcscheme similarity index 79% rename from ios/Obby.xcodeproj/xcshareddata/xcschemes/Obby-tvOS.xcscheme rename to ios/Obby Chat.xcodeproj/xcshareddata/xcschemes/Obby-tvOS.xcscheme index d3084dff..a506c321 100644 --- a/ios/Obby.xcodeproj/xcshareddata/xcschemes/Obby-tvOS.xcscheme +++ b/ios/Obby Chat.xcodeproj/xcshareddata/xcschemes/Obby-tvOS.xcscheme @@ -29,9 +29,9 @@ + BuildableName = "Obby Chat-tvOS.app" + BlueprintName = "Obby Chat-tvOS" + ReferencedContainer = "container:Obby Chat.xcodeproj"> + BuildableName = "Obby Chat-tvOSTests.xctest" + BlueprintName = "Obby Chat-tvOSTests" + ReferencedContainer = "container:Obby Chat.xcodeproj"> @@ -55,29 +55,27 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + BuildableName = "Obby Chat-tvOSTests.xctest" + BlueprintName = "Obby Chat-tvOSTests" + ReferencedContainer = "container:Obby Chat.xcodeproj"> - - - - - - + BuildableName = "Obby Chat-tvOS.app" + BlueprintName = "Obby Chat-tvOS" + ReferencedContainer = "container:Obby Chat.xcodeproj"> - - + BuildableName = "Obby Chat-tvOS.app" + BlueprintName = "Obby Chat-tvOS" + ReferencedContainer = "container:Obby Chat.xcodeproj"> diff --git a/ios/Obby.xcodeproj/xcshareddata/xcschemes/Obby.xcscheme b/ios/Obby Chat.xcodeproj/xcshareddata/xcschemes/Obby.xcscheme similarity index 79% rename from ios/Obby.xcodeproj/xcshareddata/xcschemes/Obby.xcscheme rename to ios/Obby Chat.xcodeproj/xcshareddata/xcschemes/Obby.xcscheme index 4dd1a956..9fd7a35e 100644 --- a/ios/Obby.xcodeproj/xcshareddata/xcschemes/Obby.xcscheme +++ b/ios/Obby Chat.xcodeproj/xcshareddata/xcschemes/Obby.xcscheme @@ -29,9 +29,9 @@ + BuildableName = "Obby Chat.app" + BlueprintName = "Obby Chat" + ReferencedContainer = "container:Obby Chat.xcodeproj"> + BuildableName = "Obby ChatTests.xctest" + BlueprintName = "Obby ChatTests" + ReferencedContainer = "container:Obby Chat.xcodeproj"> @@ -55,29 +55,27 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + BuildableName = "Obby ChatTests.xctest" + BlueprintName = "Obby ChatTests" + ReferencedContainer = "container:Obby Chat.xcodeproj"> - - - - - - + BuildableName = "Obby Chat.app" + BlueprintName = "Obby Chat" + ReferencedContainer = "container:Obby Chat.xcodeproj"> - - + BuildableName = "Obby Chat.app" + BlueprintName = "Obby Chat" + ReferencedContainer = "container:Obby Chat.xcodeproj"> diff --git a/ios/Obby Chat.xcworkspace/contents.xcworkspacedata b/ios/Obby Chat.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..881c9631 --- /dev/null +++ b/ios/Obby Chat.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/ios/Obby.xcworkspace/contents.xcworkspacedata b/ios/Obby.xcworkspace/contents.xcworkspacedata index d4c9646e..736e9387 100644 --- a/ios/Obby.xcworkspace/contents.xcworkspacedata +++ b/ios/Obby.xcworkspace/contents.xcworkspacedata @@ -2,7 +2,7 @@ + location = "group:/Users/daniel/Desktop/Projects/ObbyChat/ios/Obby Chat.xcodeproj"> diff --git a/ios/Obby/Base.lproj/LaunchScreen.xib b/ios/Obby/Base.lproj/LaunchScreen.xib deleted file mode 100644 index b812fbce..00000000 --- a/ios/Obby/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ios/Obby/Images.xcassets/AppIcon.appiconset/1024.png b/ios/Obby/Images.xcassets/AppIcon.appiconset/1024.png new file mode 100644 index 00000000..fb1474f5 Binary files /dev/null and b/ios/Obby/Images.xcassets/AppIcon.appiconset/1024.png differ diff --git a/ios/Obby/Images.xcassets/AppIcon.appiconset/120-1.png b/ios/Obby/Images.xcassets/AppIcon.appiconset/120-1.png new file mode 100644 index 00000000..2283da6e Binary files /dev/null and b/ios/Obby/Images.xcassets/AppIcon.appiconset/120-1.png differ diff --git a/ios/Obby/Images.xcassets/AppIcon.appiconset/120.png b/ios/Obby/Images.xcassets/AppIcon.appiconset/120.png new file mode 100644 index 00000000..2283da6e Binary files /dev/null and b/ios/Obby/Images.xcassets/AppIcon.appiconset/120.png differ diff --git a/ios/Obby/Images.xcassets/AppIcon.appiconset/180.png b/ios/Obby/Images.xcassets/AppIcon.appiconset/180.png new file mode 100644 index 00000000..464bd62f Binary files /dev/null and b/ios/Obby/Images.xcassets/AppIcon.appiconset/180.png differ diff --git a/ios/Obby/Images.xcassets/AppIcon.appiconset/40.png b/ios/Obby/Images.xcassets/AppIcon.appiconset/40.png new file mode 100644 index 00000000..24ae71cd Binary files /dev/null and b/ios/Obby/Images.xcassets/AppIcon.appiconset/40.png differ diff --git a/ios/Obby/Images.xcassets/AppIcon.appiconset/58.png b/ios/Obby/Images.xcassets/AppIcon.appiconset/58.png new file mode 100644 index 00000000..9a8e689b Binary files /dev/null and b/ios/Obby/Images.xcassets/AppIcon.appiconset/58.png differ diff --git a/ios/Obby/Images.xcassets/AppIcon.appiconset/60.png b/ios/Obby/Images.xcassets/AppIcon.appiconset/60.png new file mode 100644 index 00000000..6fcf703c Binary files /dev/null and b/ios/Obby/Images.xcassets/AppIcon.appiconset/60.png differ diff --git a/ios/Obby/Images.xcassets/AppIcon.appiconset/80.png b/ios/Obby/Images.xcassets/AppIcon.appiconset/80.png new file mode 100644 index 00000000..d890a2e8 Binary files /dev/null and b/ios/Obby/Images.xcassets/AppIcon.appiconset/80.png differ diff --git a/ios/Obby/Images.xcassets/AppIcon.appiconset/87.png b/ios/Obby/Images.xcassets/AppIcon.appiconset/87.png new file mode 100644 index 00000000..c3e8d676 Binary files /dev/null and b/ios/Obby/Images.xcassets/AppIcon.appiconset/87.png differ diff --git a/ios/Obby/Images.xcassets/AppIcon.appiconset/Contents.json b/ios/Obby/Images.xcassets/AppIcon.appiconset/Contents.json index 118c98f7..b0a1a07f 100644 --- a/ios/Obby/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/ios/Obby/Images.xcassets/AppIcon.appiconset/Contents.json @@ -1,34 +1,58 @@ { "images" : [ { + "size" : "20x20", "idiom" : "iphone", - "size" : "29x29", + "filename" : "40.png", "scale" : "2x" }, { + "size" : "20x20", "idiom" : "iphone", - "size" : "29x29", + "filename" : "60.png", "scale" : "3x" }, { + "size" : "29x29", "idiom" : "iphone", - "size" : "40x40", + "filename" : "58.png", "scale" : "2x" }, { + "size" : "29x29", "idiom" : "iphone", - "size" : "40x40", + "filename" : "87.png", "scale" : "3x" }, { + "size" : "40x40", "idiom" : "iphone", - "size" : "60x60", + "filename" : "80.png", "scale" : "2x" }, { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "120.png", + "scale" : "3x" + }, + { + "size" : "60x60", "idiom" : "iphone", + "filename" : "120-1.png", + "scale" : "2x" + }, + { "size" : "60x60", + "idiom" : "iphone", + "filename" : "180.png", "scale" : "3x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "1024.png", + "scale" : "1x" } ], "info" : { diff --git a/ios/Obby/Images.xcassets/Contents.json b/ios/Obby/Images.xcassets/Contents.json index 2d92bd53..da4a164c 100644 --- a/ios/Obby/Images.xcassets/Contents.json +++ b/ios/Obby/Images.xcassets/Contents.json @@ -3,4 +3,4 @@ "version" : 1, "author" : "xcode" } -} +} \ No newline at end of file diff --git a/ios/Obby/Info.plist b/ios/Obby/Info.plist index 60845670..98c740a6 100644 --- a/ios/Obby/Info.plist +++ b/ios/Obby/Info.plist @@ -2,12 +2,10 @@ - NSCameraUsageDescription - Your message to user when the camera is accessed for the first time CFBundleDevelopmentRegion en CFBundleDisplayName - Obby + $(PRODUCT_NAME) CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -15,7 +13,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - $(PRODUCT_NAME) + $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString @@ -23,7 +21,9 @@ CFBundleSignature ???? CFBundleVersion - 1 + $(CURRENT_PROJECT_VERSION) + ITSAppUsesNonExemptEncryption + LSRequiresIPhoneOS NSAppTransportSecurity @@ -39,22 +39,28 @@ + NSCalendarsUsageDescription + Allow $(PRODUCT_NAME) to access your calendar + NSCameraUsageDescription + Allow $(PRODUCT_NAME) to use the camera + NSContactsUsageDescription + Allow $(PRODUCT_NAME) to access your contacts + NSLocationAlwaysAndWhenInUseUsageDescription + Allow $(PRODUCT_NAME) to use your location + NSLocationAlwaysUsageDescription + Allow $(PRODUCT_NAME) to use your location NSLocationWhenInUseUsageDescription Allow $(PRODUCT_NAME) to use your location - UILaunchStoryboardName - LaunchScreen - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - + NSMicrophoneUsageDescription + Allow $(PRODUCT_NAME) to access your microphone + NSMotionUsageDescription + Allow $(PRODUCT_NAME) to access your device's accelerometer + NSPhotoLibraryAddUsageDescription + Give $(PRODUCT_NAME) permission to save photos + NSPhotoLibraryUsageDescription + Give $(PRODUCT_NAME) permission to access your photos + NSRemindersUsageDescription + Allow $(PRODUCT_NAME) to access your reminders UIAppFonts AntDesign.ttf @@ -98,25 +104,19 @@ Agenda-Light.otf Agenda-Medium.otf - NSCalendarsUsageDescription - Allow $(PRODUCT_NAME) to access your calendar - NSCameraUsageDescription - Allow $(PRODUCT_NAME) to use the camera - NSContactsUsageDescription - Allow $(PRODUCT_NAME) to access your contacts - NSLocationAlwaysAndWhenInUseUsageDescription - Allow $(PRODUCT_NAME) to use your location - NSLocationAlwaysUsageDescription - Allow $(PRODUCT_NAME) to use your location - NSMicrophoneUsageDescription - Allow $(PRODUCT_NAME) to access your microphone - NSMotionUsageDescription - Allow $(PRODUCT_NAME) to access your device's accelerometer - NSPhotoLibraryAddUsageDescription - Give $(PRODUCT_NAME) permission to save photos - NSPhotoLibraryUsageDescription - Give $(PRODUCT_NAME) permission to access your photos - NSRemindersUsageDescription - Allow $(PRODUCT_NAME) to access your reminders + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + diff --git a/ios/Podfile b/ios/Podfile index c483eb36..9bfe477d 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -2,8 +2,8 @@ platform :ios, '10.0' require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' require_relative '../node_modules/react-native-unimodules/cocoapods.rb' -target 'Obby' do - # Pods for Obby +target 'Obby Chat' do + # Pods for Obby Chat pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector" pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec" pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired" @@ -39,7 +39,7 @@ target 'Obby' do pod 'react-native-randombytes', :path => '../node_modules/react-native-randombytes' - target 'ObbyTests' do + target 'Obby ChatTests' do inherit! :search_paths # Pods for testing end @@ -48,10 +48,10 @@ target 'Obby' do use_unimodules! end -target 'Obby-tvOS' do +target 'Obby Chat-tvOS' do # Pods for Obby-tvOS - target 'Obby-tvOSTests' do + target 'Obby Chat-tvOSTests' do inherit! :search_paths # Pods for testing end diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 0bda825d..9a744cf8 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,14 +1,14 @@ PODS: - boost-for-react-native (1.63.0) - DoubleConversion (1.1.6) - - EXAppLoaderProvider (7.0.0) - - EXConstants (7.0.1): + - EXAppLoaderProvider (8.0.0) + - EXConstants (8.0.0): - UMConstantsInterface - UMCore - - EXFileSystem (7.0.0): + - EXFileSystem (8.0.0): - UMCore - UMFileSystemInterface - - EXPermissions (7.0.0): + - EXPermissions (8.0.0): - UMCore - UMPermissionsInterface - EXSecureStore (8.0.0): @@ -206,12 +206,10 @@ PODS: - React - react-native-randombytes (3.5.3): - React - - react-native-safe-area-context (0.6.4): + - react-native-safe-area-context (0.7.3): - React - react-native-udp (2.6.1): - React - - react-native-webview (7.5.2): - - React - React-RCTActionSheet (0.61.5): - React-Core/RCTActionSheetHeaders (= 0.61.5) - React-RCTAnimation (0.61.5): @@ -249,37 +247,41 @@ PODS: - ReactCommon/jscallinvoker (= 0.61.5) - RNCAsyncStorage (1.7.1): - React - - RNCMaskedView (0.1.6): + - RNCMaskedView (0.1.10): + - React + - RNDeviceInfo (5.5.3): - React - - RNGestureHandler (1.3.0): + - RNGestureHandler (1.6.1): - React - RNOS (1.2.6): - React - RNPermissions (2.0.9): - React - - RNReanimated (1.7.0): + - RNReanimated (1.8.0): - React - - RNScreens (2.0.0-alpha.32): + - RNScreens (2.7.0): + - React + - RNShare (3.2.0): - React - RNSVG (9.13.6): - React - TcpSockets (3.3.2): - React - - UMBarCodeScannerInterface (4.0.0) - - UMCameraInterface (4.0.0) - - UMConstantsInterface (4.0.0) - - UMCore (4.0.0) - - UMFaceDetectorInterface (4.0.0) - - UMFileSystemInterface (4.0.0) - - UMFontInterface (4.0.0) - - UMImageLoaderInterface (4.0.0) - - UMPermissionsInterface (4.0.0) - - UMReactNativeAdapter (4.0.0): - - React + - UMBarCodeScannerInterface (5.0.0) + - UMCameraInterface (5.0.0) + - UMConstantsInterface (5.0.0) + - UMCore (5.0.0) + - UMFaceDetectorInterface (5.0.0) + - UMFileSystemInterface (5.0.0) + - UMFontInterface (5.0.0) + - UMImageLoaderInterface (5.0.0) + - UMPermissionsInterface (5.0.0) + - UMReactNativeAdapter (5.0.0): + - React-Core - UMCore - UMFontInterface - - UMSensorsInterface (4.0.0) - - UMTaskManagerInterface (4.0.0) + - UMSensorsInterface (5.0.0) + - UMTaskManagerInterface (5.0.0) - Yoga (1.14.0) DEPENDENCIES: @@ -309,7 +311,6 @@ DEPENDENCIES: - react-native-randombytes (from `../node_modules/react-native-randombytes`) - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - react-native-udp (from `../node_modules/react-native-udp`) - - react-native-webview (from `../node_modules/react-native-webview`) - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) @@ -323,11 +324,13 @@ DEPENDENCIES: - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)" - "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)" + - RNDeviceInfo (from `../node_modules/react-native-device-info`) - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) - RNOS (from `../node_modules/react-native-os`) - RNPermissions (from `../node_modules/react-native-permissions`) - RNReanimated (from `../node_modules/react-native-reanimated`) - RNScreens (from `../node_modules/react-native-screens`) + - RNShare (from `../node_modules/react-native-share`) - RNSVG (from `../node_modules/react-native-svg`) - TcpSockets (from `../node_modules/react-native-tcp`) - UMBarCodeScannerInterface (from `../node_modules/unimodules-barcode-scanner-interface/ios`) @@ -402,8 +405,6 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-safe-area-context" react-native-udp: :path: "../node_modules/react-native-udp" - react-native-webview: - :path: "../node_modules/react-native-webview" React-RCTActionSheet: :path: "../node_modules/react-native/Libraries/ActionSheetIOS" React-RCTAnimation: @@ -428,6 +429,8 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-community/async-storage" RNCMaskedView: :path: "../node_modules/@react-native-community/masked-view" + RNDeviceInfo: + :path: "../node_modules/react-native-device-info" RNGestureHandler: :path: "../node_modules/react-native-gesture-handler" RNOS: @@ -438,6 +441,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-reanimated" RNScreens: :path: "../node_modules/react-native-screens" + RNShare: + :path: "../node_modules/react-native-share" RNSVG: :path: "../node_modules/react-native-svg" TcpSockets: @@ -484,10 +489,10 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 - EXAppLoaderProvider: 5d348813a9cf09b03bbe5b8b55437bc1bfbddbd1 - EXConstants: 857aa7b1c84e2878f8402d712061860bca16a697 - EXFileSystem: 7e53a2c30a2eb6987ba6d5158ab908f947523228 - EXPermissions: df10ad83df2f6b647aec304619354f8ab48d5f63 + EXAppLoaderProvider: ebdb6bc2632c1ccadbe49f5e4104d8d690969c49 + EXConstants: 4051b16c17ef3defa03c541d42811dc92b249146 + EXFileSystem: 6e0d9bb6cc4ea404dbb8f583c1a8a2dcdf4b83b6 + EXPermissions: 9bc08859a675d291e89be9a0870155c27c16ac35 EXSecureStore: 1448b90d665c9400aaaf6655fccb464da14698f6 FBLazyVector: aaeaf388755e4f29cd74acbc9e3b8da6d807c37f FBReactNativeSpec: 118d0d177724c2d67f08a59136eb29ef5943ec75 @@ -505,9 +510,8 @@ SPEC CHECKSUMS: React-jsinspector: fa0ecc501688c3c4c34f28834a76302233e29dc0 react-native-camera: 705c7e9412436957b4dc894a1af61f43830787e2 react-native-randombytes: 3638d24759d67c68f6ccba60c52a7a8a8faa6a23 - react-native-safe-area-context: 52342d2d80ea8faadd0ffa76d83b6051f20c5329 + react-native-safe-area-context: e200d4433aba6b7e60b52da5f37af11f7a0b0392 react-native-udp: 54a1aa9bf5c0824f930b1ba6dbfb3fd3e733bba9 - react-native-webview: d1b30cc9128256ec1a9c6d10fb572231bd371337 React-RCTActionSheet: 600b4d10e3aea0913b5a92256d2719c0cdd26d76 React-RCTAnimation: 791a87558389c80908ed06cc5dfc5e7920dfa360 React-RCTBlob: d89293cc0236d9cb0933d85e430b0bbe81ad1d72 @@ -519,28 +523,30 @@ SPEC CHECKSUMS: React-RCTVibration: a49a1f42bf8f5acf1c3e297097517c6b3af377ad ReactCommon: 198c7c8d3591f975e5431bec1b0b3b581aa1c5dd RNCAsyncStorage: 44395cb9c7c1523104c2b499eb426ef7aff82bca - RNCMaskedView: a88953beefbd347a29072d9eba90e42945fe291e - RNGestureHandler: 5329a942fce3d41c68b84c2c2276ce06a696d8b0 + RNCMaskedView: 5a8ec07677aa885546a0d98da336457e2bea557f + RNDeviceInfo: 310c1f43d418d950a193c7650de2f9559c906048 + RNGestureHandler: 8f09cd560f8d533eb36da5a6c5a843af9f056b38 RNOS: 6f2f9a70895bbbfbdad7196abd952e7b01d45027 RNPermissions: 2f74237e97b08beda01e914301e12524ddddf5b8 - RNReanimated: 031fe8d9ea93c2bd689a40f05320ef9d96f74d7f - RNScreens: a55364dc1833101f836cee70975ce1fea615a12f + RNReanimated: 955cf4068714003d2f1a6e2bae3fb1118f359aff + RNScreens: cf198f915f8a2bf163de94ca9f5bfc8d326c3706 + RNShare: 13f1b72aab353c3092b30dce99d212871bb2a8a1 RNSVG: 8ba35cbeb385a52fd960fd28db9d7d18b4c2974f TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 - UMBarCodeScannerInterface: d5a6fdc98ed6241225b0a8432a7f4e2b397668bc - UMCameraInterface: 68870a3197fee85bd5afca5609ba4a5b7257d19d - UMConstantsInterface: d25b8e8887ca7aaf568c06caf08f4d40734ee4ef - UMCore: 402cee150324974974f5c32b5404d8af65e4cff5 - UMFaceDetectorInterface: 7b4f1a92f0c726b58b086296048efe193b570678 - UMFileSystemInterface: aadb9a67aa6470d7ebc06cf04dc54fee6781ac48 - UMFontInterface: 2d3c128285086bbed3d2a650f1d698323ef3b25a - UMImageLoaderInterface: 2829a7571a12d2e754c73c55ffe7e327d8402c7d - UMPermissionsInterface: b6a6e96db0f4011a25aaca14e6022529dd3d6e4e - UMReactNativeAdapter: 93c2f520a1cdb6ef3058a7b6a95275a804e0923b - UMSensorsInterface: cf59dd7602764a2419e00167429be3e4be39c61d - UMTaskManagerInterface: 1e70fe58b872355f0ecb44fb81bb1a16484047f0 + UMBarCodeScannerInterface: 3802c8574ef119c150701d679ab386e2266d6a54 + UMCameraInterface: 985d301f688ed392f815728f0dd906ca34b7ccb1 + UMConstantsInterface: bda5f8bd3403ad99e663eb3c4da685d063c5653c + UMCore: 7ab08669a8bb2e61f557c1fe9784521cb5aa28e3 + UMFaceDetectorInterface: ce14e8e597f6a52aa66e4ab956cb5bff4fa8acf8 + UMFileSystemInterface: 2ed004c9620f43f0b36b33c42ce668500850d6a4 + UMFontInterface: 24fbc0a02ade6c60ad3ee3e2b5d597c8dcfc3208 + UMImageLoaderInterface: 3976a14c588341228881ff75970fbabf122efca4 + UMPermissionsInterface: 2abf9f7f4aa7110e27beaf634a7deda2d50ff3d7 + UMReactNativeAdapter: 230406e3335a8dbd4c9c0e654488a1cf3b44552f + UMSensorsInterface: d708a892ef1500bdd9fc3ff03f7836c66d1634d3 + UMTaskManagerInterface: a98e37a576a5220bf43b8faf33cfdc129d2f441d Yoga: f2a7cd4280bfe2cca5a7aed98ba0eb3d1310f18b -PODFILE CHECKSUM: d07be5907163bb32cfbd6ec771b7ecefe0f04f56 +PODFILE CHECKSUM: 0dcc2d9daab1826f90f0ffabb8f852b54fa415b0 COCOAPODS: 1.8.4 diff --git a/package.json b/package.json index d1defaeb..ae223455 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "scripts": { - "android": "react-native run-android", + "android": "adb reverse tcp:8081 tcp:8081 && react-native run-android", "ios": "react-native run-ios", "start": "react-native start --reset-cache", "postinstall": "npx react-native link react-native-randombytes && ./node_modules/.bin/rn-nodeify --hack --install", @@ -13,7 +13,7 @@ "dependencies": { "@expo/vector-icons": "^10.0.6", "@react-native-community/async-storage": "^1.7.1", - "@react-native-community/masked-view": "^0.1.6", + "@react-native-community/masked-view": "^0.1.10", "@redux-saga/core": "^1.1.1", "@tradle/react-native-http": "^2.0.1", "assert": "^1.5.0", @@ -27,9 +27,10 @@ "events": "^1.1.1", "expo-secure-store": "^8.0.0", "https-browserify": "0.0.1", + "jetifier": "^1.6.6", "lodash": "^4.17.15", "native-base": "^2.13.5", - "obyte": "^0.1.6", + "obyte": "^0.1.9", "path-browserify": "0.0.0", "process": "^0.11.10", "punycode": "^1.4.1", @@ -41,27 +42,28 @@ "react-native-actionsheet": "^2.4.2", "react-native-camera": "^3.16.0", "react-native-crypto": "^2.2.0", - "react-native-gesture-handler": "~1.3.0", + "react-native-device-info": "^5.5.3", + "react-native-dialog": "^5.6.0", + "react-native-gesture-handler": "^1.6.1", "react-native-gifted-chat": "^0.13.0", "react-native-level-fs": "^3.0.1", "react-native-os": "^1.2.6", "react-native-permissions": "^2.0.9", - "react-native-picker-select": "^6.3.3", "react-native-qrcode-scanner": "^1.3.1", "react-native-qrcode-svg": "^6.0.1", "react-native-randombytes": "^3.5.3", - "react-native-reanimated": "^1.7.0", + "react-native-reanimated": "^1.8.0", "react-native-root-toast": "^3.1.2", - "react-native-safe-area-context": "^0.6.4", + "react-native-safe-area-context": "^0.7.3", "react-native-safe-area-view": "^1.0.0", - "react-native-screens": "^2.0.0-alpha.32", + "react-native-screens": "^2.7.0", + "react-native-share": "^3.2.0", "react-native-svg": "^9.13.6", "react-native-tcp": "^3.3.2", "react-native-timeago": "^0.5.0", "react-native-udp": "^2.6.1", - "react-native-unimodules": "^0.6.0", + "react-native-unimodules": "^0.7.0", "react-native-user-avatar": "^1.0.4", - "react-native-webview": "^7.5.2", "react-navigation": "^4.1.0", "react-navigation-hooks": "^1.1.0", "react-navigation-stack": "^2.0.16", diff --git a/src/actions/correspondents.js b/src/actions/correspondents.js index 0f65cb70..f339ff5c 100644 --- a/src/actions/correspondents.js +++ b/src/actions/correspondents.js @@ -1,6 +1,41 @@ import { actionTypes } from './../constants'; -export const setCorrespondentDevice = payload => ({ +export const addCorrespondent = ({ + address, + name, + hub, + pubKey, + pairingSecret, + reversePairingSecret, +}) => ({ type: actionTypes.CORRESPONDENT_DEVICE_ADD, - payload, + payload: { address, name, hub, pubKey, pairingSecret, reversePairingSecret }, +}); + +export const removeCorrespondent = ({ address }) => ({ + type: actionTypes.CORRESPONDENT_DEVICE_REMOVE, + payload: { address }, +}); + +export const updateCorrespondentWalletAddress = ({ + address, + walletAddress, +}) => ({ + type: actionTypes.CORRESPONDENT_WALLET_ADDRESS_UPDATE, + payload: { address, walletAddress }, +}); + +export const setCorrespondentName = ({ name, address }) => ({ + type: actionTypes.CORRESPONDENT_NAME_SET, + payload: { name, address }, +}); + +export const acceptInvitation = ({ data }) => ({ + type: actionTypes.CORRESPONDENT_INVITATION_ACCEPT, + payload: { data }, +}); + +export const clearChatHistory = ({ address }) => ({ + type: actionTypes.CORRESPONDENT_CHAT_CLEAR, + payload: { address }, }); diff --git a/src/actions/messages.js b/src/actions/messages.js index ac5aa873..c8e0ae2b 100644 --- a/src/actions/messages.js +++ b/src/actions/messages.js @@ -64,20 +64,3 @@ export const setUnreadMessages = unreadMessages => ({ type: actionTypes.UNREAD_MESSAGE_COUNT_SET, payload: { unreadMessages }, }); - -export const addCorrespondent = ({ - address, - name, - hub, - pubKey, - pairingSecret, - reversePairingSecret, -}) => ({ - type: actionTypes.CORRESPONDENT_DEVICE_ADD, - payload: { address, name, hub, pubKey, pairingSecret, reversePairingSecret }, -}); - -export const removeCorrespondent = ({ address }) => ({ - type: actionTypes.CORRESPONDENT_DEVICE_REMOVE, - payload: { address }, -}); diff --git a/src/components/ActionSheet/index.js b/src/components/ActionSheet/index.js new file mode 100644 index 00000000..5b9a0f61 --- /dev/null +++ b/src/components/ActionSheet/index.js @@ -0,0 +1,46 @@ +import React, { useCallback, useRef } from 'react'; +import { View, Text, TouchableOpacity } from 'react-native'; +import RNActionSheet from 'react-native-actionsheet'; + +import styles from './styles'; + +export default ActionSheet = ({ + onChange, + currentValue, + items = [], + ...restProps +}) => { + const actionSheet = useRef(); + const options = [...items.map(item => item.label), 'Cancel']; + + const handleOpenActionSheet = useCallback(() => { + if (actionSheet) { + actionSheet.current.show(); + } + }, [actionSheet]); + + const onValueChanged = useCallback( + i => { + if (typeof onChange === 'function' && i !== options.length - 1) { + onChange(items[i].value); + } + }, + [options, currentValue, onChange], + ); + + return ( + + + {currentValue} + + + + ); +}; diff --git a/src/components/ActionSheet/styles.js b/src/components/ActionSheet/styles.js new file mode 100644 index 00000000..35823590 --- /dev/null +++ b/src/components/ActionSheet/styles.js @@ -0,0 +1,14 @@ +import { StyleSheet } from 'react-native'; +import { colors } from './../../constants'; + +export default StyleSheet.create({ + container: { + alignContent: 'flex-end' + }, + label: { + fontFamily: 'Agenda-Light', + fontSize: 16, + marginRight: 10, + color: colors.grey.main, + }, +}); diff --git a/src/components/Header/index.js b/src/components/Header/index.js index ab861769..c3a8baf9 100644 --- a/src/components/Header/index.js +++ b/src/components/Header/index.js @@ -14,6 +14,7 @@ const Header = ({ navigation, size, hasBackButton, + backRoute, hasBorder, }) => { const headerBorderStyle = hasBorder ? styles.headerBordered : {}; @@ -26,7 +27,9 @@ const Header = ({ {hasBackButton === true && ( navigation.pop()} + onPress={() => + backRoute ? navigation.navigate(backRoute) : navigation.pop() + } > diff --git a/src/components/Header/styles.js b/src/components/Header/styles.js index 0c1405be..8a76b9ac 100644 --- a/src/components/Header/styles.js +++ b/src/components/Header/styles.js @@ -8,7 +8,6 @@ export default StyleSheet.create({ backgroundColor: colors.white, flexDirection: 'row', justifyContent: 'space-between', - alignItems: 'stretch', }, headerCompact: { paddingTop: 30, @@ -16,7 +15,6 @@ export default StyleSheet.create({ backgroundColor: colors.white, flexDirection: 'row', justifyContent: 'space-between', - alignItems: 'stretch', }, headerBordered: { borderBottomColor: colors.grey.lightest, @@ -25,24 +23,21 @@ export default StyleSheet.create({ headerLeft: { flexDirection: 'row', marginLeft: 15, - flexWrap: 'wrap', + flexWrap: 'nowrap', alignItems: 'center', justifyContent: 'flex-start', - flex: 1, }, headerCenter: { flexDirection: 'row', - flexWrap: 'wrap', + flexWrap: 'nowrap', alignItems: 'center', justifyContent: 'center', - flex: 1, }, headerRight: { flexDirection: 'row', marginRight: 15, alignItems: 'center', justifyContent: 'flex-end', - flex: 1, }, headerTitle: { fontFamily: 'Agenda-Medium', @@ -54,5 +49,8 @@ export default StyleSheet.create({ }, backBtn: { marginRight: 10, + paddingTop: 15, + paddingRight: 15, + paddingBottom: 15, }, }); diff --git a/src/constants/actionTypes.js b/src/constants/actionTypes.js index 57a65cd0..54342477 100644 --- a/src/constants/actionTypes.js +++ b/src/constants/actionTypes.js @@ -24,6 +24,12 @@ export const UNREAD_MESSAGE_COUNT_SET = 'UNREAD_MESSAGE_COUNT_SET'; export const DEVICE_TEMP_KEY_ROTATE = 'DEVICE_TEMP_KEY_ROTATE'; export const CORRESPONDENT_DEVICE_ADD = 'CORRESPONDENT_DEVICE_ADD'; export const CORRESPONDENT_DEVICE_REMOVE = 'CORRESPONDENT_DEVICE_REMOVE'; +export const CORRESPONDENT_WALLET_ADDRESS_UPDATE = + 'CORRESPONDENT_WALLET_ADDRESS_UPDATE'; +export const CORRESPONDENT_NAME_SET = 'CORRESPONDENT_NAME_SET'; +export const CORRESPONDENT_INVITATION_ACCEPT = + 'CORRESPONDENT_INVITATION_ACCEPT'; +export const CORRESPONDENT_CHAT_CLEAR = 'CORRESPONDENT_CHAT_CLEAR'; export const MESSAGE_ADD_START = 'MESSAGE_ADD_START'; export const MESSAGE_ADD_SUCCESS = 'MESSAGE_ADD_SUCCESS'; export const MESSAGE_ADD_FAIL = 'MESSAGE_ADD_FAIL'; diff --git a/src/lib/messaging.js b/src/lib/messaging.js index 088eafb1..ca2ef1f8 100644 --- a/src/lib/messaging.js +++ b/src/lib/messaging.js @@ -1,29 +1,56 @@ import { isValidAddress } from 'obyte/lib/utils'; +import { getSignedMessageInfoFromJsonBase64 } from './oCustom'; -export const regexWalletAddress = /^([A-Z0-9]{32})$/g; -export const regexPaymentRequest = /\[.*?\]\(((?:byteball-tn|byteball|obyte-tn|obyte):([0-9A-Z]{32})(?:\?([\w=&;+%]+))?)\)/g; -export const regexTextcoin = /\[.*?\]\(((?:byteball-tn|byteball|obyte-tn|obyte):textcoin\?(.+))\)/g; -export const regexData = /\[.*?\]\(((?:byteball-tn|byteball|obyte-tn|obyte):data\?(.+))\)/g; +export const REG_WALLET_ADDRESS = /^([A-Z0-9]{32})$/g; +export const REG_REQUEST_PAYMENT = /\[.*?\]\(((?:byteball-tn|byteball|obyte-tn|obyte):([0-9A-Z]{32})(?:\?([\w=&;+%]+))?)\)/g; +export const REG_TEXTCOINT = /\[.*?\]\(((?:byteball-tn|byteball|obyte-tn|obyte):textcoin\?(.+))\)/g; +export const REGEX_DATA = /\[.*?\]\(((?:byteball-tn|byteball|obyte-tn|obyte):data\?(.+))\)/g; +export const REGEX_SIGN_MESSAGE_REQUEST = /\[(.+?)\]\(sign-message-request(-network-aware)?:(.+?)\)/g; +export const REGEX_SIGNED_MESSAGE = /\[(.+?)\]\(signed-message:(.+?)\)/g; +export const REGEX_PAIRING = /(byteball-tn|byteball|obyte-tn|obyte):([\w\/+]{44})@([\w.:\/-]+)#(.+)/g; export const parseTextMessage = originalText => { let type = null; + let params = {}; + const parsedText = originalText - .replace(regexWalletAddress, (str, address) => { + .replace(REG_WALLET_ADDRESS, (str, address) => { type = 'WALLET_ADDRESS'; return address; }) - .replace(regexPaymentRequest, (str, payload, address, params) => { + .replace(REG_REQUEST_PAYMENT, (str, payload, address, params) => { type = 'REQUEST_PAYMENT'; return `Payment request: ${params}\n${address}`; }) - .replace(regexTextcoin, str => { + .replace(REG_TEXTCOINT, str => { type = 'TEXTCOINT'; return '[UNSUPPORTED ACTION]'; }) - .replace(regexData, str => { + .replace(REGEX_DATA, str => { type = 'DATA'; return '[UNSUPPORTED ACTION]'; + }) + .replace( + REGEX_SIGN_MESSAGE_REQUEST, + (str, description, networkAware, messageToSign) => { + type = 'SIGN_MESSAGE_REQUEST'; + params = { messageToSign }; + return `Request to sign message: ${messageToSign}`; + }, + ) + .replace(REGEX_SIGNED_MESSAGE, (str, description, signedMessageBase64) => { + type = 'SIGNED_MESSAGE'; + const info = getSignedMessageInfoFromJsonBase64(signedMessageBase64); + const { objSignedMessage } = info; + let text = + typeof objSignedMessage.signed_message === 'string' + ? objSignedMessage.signed_message + : JSON.stringify(objSignedMessage.signed_message, null, '\t'); + + // TODO: signed message validation + + return `Signed message: ${text}`; }); - return { originalText, parsedText, type }; + return { originalText, parsedText, type, params }; }; diff --git a/src/lib/OCustom.js b/src/lib/oCustom.js similarity index 87% rename from src/lib/OCustom.js rename to src/lib/oCustom.js index 8e5d255c..d8186ace 100644 --- a/src/lib/OCustom.js +++ b/src/lib/oCustom.js @@ -2,7 +2,7 @@ import _ from 'lodash'; import Crypto from 'crypto'; import obyte from 'obyte'; import ecdsa from 'secp256k1'; -import { getChash160 } from 'obyte/lib/utils'; +import { getChash160, isValidAddress } from 'obyte/lib/utils'; import { common } from './../constants'; // Conf @@ -13,8 +13,8 @@ export const hubAddress = export const oClient = common.network === 'testnet' - ? new obyte.Client('wss://obyte.org/bb-test', { testnet }) - : new obyte.Client('wss://obyte.org/bb'); + ? new obyte.Client('wss://obyte.org/bb-test', { testnet, reconnect: true }) + : new obyte.Client('wss://obyte.org/bb', { reconnect: true }); export const urlHost = common.network === 'testnet' ? 'obyte-tn:' : 'obyte:'; @@ -118,42 +118,10 @@ export const verify = function(hash, b64_sig, b64_pub_key) { new Buffer.from(b64_pub_key, 'base64'), ); } catch (e) { - console.log('signature verification exception: ' + e.toString()); return false; } }; -// Pairing -export const startWaitingForPairing = handlePairingInfo => { - var pairing_secret = Crypto.randomBytes(9).toString('base64'); - var pairingInfo = { - pairing_secret: pairing_secret, - device_pubkey: myPermDeviceKey.pub_b64, - device_address: my_device_address, - hub: my_device_hub, - }; - return pairingInfo; -}; - -export const sendPairingMessage = ( - hub_host, - recipient_device_pubkey, - pairing_secret, - reverse_pairing_secret, - callbacks, -) => { - var body = { pairing_secret: pairing_secret, device_name: my_device_name }; - if (reverse_pairing_secret) - body.reverse_pairing_secret = reverse_pairing_secret; - sendMessageToHub( - hub_host, - recipient_device_pubkey, - 'pairing', - body, - callbacks, - ); -}; - // Messaging export const decryptPackage = ( objEncryptedPackage, @@ -223,7 +191,11 @@ export const decryptPackage = ( var decrypted_message = decrypted_message_buf.toString('utf8'); var json = JSON.parse(decrypted_message); if (json.encrypted_package) { - return decryptPackage(json.encrypted_package); + return decryptPackage( + json.encrypted_package, + myPermDeviceKey, + myTempDeviceKey, + ); } else return json; }; @@ -239,7 +211,6 @@ export const createEncryptedPackage = (json, recipient_device_pubkey) => { var arrChunks = []; var CHUNK_LENGTH = 2003; for (var offset = 0; offset < text.length; offset += CHUNK_LENGTH) { - // console.log('offset '+offset); arrChunks.push( cipher.update( text.slice(offset, Math.min(offset + CHUNK_LENGTH, text.length)), @@ -250,10 +221,7 @@ export const createEncryptedPackage = (json, recipient_device_pubkey) => { arrChunks.push(cipher.final()); var encrypted_message_buf = Buffer.concat(arrChunks); arrChunks = null; - // var encrypted_message_buf = Buffer.concat([cipher.update(text, "utf8"), cipher.final()]); - //console.log(encrypted_message_buf); var encrypted_message = encrypted_message_buf.toString('base64'); - //console.log(encrypted_message); var authtag = cipher.getAuthTag(); // this is visible and verifiable by the hub var encrypted_package = { @@ -307,3 +275,35 @@ export const deliverMessage = async objDeviceMessage => { }); return accepted; }; + +export const getSignedMessageInfoFromJsonBase64 = signedMessageBase64 => { + var signedMessageJson = Buffer.from(signedMessageBase64, 'base64').toString( + 'utf8', + ); + try { + var objSignedMessage = JSON.parse(signedMessageJson); + } catch (e) { + return null; + } + var info = { + objSignedMessage: objSignedMessage, + }; + + return info; +}; + +export const signMessage = (message, fromAddress) => { + const objAuthor = { + address: fromAddress, + authentifiers: {}, + }; + + const objUnit = { + signed_message: message, + authors: [objAuthor], + }; + + const result = Buffer.from(JSON.stringify(objUnit)).toString('base64'); + + return `[Signed message](signed-message:${result})`; +}; diff --git a/src/lib/utils.js b/src/lib/utils.js index bbd93452..22abb0be 100644 --- a/src/lib/utils.js +++ b/src/lib/utils.js @@ -48,9 +48,14 @@ export const unitToBytes = (n, unit) => { } }; -export const availableUnits = [ +export const PRIMARY_UNITS = [ { label: 'bytes', value: 'B', altValue: 'BYTE' }, { label: 'kB', value: 'kB', altValue: 'kBYTE' }, { label: 'MB', value: 'MB', altValue: 'MBYTE' }, { label: 'GB', value: 'GB', altValue: 'GBYTE' }, ]; + +export const SECONDARY_UNITS = [ + { label: 'USD', value: 'USD' }, + { label: 'BTC', value: 'BTC' }, +]; diff --git a/src/navigation/MainStack.js b/src/navigation/MainStack.js index c63a323a..7d292cdd 100644 --- a/src/navigation/MainStack.js +++ b/src/navigation/MainStack.js @@ -38,6 +38,7 @@ const MainStack = createBottomTabNavigator( }, { initialRouteName: 'ChatStack', + lazy: false, defaultNavigationOptions: { tabBarVisible: true, }, diff --git a/src/navigation/Root.js b/src/navigation/Root.js index 46cc6210..21601006 100644 --- a/src/navigation/Root.js +++ b/src/navigation/Root.js @@ -16,7 +16,7 @@ const RootNav = createStackNavigator( screen: MainStack, }, Chat: { - screen: ChatScreen, + screen: props => , path: '/chat/contact', }, ContactScanner: { @@ -35,6 +35,7 @@ const RootNav = createStackNavigator( {...props} {...compProps} title='Pairing QR code' + type='PAIRING_CODE' backRoute='ChatStack' /> ), @@ -56,6 +57,7 @@ const RootNav = createStackNavigator( {...props} {...compProps} title='Wallet QR code' + type='WALLET_ADDRESS' backRoute='WalletStack' /> ), diff --git a/src/navigation/service.js b/src/navigation/service.js index 7965f4aa..ccbf468b 100644 --- a/src/navigation/service.js +++ b/src/navigation/service.js @@ -1,4 +1,4 @@ -import { NavigationActions } from 'react-navigation'; +import { NavigationActions, StackActions } from 'react-navigation'; let _navigator; @@ -19,10 +19,23 @@ function back() { _navigator.dispatch(NavigationActions.back()); } -// add other navigation functions that you need and export them +function replace(routeName, params) { + _navigator.dispatch( + StackActions.replace({ + routeName, + params, + }), + ); +} + +function popToTop() { + _navigator.dispatch(StackActions.popToTop()); +} export default { navigate, back, + replace, + popToTop, setTopLevelNavigator, }; diff --git a/src/reducers/messages.js b/src/reducers/messages.js index d4dcd987..e273d543 100644 --- a/src/reducers/messages.js +++ b/src/reducers/messages.js @@ -68,6 +68,7 @@ function reducer(state = initialState, action) { pairingSecret: action.payload.pairingSecret, reversePairingSecret: action.payload.reversePairingSecret, visible: true, + walletAddress: null, messages: state.correspondents[action.payload.address]?.messages ?? [], }, @@ -81,11 +82,48 @@ function reducer(state = initialState, action) { ...state.correspondents, [action.payload.address]: { ...state.correspondents[action.payload.address], + walletAddress: null, visible: false, }, }, }; + case actionTypes.CORRESPONDENT_WALLET_ADDRESS_UPDATE: + return { + ...state, + correspondents: { + ...state.correspondents, + [action.payload.address]: { + ...state.correspondents[action.payload.address], + walletAddress: action.payload.walletAddress, + }, + }, + }; + + case actionTypes.CORRESPONDENT_NAME_SET: + return { + ...state, + correspondents: { + ...state.correspondents, + [action.payload.address]: { + ...state.correspondents[action.payload.address], + name: action.payload.name, + }, + }, + }; + + case actionTypes.CORRESPONDENT_CHAT_CLEAR: + return { + ...state, + correspondents: { + ...state.correspondents, + [action.payload.address]: { + ...state.correspondents[action.payload.address], + messages: [], + }, + }, + }; + default: return state; } diff --git a/src/reducers/wallet.js b/src/reducers/wallet.js index e0d1e5ee..3e75b04f 100644 --- a/src/reducers/wallet.js +++ b/src/reducers/wallet.js @@ -3,26 +3,29 @@ import { REHYDRATE } from 'redux-persist'; import { actionTypes } from '../constants'; const initialState = { - password: '', - seedWords: - 'wise pulp cruise wrap sunset run clap car budget key meadow diagram', + password: null, + seedWords: null, witnesses: [], + address: null, + addressPath: null, + walletWif: null, + addressWif: null, + xPrivKey: null, + publicKey: null, + privateKey: null, + walletPirvateKey: null, + walletPath: null, }; function reducer(state = initialState, action) { switch (action.type) { case REHYDRATE: - if (action.payload?.wallet) { - return action.payload.wallet; - } else { - return state; - } + return _.get(action, 'payload.wallet', state); case actionTypes.INITIAL_WALLET_CREATE_SUCCESS: return { ...state, - password: action.payload.password, - seedWords: action.payload.seedWords, + ...action.payload, }; case actionTypes.WITNESSES_GET_SUCCESS: diff --git a/src/sagas/device.js b/src/sagas/device.js index 41b787e0..2d5d38b5 100644 --- a/src/sagas/device.js +++ b/src/sagas/device.js @@ -6,11 +6,16 @@ import { put, select, all, + delay, } from '@redux-saga/core/effects'; import { channel } from '@redux-saga/core'; +import { isValidAddress } from 'obyte/lib/utils'; +import DeviceInfo from 'react-native-device-info'; +import Crypto from 'crypto'; import NavigationService from './../navigation/service'; import { actionTypes } from '../constants'; +import { REGEX_SIGNED_MESSAGE, REGEX_PAIRING } from './../lib/messaging'; import { sign, oClient, @@ -21,8 +26,16 @@ import { createEncryptedPackage, getDeviceMessageHashToSign, deliverMessage, + getSignedMessageInfoFromJsonBase64, + getDeviceAddress, } from './../lib/oCustom'; import { setToastMessage } from './../actions/app'; +import { + addCorrespondent, + removeCorrespondent, + updateCorrespondentWalletAddress, + setCorrespondentName, +} from '../actions/correspondents'; import { addMessageSuccess, addMessageFail, @@ -30,20 +43,22 @@ import { receiveMessageSuccess, receiveMessageFail, setUnreadMessages, - addCorrespondent, - removeCorrespondent, } from '../actions/messages'; import { setExchangeRates } from './../actions/exchangeRates'; +import { + selectCorrespondentByPairingSecret, + selectCorrespondent, +} from './../selectors/messages'; import { selectDeviceAddress, selectPermanentDeviceKeyObj, selectDeviceTempKeyData, } from './../selectors/device'; -import { selectCorrespondent } from '../selectors/messages'; let oChannel; if (!oChannel) { + console.log('oChannel init'); oChannel = channel(); } @@ -62,10 +77,12 @@ export function* loginToHub(challenge) { temp_pubkey: tempDeviceKeyData.pubB64, pubkey: permanentDeviceKey.pubB64, }; + objTempPubkey.signature = sign( getDeviceMessageHashToSign(objTempPubkey), permanentDeviceKey.priv, ); + oClient.api .tempPubkey(objTempPubkey) .then(result => console.log('Temp pubkey result:', result)) @@ -76,7 +93,6 @@ export function* loginToHub(challenge) { export function* subscribeToHub() { try { - console.log('subscribe'); yield oClient.subscribe((err, result) => { if (err) { throw new Error('Hub socket error'); @@ -85,22 +101,13 @@ export function* subscribeToHub() { oChannel.put({ type, payload }); } }); - const hb = yield call( - setInterval, - () => { - oClient.api.heartbeat(); - }, - 10000, - ); } catch (error) { - yield setTimeout(() => subscribeToHub(), 5000); yield put( setToastMessage({ type: 'ERROR', message: 'Hub connection error', }), ); - console.log(error); } } @@ -109,12 +116,12 @@ export function* watchHubMessages() { while (true) { const { type, payload } = yield take(oChannel); if (type === 'justsaying') { - if (payload.subject === 'hub/challenge') { + if (payload.subject === 'hub/challenge' && !!payload.body) { yield call(loginToHub, payload.body); } else if (payload.subject === 'hub/message') { - yield receiveMessage(payload); + yield call(receiveMessage, payload); } else if (payload.subject === 'exchange_rates') { - yield put(setExchangeRates(payload)); + yield put(setExchangeRates(payload.body)); } else if ( payload.subject === 'info' && /^(\d+) messages? sent$/.test(payload?.body) @@ -132,7 +139,7 @@ export function* watchHubMessages() { } } } catch (error) { - console.log(error); + console.log('UNHANDLED HUB MESSAGE ERROR', error); } } @@ -142,34 +149,90 @@ export function* receiveMessage(message) { const permDeviceKey = yield select(selectPermanentDeviceKeyObj()); try { - const decryptedMessage = decryptPackage( + const decryptedMessage = yield call( + decryptPackage, body.message.encrypted_package, permDeviceKey, tempDeviceKey, ); - console.log('ENCRYPTED MESSAGE: ', message); - console.log('DECRYPTED MESSAGE: ', decryptedMessage); if (decryptedMessage.subject === 'removed_paired_device') { yield put(removeCorrespondent({ address: decryptedMessage.from })); oClient.justsaying('hub/delete', body.message_hash); } else if (decryptedMessage.subject === 'pairing') { - const correspondent = { - address: decryptedMessage.from, - name: decryptedMessage.body.device_name, - hub: decryptedMessage.device_hub, - pubKey: body.message.pubkey, - pairingSecret: decryptedMessage.body.pairing_secret, - reversePairingSecret: decryptedMessage.body.reverse_pairing_secret, - }; - yield put(addCorrespondent(correspondent)); - yield call(NavigationService.back); - yield call(NavigationService.navigate, 'Chat', { - correspondent, - }); + console.log('Pairing'); + const existingCorrespondent = yield select( + selectCorrespondentByPairingSecret( + decryptedMessage.body.pairing_secret, + ), + ); + const reversePairingSecret = + decryptedMessage.body?.reverse_pairing_secret; + console.log('checks', existingCorrespondent, reversePairingSecret); + if (!reversePairingSecret && !existingCorrespondent) { + console.log('Correspondent started adding you'); + // Correspondent started adding you + const correspondent = { + address: decryptedMessage.from, + name: decryptedMessage.body.device_name, + hub: decryptedMessage.device_hub, + pubKey: body.message.pubkey, + pairingSecret: decryptedMessage.body.pairing_secret, + }; + yield put(addCorrespondent(correspondent)); + yield call(sendPairingMessage, { + reversePairingSecret, + hub: correspondent.hub, + address: correspondent.address, + pairingSecret: correspondent.pairingSecret, + recipientPubKey: body.message.pubkey, + }); + oClient.justsaying('hub/delete', body.message_hash); + } else if (!existingCorrespondent && reversePairingSecret) { + console.log('I send pairing confirmation'); + // I send pairing confirmation + const correspondent = { + address: decryptedMessage.from, + name: decryptedMessage.body.device_name, + hub: decryptedMessage.device_hub, + pubKey: body.message.pubkey, + pairingSecret: decryptedMessage.body.pairing_secret, + reversePairingSecret, + }; + yield put(addCorrespondent(correspondent)); + yield call(sendPairingMessage, { + reversePairingSecret, + hub: correspondent.hub, + address: correspondent.address, + pairingSecret: reversePairingSecret, + recipientPubKey: body.message.pubkey, + }); + oClient.justsaying('hub/delete', body.message_hash); + } else if ( + !reversePairingSecret && + existingCorrespondent?.reversePairingSecret === + decryptedMessage.body.pairing_secret + ) { + console.log('Correspondent sends pairing confirmation'); + // Correspondent sends pairing confirmation + yield put( + setCorrespondentName({ + address: decryptedMessage.from, + name: decryptedMessage.body.device_name ?? 'New', + }), + ); + } oClient.justsaying('hub/delete', body.message_hash); - // Navigate + const correspondent = yield select( + selectCorrespondent(decryptedMessage.from), + ); + if (!correspondent) { + console.error("Can't finish pairing, correspondent not stored"); + } } else if (decryptedMessage.subject === 'text') { + // Check if signed message with wallet address info + yield call(checkForSigning, decryptedMessage); + // Persist the message yield put( receiveMessageStart({ address: decryptedMessage.from, @@ -181,7 +244,9 @@ export function* receiveMessage(message) { timestamp: Date.now(), }), ); + oClient.justsaying('hub/delete', body.message_hash); } else if (decryptedMessage.subject === 'payment_notification') { + console.log('Payment notification', decryptedMessage); oClient.justsaying('hub/delete', body.message_hash); } } catch (error) { @@ -189,9 +254,7 @@ export function* receiveMessage(message) { error, message: message.body.message, }); - if (error === 'INVALID_DECRYPTION_KEY') { - oClient.justsaying('hub/delete', message.body.message_hash); - } + oClient.justsaying('hub/delete', message.body.message_hash); } } @@ -235,7 +298,7 @@ export function* sendMessage(action) { getDeviceMessageHashToSign(objDeviceMessage), myPermKeys.priv, ); - yield deliverMessage(objDeviceMessage); + yield call(deliverMessage, objDeviceMessage); yield put( addMessageSuccess({ message, @@ -258,7 +321,136 @@ export function* handleReceivedMessage(action) { oClient.justsaying('hub/delete', action.payload.messageHash); } catch (error) { yield put(receiveMessageFail()); - console.log('UNHANDLED ERROR: ', error); + } +} + +export function* acceptInvitation(action) { + let cDeviceAddress, cPubKey, cHub, pairingSecret; + const { data } = action.payload; + data.replace( + REGEX_PAIRING, + ( + str, + protocol, + correspondentPubKey, + correspondentHub, + correspondentPairingSecret, + ) => { + cDeviceAddress = getDeviceAddress(correspondentPubKey); + cPubKey = correspondentPubKey; + cHub = correspondentHub; + pairingSecret = correspondentPairingSecret; + }, + ); + + if (cDeviceAddress) { + const reversePairingSecret = Crypto.randomBytes(9).toString('base64'); + yield put( + addCorrespondent({ + hub: cHub, + pubKey: cPubKey, + pairingSecret, + reversePairingSecret, + address: cDeviceAddress, + name: 'New', + }), + ); + + yield call(sendPairingMessage, { + pairingSecret, + reversePairingSecret, + address: cDeviceAddress, + recipientPubKey: cPubKey, + hub: cHub, + }); + yield call(NavigationService.navigate, 'ChatList'); + } else { + yield put( + setToastMessage({ + type: 'ERROR', + message: 'Unable to accept invitation', + }), + ); + yield call(NavigationService.navifate, 'ChatList'); + } +} + +export function* checkForSigning(decryptedMessage) { + let walletAddress; + decryptedMessage.body.replace( + REGEX_SIGNED_MESSAGE, + (str, description, signedMessageBase64) => { + const info = getSignedMessageInfoFromJsonBase64(signedMessageBase64); + walletAddress = info.objSignedMessage.authors[0].address ?? null; + }, + ); + + if (isValidAddress(walletAddress)) { + yield put( + updateCorrespondentWalletAddress({ + address: decryptedMessage.from, + walletAddress, + }), + ); + } +} + +export function* sendPairingMessage({ + hub, + address, + pairingSecret, + reversePairingSecret, + recipientPubKey, +}) { + try { + const myPermKeys = yield select(selectPermanentDeviceKeyObj()); + const myDeviceAddress = yield select(selectDeviceAddress()); + const myDeviceName = yield call(DeviceInfo.getDeviceName); + + let body = { pairing_secret: pairingSecret, device_name: myDeviceName }; + if (reversePairingSecret) { + body.reverse_pairing_secret = reversePairingSecret; + } + + const packageObj = { + from: myDeviceAddress, + device_hub: hub, + subject: 'pairing', + body: body, + }; + + const encryptedPackage = createEncryptedPackage( + packageObj, + recipientPubKey, + ); + + const tempPubKeyData = yield getTempPubKey(recipientPubKey); + + const objEncryptedPackage = createEncryptedPackage( + packageObj, + tempPubKeyData.temp_pubkey, + ); + const objDeviceMessage = { + encrypted_package: objEncryptedPackage, + to: address, + pubkey: myPermKeys.pubB64, + }; + objDeviceMessage.signature = sign( + getDeviceMessageHashToSign(objDeviceMessage), + myPermKeys.priv, + ); + yield deliverMessage(objDeviceMessage); + } catch (e) { + console.log('sendPairingMessage failed', JSON.stringify(e)); + } +} + +// Deprecated, as reconnect option was introduced to obyte.js +export function* startHubHeartbeat() { + while (true) { + yield delay(10000); + yield call(oClient.api.heartbeat); + yield console.log('HB'); } } @@ -267,5 +459,6 @@ export default function* watch() { watchHubMessages(), takeEvery(actionTypes.MESSAGE_ADD_START, sendMessage), takeEvery(actionTypes.MESSAGE_RECEIVE_START, handleReceivedMessage), + takeEvery(actionTypes.CORRESPONDENT_INVITATION_ACCEPT, acceptInvitation), ]); } diff --git a/src/sagas/wallet.js b/src/sagas/wallet.js index f190e0a0..4b6cabf4 100644 --- a/src/sagas/wallet.js +++ b/src/sagas/wallet.js @@ -1,7 +1,9 @@ -import { takeLatest, call, put, select } from '@redux-saga/core/effects'; +import { takeLatest, take, call, put, select } from '@redux-saga/core/effects'; import Mnemonic from 'bitcore-mnemonic'; +import { toWif, getChash160 } from 'obyte/lib/utils'; +import { REHYDRATE } from 'redux-persist'; import NavigationService from './../navigation/service'; -import { oClient } from './../lib/oCustom'; +import { oClient, testnet } from './../lib/oCustom'; import { actionTypes } from './../constants'; import { subscribeToHub } from './device'; import { setToastMessage } from './../actions/app'; @@ -25,33 +27,23 @@ import { loadWalletBalancesFail, } from './../actions/balances'; import { - selectWallet, selectWalletAddress, selectWitnesses, selectAddressWif, } from './../selectors/wallet'; -let initiated = false; - export function* initWallet() { try { - console.log('reload', initiated); - if (!initiated) { - const walletData = yield select(selectWallet()); - if (walletData.password === null || walletData.seedWords === null) { - yield put(createInitialWalletStart()); - } - - // Handle websocket traffic - yield call(subscribeToHub); - // Fetch wallet data from hub - yield call(fetchBalances); - yield call(fetchWitnesses); - yield put(loadWalletHistory()); - yield put(initWalletSuccess()); - initiated = true; - } + yield put(createInitialWalletStart()); + // Handle websocket traffic + yield call(subscribeToHub); + // Fetch wallet data from hub + yield call(fetchBalances); + yield call(fetchWitnesses); + yield put(loadWalletHistory()); + yield put(initWalletSuccess()); } catch (error) { + console.log(error); yield put(initWalletFail()); yield put( setToastMessage({ @@ -59,26 +51,68 @@ export function* initWallet() { message: 'Unable to init wallet.', }), ); - console.log(error); } } export function* createInitialWallet(action) { + // Take two as we have two different persisted stores + const { payload: payload1 } = yield take(REHYDRATE); + const { payload: payload2 } = yield take(REHYDRATE); + const payload = { ...payload1, ...payload2 }; + try { - const password = ''; - let mnemonic = new Mnemonic(); - while (!Mnemonic.isValid(mnemonic.toString())) { - mnemonic = new Mnemonic(); - } + if (!payload?.wallet?.address) { + const password = ''; + let mnemonic = new Mnemonic(); + while (!Mnemonic.isValid(mnemonic.toString())) { + mnemonic = new Mnemonic(); + } + const xPrivKey = mnemonic.toHDPrivateKey(); - yield put( - createInitialWalletSuccess({ - password, - seedWords: mnemonic.phrase, - }), - ); + // Wallet wif + const walletPath = testnet ? "m/44'/1'/0'/0'" : "m/44'/0'/0'/0"; + const { privateKey: walletPirvateKey } = yield xPrivKey.derive( + walletPath, + ); + const walletPrivKeyBuf = yield walletPirvateKey.bn.toBuffer({ + size: 32, + }); + const walletWif = yield call(toWif, walletPrivKeyBuf, testnet); + + // Address and address wif + const addressPath = testnet ? "m/44'/1'/0'/0/0" : "m/44'/0'/0'/0/0"; + const { privateKey } = yield xPrivKey.derive(addressPath); + const publicKeyBuffer = yield privateKey.publicKey.toBuffer(); + const publicKey = yield publicKeyBuffer.toString('base64'); + const addressPrivKeyBuf = yield privateKey.bn.toBuffer({ size: 32 }); + const addressWif = yield call(toWif, addressPrivKeyBuf, testnet); + const address = yield call(getChash160, ['sig', { pubkey: publicKey }]); + + yield put( + createInitialWalletSuccess({ + password, + address, + addressPath, + walletWif, + addressWif, + xPrivKey, + publicKey, + privateKey, + walletPirvateKey, + walletPath, + seedWords: mnemonic.phrase, + }), + ); + + yield put( + setToastMessage({ + type: 'SUCCESS', + message: 'Your wallet is ready to use!', + }), + ); + } } catch (error) { - console.log(error); + console.log('createInitialWallet ERROR: ', error); yield put(createInitialWalletFail()); yield put( setToastMessage({ @@ -90,20 +124,20 @@ export function* createInitialWallet(action) { } export function* fetchBalances(action) { - try { - const walletAddress = yield select(selectWalletAddress()); - console.log('WALLET ADDRESS: ', walletAddress); - const balances = yield call(oClient.api.getBalances, [walletAddress]); - yield put(loadWalletBalancesSuccess(balances)); - } catch (error) { - yield put(loadWalletBalancesFail()); - yield put( - setToastMessage({ - type: 'ERROR', - message: 'Unable to fetch balances.', - }), - ); - console.log(error); + const walletAddress = yield select(selectWalletAddress()); + if (walletAddress) { + try { + const balances = yield call(oClient.api.getBalances, [walletAddress]); + yield put(loadWalletBalancesSuccess(balances)); + } catch (error) { + yield put(loadWalletBalancesFail()); + yield put( + setToastMessage({ + type: 'ERROR', + message: 'Unable to fetch balances.', + }), + ); + } } } @@ -121,53 +155,54 @@ export function* fetchWitnesses(action) { const witnesses = yield witnessesPromise; yield put(getWitnessesSuccess(witnesses)); } catch (error) { - console.log({ error }); + // console.log({ error }); } } export function* fetchWalletHistory(action) { - try { - const witnesses = yield select(selectWitnesses()); - const walletAddress = yield select(selectWalletAddress()); - const params = { - witnesses: witnesses, - addresses: [walletAddress], - }; + const walletAddress = yield select(selectWalletAddress()); + if (walletAddress) { + try { + const witnesses = yield select(selectWitnesses()); + const params = { + witnesses: witnesses, + addresses: [walletAddress], + }; - const historyPromise = new Promise((resolve, reject) => - oClient.api.getHistory(params, (err, history) => { - if (err) { - reject(err); - } else { - resolve(history); - } - }), - ); - const history = yield historyPromise; - yield put(loadWalletHistorySuccess(history)); - } catch (error) { - yield put(loadWalletHistoryFail()); - yield put( - setToastMessage({ - type: 'ERROR', - message: 'Unable to fetch transactions.', - }), - ); - console.log({ error }); + const historyPromise = new Promise((resolve, reject) => + oClient.api.getHistory(params, (err, history) => { + if (err) { + reject(err); + } else { + resolve(history); + } + }), + ); + const history = yield historyPromise; + yield put(loadWalletHistorySuccess(history)); + } catch (error) { + yield put(loadWalletHistoryFail()); + yield put( + setToastMessage({ + type: 'ERROR', + message: 'Unable to fetch transactions.', + }), + ); + } } } export function* sendPayment(action) { try { - const walletWif = yield select(selectAddressWif()); + const addressWif = yield select(selectAddressWif()); const params = { ...action.payload, }; - yield call(oClient.post.payment, params, walletWif); + yield call(oClient.post.payment, params, addressWif); yield call(fetchBalances, action); yield call(fetchWalletHistory, action); - yield call(NavigationService.back); + yield call(NavigationService.navigate, 'Wallet'); yield put(sendPaymentSuccess()); yield put( setToastMessage({ @@ -183,7 +218,6 @@ export function* sendPayment(action) { message: 'Unable to send payment', }), ); - console.log({ error }); } } diff --git a/src/screens/ChatListScreen/ActionsBar.js b/src/screens/ChatListScreen/ActionsBar.js index f1498d21..97e2da2e 100644 --- a/src/screens/ChatListScreen/ActionsBar.js +++ b/src/screens/ChatListScreen/ActionsBar.js @@ -35,7 +35,7 @@ class ActionsBar extends React.Component { style={styles.iconButton} onPress={() => this.props.navigation.navigate('MyQR', { - qrData: `${urlHost}${this._getPairingCode()}`, + qrData: this._getPairingCode(), }) } > diff --git a/src/screens/ChatListScreen/index.js b/src/screens/ChatListScreen/index.js index cd938b0a..f385ecb7 100644 --- a/src/screens/ChatListScreen/index.js +++ b/src/screens/ChatListScreen/index.js @@ -1,21 +1,48 @@ import React from 'react'; import { connect } from 'react-redux'; import { createStructuredSelector } from 'reselect'; -import { ScrollView } from 'react-native'; +import { ScrollView, View, TextInput } from 'react-native'; import TimeAgo from 'react-native-timeago'; import UserAvatar from 'react-native-user-avatar'; import makeBlockie from 'ethereum-blockies-base64'; import SafeAreaView from 'react-native-safe-area-view'; import { List, ListItem, Left, Right, Body, Text } from 'native-base'; +import Dialog from 'react-native-dialog'; +import { setCorrespondentName } from '../../actions/correspondents'; import { selectCorrespondents } from '../../selectors/messages'; import styles from './styles'; import ActionsBar from './ActionsBar'; import Header from '../../components/Header'; class ChatListScreen extends React.Component { + constructor(props) { + super(props); + + this.changeContactName = this.changeContactName.bind(this); + this.state = { + changeNameDialog: { + visible: false, + correspondent: {}, + }, + }; + } + + changeContactName(e) { + const { name, address } = this.state.changeNameDialog.correspondent; + this.props.setCorrespondentName({ name, address }); + this.setState({ + changeNameDialog: { + visible: false, + correspondent: {}, + }, + }); + } + render() { const { correspondents } = this.props; + const { changeNameDialog } = this.state; + return ( } /> - - - {correspondents.map((correspondent, i) => ( - - this.props.navigation.navigate('Chat', { - correspondent, - }) - } - > - - - - - - {correspondent.name} - - - {correspondent.lastMessagePreview} - - - - - {correspondent.lastMessageTimestamp !== undefined && ( - - )} - - - - ))} - - + {!correspondents.length && ( + + + Start adding contacts by sharing your QR code or scanning someone + else's! + + + )} + {!!correspondents.length && ( + + + {correspondents.map((correspondent, i) => ( + + this.props.navigation.navigate('Chat', { + correspondent, + }) + } + onLongPress={() => { + this.setState({ + changeNameDialog: { + ...changeNameDialog, + correspondent, + visible: true, + }, + }); + }} + > + + + + + + {correspondent.name} + + + {correspondent.lastMessagePreview} + + + + + {correspondent.lastMessageTimestamp !== undefined && ( + + )} + + + + ))} + + + )} + + Change contact name + + this.setState({ + changeNameDialog: { + ...changeNameDialog, + correspondent: { ...changeNameDialog.correspondent, name }, + }, + }) + } + value={changeNameDialog.correspondent.name} + /> + + this.setState({ + changeNameDialog: { ...changeNameDialog, visible: false }, + }) + } + /> + + ); } @@ -78,7 +148,10 @@ const mapStateToProps = createStructuredSelector({ correspondents: selectCorrespondents(), }); -const mapDispatchToProps = dispatch => ({}); +const mapDispatchToProps = dispatch => ({ + setCorrespondentName: ({ name, address }) => + dispatch(setCorrespondentName({ address, name })), +}); ChatListScreen = connect(mapStateToProps, mapDispatchToProps)(ChatListScreen); export default ChatListScreen; diff --git a/src/screens/ChatListScreen/styles.js b/src/screens/ChatListScreen/styles.js index 4ccb82f8..095888f7 100644 --- a/src/screens/ChatListScreen/styles.js +++ b/src/screens/ChatListScreen/styles.js @@ -45,4 +45,28 @@ export default StyleSheet.create({ actionsBar: { flexDirection: 'row', }, + noContactsContainer: { + flex: 1, + padding: 10, + flexDirection: 'column', + justifyContent: 'center', + }, + noContactsText: { + color: colors.grey.main, + justifyContent: 'center', + textAlign: 'center', + fontFamily: 'Agenda-Light', + fontSize: 16, + }, + changeNameDialogInput: { + alignSelf: 'stretch', + padding: 10, + marginTop: 10, + marginBottom: 10, + color: colors.grey.dark, + height: 40, + fontSize: 15, + backgroundColor: colors.grey.lightest, + textAlign: 'center', + }, }); diff --git a/src/screens/ChatScreen/ActionsBar.js b/src/screens/ChatScreen/ActionsBar.js index bb4bf3be..5d8ae770 100644 --- a/src/screens/ChatScreen/ActionsBar.js +++ b/src/screens/ChatScreen/ActionsBar.js @@ -1,5 +1,5 @@ import React, { useRef, useCallback } from 'react'; -import { View, TouchableOpacity } from 'react-native'; +import { Alert, View, TouchableOpacity } from 'react-native'; import ActionSheet from 'react-native-actionsheet'; import UserAvatar from 'react-native-user-avatar'; import makeBlockie from 'ethereum-blockies-base64'; @@ -11,20 +11,66 @@ import styles from './styles'; const ActionsBar = ({ navigation, - onRequestPayment, - onSendPayment, onSend, - address, + clearChatHistory, + removeCorrespondent, myWalletAddress, + correspondentWalletAddress, + correspondentAddress, }) => { const actionSheet = useRef(); + const handleClearChat = useCallback(() => { + Alert.alert( + 'Clear chat history', + 'Are you sure?', + [ + { + text: 'No', + style: 'cancel', + }, + { + text: 'Yes', + onPress: () => clearChatHistory(correspondentAddress), + }, + ], + { cancelable: false }, + ); + }, [clearChatHistory, correspondentAddress]); + + const handleDeleteContact = useCallback(() => { + Alert.alert( + 'Delete contact', + 'Are you sure?', + [ + { + text: 'No', + style: 'cancel', + }, + { + text: 'Yes', + onPress: () => { + removeCorrespondent(correspondentAddress); + navigation.navigate('ChatList'); + }, + }, + ], + { cancelable: false }, + ); + }, [correspondentAddress]); + const handleActionPress = useCallback( index => { switch (index) { case 0: onSend([{ text: myWalletAddress }]); break; + case 1: + handleClearChat(); + break; + case 2: + handleDeleteContact(); + break; default: } }, @@ -37,22 +83,57 @@ const ActionsBar = ({ } }, []); + const handleRequestPayment = useCallback(() => { + navigation.navigate('RequestPayment', { + walletAddress: myWalletAddress, + callback: text => { + onSend([{ text }]); + }, + }); + }, [myWalletAddress, navigation]); + + const handleSendPayment = useCallback(() => { + if (!correspondentWalletAddress) { + Alert.alert( + '', + "You don't know their wallet address yet. Do you want to ask for it?", + [ + { + text: 'No', + style: 'cancel', + }, + { + text: 'Yes', + onPress: () => + onSend([ + { + text: + '[Data request](sign-message-request:Requesting wallet address to send payment)', + }, + ]), + }, + ], + { cancelable: false }, + ); + } else { + navigation.navigate('MakePayment', { + walletAddress: correspondentWalletAddress, + }); + } + }, [Alert, correspondentWalletAddress, navigation]); + return ( - navigation.navigate('RequestPayment', { - walletAddress: myWalletAddress, - callback: text => { - onRequestPayment([{ text }]); - }, - }) - } + onPress={handleRequestPayment} > - + diff --git a/src/screens/ChatScreen/index.js b/src/screens/ChatScreen/index.js index 50c75163..d0fe5b63 100644 --- a/src/screens/ChatScreen/index.js +++ b/src/screens/ChatScreen/index.js @@ -1,17 +1,22 @@ import React from 'react'; import { connect } from 'react-redux'; import { createStructuredSelector } from 'reselect'; -import { TouchableOpacity, Text, Clipboard } from 'react-native'; +import { TouchableOpacity, Text, Clipboard, Alert } from 'react-native'; import SafeAreaView from 'react-native-safe-area-view'; import { GiftedChat } from 'react-native-gifted-chat'; - import _ from 'lodash'; import styles from './styles'; +import { signMessage } from '../../lib/oCustom'; +import { parseTextMessage } from '../../lib/messaging'; import { addMessageStart, removeMessage } from '../../actions/messages'; +import { + clearChatHistory, + removeCorrespondent, +} from '../../actions/correspondents'; import { selectCorrespondentMessages } from '../../selectors/messages'; import { selectWalletAddress } from '../../selectors/wallet'; -import { parseTextMessage } from '../../lib/messaging'; +import { selectCorrespondentWalletAddress } from '../../selectors/messages'; import ActionsBar from './ActionsBar'; import Header from '../../components/Header'; @@ -19,6 +24,7 @@ class ChatScreen extends React.Component { constructor(props) { super(props); this.onSend = this.onSend.bind(this); + this.renderText = this.renderText.bind(this); this.onLoadEarlier = this.onLoadEarlier.bind(this); this.renderChat = this.renderChat.bind(this); this.state = { @@ -47,22 +53,59 @@ class ChatScreen extends React.Component { renderText(props) { const { text, user } = props.currentMessage; - const { parsedText } = parseTextMessage(text); + const { parsedText, type, params } = parseTextMessage(text); let style = { ...styles.textMessage }; + let pressAction = () => {}; + + if (type) { + style = { ...style, ...styles.actionMessage }; + } if (user._id === 1) { style = { ...style, ...styles.textMessageSent }; + } else { + if (type === 'SIGN_MESSAGE_REQUEST') { + pressAction = () => { + Alert.alert('Do you want to sign this message?', '', [ + { text: 'No', style: 'cancel' }, + { + text: 'Yes', + onPress: () => { + const signedMessage = signMessage( + params.messageToSign, + this.props.myWalletAddress, + ); + this.onSend([{ text: signedMessage }]); + }, + }, + ]); + }; + } } - return ( - { - Clipboard.setString(parsedText); - }} - > - {parsedText} - - ); + if (type) { + return ( + { + Clipboard.setString(parsedText); + }} + > + {parsedText} + + ); + } else { + return ( + { + Clipboard.setString(parsedText); + }} + > + {parsedText} + + ); + } } renderChat() { @@ -86,8 +129,8 @@ class ChatScreen extends React.Component { } render() { - const { navigation } = this.props; - const { name } = _.get(this.props.navigation, 'state.params.correspondent'); + const { navigation, backRoute } = this.props; + const correspondent = _.get(navigation, 'state.params.correspondent'); return ( alert('TODO')} + removeCorrespondent={this.props.removeCorrespondent} onSend={this.onSend} + correspondentWalletAddress={this.props.correspondentWalletAddress} + correspondentAddress={correspondent.address} /> } navigation={navigation} @@ -119,6 +164,9 @@ class ChatScreen extends React.Component { const mapStateToProps = (state, props) => createStructuredSelector({ myWalletAddress: selectWalletAddress(), + correspondentWalletAddress: selectCorrespondentWalletAddress( + props.navigation.state.params.correspondent.address, + ), messages: selectCorrespondentMessages({ address: props.navigation.state.params.correspondent.address, }), @@ -127,6 +175,8 @@ const mapStateToProps = (state, props) => const mapDispatchToProps = dispatch => ({ addMessageStart: payload => dispatch(addMessageStart(payload)), removeMessage: payload => dispatch(removeMessage(payload)), + removeCorrespondent: address => dispatch(removeCorrespondent({ address })), + clearChatHistory: address => dispatch(clearChatHistory({ address })), }); ChatScreen = connect(mapStateToProps, mapDispatchToProps)(ChatScreen); diff --git a/src/screens/ChatScreen/styles.js b/src/screens/ChatScreen/styles.js index 5a6dae0e..b25f3743 100644 --- a/src/screens/ChatScreen/styles.js +++ b/src/screens/ChatScreen/styles.js @@ -107,13 +107,13 @@ export default StyleSheet.create({ marginTop: 10, marginBottom: 5, fontFamily: 'Lato-Regular', - fontSize: 16, + fontSize: 13, color: colors.black, }, + actionMessage: { + fontStyle: 'italic', + }, textMessageSent: { color: colors.white, }, - textMessageActionable: { - color: colors.cyan.main, - }, }); diff --git a/src/screens/LoadingScreen/index.js b/src/screens/LoadingScreen/index.js new file mode 100644 index 00000000..775c5995 --- /dev/null +++ b/src/screens/LoadingScreen/index.js @@ -0,0 +1,49 @@ +import React, { useRef, useEffect } from 'react'; +import PropTypes from 'prop-types'; +import { View, Text, Image, Animated } from 'react-native'; +import _ from 'lodash'; +import SafeAreaView from 'react-native-safe-area-view'; +import styles from './styles'; + +const LoadingScreen = ({ messages = [] }) => { + const loadingAnimationValue = useRef(new Animated.Value(0)).current; + + useEffect(() => { + Animated.loop( + Animated.sequence([ + Animated.timing(loadingAnimationValue, { + toValue: 1, + duration: 1000, + }), + Animated.timing(loadingAnimationValue, { + toValue: 0, + duration: 1000, + }), + ]), + ).start(); + }, [loadingAnimationValue]); + + return ( + + + + {messages.map(message => ( + {message} + ))} + + + ); +}; + +LoadingScreen.propTypes = { + messages: PropTypes.array, +}; + +export default LoadingScreen; diff --git a/src/screens/LoadingScreen/styles.js b/src/screens/LoadingScreen/styles.js new file mode 100644 index 00000000..4ba3adc3 --- /dev/null +++ b/src/screens/LoadingScreen/styles.js @@ -0,0 +1,19 @@ +import { StyleSheet } from 'react-native'; +import { colors } from '../../constants'; + +export default StyleSheet.create({ + container: { + backgroundColor: colors.white, + flex: 1, + }, + content: { + alignItems: 'center', + justifyContent: 'center', + flexDirection: 'column', + flex: 1, + }, + logo: { + width: 150, + height: 150, + }, +}); diff --git a/src/screens/PaymentScreen/index.js b/src/screens/PaymentScreen/index.js index 72f4cb9e..7d644a80 100644 --- a/src/screens/PaymentScreen/index.js +++ b/src/screens/PaymentScreen/index.js @@ -9,7 +9,6 @@ import { View, Text, } from 'react-native'; -import RNPickerSelect from 'react-native-picker-select'; import CopyIcon from './../../assets/images/icon-copy.svg'; import SafeAreaView from 'react-native-safe-area-view'; import _ from 'lodash'; @@ -17,13 +16,14 @@ import { isValidAddress } from 'obyte/lib/utils'; import Header from '../../components/Header'; import Button from '../../components/Button'; +import ActionSheet from '../../components/ActionSheet'; import styles from './styles'; import { colors } from '../../constants'; import { TouchableOpacity } from 'react-native-gesture-handler'; import { selectExchangeRates } from './../../selectors/exchangeRates'; import { selectWalletAddress } from './../../selectors/wallet'; import { sendPaymentStart } from './../../actions/wallet'; -import { availableUnits, unitToBytes } from './../../lib/utils'; +import { PRIMARY_UNITS, SECONDARY_UNITS, unitToBytes } from './../../lib/utils'; import { urlHost } from './../../lib/oCustom'; export const Methods = { @@ -110,8 +110,14 @@ class PaymentScreen extends React.Component { } this.setState({ - primaryValue: type === 'primary' ? value : primaryValue, - secondaryValue: type === 'secondary' ? value : secondaryValue, + primaryValue: + type === 'primary' ? value : !isNaN(primaryValue) ? primaryValue : 0, + secondaryValue: + type === 'secondary' + ? value + : !isNaN(secondaryValue) + ? secondaryValue + : 0, }); } @@ -179,7 +185,6 @@ class PaymentScreen extends React.Component { 'navigation.state.params.callback', false, ); - // TODO: finish the string const requestString = `[${this.state.primaryValue} ${ this.state.primaryUnit }](${urlHost}${this.props.myWalletAddress}?amount=${unitToBytes( @@ -233,7 +238,7 @@ class PaymentScreen extends React.Component { return (
- this.changePrimaryUnit(value)} - items={availableUnits.map(unit => ({ - label: unit.label, - value: unit.altValue, + this.changePrimaryUnit(value)} + items={PRIMARY_UNITS.map(({ label, altValue }) => ({ + label, + value: altValue, }))} /> @@ -307,13 +311,13 @@ class PaymentScreen extends React.Component { value={!secondaryValue ? '' : String(secondaryValue)} keyboardType='decimal-pad' /> - this.changeSecondaryUnit(value)} - items={[ - { label: 'USD', value: 'USD' }, - { label: 'BTC', value: 'BTC' }, - ]} + this.changeSecondaryUnit(value)} + items={SECONDARY_UNITS.map(({ label, altValue }) => ({ + label, + value: altValue, + }))} />