mirror of
https://github.com/zhigang1992/react-native-chat-ui.git
synced 2026-01-12 22:50:15 +08:00
Feature/refactor (#1)
* Refactor types * Refactor messages * Add image preview * Use Context API * Update dependencies * Add tests
This commit is contained in:
@@ -20,7 +20,7 @@ import com.android.build.OutputFile
|
||||
* // default. Can be overridden with ENTRY_FILE environment variable.
|
||||
* entryFile: "index.android.js",
|
||||
*
|
||||
* // https://facebook.github.io/react-native/docs/performance#enable-the-ram-format
|
||||
* // https://reactnative.dev/docs/performance#enable-the-ram-format
|
||||
* bundleCommand: "ram-bundle",
|
||||
*
|
||||
* // whether to bundle JS and assets in debug mode
|
||||
@@ -78,7 +78,7 @@ import com.android.build.OutputFile
|
||||
*/
|
||||
|
||||
project.ext.react = [
|
||||
enableHermes: false, // clean and rebuild if changing
|
||||
enableHermes: false, // clean and rebuild if changing
|
||||
]
|
||||
|
||||
apply from: "../../node_modules/react-native/react.gradle"
|
||||
@@ -157,20 +157,13 @@ android {
|
||||
}
|
||||
release {
|
||||
// Caution! In production, you need to generate your own keystore file.
|
||||
// see https://facebook.github.io/react-native/docs/signed-apk-android.
|
||||
// see https://reactnative.dev/docs/signed-apk-android.
|
||||
signingConfig signingConfigs.debug
|
||||
minifyEnabled enableProguardInReleaseBuilds
|
||||
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
||||
}
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
pickFirst "lib/armeabi-v7a/libc++_shared.so"
|
||||
pickFirst "lib/arm64-v8a/libc++_shared.so"
|
||||
pickFirst "lib/x86/libc++_shared.so"
|
||||
pickFirst "lib/x86_64/libc++_shared.so"
|
||||
}
|
||||
|
||||
// applicationVariants are e.g. debug, release
|
||||
applicationVariants.all { variant ->
|
||||
variant.outputs.each { output ->
|
||||
@@ -192,19 +185,20 @@ dependencies {
|
||||
//noinspection GradleDynamicVersion
|
||||
implementation "com.facebook.react:react-native:+" // From node_modules
|
||||
|
||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
|
||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
|
||||
|
||||
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
|
||||
exclude group:'com.facebook.fbjni'
|
||||
}
|
||||
|
||||
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
|
||||
exclude group:'com.facebook.flipper'
|
||||
}
|
||||
|
||||
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
|
||||
exclude group:'com.facebook.flipper'
|
||||
}
|
||||
exclude group: 'com.facebook.fbjni'
|
||||
}
|
||||
|
||||
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
|
||||
exclude group: 'com.facebook.flipper'
|
||||
exclude group: 'com.squareup.okhttp3', module: 'okhttp'
|
||||
}
|
||||
|
||||
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
|
||||
exclude group: 'com.facebook.flipper'
|
||||
}
|
||||
|
||||
if (enableHermes) {
|
||||
def hermesPath = "../../node_modules/hermes-engine/android/";
|
||||
|
||||
@@ -12,7 +12,7 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath('com.android.tools.build:gradle:3.6.2')
|
||||
classpath('com.android.tools.build:gradle:4.0.1')
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
||||
@@ -25,4 +25,4 @@ android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
|
||||
# Version of flipper SDK to use with React Native
|
||||
FLIPPER_VERSION=0.37.0
|
||||
FLIPPER_VERSION=0.39.0
|
||||
|
||||
BIN
example/android/gradle/wrapper/gradle-wrapper.jar
vendored
BIN
example/android/gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
29
example/android/gradlew
vendored
29
example/android/gradlew
vendored
@@ -154,19 +154,19 @@ if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
@@ -175,14 +175,9 @@ save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
3
example/android/gradlew.bat
vendored
3
example/android/gradlew.bat
vendored
@@ -29,6 +29,9 @@ if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
|
||||
@@ -1,90 +1,18 @@
|
||||
platform :ios, '9.0'
|
||||
require_relative '../node_modules/react-native/scripts/react_native_pods'
|
||||
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
|
||||
|
||||
def add_flipper_pods!(versions = {})
|
||||
versions['Flipper'] ||= '~> 0.37.0'
|
||||
versions['DoubleConversion'] ||= '1.1.7'
|
||||
versions['Flipper-Folly'] ||= '~> 2.2'
|
||||
versions['Flipper-Glog'] ||= '0.3.6'
|
||||
versions['Flipper-PeerTalk'] ||= '~> 0.0.4'
|
||||
versions['Flipper-RSocket'] ||= '~> 1.1'
|
||||
|
||||
pod 'FlipperKit', versions['Flipper'], :configuration => 'Debug'
|
||||
pod 'FlipperKit/FlipperKitLayoutComponentKitSupport', versions['Flipper'], :configuration => 'Debug'
|
||||
pod 'FlipperKit/FlipperKitLayoutPlugin', versions['Flipper'], :configuration => 'Debug'
|
||||
pod 'FlipperKit/SKIOSNetworkPlugin', versions['Flipper'], :configuration => 'Debug'
|
||||
pod 'FlipperKit/FlipperKitUserDefaultsPlugin', versions['Flipper'], :configuration => 'Debug'
|
||||
pod 'FlipperKit/FlipperKitReactPlugin', versions['Flipper'], :configuration => 'Debug'
|
||||
|
||||
# List all transitive dependencies for FlipperKit pods
|
||||
# to avoid them being linked in Release builds
|
||||
pod 'Flipper', versions['Flipper'], :configuration => 'Debug'
|
||||
pod 'Flipper-DoubleConversion', versions['DoubleConversion'], :configuration => 'Debug'
|
||||
pod 'Flipper-Folly', versions['Flipper-Folly'], :configuration => 'Debug'
|
||||
pod 'Flipper-Glog', versions['Flipper-Glog'], :configuration => 'Debug'
|
||||
pod 'Flipper-PeerTalk', versions['Flipper-PeerTalk'], :configuration => 'Debug'
|
||||
pod 'Flipper-RSocket', versions['Flipper-RSocket'], :configuration => 'Debug'
|
||||
pod 'FlipperKit/Core', versions['Flipper'], :configuration => 'Debug'
|
||||
pod 'FlipperKit/CppBridge', versions['Flipper'], :configuration => 'Debug'
|
||||
pod 'FlipperKit/FBCxxFollyDynamicConvert', versions['Flipper'], :configuration => 'Debug'
|
||||
pod 'FlipperKit/FBDefines', versions['Flipper'], :configuration => 'Debug'
|
||||
pod 'FlipperKit/FKPortForwarding', versions['Flipper'], :configuration => 'Debug'
|
||||
pod 'FlipperKit/FlipperKitHighlightOverlay', versions['Flipper'], :configuration => 'Debug'
|
||||
pod 'FlipperKit/FlipperKitLayoutTextSearchable', versions['Flipper'], :configuration => 'Debug'
|
||||
pod 'FlipperKit/FlipperKitNetworkPlugin', versions['Flipper'], :configuration => 'Debug'
|
||||
end
|
||||
|
||||
# Post Install processing for Flipper
|
||||
def flipper_post_install(installer)
|
||||
installer.pods_project.targets.each do |target|
|
||||
if target.name == 'YogaKit'
|
||||
target.build_configurations.each do |config|
|
||||
config.build_settings['SWIFT_VERSION'] = '4.1'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
platform :ios, '10.0'
|
||||
|
||||
target 'example' do
|
||||
# Pods for example
|
||||
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"
|
||||
pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety"
|
||||
pod 'React', :path => '../node_modules/react-native/'
|
||||
pod 'React-Core', :path => '../node_modules/react-native/'
|
||||
pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'
|
||||
pod 'React-Core/DevSupport', :path => '../node_modules/react-native/'
|
||||
pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
|
||||
pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
|
||||
pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
|
||||
pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
|
||||
pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
|
||||
pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
|
||||
pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
|
||||
pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
|
||||
pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
|
||||
pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/'
|
||||
config = use_native_modules!
|
||||
|
||||
pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
|
||||
pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
|
||||
pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
|
||||
pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
|
||||
pod 'ReactCommon/callinvoker', :path => "../node_modules/react-native/ReactCommon"
|
||||
pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
|
||||
pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga', :modular_headers => true
|
||||
|
||||
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
|
||||
pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
|
||||
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
|
||||
|
||||
use_native_modules!
|
||||
use_react_native!(:path => config["reactNativePath"])
|
||||
|
||||
# Enables Flipper.
|
||||
#
|
||||
# Note that if you have use_frameworks! enabled, Flipper will not work and
|
||||
# you should disable these next few lines.
|
||||
add_flipper_pods!
|
||||
use_flipper!
|
||||
post_install do |installer|
|
||||
flipper_post_install(installer)
|
||||
end
|
||||
|
||||
@@ -2,19 +2,16 @@ PODS:
|
||||
- boost-for-react-native (1.63.0)
|
||||
- CocoaAsyncSocket (7.6.4)
|
||||
- CocoaLibEvent (1.0.0)
|
||||
- ComponentKit (0.30):
|
||||
- RenderCore (= 0.30)
|
||||
- Yoga (~> 1.14)
|
||||
- DoubleConversion (1.1.6)
|
||||
- FBLazyVector (0.62.2)
|
||||
- FBReactNativeSpec (0.62.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- RCTRequired (= 0.62.2)
|
||||
- RCTTypeSafety (= 0.62.2)
|
||||
- React-Core (= 0.62.2)
|
||||
- React-jsi (= 0.62.2)
|
||||
- ReactCommon/turbomodule/core (= 0.62.2)
|
||||
- Flipper (0.37.0):
|
||||
- FBLazyVector (0.63.2)
|
||||
- FBReactNativeSpec (0.63.2):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- RCTRequired (= 0.63.2)
|
||||
- RCTTypeSafety (= 0.63.2)
|
||||
- React-Core (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- ReactCommon/turbomodule/core (= 0.63.2)
|
||||
- Flipper (0.41.5):
|
||||
- Flipper-Folly (~> 2.2)
|
||||
- Flipper-RSocket (~> 1.1)
|
||||
- Flipper-DoubleConversion (1.1.7)
|
||||
@@ -28,50 +25,44 @@ PODS:
|
||||
- Flipper-PeerTalk (0.0.4)
|
||||
- Flipper-RSocket (1.1.0):
|
||||
- Flipper-Folly (~> 2.2)
|
||||
- FlipperKit (0.37.0):
|
||||
- FlipperKit/Core (= 0.37.0)
|
||||
- FlipperKit/Core (0.37.0):
|
||||
- Flipper (~> 0.37.0)
|
||||
- FlipperKit (0.41.5):
|
||||
- FlipperKit/Core (= 0.41.5)
|
||||
- FlipperKit/Core (0.41.5):
|
||||
- Flipper (~> 0.41.5)
|
||||
- FlipperKit/CppBridge
|
||||
- FlipperKit/FBCxxFollyDynamicConvert
|
||||
- FlipperKit/FBDefines
|
||||
- FlipperKit/FKPortForwarding
|
||||
- FlipperKit/CppBridge (0.37.0):
|
||||
- Flipper (~> 0.37.0)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (0.37.0):
|
||||
- FlipperKit/CppBridge (0.41.5):
|
||||
- Flipper (~> 0.41.5)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (0.41.5):
|
||||
- Flipper-Folly (~> 2.2)
|
||||
- FlipperKit/FBDefines (0.37.0)
|
||||
- FlipperKit/FKPortForwarding (0.37.0):
|
||||
- FlipperKit/FBDefines (0.41.5)
|
||||
- FlipperKit/FKPortForwarding (0.41.5):
|
||||
- CocoaAsyncSocket (~> 7.6)
|
||||
- Flipper-PeerTalk (~> 0.0.4)
|
||||
- FlipperKit/FlipperKitHighlightOverlay (0.37.0)
|
||||
- FlipperKit/FlipperKitLayoutComponentKitSupport (0.37.0):
|
||||
- ComponentKit (~> 0.0)
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutPlugin
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable
|
||||
- FlipperKit/FlipperKitLayoutPlugin (0.37.0):
|
||||
- FlipperKit/FlipperKitHighlightOverlay (0.41.5)
|
||||
- FlipperKit/FlipperKitLayoutPlugin (0.41.5):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable
|
||||
- YogaKit (~> 1.18)
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (0.37.0)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (0.37.0):
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (0.41.5)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (0.41.5):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitReactPlugin (0.37.0):
|
||||
- FlipperKit/FlipperKitReactPlugin (0.41.5):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (0.37.0):
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (0.41.5):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/SKIOSNetworkPlugin (0.37.0):
|
||||
- FlipperKit/SKIOSNetworkPlugin (0.41.5):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitNetworkPlugin
|
||||
- Folly (2018.10.22.00):
|
||||
- Folly (2020.01.13.00):
|
||||
- boost-for-react-native
|
||||
- DoubleConversion
|
||||
- Folly/Default (= 2018.10.22.00)
|
||||
- Folly/Default (= 2020.01.13.00)
|
||||
- glog
|
||||
- Folly/Default (2018.10.22.00):
|
||||
- Folly/Default (2020.01.13.00):
|
||||
- boost-for-react-native
|
||||
- DoubleConversion
|
||||
- glog
|
||||
@@ -79,231 +70,236 @@ PODS:
|
||||
- OpenSSL-Universal (1.0.2.19):
|
||||
- OpenSSL-Universal/Static (= 1.0.2.19)
|
||||
- OpenSSL-Universal/Static (1.0.2.19)
|
||||
- RCTRequired (0.62.2)
|
||||
- RCTTypeSafety (0.62.2):
|
||||
- FBLazyVector (= 0.62.2)
|
||||
- Folly (= 2018.10.22.00)
|
||||
- RCTRequired (= 0.62.2)
|
||||
- React-Core (= 0.62.2)
|
||||
- React (0.62.2):
|
||||
- React-Core (= 0.62.2)
|
||||
- React-Core/DevSupport (= 0.62.2)
|
||||
- React-Core/RCTWebSocket (= 0.62.2)
|
||||
- React-RCTActionSheet (= 0.62.2)
|
||||
- React-RCTAnimation (= 0.62.2)
|
||||
- React-RCTBlob (= 0.62.2)
|
||||
- React-RCTImage (= 0.62.2)
|
||||
- React-RCTLinking (= 0.62.2)
|
||||
- React-RCTNetwork (= 0.62.2)
|
||||
- React-RCTSettings (= 0.62.2)
|
||||
- React-RCTText (= 0.62.2)
|
||||
- React-RCTVibration (= 0.62.2)
|
||||
- React-Core (0.62.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- RCTRequired (0.63.2)
|
||||
- RCTTypeSafety (0.63.2):
|
||||
- FBLazyVector (= 0.63.2)
|
||||
- Folly (= 2020.01.13.00)
|
||||
- RCTRequired (= 0.63.2)
|
||||
- React-Core (= 0.63.2)
|
||||
- React (0.63.2):
|
||||
- React-Core (= 0.63.2)
|
||||
- React-Core/DevSupport (= 0.63.2)
|
||||
- React-Core/RCTWebSocket (= 0.63.2)
|
||||
- React-RCTActionSheet (= 0.63.2)
|
||||
- React-RCTAnimation (= 0.63.2)
|
||||
- React-RCTBlob (= 0.63.2)
|
||||
- React-RCTImage (= 0.63.2)
|
||||
- React-RCTLinking (= 0.63.2)
|
||||
- React-RCTNetwork (= 0.63.2)
|
||||
- React-RCTSettings (= 0.63.2)
|
||||
- React-RCTText (= 0.63.2)
|
||||
- React-RCTVibration (= 0.63.2)
|
||||
- React-callinvoker (0.63.2)
|
||||
- React-Core (0.63.2):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default (= 0.62.2)
|
||||
- React-cxxreact (= 0.62.2)
|
||||
- React-jsi (= 0.62.2)
|
||||
- React-jsiexecutor (= 0.62.2)
|
||||
- React-Core/Default (= 0.63.2)
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- Yoga
|
||||
- React-Core/CoreModulesHeaders (0.62.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- React-Core/CoreModulesHeaders (0.63.2):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.62.2)
|
||||
- React-jsi (= 0.62.2)
|
||||
- React-jsiexecutor (= 0.62.2)
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- Yoga
|
||||
- React-Core/Default (0.62.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- React-Core/Default (0.63.2):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-cxxreact (= 0.62.2)
|
||||
- React-jsi (= 0.62.2)
|
||||
- React-jsiexecutor (= 0.62.2)
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- Yoga
|
||||
- React-Core/DevSupport (0.62.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- React-Core/DevSupport (0.63.2):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default (= 0.62.2)
|
||||
- React-Core/RCTWebSocket (= 0.62.2)
|
||||
- React-cxxreact (= 0.62.2)
|
||||
- React-jsi (= 0.62.2)
|
||||
- React-jsiexecutor (= 0.62.2)
|
||||
- React-jsinspector (= 0.62.2)
|
||||
- React-Core/Default (= 0.63.2)
|
||||
- React-Core/RCTWebSocket (= 0.63.2)
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- React-jsinspector (= 0.63.2)
|
||||
- Yoga
|
||||
- React-Core/RCTActionSheetHeaders (0.62.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- React-Core/RCTActionSheetHeaders (0.63.2):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.62.2)
|
||||
- React-jsi (= 0.62.2)
|
||||
- React-jsiexecutor (= 0.62.2)
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- Yoga
|
||||
- React-Core/RCTAnimationHeaders (0.62.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- React-Core/RCTAnimationHeaders (0.63.2):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.62.2)
|
||||
- React-jsi (= 0.62.2)
|
||||
- React-jsiexecutor (= 0.62.2)
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- Yoga
|
||||
- React-Core/RCTBlobHeaders (0.62.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- React-Core/RCTBlobHeaders (0.63.2):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.62.2)
|
||||
- React-jsi (= 0.62.2)
|
||||
- React-jsiexecutor (= 0.62.2)
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- Yoga
|
||||
- React-Core/RCTImageHeaders (0.62.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- React-Core/RCTImageHeaders (0.63.2):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.62.2)
|
||||
- React-jsi (= 0.62.2)
|
||||
- React-jsiexecutor (= 0.62.2)
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- Yoga
|
||||
- React-Core/RCTLinkingHeaders (0.62.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- React-Core/RCTLinkingHeaders (0.63.2):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.62.2)
|
||||
- React-jsi (= 0.62.2)
|
||||
- React-jsiexecutor (= 0.62.2)
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- Yoga
|
||||
- React-Core/RCTNetworkHeaders (0.62.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- React-Core/RCTNetworkHeaders (0.63.2):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.62.2)
|
||||
- React-jsi (= 0.62.2)
|
||||
- React-jsiexecutor (= 0.62.2)
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- Yoga
|
||||
- React-Core/RCTSettingsHeaders (0.62.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- React-Core/RCTSettingsHeaders (0.63.2):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.62.2)
|
||||
- React-jsi (= 0.62.2)
|
||||
- React-jsiexecutor (= 0.62.2)
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- Yoga
|
||||
- React-Core/RCTTextHeaders (0.62.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- React-Core/RCTTextHeaders (0.63.2):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.62.2)
|
||||
- React-jsi (= 0.62.2)
|
||||
- React-jsiexecutor (= 0.62.2)
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- Yoga
|
||||
- React-Core/RCTVibrationHeaders (0.62.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- React-Core/RCTVibrationHeaders (0.63.2):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.62.2)
|
||||
- React-jsi (= 0.62.2)
|
||||
- React-jsiexecutor (= 0.62.2)
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- Yoga
|
||||
- React-Core/RCTWebSocket (0.62.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- React-Core/RCTWebSocket (0.63.2):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default (= 0.62.2)
|
||||
- React-cxxreact (= 0.62.2)
|
||||
- React-jsi (= 0.62.2)
|
||||
- React-jsiexecutor (= 0.62.2)
|
||||
- React-Core/Default (= 0.63.2)
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- Yoga
|
||||
- React-CoreModules (0.62.2):
|
||||
- FBReactNativeSpec (= 0.62.2)
|
||||
- Folly (= 2018.10.22.00)
|
||||
- RCTTypeSafety (= 0.62.2)
|
||||
- React-Core/CoreModulesHeaders (= 0.62.2)
|
||||
- React-RCTImage (= 0.62.2)
|
||||
- ReactCommon/turbomodule/core (= 0.62.2)
|
||||
- React-cxxreact (0.62.2):
|
||||
- React-CoreModules (0.63.2):
|
||||
- FBReactNativeSpec (= 0.63.2)
|
||||
- Folly (= 2020.01.13.00)
|
||||
- RCTTypeSafety (= 0.63.2)
|
||||
- React-Core/CoreModulesHeaders (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-RCTImage (= 0.63.2)
|
||||
- ReactCommon/turbomodule/core (= 0.63.2)
|
||||
- React-cxxreact (0.63.2):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-jsinspector (= 0.62.2)
|
||||
- React-jsi (0.62.2):
|
||||
- React-callinvoker (= 0.63.2)
|
||||
- React-jsinspector (= 0.63.2)
|
||||
- React-jsi (0.63.2):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-jsi/Default (= 0.62.2)
|
||||
- React-jsi/Default (0.62.2):
|
||||
- React-jsi/Default (= 0.63.2)
|
||||
- React-jsi/Default (0.63.2):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-jsiexecutor (0.62.2):
|
||||
- React-jsiexecutor (0.63.2):
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-cxxreact (= 0.62.2)
|
||||
- React-jsi (= 0.62.2)
|
||||
- React-jsinspector (0.62.2)
|
||||
- react-native-safe-area-context (3.0.7):
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsinspector (0.63.2)
|
||||
- react-native-image-picker (2.3.3):
|
||||
- React
|
||||
- React-RCTActionSheet (0.62.2):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.62.2)
|
||||
- React-RCTAnimation (0.62.2):
|
||||
- FBReactNativeSpec (= 0.62.2)
|
||||
- Folly (= 2018.10.22.00)
|
||||
- RCTTypeSafety (= 0.62.2)
|
||||
- React-Core/RCTAnimationHeaders (= 0.62.2)
|
||||
- ReactCommon/turbomodule/core (= 0.62.2)
|
||||
- React-RCTBlob (0.62.2):
|
||||
- FBReactNativeSpec (= 0.62.2)
|
||||
- Folly (= 2018.10.22.00)
|
||||
- React-Core/RCTBlobHeaders (= 0.62.2)
|
||||
- React-Core/RCTWebSocket (= 0.62.2)
|
||||
- React-jsi (= 0.62.2)
|
||||
- React-RCTNetwork (= 0.62.2)
|
||||
- ReactCommon/turbomodule/core (= 0.62.2)
|
||||
- React-RCTImage (0.62.2):
|
||||
- FBReactNativeSpec (= 0.62.2)
|
||||
- Folly (= 2018.10.22.00)
|
||||
- RCTTypeSafety (= 0.62.2)
|
||||
- React-Core/RCTImageHeaders (= 0.62.2)
|
||||
- React-RCTNetwork (= 0.62.2)
|
||||
- ReactCommon/turbomodule/core (= 0.62.2)
|
||||
- React-RCTLinking (0.62.2):
|
||||
- FBReactNativeSpec (= 0.62.2)
|
||||
- React-Core/RCTLinkingHeaders (= 0.62.2)
|
||||
- ReactCommon/turbomodule/core (= 0.62.2)
|
||||
- React-RCTNetwork (0.62.2):
|
||||
- FBReactNativeSpec (= 0.62.2)
|
||||
- Folly (= 2018.10.22.00)
|
||||
- RCTTypeSafety (= 0.62.2)
|
||||
- React-Core/RCTNetworkHeaders (= 0.62.2)
|
||||
- ReactCommon/turbomodule/core (= 0.62.2)
|
||||
- React-RCTSettings (0.62.2):
|
||||
- FBReactNativeSpec (= 0.62.2)
|
||||
- Folly (= 2018.10.22.00)
|
||||
- RCTTypeSafety (= 0.62.2)
|
||||
- React-Core/RCTSettingsHeaders (= 0.62.2)
|
||||
- ReactCommon/turbomodule/core (= 0.62.2)
|
||||
- React-RCTText (0.62.2):
|
||||
- React-Core/RCTTextHeaders (= 0.62.2)
|
||||
- React-RCTVibration (0.62.2):
|
||||
- FBReactNativeSpec (= 0.62.2)
|
||||
- Folly (= 2018.10.22.00)
|
||||
- React-Core/RCTVibrationHeaders (= 0.62.2)
|
||||
- ReactCommon/turbomodule/core (= 0.62.2)
|
||||
- ReactCommon/callinvoker (0.62.2):
|
||||
- react-native-safe-area-context (3.1.4):
|
||||
- React
|
||||
- React-RCTActionSheet (0.63.2):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.63.2)
|
||||
- React-RCTAnimation (0.63.2):
|
||||
- FBReactNativeSpec (= 0.63.2)
|
||||
- Folly (= 2020.01.13.00)
|
||||
- RCTTypeSafety (= 0.63.2)
|
||||
- React-Core/RCTAnimationHeaders (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- ReactCommon/turbomodule/core (= 0.63.2)
|
||||
- React-RCTBlob (0.63.2):
|
||||
- FBReactNativeSpec (= 0.63.2)
|
||||
- Folly (= 2020.01.13.00)
|
||||
- React-Core/RCTBlobHeaders (= 0.63.2)
|
||||
- React-Core/RCTWebSocket (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-RCTNetwork (= 0.63.2)
|
||||
- ReactCommon/turbomodule/core (= 0.63.2)
|
||||
- React-RCTImage (0.63.2):
|
||||
- FBReactNativeSpec (= 0.63.2)
|
||||
- Folly (= 2020.01.13.00)
|
||||
- RCTTypeSafety (= 0.63.2)
|
||||
- React-Core/RCTImageHeaders (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-RCTNetwork (= 0.63.2)
|
||||
- ReactCommon/turbomodule/core (= 0.63.2)
|
||||
- React-RCTLinking (0.63.2):
|
||||
- FBReactNativeSpec (= 0.63.2)
|
||||
- React-Core/RCTLinkingHeaders (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- ReactCommon/turbomodule/core (= 0.63.2)
|
||||
- React-RCTNetwork (0.63.2):
|
||||
- FBReactNativeSpec (= 0.63.2)
|
||||
- Folly (= 2020.01.13.00)
|
||||
- RCTTypeSafety (= 0.63.2)
|
||||
- React-Core/RCTNetworkHeaders (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- ReactCommon/turbomodule/core (= 0.63.2)
|
||||
- React-RCTSettings (0.63.2):
|
||||
- FBReactNativeSpec (= 0.63.2)
|
||||
- Folly (= 2020.01.13.00)
|
||||
- RCTTypeSafety (= 0.63.2)
|
||||
- React-Core/RCTSettingsHeaders (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- ReactCommon/turbomodule/core (= 0.63.2)
|
||||
- React-RCTText (0.63.2):
|
||||
- React-Core/RCTTextHeaders (= 0.63.2)
|
||||
- React-RCTVibration (0.63.2):
|
||||
- FBReactNativeSpec (= 0.63.2)
|
||||
- Folly (= 2020.01.13.00)
|
||||
- React-Core/RCTVibrationHeaders (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- ReactCommon/turbomodule/core (= 0.63.2)
|
||||
- ReactCommon/turbomodule/core (0.63.2):
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-cxxreact (= 0.62.2)
|
||||
- ReactCommon/turbomodule/core (0.62.2):
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core (= 0.62.2)
|
||||
- React-cxxreact (= 0.62.2)
|
||||
- React-jsi (= 0.62.2)
|
||||
- ReactCommon/callinvoker (= 0.62.2)
|
||||
- RenderCore (0.30)
|
||||
- React-callinvoker (= 0.63.2)
|
||||
- React-Core (= 0.63.2)
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- Yoga (1.14.0)
|
||||
- YogaKit (1.18.1):
|
||||
- Yoga (~> 1.14)
|
||||
@@ -312,31 +308,31 @@ DEPENDENCIES:
|
||||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
||||
- FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`)
|
||||
- Flipper (~> 0.37.0)
|
||||
- Flipper (~> 0.41.1)
|
||||
- Flipper-DoubleConversion (= 1.1.7)
|
||||
- Flipper-Folly (~> 2.2)
|
||||
- Flipper-Glog (= 0.3.6)
|
||||
- Flipper-PeerTalk (~> 0.0.4)
|
||||
- Flipper-RSocket (~> 1.1)
|
||||
- FlipperKit (~> 0.37.0)
|
||||
- FlipperKit/Core (~> 0.37.0)
|
||||
- FlipperKit/CppBridge (~> 0.37.0)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (~> 0.37.0)
|
||||
- FlipperKit/FBDefines (~> 0.37.0)
|
||||
- FlipperKit/FKPortForwarding (~> 0.37.0)
|
||||
- FlipperKit/FlipperKitHighlightOverlay (~> 0.37.0)
|
||||
- FlipperKit/FlipperKitLayoutComponentKitSupport (~> 0.37.0)
|
||||
- FlipperKit/FlipperKitLayoutPlugin (~> 0.37.0)
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (~> 0.37.0)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (~> 0.37.0)
|
||||
- FlipperKit/FlipperKitReactPlugin (~> 0.37.0)
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.37.0)
|
||||
- FlipperKit/SKIOSNetworkPlugin (~> 0.37.0)
|
||||
- FlipperKit (~> 0.41.1)
|
||||
- FlipperKit/Core (~> 0.41.1)
|
||||
- FlipperKit/CppBridge (~> 0.41.1)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (~> 0.41.1)
|
||||
- FlipperKit/FBDefines (~> 0.41.1)
|
||||
- FlipperKit/FKPortForwarding (~> 0.41.1)
|
||||
- FlipperKit/FlipperKitHighlightOverlay (~> 0.41.1)
|
||||
- FlipperKit/FlipperKitLayoutPlugin (~> 0.41.1)
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (~> 0.41.1)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (~> 0.41.1)
|
||||
- FlipperKit/FlipperKitReactPlugin (~> 0.41.1)
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.41.1)
|
||||
- FlipperKit/SKIOSNetworkPlugin (~> 0.41.1)
|
||||
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
|
||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
|
||||
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
|
||||
- React (from `../node_modules/react-native/`)
|
||||
- React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
|
||||
- React-Core (from `../node_modules/react-native/`)
|
||||
- React-Core/DevSupport (from `../node_modules/react-native/`)
|
||||
- React-Core/RCTWebSocket (from `../node_modules/react-native/`)
|
||||
@@ -345,6 +341,7 @@ DEPENDENCIES:
|
||||
- React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
|
||||
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
|
||||
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
|
||||
- react-native-image-picker (from `../node_modules/react-native-image-picker`)
|
||||
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
|
||||
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
|
||||
- React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
|
||||
@@ -355,7 +352,6 @@ DEPENDENCIES:
|
||||
- React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`)
|
||||
- React-RCTText (from `../node_modules/react-native/Libraries/Text`)
|
||||
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
|
||||
- ReactCommon/callinvoker (from `../node_modules/react-native/ReactCommon`)
|
||||
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
|
||||
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
||||
|
||||
@@ -364,7 +360,6 @@ SPEC REPOS:
|
||||
- boost-for-react-native
|
||||
- CocoaAsyncSocket
|
||||
- CocoaLibEvent
|
||||
- ComponentKit
|
||||
- Flipper
|
||||
- Flipper-DoubleConversion
|
||||
- Flipper-Folly
|
||||
@@ -373,7 +368,6 @@ SPEC REPOS:
|
||||
- Flipper-RSocket
|
||||
- FlipperKit
|
||||
- OpenSSL-Universal
|
||||
- RenderCore
|
||||
- YogaKit
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
@@ -393,6 +387,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/Libraries/TypeSafety"
|
||||
React:
|
||||
:path: "../node_modules/react-native/"
|
||||
React-callinvoker:
|
||||
:path: "../node_modules/react-native/ReactCommon/callinvoker"
|
||||
React-Core:
|
||||
:path: "../node_modules/react-native/"
|
||||
React-CoreModules:
|
||||
@@ -405,6 +401,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsiexecutor"
|
||||
React-jsinspector:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsinspector"
|
||||
react-native-image-picker:
|
||||
:path: "../node_modules/react-native-image-picker"
|
||||
react-native-safe-area-context:
|
||||
:path: "../node_modules/react-native-safe-area-context"
|
||||
React-RCTActionSheet:
|
||||
@@ -434,44 +432,44 @@ SPEC CHECKSUMS:
|
||||
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
||||
CocoaAsyncSocket: 694058e7c0ed05a9e217d1b3c7ded962f4180845
|
||||
CocoaLibEvent: 2fab71b8bd46dd33ddb959f7928ec5909f838e3f
|
||||
ComponentKit: c34da1ab3515cf18db68a4ba22c6599568d1de74
|
||||
DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2
|
||||
FBLazyVector: 4aab18c93cd9546e4bfed752b4084585eca8b245
|
||||
FBReactNativeSpec: 5465d51ccfeecb7faa12f9ae0024f2044ce4044e
|
||||
Flipper: 1670db365568191bd123a0c905b834e77ba9e3d3
|
||||
DoubleConversion: cde416483dac037923206447da6e1454df403714
|
||||
FBLazyVector: 3ef4a7f62e7db01092f9d517d2ebc0d0677c4a37
|
||||
FBReactNativeSpec: dc7fa9088f0f2a998503a352b0554d69a4391c5a
|
||||
Flipper: 33585e2d9810fe5528346be33bcf71b37bb7ae13
|
||||
Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41
|
||||
Flipper-Folly: c12092ea368353b58e992843a990a3225d4533c3
|
||||
Flipper-Glog: 1dfd6abf1e922806c52ceb8701a3599a79a200a6
|
||||
Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
|
||||
Flipper-RSocket: 64e7431a55835eb953b0bf984ef3b90ae9fdddd7
|
||||
FlipperKit: afd4259ef9eadeeb2d30250b37d95cb3b6b97a69
|
||||
Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51
|
||||
glog: 1f3da668190260b06b429bb211bfbee5cd790c28
|
||||
FlipperKit: bc68102cd4952a258a23c9c1b316c7bec1fecf83
|
||||
Folly: b73c3869541e86821df3c387eb0af5f65addfab4
|
||||
glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3
|
||||
OpenSSL-Universal: 8b48cc0d10c1b2923617dfe5c178aa9ed2689355
|
||||
RCTRequired: cec6a34b3ac8a9915c37e7e4ad3aa74726ce4035
|
||||
RCTTypeSafety: 93006131180074cffa227a1075802c89a49dd4ce
|
||||
React: 29a8b1a02bd764fb7644ef04019270849b9a7ac3
|
||||
React-Core: b12bffb3f567fdf99510acb716ef1abd426e0e05
|
||||
React-CoreModules: 4a9b87bbe669d6c3173c0132c3328e3b000783d0
|
||||
React-cxxreact: e65f9c2ba0ac5be946f53548c1aaaee5873a8103
|
||||
React-jsi: b6dc94a6a12ff98e8877287a0b7620d365201161
|
||||
React-jsiexecutor: 1540d1c01bb493ae3124ed83351b1b6a155db7da
|
||||
React-jsinspector: 512e560d0e985d0e8c479a54a4e5c147a9c83493
|
||||
react-native-safe-area-context: ef6f16c66b0797ecae1bf86c103dfb3dc16fc33d
|
||||
React-RCTActionSheet: f41ea8a811aac770e0cc6e0ad6b270c644ea8b7c
|
||||
React-RCTAnimation: 49ab98b1c1ff4445148b72a3d61554138565bad0
|
||||
React-RCTBlob: a332773f0ebc413a0ce85942a55b064471587a71
|
||||
React-RCTImage: e70be9b9c74fe4e42d0005f42cace7981c994ac3
|
||||
React-RCTLinking: c1b9739a88d56ecbec23b7f63650e44672ab2ad2
|
||||
React-RCTNetwork: 73138b6f45e5a2768ad93f3d57873c2a18d14b44
|
||||
React-RCTSettings: 6e3738a87e21b39a8cb08d627e68c44acf1e325a
|
||||
React-RCTText: fae545b10cfdb3d247c36c56f61a94cfd6dba41d
|
||||
React-RCTVibration: 4356114dbcba4ce66991096e51a66e61eda51256
|
||||
ReactCommon: ed4e11d27609d571e7eee8b65548efc191116eb3
|
||||
RenderCore: d779c47622b313ce2d51bb36d084517af38b0dc1
|
||||
Yoga: 3ebccbdd559724312790e7742142d062476b698e
|
||||
RCTRequired: f13f25e7b12f925f1f6a6a8c69d929a03c0129fe
|
||||
RCTTypeSafety: 44982c5c8e43ff4141eb519a8ddc88059acd1f3a
|
||||
React: e1c65dd41cb9db13b99f24608e47dd595f28ca9a
|
||||
React-callinvoker: 552a6a6bc8b3bb794cf108ad59e5a9e2e3b4fc98
|
||||
React-Core: 9d341e725dc9cd2f49e4c49ad1fc4e8776aa2639
|
||||
React-CoreModules: 5335e168165da7f7083ce7147768d36d3e292318
|
||||
React-cxxreact: d3261ec5f7d11743fbf21e263a34ea51d1f13ebc
|
||||
React-jsi: 54245e1d5f4b690dec614a73a3795964eeef13a8
|
||||
React-jsiexecutor: 8ca588cc921e70590820ce72b8789b02c67cce38
|
||||
React-jsinspector: b14e62ebe7a66e9231e9581279909f2fc3db6606
|
||||
react-native-image-picker: 3d3f85baabca60a00b75fb8facc1376db7bbdafa
|
||||
react-native-safe-area-context: eb91fe1fb3f7b87d9c30a7f0808407d8569d539d
|
||||
React-RCTActionSheet: 910163b6b09685a35c4ebbc52b66d1bfbbe39fc5
|
||||
React-RCTAnimation: 9a883bbe1e9d2e158d4fb53765ed64c8dc2200c6
|
||||
React-RCTBlob: 39cf0ece1927996c4466510e25d2105f67010e13
|
||||
React-RCTImage: de355d738727b09ad3692f2a979affbd54b5f378
|
||||
React-RCTLinking: 8122f221d395a63364b2c0078ce284214bd04575
|
||||
React-RCTNetwork: 8f96c7b49ea6a0f28f98258f347b6ad218bc0830
|
||||
React-RCTSettings: 8a49622aff9c1925f5455fa340b6fe4853d64ab6
|
||||
React-RCTText: 1b6773e776e4b33f90468c20fe3b16ca3e224bb8
|
||||
React-RCTVibration: 4d2e726957f4087449739b595f107c0d4b6c2d2d
|
||||
ReactCommon: a0a1edbebcac5e91338371b72ffc66aa822792ce
|
||||
Yoga: 7740b94929bbacbddda59bf115b5317e9a161598
|
||||
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
|
||||
|
||||
PODFILE CHECKSUM: acbd6610b7831a74207daab8c8f1f3a49b537e00
|
||||
PODFILE CHECKSUM: 92b8aaa3885dd8bbc49d40800e635370282f63b6
|
||||
|
||||
COCOAPODS: 1.9.3
|
||||
|
||||
@@ -112,6 +112,7 @@
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
||||
DA902D70F8ECC07833B03010 /* [CP] Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@@ -203,6 +204,24 @@
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
DA902D70F8ECC07833B03010 /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources.sh",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
FD10A7F022414F080027D42C /* Start Packager */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -244,10 +263,6 @@
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(inherited)",
|
||||
"FB_SONARKIT_ENABLED=1",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"${PODS_ROOT}/Headers/Public\"",
|
||||
@@ -375,7 +390,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_SWIFT_FLAGS = "-D DEBUG";
|
||||
@@ -423,7 +438,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
|
||||
@@ -16,9 +16,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, RCTBridgeDelegate {
|
||||
var window: UIWindow?
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
#if DEBUG
|
||||
initializeFlipper(with: application)
|
||||
#endif
|
||||
|
||||
let bridge = RCTBridge(delegate: self, launchOptions: launchOptions)
|
||||
let rootView = RCTRootView(bridge: bridge!, moduleName: "example", initialProperties: nil)
|
||||
@@ -42,16 +40,15 @@ class AppDelegate: UIResponder, UIApplicationDelegate, RCTBridgeDelegate {
|
||||
#endif
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
private func initializeFlipper(with application: UIApplication) {
|
||||
#if DEBUG
|
||||
let client = FlipperClient.shared()
|
||||
let layoutDescriptionMapper = SKDescriptorMapper(defaults: ())
|
||||
FlipperKitLayoutComponentKitSupport.setUpWith(layoutDescriptionMapper)
|
||||
client?.add(FlipperKitLayoutPlugin(rootNode: application, with: layoutDescriptionMapper))
|
||||
client?.add(FKUserDefaultsPlugin(suiteName: nil))
|
||||
client?.add(FlipperKitReactPlugin())
|
||||
client?.add(FlipperKitNetworkPlugin(networkAdapter: SKIOSNetworkAdapter()))
|
||||
client?.start()
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13142" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12042"/>
|
||||
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
@@ -15,8 +16,8 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Copyright © 2020 Facebook. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="obG-Y5-kRd">
|
||||
<rect key="frame" x="0.0" y="626.5" width="375" height="20.5"/>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="obG-Y5-kRd">
|
||||
<rect key="frame" x="0.0" y="647" width="375" height="0.0"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -27,22 +28,31 @@
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Powered by React Native" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="MN2-I3-ftu">
|
||||
<rect key="frame" x="0.0" y="626" width="375" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="Bcu-3y-fUS" firstAttribute="centerX" secondItem="obG-Y5-kRd" secondAttribute="centerX" id="5cz-MP-9tL"/>
|
||||
<constraint firstItem="Bcu-3y-fUS" firstAttribute="bottom" secondItem="MN2-I3-ftu" secondAttribute="bottom" constant="20" id="OZV-Vh-mqD"/>
|
||||
<constraint firstItem="Bcu-3y-fUS" firstAttribute="centerX" secondItem="GJd-Yh-RWb" secondAttribute="centerX" id="Q3B-4B-g5h"/>
|
||||
<constraint firstItem="obG-Y5-kRd" firstAttribute="leading" secondItem="Bcu-3y-fUS" secondAttribute="leading" constant="20" symbolic="YES" id="SfN-ll-jLj"/>
|
||||
<constraint firstItem="obG-Y5-kRd" firstAttribute="leading" secondItem="Bcu-3y-fUS" secondAttribute="leading" symbolic="YES" id="SfN-ll-jLj"/>
|
||||
<constraint firstAttribute="bottom" secondItem="obG-Y5-kRd" secondAttribute="bottom" constant="20" id="Y44-ml-fuU"/>
|
||||
<constraint firstItem="MN2-I3-ftu" firstAttribute="centerX" secondItem="Bcu-3y-fUS" secondAttribute="centerX" id="akx-eg-2ui"/>
|
||||
<constraint firstItem="MN2-I3-ftu" firstAttribute="leading" secondItem="Bcu-3y-fUS" secondAttribute="leading" id="i1E-0Y-4RG"/>
|
||||
<constraint firstItem="GJd-Yh-RWb" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="bottom" multiplier="1/3" constant="1" id="moa-c2-u7t"/>
|
||||
<constraint firstItem="GJd-Yh-RWb" firstAttribute="leading" secondItem="Bcu-3y-fUS" secondAttribute="leading" constant="20" symbolic="YES" id="x7j-FC-K8j"/>
|
||||
<constraint firstItem="GJd-Yh-RWb" firstAttribute="leading" secondItem="Bcu-3y-fUS" secondAttribute="leading" symbolic="YES" id="x7j-FC-K8j"/>
|
||||
</constraints>
|
||||
<viewLayoutGuide key="safeArea" id="Bcu-3y-fUS"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="53" y="375"/>
|
||||
<point key="canvasLocation" x="52.173913043478265" y="375"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
</document>
|
||||
@@ -14,26 +14,27 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "^16.13.1",
|
||||
"react-native": "^0.62.2",
|
||||
"react-native-safe-area-context": "^3.0.7"
|
||||
"react-native": "^0.63.2",
|
||||
"react-native-image-picker": "^2.3.3",
|
||||
"react-native-safe-area-context": "^3.1.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.10.3",
|
||||
"@babel/runtime": "^7.10.3",
|
||||
"@babel/core": "^7.11.1",
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@react-native-community/eslint-config": "^2.0.0",
|
||||
"@types/jest": "^26.0.3",
|
||||
"@types/react-native": "^0.62.14",
|
||||
"@types/react-test-renderer": "^16.9.2",
|
||||
"@types/uuid": "^8.0.0",
|
||||
"babel-jest": "^26.1.0",
|
||||
"@types/jest": "^26.0.9",
|
||||
"@types/react-native": "^0.63.6",
|
||||
"@types/react-test-renderer": "^16.9.3",
|
||||
"@types/uuid": "^8.0.1",
|
||||
"babel-jest": "^26.2.2",
|
||||
"casual": "^1.6.2",
|
||||
"eslint": "^7.3.1",
|
||||
"eslint": "^7.6.0",
|
||||
"eslint-plugin-simple-import-sort": "^5.0.3",
|
||||
"jest": "^26.1.0",
|
||||
"metro-react-native-babel-preset": "^0.59.0",
|
||||
"jest": "^26.2.2",
|
||||
"metro-react-native-babel-preset": "^0.61.0",
|
||||
"react-test-renderer": "^16.13.1",
|
||||
"typescript": "^3.9.5",
|
||||
"uuid": "^8.2.0"
|
||||
"typescript": "^3.9.7",
|
||||
"uuid": "^8.3.0"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "react-native",
|
||||
|
||||
@@ -23,6 +23,7 @@ const messages = [...Array(numberOfMessages)].map((_, index) => {
|
||||
id: uuidv4(),
|
||||
text,
|
||||
timestamp,
|
||||
type: 'text',
|
||||
}
|
||||
return data
|
||||
})
|
||||
|
||||
@@ -1,19 +1,46 @@
|
||||
import { Chat, Message } from '@flyerhq/react-native-chat-ui'
|
||||
import {
|
||||
Chat,
|
||||
MessageType,
|
||||
SendImageCallback,
|
||||
} from '@flyerhq/react-native-chat-ui'
|
||||
import React, { useState } from 'react'
|
||||
import { StatusBar } from 'react-native'
|
||||
import ImagePicker from 'react-native-image-picker'
|
||||
import { SafeAreaProvider } from 'react-native-safe-area-context'
|
||||
import data from './messages.json'
|
||||
import users from './users.json'
|
||||
|
||||
const App = () => {
|
||||
const [messages, setMessages] = useState<Message[]>(data)
|
||||
const [messages, setMessages] = useState(data as MessageType.Any[])
|
||||
|
||||
const handleSendPress = (message: Message) => {
|
||||
const handleAttachmentPress = (send: SendImageCallback) => {
|
||||
ImagePicker.showImagePicker(
|
||||
{ maxWidth: 1440, quality: 0.7 },
|
||||
(response) => {
|
||||
if (response.data) {
|
||||
send({
|
||||
height: response.height,
|
||||
imageUrl: 'data:image/jpeg;base64,' + response.data,
|
||||
width: response.width,
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
const handleSendPress = (message: MessageType.Any) => {
|
||||
setMessages([message, ...messages])
|
||||
}
|
||||
|
||||
return (
|
||||
<SafeAreaProvider>
|
||||
<Chat messages={messages} onSendPress={handleSendPress} user={users[0]} />
|
||||
<StatusBar barStyle='dark-content' />
|
||||
<Chat
|
||||
messages={messages}
|
||||
onAttachmentPress={handleAttachmentPress}
|
||||
onSendPress={handleSendPress}
|
||||
user={users[0]}
|
||||
/>
|
||||
</SafeAreaProvider>
|
||||
)
|
||||
}
|
||||
|
||||
1586
example/yarn.lock
1586
example/yarn.lock
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,13 @@
|
||||
import { Message, Size, User } from '../src/types'
|
||||
import { MessageType, Size, User } from '../src/types'
|
||||
|
||||
export const message: Message = {
|
||||
export const imageMessage: MessageType.Image = {
|
||||
authorId: 'userId',
|
||||
height: 100,
|
||||
id: 'uuidv4',
|
||||
text: 'text',
|
||||
imageUrl: 'https://avatars1.githubusercontent.com/u/59206044',
|
||||
timestamp: 0,
|
||||
type: 'image',
|
||||
width: 100,
|
||||
}
|
||||
|
||||
export const size: Size = {
|
||||
@@ -12,6 +15,14 @@ export const size: Size = {
|
||||
width: 414,
|
||||
}
|
||||
|
||||
export const textMessage: MessageType.Text = {
|
||||
authorId: 'userId',
|
||||
id: 'uuidv4',
|
||||
text: 'text',
|
||||
timestamp: 0,
|
||||
type: 'text',
|
||||
}
|
||||
|
||||
export const user: User = {
|
||||
id: 'userId',
|
||||
name: 'Alex',
|
||||
|
||||
33
package.json
33
package.json
@@ -21,29 +21,30 @@
|
||||
"type-coverage": "type-coverage --is 100 --strict --ignore-catch --cache"
|
||||
},
|
||||
"dependencies": {
|
||||
"@flyerhq/react-native-keyboard-accessory-view": "^1.2.0"
|
||||
"@flyerhq/react-native-keyboard-accessory-view": "^1.3.0",
|
||||
"react-native-image-viewing": "^0.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.10.3",
|
||||
"@babel/runtime": "^7.10.3",
|
||||
"@babel/core": "^7.11.1",
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@react-native-community/eslint-config": "^2.0.0",
|
||||
"@types/jest": "^26.0.3",
|
||||
"@types/react-native": "^0.62.14",
|
||||
"@types/react-test-renderer": "^16.9.2",
|
||||
"babel-jest": "^26.1.0",
|
||||
"@testing-library/react-native": "^7.0.1",
|
||||
"@types/jest": "^26.0.9",
|
||||
"@types/react-native": "^0.63.6",
|
||||
"@types/react-test-renderer": "^16.9.3",
|
||||
"babel-jest": "^26.2.2",
|
||||
"copyfiles": "^2.3.0",
|
||||
"eslint": "^7.3.1",
|
||||
"eslint-plugin-jest": "^23.17.1",
|
||||
"eslint": "^7.6.0",
|
||||
"eslint-plugin-jest": "^23.20.0",
|
||||
"eslint-plugin-simple-import-sort": "^5.0.3",
|
||||
"jest": "^26.1.0",
|
||||
"metro-react-native-babel-preset": "^0.59.0",
|
||||
"jest": "^26.2.2",
|
||||
"metro-react-native-babel-preset": "^0.61.0",
|
||||
"react": "^16.13.1",
|
||||
"react-native": "^0.62.2",
|
||||
"react-native-safe-area-context": "^3.0.7",
|
||||
"react-native-testing-library": "^2.1.0",
|
||||
"react-native": "^0.63.2",
|
||||
"react-native-safe-area-context": "^3.1.4",
|
||||
"react-test-renderer": "^16.13.1",
|
||||
"type-coverage": "^2.8.2",
|
||||
"typescript": "^3.9.5"
|
||||
"type-coverage": "^2.9.0",
|
||||
"typescript": "^3.9.7"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
|
||||
@@ -7,13 +7,11 @@ import {
|
||||
} from 'react-native'
|
||||
|
||||
export interface AttachmentButtonProps {
|
||||
disabled?: boolean
|
||||
onPress?: () => void
|
||||
touchableOpacityProps?: TouchableOpacityProps
|
||||
}
|
||||
|
||||
export const AttachmentButton = ({
|
||||
disabled,
|
||||
onPress,
|
||||
touchableOpacityProps,
|
||||
}: AttachmentButtonProps) => {
|
||||
@@ -26,8 +24,6 @@ export const AttachmentButton = ({
|
||||
<TouchableOpacity
|
||||
accessibilityRole='button'
|
||||
accessibilityLabel='Add an attachment'
|
||||
accessibilityState={{ disabled }}
|
||||
disabled={disabled}
|
||||
{...touchableOpacityProps}
|
||||
onPress={handlePress}
|
||||
>
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
import * as React from 'react'
|
||||
import { fireEvent, render } from 'react-native-testing-library'
|
||||
import { AttachmentButton } from '../AttachmentButton'
|
||||
|
||||
describe('attachment button', () => {
|
||||
it('sends an event', () => {
|
||||
expect.assertions(1)
|
||||
const onPress = jest.fn()
|
||||
const { getByA11yLabel } = render(<AttachmentButton onPress={onPress} />)
|
||||
const button = getByA11yLabel('Add an attachment')
|
||||
fireEvent.press(button)
|
||||
expect(onPress).toHaveBeenCalledWith()
|
||||
})
|
||||
})
|
||||
@@ -3,14 +3,16 @@ import {
|
||||
usePanResponder,
|
||||
} from '@flyerhq/react-native-keyboard-accessory-view'
|
||||
import * as React from 'react'
|
||||
import { FlatList, SafeAreaView } from 'react-native'
|
||||
import { Message, User } from '../../types'
|
||||
import { FlatList, SafeAreaView, StatusBar, View } from 'react-native'
|
||||
import ImageView from 'react-native-image-viewing'
|
||||
import { MessageType, User } from '../../types'
|
||||
import { UserContext } from '../../utils'
|
||||
import { Input, InputProps } from '../Input'
|
||||
import { TextMessage } from '../TextMessage'
|
||||
import { Message } from '../Message'
|
||||
import styles from './styles'
|
||||
|
||||
export interface ChatProps extends InputProps {
|
||||
messages: Message[]
|
||||
messages: MessageType.Any[]
|
||||
user: User
|
||||
}
|
||||
|
||||
@@ -18,15 +20,22 @@ export const Chat = ({
|
||||
messages,
|
||||
onAttachmentPress,
|
||||
onSendPress,
|
||||
textInputProps,
|
||||
user,
|
||||
}: ChatProps) => {
|
||||
const { onLayout, size } = useComponentSize()
|
||||
const { panHandlers, positionY } = usePanResponder()
|
||||
const [contentBottomInset, setContentBottomInset] = React.useState(0)
|
||||
const [isImageViewVisible, setIsImageViewVisible] = React.useState(false)
|
||||
const [imageViewIndex, setImageViewIndex] = React.useState(0)
|
||||
const images = messages
|
||||
.filter((message): message is MessageType.Image => message.type === 'image')
|
||||
.map((message) => ({ uri: message.imageUrl }))
|
||||
.reverse()
|
||||
|
||||
const list = React.useRef<FlatList<Message>>(null)
|
||||
const list = React.useRef<FlatList<MessageType.Any>>(null)
|
||||
|
||||
const handleSendPress = (message: Message) => {
|
||||
const handleSendPress = (message: MessageType.Any) => {
|
||||
onSendPress(message)
|
||||
list.current?.scrollToOffset({
|
||||
animated: true,
|
||||
@@ -34,34 +43,71 @@ export const Chat = ({
|
||||
})
|
||||
}
|
||||
|
||||
const keyExtractor = (item: Message) => item.id
|
||||
const keyExtractor = (item: MessageType.Any) => item.id
|
||||
|
||||
const renderItem = ({ item }: { item: Message }) => (
|
||||
<TextMessage message={item} parentComponentSize={size} user={user} />
|
||||
)
|
||||
const renderItem = ({
|
||||
item,
|
||||
index,
|
||||
}: {
|
||||
item: MessageType.Any
|
||||
index: number
|
||||
}) => {
|
||||
const previousMessageSameAuthor =
|
||||
messages[index - 1]?.authorId === item.authorId
|
||||
|
||||
return (
|
||||
<Message
|
||||
message={item}
|
||||
onImagePress={(imageUrl) => {
|
||||
setImageViewIndex(images.findIndex((image) => image.uri === imageUrl))
|
||||
setIsImageViewVisible(true)
|
||||
StatusBar.setHidden(true, 'slide')
|
||||
}}
|
||||
parentComponentSize={size}
|
||||
previousMessageSameAuthor={previousMessageSameAuthor}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container} onLayout={onLayout}>
|
||||
<FlatList
|
||||
ref={list}
|
||||
contentContainerStyle={{ paddingTop: contentBottomInset }}
|
||||
style={styles.list}
|
||||
data={messages}
|
||||
renderItem={renderItem}
|
||||
automaticallyAdjustContentInsets={false}
|
||||
inverted
|
||||
keyboardDismissMode='interactive'
|
||||
keyExtractor={keyExtractor}
|
||||
scrollIndicatorInsets={{ top: contentBottomInset }}
|
||||
{...panHandlers}
|
||||
/>
|
||||
<Input
|
||||
onAttachmentPress={onAttachmentPress}
|
||||
onContentBottomInsetUpdate={setContentBottomInset}
|
||||
onSendPress={handleSendPress}
|
||||
panResponderPositionY={positionY}
|
||||
user={user}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
<UserContext.Provider value={user}>
|
||||
<SafeAreaView style={styles.container} onLayout={onLayout}>
|
||||
<FlatList
|
||||
ref={list}
|
||||
contentContainerStyle={{ paddingTop: contentBottomInset }}
|
||||
style={styles.list}
|
||||
data={messages}
|
||||
renderItem={renderItem}
|
||||
automaticallyAdjustContentInsets={false}
|
||||
inverted
|
||||
keyboardDismissMode='interactive'
|
||||
keyExtractor={keyExtractor}
|
||||
scrollIndicatorInsets={{ top: contentBottomInset }}
|
||||
ListFooterComponent={<View />}
|
||||
ListFooterComponentStyle={styles.footer}
|
||||
{...panHandlers}
|
||||
/>
|
||||
<Input
|
||||
onAttachmentPress={onAttachmentPress}
|
||||
onContentBottomInsetUpdate={setContentBottomInset}
|
||||
onSendPress={handleSendPress}
|
||||
panResponderPositionY={positionY}
|
||||
textInputProps={textInputProps}
|
||||
/>
|
||||
<ImageView
|
||||
images={images}
|
||||
imageIndex={imageViewIndex}
|
||||
// TODO: Tapping on a close button results in the next warning:
|
||||
// `An update to ImageViewing inside a test was not wrapped in act(...).`
|
||||
onRequestClose={
|
||||
/* istanbul ignore next */ () => {
|
||||
setIsImageViewVisible(false)
|
||||
StatusBar.setHidden(false, 'slide')
|
||||
}
|
||||
}
|
||||
visible={isImageViewVisible}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
</UserContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,18 +1,37 @@
|
||||
import { fireEvent, render, waitFor } from '@testing-library/react-native'
|
||||
import * as React from 'react'
|
||||
import { fireEvent, render } from 'react-native-testing-library'
|
||||
import { message, user } from '../../../../jest/fixtures'
|
||||
import { imageMessage, textMessage, user } from '../../../../jest/fixtures'
|
||||
import { Chat } from '../Chat'
|
||||
|
||||
describe('chat', () => {
|
||||
it('calls onSendPress', () => {
|
||||
it('renders image preview', async () => {
|
||||
expect.assertions(1)
|
||||
const messages = [message]
|
||||
const messages = [imageMessage]
|
||||
const onSendPress = jest.fn()
|
||||
const { getByA11yLabel } = render(
|
||||
const { getByRole, getByText } = render(
|
||||
<Chat messages={messages} onSendPress={onSendPress} user={user} />
|
||||
)
|
||||
const button = getByA11yLabel('Send a message')
|
||||
const button = getByRole('image').parent
|
||||
fireEvent.press(button)
|
||||
expect(onSendPress).toHaveBeenCalledWith({ ...message, text: '' })
|
||||
await waitFor(() => getByText('✕'))
|
||||
const closeButton = getByText('✕')
|
||||
expect(closeButton).toBeDefined()
|
||||
})
|
||||
|
||||
it('sends a text message', () => {
|
||||
expect.assertions(1)
|
||||
const messages = [textMessage]
|
||||
const onSendPress = jest.fn()
|
||||
const { getByLabelText } = render(
|
||||
<Chat
|
||||
messages={messages}
|
||||
onSendPress={onSendPress}
|
||||
textInputProps={{ defaultValue: 'text' }}
|
||||
user={user}
|
||||
/>
|
||||
)
|
||||
const button = getByLabelText('Send a message')
|
||||
fireEvent.press(button)
|
||||
expect(onSendPress).toHaveBeenCalledWith(textMessage)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -4,6 +4,9 @@ export default StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
footer: {
|
||||
height: 24,
|
||||
},
|
||||
list: {
|
||||
backgroundColor: '#fff',
|
||||
},
|
||||
|
||||
42
src/components/ImageMessage/ImageMessage.tsx
Normal file
42
src/components/ImageMessage/ImageMessage.tsx
Normal file
@@ -0,0 +1,42 @@
|
||||
import * as React from 'react'
|
||||
import { Image, TouchableWithoutFeedback } from 'react-native'
|
||||
import { MessageType, Size } from '../../types'
|
||||
import styles from './styles'
|
||||
|
||||
export interface ImageMessageProps {
|
||||
message: MessageType.Image
|
||||
onPress: (imageUrl: string) => void
|
||||
}
|
||||
|
||||
export const ImageMessage = ({ message, onPress }: ImageMessageProps) => {
|
||||
const defaultHeight = message.height ?? 0
|
||||
const defaultWidth = message.width ?? 0
|
||||
const [size, setSize] = React.useState<Size>({
|
||||
height: defaultHeight,
|
||||
width: defaultWidth,
|
||||
})
|
||||
const { image } = styles({ size })
|
||||
|
||||
React.useEffect(() => {
|
||||
if (defaultHeight <= 0 || defaultWidth <= 0)
|
||||
Image.getSize(
|
||||
message.imageUrl,
|
||||
(width, height) => setSize({ height, width }),
|
||||
() => setSize({ height: 0, width: 0 })
|
||||
)
|
||||
}, [defaultHeight, defaultWidth, message.imageUrl])
|
||||
|
||||
const handlePress = () => {
|
||||
onPress(message.imageUrl)
|
||||
}
|
||||
|
||||
return (
|
||||
<TouchableWithoutFeedback onPress={handlePress}>
|
||||
<Image
|
||||
accessibilityRole='image'
|
||||
source={{ uri: message.imageUrl }}
|
||||
style={image}
|
||||
/>
|
||||
</TouchableWithoutFeedback>
|
||||
)
|
||||
}
|
||||
49
src/components/ImageMessage/__tests__/ImageMessage.test.tsx
Normal file
49
src/components/ImageMessage/__tests__/ImageMessage.test.tsx
Normal file
@@ -0,0 +1,49 @@
|
||||
import { act, fireEvent, render } from '@testing-library/react-native'
|
||||
import * as React from 'react'
|
||||
import { Image } from 'react-native'
|
||||
import { imageMessage, size } from '../../../../jest/fixtures'
|
||||
import { ImageMessage } from '../ImageMessage'
|
||||
|
||||
describe('text message', () => {
|
||||
it('gets image size and renders', () => {
|
||||
expect.assertions(4)
|
||||
const getSizeMock = jest.spyOn(Image, 'getSize')
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
getSizeMock.mockImplementation(() => {})
|
||||
const message = { ...imageMessage, height: undefined, width: undefined }
|
||||
const onPress = jest.fn()
|
||||
const { getByRole } = render(
|
||||
<ImageMessage message={message} onPress={onPress} />
|
||||
)
|
||||
expect(getSizeMock).toHaveBeenCalledTimes(1)
|
||||
const getSizeArgs = getSizeMock.mock.calls[0]
|
||||
expect(getSizeArgs[0]).toBe(imageMessage.imageUrl)
|
||||
const success = getSizeArgs[1]
|
||||
const error = getSizeArgs[2]
|
||||
act(() => {
|
||||
success(size.width, size.height)
|
||||
})
|
||||
const successImageComponent = getByRole('image')
|
||||
expect(successImageComponent.props).toHaveProperty(
|
||||
'style.width',
|
||||
size.width
|
||||
)
|
||||
act(() => {
|
||||
error(new Error())
|
||||
})
|
||||
const errorImageComponent = getByRole('image')
|
||||
expect(errorImageComponent.props).toHaveProperty('style.width', 0)
|
||||
getSizeMock.mockRestore()
|
||||
})
|
||||
|
||||
it('handles press', () => {
|
||||
expect.assertions(1)
|
||||
const onPress = jest.fn()
|
||||
const { getByRole } = render(
|
||||
<ImageMessage message={imageMessage} onPress={onPress} />
|
||||
)
|
||||
const button = getByRole('image').parent
|
||||
fireEvent.press(button)
|
||||
expect(onPress).toHaveBeenCalledWith(imageMessage.imageUrl)
|
||||
})
|
||||
})
|
||||
1
src/components/ImageMessage/index.ts
Normal file
1
src/components/ImageMessage/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './ImageMessage'
|
||||
12
src/components/ImageMessage/styles.ts
Normal file
12
src/components/ImageMessage/styles.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { StyleSheet } from 'react-native'
|
||||
import { Size } from '../../types'
|
||||
|
||||
const styles = ({ size }: { size: Size }) =>
|
||||
StyleSheet.create({
|
||||
image: {
|
||||
aspectRatio: size.height > 0 ? size.width / size.height : 1,
|
||||
width: size.width < 520 ? size.width : '100%',
|
||||
},
|
||||
})
|
||||
|
||||
export default styles
|
||||
@@ -1,19 +1,24 @@
|
||||
import { KeyboardAccessoryView } from '@flyerhq/react-native-keyboard-accessory-view'
|
||||
import * as React from 'react'
|
||||
import { Animated, TextInput, TextInputProps, View } from 'react-native'
|
||||
import { Message, User } from '../../types'
|
||||
import { uuidv4 } from '../../utils'
|
||||
import {
|
||||
Animated,
|
||||
StyleSheet,
|
||||
TextInput,
|
||||
TextInputProps,
|
||||
View,
|
||||
} from 'react-native'
|
||||
import { MessageType, SendImageCallback } from '../../types'
|
||||
import { UserContext, uuidv4 } from '../../utils'
|
||||
import { AttachmentButton } from '../AttachmentButton'
|
||||
import { SendButton } from '../SendButton'
|
||||
import styles from './styles'
|
||||
|
||||
export interface InputProps {
|
||||
onAttachmentPress?: () => void
|
||||
onAttachmentPress?: (send: SendImageCallback) => void
|
||||
onContentBottomInsetUpdate?: (contentBottomInset: number) => void
|
||||
onSendPress: (message: Message) => void
|
||||
onSendPress: (message: MessageType.Any) => void
|
||||
panResponderPositionY?: Animated.Value
|
||||
textInputProps?: TextInputProps
|
||||
user: User
|
||||
}
|
||||
|
||||
export const Input = ({
|
||||
@@ -22,13 +27,21 @@ export const Input = ({
|
||||
onSendPress,
|
||||
panResponderPositionY,
|
||||
textInputProps,
|
||||
user,
|
||||
}: InputProps) => {
|
||||
const user = React.useContext(UserContext)
|
||||
// Use `defaultValue` if provided
|
||||
const [text, setText] = React.useState(textInputProps?.defaultValue ?? '')
|
||||
|
||||
const value = textInputProps?.value ?? text
|
||||
|
||||
const defaultMessageParams = () => ({
|
||||
// Buttons only rendered when the user exists, so we can safely force unwrap it
|
||||
/* type-coverage:ignore-next-line */ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
authorId: user!.id,
|
||||
id: uuidv4(),
|
||||
timestamp: Math.floor(Date.now() / 1000),
|
||||
})
|
||||
|
||||
const handleChangeText = (newText: string) => {
|
||||
// Track local state in case `onChangeText` is provided and `value` is not
|
||||
setText(newText)
|
||||
@@ -37,14 +50,29 @@ export const Input = ({
|
||||
|
||||
const handleSend = () => {
|
||||
onSendPress({
|
||||
authorId: user.id,
|
||||
id: uuidv4(),
|
||||
text: value,
|
||||
timestamp: Math.floor(Date.now() / 1000),
|
||||
...defaultMessageParams(),
|
||||
text: value.trim(),
|
||||
type: 'text',
|
||||
})
|
||||
setText('')
|
||||
}
|
||||
|
||||
// TODO: This function is binded to the `onAttachmentPress`, how to mock this in tests?
|
||||
/* istanbul ignore next */
|
||||
const handleSendImage = ({
|
||||
height,
|
||||
imageUrl,
|
||||
width,
|
||||
}: Parameters<SendImageCallback>[0]) => {
|
||||
onSendPress({
|
||||
...defaultMessageParams(),
|
||||
height,
|
||||
imageUrl,
|
||||
type: 'image',
|
||||
width,
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<KeyboardAccessoryView
|
||||
onContentBottomInsetUpdate={onContentBottomInsetUpdate}
|
||||
@@ -52,7 +80,11 @@ export const Input = ({
|
||||
style={styles.keyboardAccessoryView}
|
||||
>
|
||||
<View style={styles.container}>
|
||||
<AttachmentButton onPress={onAttachmentPress} />
|
||||
{user && (
|
||||
<AttachmentButton
|
||||
onPress={onAttachmentPress?.bind(null, handleSendImage)}
|
||||
/>
|
||||
)}
|
||||
<TextInput
|
||||
multiline
|
||||
placeholder='Your message here'
|
||||
@@ -60,11 +92,11 @@ export const Input = ({
|
||||
underlineColorAndroid='transparent'
|
||||
{...textInputProps}
|
||||
// Keep our implementation but allow user to use these `TextInputProps`
|
||||
style={[styles.input, textInputProps?.style]}
|
||||
style={StyleSheet.flatten([styles.input, textInputProps?.style])}
|
||||
onChangeText={handleChangeText}
|
||||
value={value}
|
||||
/>
|
||||
<SendButton onPress={handleSend} />
|
||||
{user && value.trim() ? <SendButton onPress={handleSend} /> : null}
|
||||
</View>
|
||||
</KeyboardAccessoryView>
|
||||
)
|
||||
|
||||
@@ -1,100 +1,123 @@
|
||||
import { fireEvent, render } from '@testing-library/react-native'
|
||||
import * as React from 'react'
|
||||
import { fireEvent, render } from 'react-native-testing-library'
|
||||
import { message, user } from '../../../../jest/fixtures'
|
||||
import { textMessage, user } from '../../../../jest/fixtures'
|
||||
import { UserContext } from '../../../utils'
|
||||
import { Input } from '../Input'
|
||||
|
||||
describe('input', () => {
|
||||
it('sends a correct message', () => {
|
||||
it('sends a text message', () => {
|
||||
expect.assertions(2)
|
||||
const onSendPress = jest.fn()
|
||||
const { getByPlaceholder, getByA11yLabel } = render(
|
||||
<Input onSendPress={onSendPress} user={user} />
|
||||
const { getByPlaceholderText, getByLabelText } = render(
|
||||
<UserContext.Provider value={user}>
|
||||
<Input onSendPress={onSendPress} />
|
||||
</UserContext.Provider>
|
||||
)
|
||||
const textInput = getByPlaceholder('Your message here')
|
||||
const button = getByA11yLabel('Send a message')
|
||||
const textInput = getByPlaceholderText('Your message here')
|
||||
fireEvent.changeText(textInput, 'text')
|
||||
const button = getByLabelText('Send a message')
|
||||
fireEvent.press(button)
|
||||
expect(onSendPress).toHaveBeenCalledWith(message)
|
||||
expect(textInput.props.value).toStrictEqual('')
|
||||
expect(onSendPress).toHaveBeenCalledWith(textMessage)
|
||||
expect(textInput.props).toHaveProperty('value', '')
|
||||
})
|
||||
|
||||
it('sends a correct message if onChangeText and value are provided', () => {
|
||||
it('sends a text message if onChangeText and value are provided', () => {
|
||||
expect.assertions(2)
|
||||
const onSendPress = jest.fn()
|
||||
const value = 'value'
|
||||
const onChangeText = jest.fn((newValue) => {
|
||||
rerender(
|
||||
<Input
|
||||
onSendPress={onSendPress}
|
||||
textInputProps={{ onChangeText, value: newValue }}
|
||||
user={user}
|
||||
/>
|
||||
<UserContext.Provider value={user}>
|
||||
<Input
|
||||
onSendPress={onSendPress}
|
||||
textInputProps={{ onChangeText, value: newValue }}
|
||||
/>
|
||||
</UserContext.Provider>
|
||||
)
|
||||
})
|
||||
const { getByPlaceholder, getByA11yLabel, rerender } = render(
|
||||
<Input
|
||||
onSendPress={onSendPress}
|
||||
textInputProps={{ onChangeText, value }}
|
||||
user={user}
|
||||
/>
|
||||
const { getByPlaceholderText, getByLabelText, rerender } = render(
|
||||
<UserContext.Provider value={user}>
|
||||
<Input
|
||||
onSendPress={onSendPress}
|
||||
textInputProps={{ onChangeText, value }}
|
||||
/>
|
||||
</UserContext.Provider>
|
||||
)
|
||||
const textInput = getByPlaceholder('Your message here')
|
||||
const button = getByA11yLabel('Send a message')
|
||||
const textInput = getByPlaceholderText('Your message here')
|
||||
fireEvent.changeText(textInput, 'text')
|
||||
const button = getByLabelText('Send a message')
|
||||
fireEvent.press(button)
|
||||
expect(onSendPress).toHaveBeenCalledWith(message)
|
||||
expect(textInput.props.value).toStrictEqual('text')
|
||||
expect(onSendPress).toHaveBeenCalledWith(textMessage)
|
||||
expect(textInput.props).toHaveProperty('value', 'text')
|
||||
})
|
||||
|
||||
it('sends a correct message if onChangeText is provided', () => {
|
||||
it('sends a text message if onChangeText is provided', () => {
|
||||
expect.assertions(2)
|
||||
const onSendPress = jest.fn()
|
||||
const onChangeText = jest.fn()
|
||||
const { getByPlaceholder, getByA11yLabel } = render(
|
||||
<Input
|
||||
onSendPress={onSendPress}
|
||||
textInputProps={{ onChangeText }}
|
||||
user={user}
|
||||
/>
|
||||
const { getByPlaceholderText, getByLabelText } = render(
|
||||
<UserContext.Provider value={user}>
|
||||
<Input onSendPress={onSendPress} textInputProps={{ onChangeText }} />
|
||||
</UserContext.Provider>
|
||||
)
|
||||
const textInput = getByPlaceholder('Your message here')
|
||||
const button = getByA11yLabel('Send a message')
|
||||
const textInput = getByPlaceholderText('Your message here')
|
||||
fireEvent.changeText(textInput, 'text')
|
||||
const button = getByLabelText('Send a message')
|
||||
fireEvent.press(button)
|
||||
expect(onSendPress).toHaveBeenCalledWith(message)
|
||||
expect(textInput.props.value).toStrictEqual('')
|
||||
expect(onSendPress).toHaveBeenCalledWith(textMessage)
|
||||
expect(textInput.props).toHaveProperty('value', '')
|
||||
})
|
||||
|
||||
it('sends a correct message if value is provided', () => {
|
||||
it('sends a text message if value is provided', () => {
|
||||
expect.assertions(2)
|
||||
const onSendPress = jest.fn()
|
||||
const value = 'value'
|
||||
const { getByPlaceholder, getByA11yLabel } = render(
|
||||
<Input onSendPress={onSendPress} textInputProps={{ value }} user={user} />
|
||||
const { getByPlaceholderText, getByLabelText } = render(
|
||||
<UserContext.Provider value={user}>
|
||||
<Input onSendPress={onSendPress} textInputProps={{ value }} />
|
||||
</UserContext.Provider>
|
||||
)
|
||||
const textInput = getByPlaceholder('Your message here')
|
||||
const button = getByA11yLabel('Send a message')
|
||||
const textInput = getByPlaceholderText('Your message here')
|
||||
fireEvent.changeText(textInput, 'text')
|
||||
const button = getByLabelText('Send a message')
|
||||
fireEvent.press(button)
|
||||
expect(onSendPress).toHaveBeenCalledWith({ ...message, text: value })
|
||||
expect(textInput.props.value).toStrictEqual(value)
|
||||
expect(onSendPress).toHaveBeenCalledWith({ ...textMessage, text: value })
|
||||
expect(textInput.props).toHaveProperty('value', value)
|
||||
})
|
||||
|
||||
it('sends a correct message if defaultValue is provided', () => {
|
||||
it('sends a text message if defaultValue is provided', () => {
|
||||
expect.assertions(2)
|
||||
const onSendPress = jest.fn()
|
||||
const defaultValue = 'defaultValue'
|
||||
const { getByPlaceholder, getByA11yLabel } = render(
|
||||
<Input
|
||||
onSendPress={onSendPress}
|
||||
textInputProps={{ defaultValue }}
|
||||
user={user}
|
||||
/>
|
||||
const { getByPlaceholderText, getByLabelText } = render(
|
||||
<UserContext.Provider value={user}>
|
||||
<Input onSendPress={onSendPress} textInputProps={{ defaultValue }} />
|
||||
</UserContext.Provider>
|
||||
)
|
||||
const textInput = getByPlaceholder('Your message here')
|
||||
const button = getByA11yLabel('Send a message')
|
||||
const textInput = getByPlaceholderText('Your message here')
|
||||
const button = getByLabelText('Send a message')
|
||||
fireEvent.press(button)
|
||||
expect(onSendPress).toHaveBeenCalledWith({ ...message, text: defaultValue })
|
||||
expect(textInput.props.value).toStrictEqual('')
|
||||
expect(onSendPress).toHaveBeenCalledWith({
|
||||
...textMessage,
|
||||
text: defaultValue,
|
||||
})
|
||||
expect(textInput.props).toHaveProperty('value', '')
|
||||
})
|
||||
|
||||
it('sends an image message', () => {
|
||||
expect.assertions(1)
|
||||
const onAttachmentPress = jest.fn()
|
||||
const onSendPress = jest.fn()
|
||||
const { getByLabelText } = render(
|
||||
<UserContext.Provider value={user}>
|
||||
<Input
|
||||
onAttachmentPress={onAttachmentPress}
|
||||
onSendPress={onSendPress}
|
||||
/>
|
||||
</UserContext.Provider>
|
||||
)
|
||||
const button = getByLabelText('Add an attachment')
|
||||
fireEvent.press(button)
|
||||
expect(onAttachmentPress).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -2,27 +2,26 @@ import { StyleSheet } from 'react-native'
|
||||
|
||||
export default StyleSheet.create({
|
||||
container: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
padding: 24,
|
||||
flexDirection: 'row',
|
||||
paddingHorizontal: 24,
|
||||
paddingVertical: 20,
|
||||
},
|
||||
input: {
|
||||
color: '#fff',
|
||||
flex: 1,
|
||||
fontSize: 16,
|
||||
fontWeight: '500',
|
||||
lineHeight: 20,
|
||||
maxHeight: 200,
|
||||
// Fixes default Android paddings
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
// Fixes default paddings
|
||||
paddingBottom: 0,
|
||||
paddingHorizontal: 16,
|
||||
paddingBottom: 8,
|
||||
// Fixes iOS top padding for multiline
|
||||
paddingTop: 8,
|
||||
flex: 1,
|
||||
paddingTop: 0,
|
||||
},
|
||||
keyboardAccessoryView: {
|
||||
backgroundColor: '#000',
|
||||
borderTopLeftRadius: 24,
|
||||
borderTopRightRadius: 24,
|
||||
borderTopLeftRadius: 20,
|
||||
borderTopRightRadius: 20,
|
||||
},
|
||||
})
|
||||
|
||||
44
src/components/Message/Message.tsx
Normal file
44
src/components/Message/Message.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import * as React from 'react'
|
||||
import { View } from 'react-native'
|
||||
import { MessageType, Size } from '../../types'
|
||||
import { UserContext } from '../../utils'
|
||||
import { ImageMessage } from '../ImageMessage'
|
||||
import { TextMessage } from '../TextMessage'
|
||||
import styles from './styles'
|
||||
|
||||
export interface MessageProps {
|
||||
message: MessageType.Any
|
||||
onImagePress: (imageUrl: string) => void
|
||||
parentComponentSize: Size
|
||||
previousMessageSameAuthor: boolean
|
||||
}
|
||||
|
||||
export const Message = ({
|
||||
message,
|
||||
onImagePress,
|
||||
parentComponentSize,
|
||||
previousMessageSameAuthor,
|
||||
}: MessageProps) => {
|
||||
const user = React.useContext(UserContext)
|
||||
const { container, contentContainer } = styles({
|
||||
message,
|
||||
parentComponentSize,
|
||||
previousMessageSameAuthor,
|
||||
user,
|
||||
})
|
||||
|
||||
const renderMessage = () => {
|
||||
switch (message.type) {
|
||||
case 'image':
|
||||
return <ImageMessage message={message} onPress={onImagePress} />
|
||||
case 'text':
|
||||
return <TextMessage message={message} />
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={container}>
|
||||
<View style={contentContainer}>{renderMessage()}</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
1
src/components/Message/index.ts
Normal file
1
src/components/Message/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './Message'
|
||||
39
src/components/Message/styles.ts
Normal file
39
src/components/Message/styles.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { StyleSheet } from 'react-native'
|
||||
import { MessageType, Size, User } from '../../types'
|
||||
|
||||
const styles = ({
|
||||
message,
|
||||
parentComponentSize,
|
||||
previousMessageSameAuthor,
|
||||
user,
|
||||
}: {
|
||||
message: MessageType.Any
|
||||
parentComponentSize: Size
|
||||
previousMessageSameAuthor: boolean
|
||||
user?: User
|
||||
}) =>
|
||||
StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
justifyContent: user?.id === message.authorId ? 'flex-end' : 'flex-start',
|
||||
marginBottom: previousMessageSameAuthor ? 8 : 24,
|
||||
},
|
||||
contentContainer: {
|
||||
backgroundColor:
|
||||
user?.id !== message.authorId || message.type === 'image'
|
||||
? '#f7f7f8'
|
||||
: '#6054c9',
|
||||
borderBottomLeftRadius: user?.id === message.authorId ? 20 : 0,
|
||||
borderBottomRightRadius: user?.id === message.authorId ? 0 : 20,
|
||||
borderRadius: 20,
|
||||
marginHorizontal: 24,
|
||||
maxWidth:
|
||||
parentComponentSize.width * 0.8 < 520
|
||||
? parentComponentSize.width * 0.8
|
||||
: 520,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
})
|
||||
|
||||
export default styles
|
||||
@@ -7,13 +7,11 @@ import {
|
||||
} from 'react-native'
|
||||
|
||||
export interface SendButtonProps {
|
||||
disabled?: boolean
|
||||
onPress: () => void
|
||||
touchableOpacityProps?: TouchableOpacityProps
|
||||
}
|
||||
|
||||
export const SendButton = ({
|
||||
disabled,
|
||||
onPress,
|
||||
touchableOpacityProps,
|
||||
}: SendButtonProps) => {
|
||||
@@ -26,8 +24,6 @@ export const SendButton = ({
|
||||
<TouchableOpacity
|
||||
accessibilityRole='button'
|
||||
accessibilityLabel='Send a message'
|
||||
accessibilityState={{ disabled }}
|
||||
disabled={disabled}
|
||||
{...touchableOpacityProps}
|
||||
onPress={handlePress}
|
||||
>
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
import * as React from 'react'
|
||||
import { fireEvent, render } from 'react-native-testing-library'
|
||||
import { SendButton } from '../SendButton'
|
||||
|
||||
describe('send button', () => {
|
||||
it('sends an event', () => {
|
||||
expect.assertions(1)
|
||||
const onPress = jest.fn()
|
||||
const { getByA11yLabel } = render(<SendButton onPress={onPress} />)
|
||||
const button = getByA11yLabel('Send a message')
|
||||
fireEvent.press(button)
|
||||
expect(onPress).toHaveBeenCalledWith()
|
||||
})
|
||||
})
|
||||
@@ -1,32 +1,23 @@
|
||||
import * as React from 'react'
|
||||
import { Text, View } from 'react-native'
|
||||
import { Message, Size, User } from '../../types'
|
||||
import { Text } from 'react-native'
|
||||
import { MessageType } from '../../types'
|
||||
import { UserContext } from '../../utils'
|
||||
import styles from './styles'
|
||||
|
||||
export interface TextMessageProps {
|
||||
message: Message
|
||||
parentComponentSize: Size
|
||||
user: User
|
||||
message: MessageType.Text
|
||||
}
|
||||
|
||||
export const TextMessage = ({
|
||||
message,
|
||||
parentComponentSize,
|
||||
user,
|
||||
}: TextMessageProps) => {
|
||||
const { container, message: messageStyle, messageContainer } = styles({
|
||||
export const TextMessage = ({ message }: TextMessageProps) => {
|
||||
const user = React.useContext(UserContext)
|
||||
const { text } = styles({
|
||||
message,
|
||||
parentComponentSize,
|
||||
user,
|
||||
})
|
||||
|
||||
return (
|
||||
<View style={container}>
|
||||
<View style={messageContainer}>
|
||||
<Text accessibilityRole='text' style={messageStyle}>
|
||||
{message.text}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<Text accessibilityRole='text' style={text}>
|
||||
{message.text}
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import * as React from 'react'
|
||||
import { render } from 'react-native-testing-library'
|
||||
import { message, size, user } from '../../../../jest/fixtures'
|
||||
import { TextMessage } from '../TextMessage'
|
||||
|
||||
describe('text message', () => {
|
||||
it('renders text', () => {
|
||||
expect.assertions(1)
|
||||
const text = 'text'
|
||||
const { getByText } = render(
|
||||
<TextMessage message={message} parentComponentSize={size} user={user} />
|
||||
)
|
||||
const textComponent = getByText(text)
|
||||
expect(textComponent).toBeDefined()
|
||||
})
|
||||
})
|
||||
@@ -1,42 +1,21 @@
|
||||
import { StyleSheet } from 'react-native'
|
||||
import { Message, Size, User } from '../../types'
|
||||
import { MessageType, User } from '../../types'
|
||||
|
||||
const styles = ({
|
||||
message,
|
||||
parentComponentSize,
|
||||
user,
|
||||
}: {
|
||||
message: Message
|
||||
parentComponentSize: Size
|
||||
user: User
|
||||
message: MessageType.Text
|
||||
user?: User
|
||||
}) =>
|
||||
StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
marginVertical: 8,
|
||||
justifyContent: user.id === message.authorId ? 'flex-end' : 'flex-start',
|
||||
},
|
||||
messageContainer: {
|
||||
paddingHorizontal: 24,
|
||||
marginHorizontal: 24,
|
||||
paddingVertical: 20,
|
||||
borderRadius: 16,
|
||||
overflow: 'hidden',
|
||||
borderWidth: 1,
|
||||
borderBottomLeftRadius: user.id === message.authorId ? 16 : 0,
|
||||
borderBottomRightRadius: user.id === message.authorId ? 0 : 16,
|
||||
borderColor: user.id === message.authorId ? '#00cdbd' : '#72738e1f',
|
||||
backgroundColor: user.id === message.authorId ? '#00cdbd' : '#fff',
|
||||
maxWidth:
|
||||
parentComponentSize.width * 0.9 < 520
|
||||
? parentComponentSize.width * 0.9
|
||||
: 520,
|
||||
},
|
||||
message: {
|
||||
text: {
|
||||
color: user?.id === message.authorId ? '#fff' : '#2e2c2c',
|
||||
fontSize: 16,
|
||||
fontWeight: '500',
|
||||
color: user.id === message.authorId ? '#fff' : '#2e2c2c',
|
||||
lineHeight: 20,
|
||||
marginHorizontal: 24,
|
||||
marginVertical: 16,
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
export * from './AttachmentButton'
|
||||
export * from './Chat'
|
||||
export * from './ImageMessage'
|
||||
export * from './Input'
|
||||
export * from './Message'
|
||||
export * from './SendButton'
|
||||
export * from './TextMessage'
|
||||
|
||||
32
src/types.ts
32
src/types.ts
@@ -1,10 +1,32 @@
|
||||
export interface Message {
|
||||
authorId: string
|
||||
id: string
|
||||
text: string
|
||||
timestamp: number
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
export namespace MessageType {
|
||||
export type Any = Image | Text
|
||||
|
||||
interface Base {
|
||||
authorId: string
|
||||
id: string
|
||||
timestamp: number
|
||||
}
|
||||
|
||||
export interface Image extends Base {
|
||||
height?: number
|
||||
imageUrl: string
|
||||
type: 'image'
|
||||
width?: number
|
||||
}
|
||||
|
||||
export interface Text extends Base {
|
||||
text: string
|
||||
type: 'text'
|
||||
}
|
||||
}
|
||||
|
||||
export type SendImageCallback = (payload: {
|
||||
height?: number
|
||||
imageUrl: string
|
||||
width?: number
|
||||
}) => void
|
||||
|
||||
export interface Size {
|
||||
height: number
|
||||
width: number
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import * as React from 'react'
|
||||
import Blob from 'react-native/Libraries/Blob/Blob'
|
||||
import { User } from '../types'
|
||||
|
||||
export const UserContext = React.createContext<User | undefined>(undefined)
|
||||
|
||||
export const getTextSizeInBytes = (text: string) => {
|
||||
return new Blob([text]).size
|
||||
|
||||
Reference in New Issue
Block a user