regression: Rollback to React Native 0.69.8 (#5162)

This commit is contained in:
Diego Mello 2023-08-18 14:48:33 -03:00 committed by GitHub
parent 65b409beb0
commit 529891fcc0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
140 changed files with 4888 additions and 3887 deletions

6
.buckconfig Normal file
View File

@ -0,0 +1,6 @@
[android]
target = Google Inc.:Google APIs:23
[maven_repositories]
central = https://repo1.maven.org/maven2

View File

@ -1,10 +1,6 @@
defaults: &defaults
working_directory: ~/repo
android-img: &android-img
docker:
- image: cimg/android:2023.04.1-node
orbs:
android: circleci/android@2.1.2
@ -58,13 +54,14 @@ save-gems-cache: &save-gems-cache
update-fastlane-ios: &update-fastlane-ios
name: Update Fastlane
command: |
echo "ruby-2.7.7" > ~/.ruby-version
bundle install
working_directory: ios
update-fastlane-android: &update-fastlane-android
name: Update Fastlane
command: |
bundle config set --local deployment 'true'
echo "ruby-2.7.7" > ~/.ruby-version
bundle install
working_directory: android
@ -114,10 +111,10 @@ commands:
name: Configure Gradle
command: |
echo -e "" > ./gradle.properties
# echo -e "android.enableAapt2=false" >> ./gradle.properties
echo -e "android.useAndroidX=true" >> ./gradle.properties
echo -e "android.enableJetifier=true" >> ./gradle.properties
echo -e "newArchEnabled=false" >> ./gradle.properties
echo -e "hermesEnabled=true" >> ./gradle.properties
echo -e "FLIPPER_VERSION=0.125.0" >> ./gradle.properties
echo -e "VERSIONCODE=$CIRCLE_BUILD_NUM" >> ./gradle.properties
@ -150,9 +147,7 @@ commands:
- run:
name: Build App
no_output_timeout: 40m
command: |
sudo apt install -y libicu-dev
if [[ $CIRCLE_JOB == "android-build-official" ]]; then
./gradlew bundleOfficialPlayRelease
fi
@ -172,16 +167,16 @@ commands:
--api-key=$BUGSNAG_KEY_OFFICIAL \
--app-version-code=$CIRCLE_BUILD_NUM \
--platform android \
--source-map=android/app/build/generated/sourcemaps/react/officialPlayRelease/index.android.bundle.map \
--bundle android/app/build/ASSETS/createBundleOfficialPlayReleaseJsAndAssets/index.android.bundle
--source-map=android/app/build/generated/sourcemaps/react/officialPlay/release/app.bundle.map \
--bundle android/app/build/generated/assets/react/officialPlay/release/app.bundle
fi
if [[ $CIRCLE_JOB == "android-build-experimental" || "android-automatic-build-experimental" ]]; then
npx bugsnag-source-maps upload-react-native \
--api-key=$BUGSNAG_KEY \
--app-version-code=$CIRCLE_BUILD_NUM \
--platform android \
--source-map=android/app/build/generated/sourcemaps/react/experimentalPlayRelease/index.android.bundle.map \
--bundle android/app/build/ASSETS/createBundleExperimentalPlayReleaseJsAndAssets/index.android.bundle
--source-map=android/app/build/generated/sourcemaps/react/experimentalPlay/release/app.bundle.map \
--bundle android/app/build/generated/assets/react/experimentalPlay/release/app.bundle
fi
- store_artifacts:
@ -389,45 +384,50 @@ jobs:
# Android builds
android-build-experimental:
<<: *defaults
<<: *android-img
docker:
- image: cimg/android:2022.03.1-node
environment:
<<: *android-env
<<: *bash-env
resource_class: xlarge
resource_class: large
steps:
- android-build
# Android automatic builds
android-automatic-build-experimental:
<<: *defaults
<<: *android-img
docker:
- image: circleci/android:api-29-node
environment:
<<: *android-env
<<: *bash-env
resource_class: xlarge
resource_class: large
steps:
- android-build
android-build-official:
<<: *defaults
<<: *android-img
docker:
- image: cimg/android:2022.03.1-node
environment:
<<: *android-env
<<: *bash-env
resource_class: xlarge
resource_class: large
steps:
- android-build
android-internal-app-sharing-experimental:
<<: *defaults
<<: *android-img
docker:
- image: cimg/android:2022.03.1-node
steps:
- upload-to-internal-app-sharing
android-google-play-beta-experimental:
<<: *defaults
<<: *android-img
docker:
- image: cimg/android:2022.03.1-node
steps:
- upload-to-google-play-beta:
@ -435,13 +435,15 @@ jobs:
android-google-play-production-experimental:
<<: *defaults
<<: *android-img
docker:
- image: cimg/android:2022.03.1-node
steps:
- upload-to-google-play-production
android-google-play-beta-official:
<<: *defaults
<<: *android-img
docker:
- image: cimg/android:2022.03.1-node
steps:
- upload-to-google-play-beta:
@ -452,7 +454,7 @@ jobs:
executor:
name: android/android-machine
resource-class: xlarge
tag: 2023.04.1
tag: 2022.12.1
environment:
<<: *android-env
steps:
@ -469,7 +471,6 @@ jobs:
echo -e "android.useAndroidX=true" >> ./gradle.properties
echo -e "android.enableJetifier=true" >> ./gradle.properties
echo -e "newArchEnabled=false" >> ./gradle.properties
echo -e "hermesEnabled=true" >> ./gradle.properties
echo -e "FLIPPER_VERSION=0.125.0" >> ./gradle.properties
echo -e "VERSIONCODE=$CIRCLE_BUILD_NUM" >> ./gradle.properties
echo -e "APPLICATION_ID=chat.rocket.reactnative" >> ./gradle.properties
@ -482,7 +483,6 @@ jobs:
working_directory: android
- run:
name: Build Android
no_output_timeout: 20m
command: |
export RUNNING_E2E_TESTS=true
yarn e2e:android-build
@ -501,7 +501,7 @@ jobs:
executor:
name: android/android-machine
resource-class: xlarge
tag: 2023.04.1
tag: 2022.12.1
parallelism: 4
steps:
- checkout
@ -522,10 +522,6 @@ jobs:
echo "hw.lcd.density = 440" >> ~/.android/avd/Pixel_API_31_AOSP.avd/config.ini
echo "hw.lcd.height = 2280" >> ~/.android/avd/Pixel_API_31_AOSP.avd/config.ini
echo "hw.lcd.width = 1080" >> ~/.android/avd/Pixel_API_31_AOSP.avd/config.ini
- android/start-emulator:
avd-name: Pixel_API_31_AOSP
verbose: true
post-emulator-launch-assemble-command: ''
- run:
name: Run Detox Tests
command: |
@ -582,7 +578,6 @@ jobs:
brew install applesimutils
- run:
name: Build
no_output_timeout: 20m
command: |
/usr/libexec/PlistBuddy -c "Set :bugsnag:apiKey $BUGSNAG_KEY" ./ios/RocketChatRN/Info.plist
/usr/libexec/PlistBuddy -c "Set :bugsnag:apiKey $BUGSNAG_KEY" ./ios/ShareRocketChatRN/Info.plist

2
.env
View File

@ -1,2 +0,0 @@
# DON'T COMMIT CHANGES ON THIS FILE
RUNNING_E2E_TESTS=

19
.gitignore vendored
View File

@ -24,7 +24,6 @@ project.xcworkspace
*.mobileprovision
ios/Pods/
/vendor/bundle/
ios/.xcode.env.local
# Android/IntelliJ
#
@ -33,10 +32,6 @@ build/
.gradle
local.properties
*.iml
.cxx/
*.keystore
!debug.keystore
*.jks
# node.js
#
@ -46,6 +41,12 @@ yarn-error.log
coverage/
# BUCK
buck-out/
\.buckd/
*.keystore
*.jks
# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
@ -62,10 +63,10 @@ coverage
artifacts
.vscode/
e2e/docker/rc_test_env/docker-compose.yml
e2e/docker/data/db
e2e/e2e_account.js
e2e/e2e_account.ts
junit.xml
*.p8
# Temporary files created by Metro to check the health of the file watcher
.metro-health-check*
*.p8

View File

@ -1 +0,0 @@
18

1
.ruby-version Normal file
View File

@ -0,0 +1 @@
2.7.7

View File

@ -1,6 +1,4 @@
source 'https://rubygems.org'
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
ruby '>= 2.6.10'
gem 'cocoapods', '>= 1.11.3'
ruby '2.7.7'
gem 'cocoapods', '~> 1.11', '>= 1.11.2'

View File

@ -26,7 +26,7 @@ exports[`Storyshots Avatar Room Avatar External Provider Url 1`] = `"{\\"type\\"
exports[`Storyshots Avatar Static 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://user-images.githubusercontent.com/29778115/89444446-14738480-d728-11ea-9412-75fd978d95fb.jpg\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`;
exports[`Storyshots Avatar Touchable 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityState\\":{},\\"accessibilityValue\\":{},\\"focusable\\":true,\\"collapsable\\":false,\\"style\\":{\\"opacity\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/Avatar?format=png&size=112\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}]}"`;
exports[`Storyshots Avatar Touchable 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"focusable\\":true,\\"collapsable\\":false,\\"style\\":{\\"opacity\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/Avatar?format=png&size=112\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}]}"`;
exports[`Storyshots Avatar With E Tag 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4},null],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":56,\\"height\\":56,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/djorkaeff.alexandre?format=png&size=112&etag=5ag8KffJcZj9m5rCv\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]}"`;

View File

@ -1,13 +1,13 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Storyshots Button Custom Button 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityLabel\\":\\"Press me!\\",\\"accessibilityState\\":{\\"disabled\\":false},\\"accessibilityValue\\":{},\\"testID\\":\\"testButton\\",\\"focusable\\":true,\\"collapsable\\":false,\\"style\\":{\\"paddingHorizontal\\":14,\\"justifyContent\\":\\"center\\",\\"height\\":48,\\"borderRadius\\":4,\\"marginBottom\\":12,\\"backgroundColor\\":\\"purple\\",\\"padding\\":10,\\"opacity\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"textAlign\\":\\"center\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"yellow\\",\\"fontSize\\":18},[{\\"textAlign\\":\\"left\\"}]],\\"accessibilityLabel\\":\\"Press me!\\"},\\"children\\":[\\"Press me!\\"]}]}"`;
exports[`Storyshots Button Custom Button 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityLabel\\":\\"Press me!\\",\\"accessibilityState\\":{\\"disabled\\":false},\\"testID\\":\\"testButton\\",\\"focusable\\":true,\\"collapsable\\":false,\\"style\\":{\\"paddingHorizontal\\":14,\\"justifyContent\\":\\"center\\",\\"height\\":48,\\"borderRadius\\":4,\\"marginBottom\\":12,\\"backgroundColor\\":\\"purple\\",\\"padding\\":10,\\"opacity\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"textAlign\\":\\"center\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"yellow\\",\\"fontSize\\":18},[{\\"textAlign\\":\\"left\\"}]],\\"accessibilityLabel\\":\\"Press me!\\"},\\"children\\":[\\"Press me!\\"]}]}"`;
exports[`Storyshots Button Disabled Button 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityLabel\\":\\"Press me!\\",\\"accessibilityState\\":{\\"disabled\\":true},\\"accessibilityValue\\":{},\\"testID\\":\\"testButton\\",\\"focusable\\":true,\\"collapsable\\":false,\\"style\\":{\\"paddingHorizontal\\":14,\\"justifyContent\\":\\"center\\",\\"height\\":48,\\"borderRadius\\":4,\\"marginBottom\\":12,\\"backgroundColor\\":\\"#1d74f5\\",\\"opacity\\":0.3}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"textAlign\\":\\"center\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#ffffff\\",\\"fontSize\\":16},null],\\"accessibilityLabel\\":\\"Press me!\\"},\\"children\\":[\\"Press me!\\"]}]}"`;
exports[`Storyshots Button Disabled Button 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityLabel\\":\\"Press me!\\",\\"accessibilityState\\":{\\"disabled\\":true},\\"testID\\":\\"testButton\\",\\"focusable\\":true,\\"collapsable\\":false,\\"style\\":{\\"paddingHorizontal\\":14,\\"justifyContent\\":\\"center\\",\\"height\\":48,\\"borderRadius\\":4,\\"marginBottom\\":12,\\"backgroundColor\\":\\"#1d74f5\\",\\"opacity\\":0.3}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"textAlign\\":\\"center\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#ffffff\\",\\"fontSize\\":16},null],\\"accessibilityLabel\\":\\"Press me!\\"},\\"children\\":[\\"Press me!\\"]}]}"`;
exports[`Storyshots Button Disabled Loading Button 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityLabel\\":\\"Press me!\\",\\"accessibilityState\\":{\\"disabled\\":true},\\"accessibilityValue\\":{},\\"testID\\":\\"testButton\\",\\"focusable\\":true,\\"collapsable\\":false,\\"style\\":{\\"paddingHorizontal\\":14,\\"justifyContent\\":\\"center\\",\\"height\\":48,\\"borderRadius\\":4,\\"marginBottom\\":12,\\"backgroundColor\\":\\"#1d74f5\\",\\"opacity\\":0.3}},\\"children\\":[{\\"type\\":\\"ActivityIndicator\\",\\"props\\":{\\"style\\":[{\\"padding\\":16,\\"flex\\":1},null],\\"color\\":\\"#ffffff\\"},\\"children\\":null}]}"`;
exports[`Storyshots Button Disabled Loading Button 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityLabel\\":\\"Press me!\\",\\"accessibilityState\\":{\\"disabled\\":true},\\"testID\\":\\"testButton\\",\\"focusable\\":true,\\"collapsable\\":false,\\"style\\":{\\"paddingHorizontal\\":14,\\"justifyContent\\":\\"center\\",\\"height\\":48,\\"borderRadius\\":4,\\"marginBottom\\":12,\\"backgroundColor\\":\\"#1d74f5\\",\\"opacity\\":0.3}},\\"children\\":[{\\"type\\":\\"ActivityIndicator\\",\\"props\\":{\\"style\\":[{\\"padding\\":16,\\"flex\\":1},null],\\"color\\":\\"#ffffff\\"},\\"children\\":null}]}"`;
exports[`Storyshots Button Loading Button 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityLabel\\":\\"Press me!\\",\\"accessibilityState\\":{\\"disabled\\":true},\\"accessibilityValue\\":{},\\"testID\\":\\"testButton\\",\\"focusable\\":true,\\"collapsable\\":false,\\"style\\":{\\"paddingHorizontal\\":14,\\"justifyContent\\":\\"center\\",\\"height\\":48,\\"borderRadius\\":4,\\"marginBottom\\":12,\\"backgroundColor\\":\\"#1d74f5\\",\\"opacity\\":1}},\\"children\\":[{\\"type\\":\\"ActivityIndicator\\",\\"props\\":{\\"style\\":[{\\"padding\\":16,\\"flex\\":1},null],\\"color\\":\\"#ffffff\\"},\\"children\\":null}]}"`;
exports[`Storyshots Button Loading Button 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityLabel\\":\\"Press me!\\",\\"accessibilityState\\":{\\"disabled\\":true},\\"testID\\":\\"testButton\\",\\"focusable\\":true,\\"collapsable\\":false,\\"style\\":{\\"paddingHorizontal\\":14,\\"justifyContent\\":\\"center\\",\\"height\\":48,\\"borderRadius\\":4,\\"marginBottom\\":12,\\"backgroundColor\\":\\"#1d74f5\\",\\"opacity\\":1}},\\"children\\":[{\\"type\\":\\"ActivityIndicator\\",\\"props\\":{\\"style\\":[{\\"padding\\":16,\\"flex\\":1},null],\\"color\\":\\"#ffffff\\"},\\"children\\":null}]}"`;
exports[`Storyshots Button Primary Button 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityLabel\\":\\"Press me!\\",\\"accessibilityState\\":{\\"disabled\\":false},\\"accessibilityValue\\":{},\\"testID\\":\\"testButton\\",\\"focusable\\":true,\\"collapsable\\":false,\\"style\\":{\\"paddingHorizontal\\":14,\\"justifyContent\\":\\"center\\",\\"height\\":48,\\"borderRadius\\":4,\\"marginBottom\\":12,\\"backgroundColor\\":\\"#1d74f5\\",\\"opacity\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"textAlign\\":\\"center\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#ffffff\\",\\"fontSize\\":16},null],\\"accessibilityLabel\\":\\"Press me!\\"},\\"children\\":[\\"Press me!\\"]}]}"`;
exports[`Storyshots Button Primary Button 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityLabel\\":\\"Press me!\\",\\"accessibilityState\\":{\\"disabled\\":false},\\"testID\\":\\"testButton\\",\\"focusable\\":true,\\"collapsable\\":false,\\"style\\":{\\"paddingHorizontal\\":14,\\"justifyContent\\":\\"center\\",\\"height\\":48,\\"borderRadius\\":4,\\"marginBottom\\":12,\\"backgroundColor\\":\\"#1d74f5\\",\\"opacity\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"textAlign\\":\\"center\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#ffffff\\",\\"fontSize\\":16},null],\\"accessibilityLabel\\":\\"Press me!\\"},\\"children\\":[\\"Press me!\\"]}]}"`;
exports[`Storyshots Button Secondary Button 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityLabel\\":\\"Press me!\\",\\"accessibilityState\\":{\\"disabled\\":false},\\"accessibilityValue\\":{},\\"testID\\":\\"testButton\\",\\"focusable\\":true,\\"collapsable\\":false,\\"style\\":{\\"paddingHorizontal\\":14,\\"justifyContent\\":\\"center\\",\\"height\\":48,\\"borderRadius\\":4,\\"marginBottom\\":12,\\"backgroundColor\\":\\"#ffffff\\",\\"opacity\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"textAlign\\":\\"center\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#2f343d\\",\\"fontSize\\":16},null],\\"accessibilityLabel\\":\\"Press me!\\"},\\"children\\":[\\"Press me!\\"]}]}"`;
exports[`Storyshots Button Secondary Button 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityLabel\\":\\"Press me!\\",\\"accessibilityState\\":{\\"disabled\\":false},\\"testID\\":\\"testButton\\",\\"focusable\\":true,\\"collapsable\\":false,\\"style\\":{\\"paddingHorizontal\\":14,\\"justifyContent\\":\\"center\\",\\"height\\":48,\\"borderRadius\\":4,\\"marginBottom\\":12,\\"backgroundColor\\":\\"#ffffff\\",\\"opacity\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"textAlign\\":\\"center\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#2f343d\\",\\"fontSize\\":16},null],\\"accessibilityLabel\\":\\"Press me!\\"},\\"children\\":[\\"Press me!\\"]}]}"`;

View File

@ -1,11 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Storyshots Chip Chip Text 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"alignItems\\":\\"flex-start\\",\\"padding\\":16}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityState\\":{\\"disabled\\":false},\\"focusable\\":true,\\"accessibilityValue\\":{},\\"style\\":[{\\"paddingHorizontal\\":8,\\"marginRight\\":8,\\"borderRadius\\":4,\\"justifyContent\\":\\"center\\",\\"maxWidth\\":192},{\\"backgroundColor\\":\\"#efeff4\\"},null],\\"collapsable\\":false},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"center\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":28,\\"height\\":28,\\"borderRadius\\":4},{\\"marginRight\\":8,\\"marginVertical\\":8}],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":28,\\"height\\":28,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/rocket.cat?format=png&size=56\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginRight\\":8,\\"maxWidth\\":120}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#2f343d\\"}],\\"numberOfLines\\":1},\\"children\\":[\\"Rocket.Cat\\"]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"selectable\\":false,\\"allowFontScaling\\":false,\\"style\\":[{\\"fontSize\\":16,\\"color\\":\\"#6C727A\\"},null,{\\"fontFamily\\":\\"custom\\",\\"fontWeight\\":\\"normal\\",\\"fontStyle\\":\\"normal\\"},{}]},\\"children\\":[\\"\\"]}]}]}]}"`;
exports[`Storyshots Chip Chip Text 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"alignItems\\":\\"flex-start\\",\\"padding\\":16}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityState\\":{\\"disabled\\":false},\\"focusable\\":true,\\"style\\":[{\\"paddingHorizontal\\":8,\\"marginRight\\":8,\\"borderRadius\\":4,\\"justifyContent\\":\\"center\\",\\"maxWidth\\":192},{\\"backgroundColor\\":\\"#efeff4\\"},null],\\"collapsable\\":false},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"center\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":28,\\"height\\":28,\\"borderRadius\\":4},{\\"marginRight\\":8,\\"marginVertical\\":8}],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":28,\\"height\\":28,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/rocket.cat?format=png&size=56\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginRight\\":8,\\"maxWidth\\":120}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#2f343d\\"}],\\"numberOfLines\\":1},\\"children\\":[\\"Rocket.Cat\\"]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"selectable\\":false,\\"allowFontScaling\\":false,\\"style\\":[{\\"fontSize\\":16,\\"color\\":\\"#6C727A\\"},null,{\\"fontFamily\\":\\"custom\\",\\"fontWeight\\":\\"normal\\",\\"fontStyle\\":\\"normal\\"},{}]},\\"children\\":[\\"\\"]}]}]}]}"`;
exports[`Storyshots Chip Chip With Short Text 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"alignItems\\":\\"flex-start\\",\\"padding\\":16}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityState\\":{\\"disabled\\":false},\\"focusable\\":true,\\"accessibilityValue\\":{},\\"style\\":[{\\"paddingHorizontal\\":8,\\"marginRight\\":8,\\"borderRadius\\":4,\\"justifyContent\\":\\"center\\",\\"maxWidth\\":192},{\\"backgroundColor\\":\\"#efeff4\\"},null],\\"collapsable\\":false},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"center\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":28,\\"height\\":28,\\"borderRadius\\":4},{\\"marginRight\\":8,\\"marginVertical\\":8}],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":28,\\"height\\":28,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/rocket.cat?format=png&size=56\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginRight\\":8,\\"maxWidth\\":120}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#2f343d\\"}],\\"numberOfLines\\":1},\\"children\\":[\\"Short\\"]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"selectable\\":false,\\"allowFontScaling\\":false,\\"style\\":[{\\"fontSize\\":16,\\"color\\":\\"#6C727A\\"},null,{\\"fontFamily\\":\\"custom\\",\\"fontWeight\\":\\"normal\\",\\"fontStyle\\":\\"normal\\"},{}]},\\"children\\":[\\"\\"]}]}]}]}"`;
exports[`Storyshots Chip Chip With Short Text 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"alignItems\\":\\"flex-start\\",\\"padding\\":16}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityState\\":{\\"disabled\\":false},\\"focusable\\":true,\\"style\\":[{\\"paddingHorizontal\\":8,\\"marginRight\\":8,\\"borderRadius\\":4,\\"justifyContent\\":\\"center\\",\\"maxWidth\\":192},{\\"backgroundColor\\":\\"#efeff4\\"},null],\\"collapsable\\":false},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"center\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":28,\\"height\\":28,\\"borderRadius\\":4},{\\"marginRight\\":8,\\"marginVertical\\":8}],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":28,\\"height\\":28,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/rocket.cat?format=png&size=56\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginRight\\":8,\\"maxWidth\\":120}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#2f343d\\"}],\\"numberOfLines\\":1},\\"children\\":[\\"Short\\"]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"selectable\\":false,\\"allowFontScaling\\":false,\\"style\\":[{\\"fontSize\\":16,\\"color\\":\\"#6C727A\\"},null,{\\"fontFamily\\":\\"custom\\",\\"fontWeight\\":\\"normal\\",\\"fontStyle\\":\\"normal\\"},{}]},\\"children\\":[\\"\\"]}]}]}]}"`;
exports[`Storyshots Chip Chip Without Avatar 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"alignItems\\":\\"flex-start\\",\\"padding\\":16}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityState\\":{\\"disabled\\":false},\\"focusable\\":true,\\"accessibilityValue\\":{},\\"style\\":[{\\"paddingHorizontal\\":8,\\"marginRight\\":8,\\"borderRadius\\":4,\\"justifyContent\\":\\"center\\",\\"maxWidth\\":192},{\\"backgroundColor\\":\\"#efeff4\\"},null],\\"collapsable\\":false},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"center\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginRight\\":8,\\"maxWidth\\":120}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#2f343d\\"}],\\"numberOfLines\\":1},\\"children\\":[\\"Without Avatar\\"]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"selectable\\":false,\\"allowFontScaling\\":false,\\"style\\":[{\\"fontSize\\":16,\\"color\\":\\"#6C727A\\"},null,{\\"fontFamily\\":\\"custom\\",\\"fontWeight\\":\\"normal\\",\\"fontStyle\\":\\"normal\\"},{}]},\\"children\\":[\\"\\"]}]}]}]}"`;
exports[`Storyshots Chip Chip Without Avatar 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"alignItems\\":\\"flex-start\\",\\"padding\\":16}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityState\\":{\\"disabled\\":false},\\"focusable\\":true,\\"style\\":[{\\"paddingHorizontal\\":8,\\"marginRight\\":8,\\"borderRadius\\":4,\\"justifyContent\\":\\"center\\",\\"maxWidth\\":192},{\\"backgroundColor\\":\\"#efeff4\\"},null],\\"collapsable\\":false},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"center\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginRight\\":8,\\"maxWidth\\":120}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#2f343d\\"}],\\"numberOfLines\\":1},\\"children\\":[\\"Without Avatar\\"]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"selectable\\":false,\\"allowFontScaling\\":false,\\"style\\":[{\\"fontSize\\":16,\\"color\\":\\"#6C727A\\"},null,{\\"fontFamily\\":\\"custom\\",\\"fontWeight\\":\\"normal\\",\\"fontStyle\\":\\"normal\\"},{}]},\\"children\\":[\\"\\"]}]}]}]}"`;
exports[`Storyshots Chip Chip Without Avatar And Icon 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"alignItems\\":\\"flex-start\\",\\"padding\\":16}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityState\\":{\\"disabled\\":true},\\"focusable\\":true,\\"accessibilityValue\\":{},\\"style\\":[{\\"paddingHorizontal\\":8,\\"marginRight\\":8,\\"borderRadius\\":4,\\"justifyContent\\":\\"center\\",\\"maxWidth\\":192},{\\"backgroundColor\\":\\"#efeff4\\"},null],\\"collapsable\\":false},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"center\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginRight\\":8,\\"maxWidth\\":120}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#2f343d\\"}],\\"numberOfLines\\":1},\\"children\\":[\\"Without Avatar and Icon\\"]}]}]}]}]}"`;
exports[`Storyshots Chip Chip Without Avatar And Icon 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"alignItems\\":\\"flex-start\\",\\"padding\\":16}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityState\\":{\\"disabled\\":true},\\"focusable\\":true,\\"style\\":[{\\"paddingHorizontal\\":8,\\"marginRight\\":8,\\"borderRadius\\":4,\\"justifyContent\\":\\"center\\",\\"maxWidth\\":192},{\\"backgroundColor\\":\\"#efeff4\\"},null],\\"collapsable\\":false},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"center\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginRight\\":8,\\"maxWidth\\":120}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#2f343d\\"}],\\"numberOfLines\\":1},\\"children\\":[\\"Without Avatar and Icon\\"]}]}]}]}]}"`;
exports[`Storyshots Chip Chip Without Icon 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"alignItems\\":\\"flex-start\\",\\"padding\\":16}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityState\\":{\\"disabled\\":true},\\"focusable\\":true,\\"accessibilityValue\\":{},\\"style\\":[{\\"paddingHorizontal\\":8,\\"marginRight\\":8,\\"borderRadius\\":4,\\"justifyContent\\":\\"center\\",\\"maxWidth\\":192},{\\"backgroundColor\\":\\"#efeff4\\"},null],\\"collapsable\\":false},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"center\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":28,\\"height\\":28,\\"borderRadius\\":4},{\\"marginRight\\":8,\\"marginVertical\\":8}],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":28,\\"height\\":28,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/rocket.cat?format=png&size=56\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginRight\\":8,\\"maxWidth\\":120}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#2f343d\\"}],\\"numberOfLines\\":1},\\"children\\":[\\"Without Icon\\"]}]}]}]}]}"`;
exports[`Storyshots Chip Chip Without Icon 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"alignItems\\":\\"flex-start\\",\\"padding\\":16}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityState\\":{\\"disabled\\":true},\\"focusable\\":true,\\"style\\":[{\\"paddingHorizontal\\":8,\\"marginRight\\":8,\\"borderRadius\\":4,\\"justifyContent\\":\\"center\\",\\"maxWidth\\":192},{\\"backgroundColor\\":\\"#efeff4\\"},null],\\"collapsable\\":false},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"center\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"width\\":28,\\"height\\":28,\\"borderRadius\\":4},{\\"marginRight\\":8,\\"marginVertical\\":8}],\\"testID\\":\\"avatar\\"},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},{\\"width\\":28,\\"height\\":28,\\"borderRadius\\":4}]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/avatar/rocket.cat?format=png&size=56\\",\\"headers\\":{\\"User-Agent\\":\\"RC Mobile; ios unknown; vunknown (unknown)\\"},\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"cover\\"},\\"children\\":null}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginRight\\":8,\\"maxWidth\\":120}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#2f343d\\"}],\\"numberOfLines\\":1},\\"children\\":[\\"Without Icon\\"]}]}]}]}]}"`;

View File

@ -1,5 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Storyshots Login Services Separators 1`] = `"[{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityLabel\\":\\"More options\\",\\"accessibilityState\\":{\\"disabled\\":false},\\"accessibilityValue\\":{},\\"focusable\\":true,\\"collapsable\\":false,\\"style\\":{\\"paddingHorizontal\\":14,\\"justifyContent\\":\\"center\\",\\"height\\":48,\\"borderRadius\\":4,\\"marginBottom\\":0,\\"backgroundColor\\":\\"#ffffff\\",\\"opacity\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"textAlign\\":\\"center\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#1d74f5\\",\\"fontSize\\":16},null],\\"accessibilityLabel\\":\\"More options\\"},\\"children\\":[\\"More options\\"]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"center\\",\\"marginVertical\\":24}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"height\\":1,\\"flex\\":1},{\\"backgroundColor\\":\\"#e1e5e8\\"}]},\\"children\\":null},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":14,\\"marginLeft\\":14,\\"marginRight\\":14,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#9ca2a8\\"}]},\\"children\\":[\\"OR\\"]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"height\\":1,\\"flex\\":1},{\\"backgroundColor\\":\\"#e1e5e8\\"}]},\\"children\\":null}]},{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityLabel\\":\\"Less options\\",\\"accessibilityState\\":{\\"disabled\\":false},\\"accessibilityValue\\":{},\\"focusable\\":true,\\"collapsable\\":false,\\"style\\":{\\"paddingHorizontal\\":14,\\"justifyContent\\":\\"center\\",\\"height\\":48,\\"borderRadius\\":4,\\"marginBottom\\":0,\\"backgroundColor\\":\\"#ffffff\\",\\"opacity\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"textAlign\\":\\"center\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#1d74f5\\",\\"fontSize\\":16},null],\\"accessibilityLabel\\":\\"Less options\\"},\\"children\\":[\\"Less options\\"]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"center\\",\\"marginVertical\\":24}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"height\\":1,\\"flex\\":1},{\\"backgroundColor\\":\\"#e1e5e8\\"}]},\\"children\\":null},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":14,\\"marginLeft\\":14,\\"marginRight\\":14,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#9ca2a8\\"}]},\\"children\\":[\\"OR\\"]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"height\\":1,\\"flex\\":1},{\\"backgroundColor\\":\\"#e1e5e8\\"}]},\\"children\\":null}]}]"`;
exports[`Storyshots Login Services Separators 1`] = `"[{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityLabel\\":\\"More options\\",\\"accessibilityState\\":{\\"disabled\\":false},\\"focusable\\":true,\\"collapsable\\":false,\\"style\\":{\\"paddingHorizontal\\":14,\\"justifyContent\\":\\"center\\",\\"height\\":48,\\"borderRadius\\":4,\\"marginBottom\\":0,\\"backgroundColor\\":\\"#ffffff\\",\\"opacity\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"textAlign\\":\\"center\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#1d74f5\\",\\"fontSize\\":16},null],\\"accessibilityLabel\\":\\"More options\\"},\\"children\\":[\\"More options\\"]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"center\\",\\"marginVertical\\":24}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"height\\":1,\\"flex\\":1},{\\"backgroundColor\\":\\"#e1e5e8\\"}]},\\"children\\":null},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":14,\\"marginLeft\\":14,\\"marginRight\\":14,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#9ca2a8\\"}]},\\"children\\":[\\"OR\\"]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"height\\":1,\\"flex\\":1},{\\"backgroundColor\\":\\"#e1e5e8\\"}]},\\"children\\":null}]},{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityLabel\\":\\"Less options\\",\\"accessibilityState\\":{\\"disabled\\":false},\\"focusable\\":true,\\"collapsable\\":false,\\"style\\":{\\"paddingHorizontal\\":14,\\"justifyContent\\":\\"center\\",\\"height\\":48,\\"borderRadius\\":4,\\"marginBottom\\":0,\\"backgroundColor\\":\\"#ffffff\\",\\"opacity\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"textAlign\\":\\"center\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#1d74f5\\",\\"fontSize\\":16},null],\\"accessibilityLabel\\":\\"Less options\\"},\\"children\\":[\\"Less options\\"]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"center\\",\\"marginVertical\\":24}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"height\\":1,\\"flex\\":1},{\\"backgroundColor\\":\\"#e1e5e8\\"}]},\\"children\\":null},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":14,\\"marginLeft\\":14,\\"marginRight\\":14,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#9ca2a8\\"}]},\\"children\\":[\\"OR\\"]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"height\\":1,\\"flex\\":1},{\\"backgroundColor\\":\\"#e1e5e8\\"}]},\\"children\\":null}]}]"`;
exports[`Storyshots Login Services Service List 1`] = `"[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"borderRadius\\":4,\\"width\\":\\"100%\\",\\"height\\":48,\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"center\\",\\"justifyContent\\":\\"center\\",\\"paddingHorizontal\\":15}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"selectable\\":false,\\"allowFontScaling\\":false,\\"style\\":[{\\"fontSize\\":24,\\"color\\":\\"#0d0e12\\"},{\\"position\\":\\"absolute\\",\\"left\\":15,\\"top\\":12,\\"width\\":24,\\"height\\":24},{\\"fontFamily\\":\\"custom\\",\\"fontWeight\\":\\"normal\\",\\"fontStyle\\":\\"normal\\"},{}]},\\"children\\":[\\"\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"400\\",\\"fontSize\\":16},{\\"color\\":\\"#0d0e12\\"}]},\\"children\\":[\\"Continue with\\",\\" \\",{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"600\\"}},\\"children\\":[\\"github\\"]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"borderRadius\\":4,\\"width\\":\\"100%\\",\\"height\\":48,\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"center\\",\\"justifyContent\\":\\"center\\",\\"paddingHorizontal\\":15}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"selectable\\":false,\\"allowFontScaling\\":false,\\"style\\":[{\\"fontSize\\":24,\\"color\\":\\"#0d0e12\\"},{\\"position\\":\\"absolute\\",\\"left\\":15,\\"top\\":12,\\"width\\":24,\\"height\\":24},{\\"fontFamily\\":\\"custom\\",\\"fontWeight\\":\\"normal\\",\\"fontStyle\\":\\"normal\\"},{}]},\\"children\\":[\\"\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"400\\",\\"fontSize\\":16},{\\"color\\":\\"#0d0e12\\"}]},\\"children\\":[\\"Continue with\\",\\" \\",{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"600\\"}},\\"children\\":[\\"gitlab\\"]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"borderRadius\\":4,\\"width\\":\\"100%\\",\\"height\\":48,\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"center\\",\\"justifyContent\\":\\"center\\",\\"paddingHorizontal\\":15}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"selectable\\":false,\\"allowFontScaling\\":false,\\"style\\":[{\\"fontSize\\":24,\\"color\\":\\"#0d0e12\\"},{\\"position\\":\\"absolute\\",\\"left\\":15,\\"top\\":12,\\"width\\":24,\\"height\\":24},{\\"fontFamily\\":\\"custom\\",\\"fontWeight\\":\\"normal\\",\\"fontStyle\\":\\"normal\\"},{}]},\\"children\\":[\\"\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"400\\",\\"fontSize\\":16},{\\"color\\":\\"#0d0e12\\"}]},\\"children\\":[\\"Continue with\\",\\" \\",{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"600\\"}},\\"children\\":[\\"google\\"]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"borderRadius\\":4,\\"width\\":\\"100%\\",\\"height\\":48,\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"center\\",\\"justifyContent\\":\\"center\\",\\"paddingHorizontal\\":15}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"selectable\\":false,\\"allowFontScaling\\":false,\\"style\\":[{\\"fontSize\\":24,\\"color\\":\\"#0d0e12\\"},{\\"position\\":\\"absolute\\",\\"left\\":15,\\"top\\":12,\\"width\\":24,\\"height\\":24},{\\"fontFamily\\":\\"custom\\",\\"fontWeight\\":\\"normal\\",\\"fontStyle\\":\\"normal\\"},{}]},\\"children\\":[\\"\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"400\\",\\"fontSize\\":16},{\\"color\\":\\"#0d0e12\\"}]},\\"children\\":[\\"Continue with\\",\\" \\",{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"600\\"}},\\"children\\":[\\"apple\\"]}]}]}]"`;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Storyshots CollapsibleQuote Item 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"padding\\":10}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"accessibilityState\\":{},\\"accessibilityValue\\":{},\\"testID\\":\\"collapsibleQuoteTouchable-Engineering (9 today)\\",\\"hitSlop\\":{\\"top\\":4,\\"right\\":4,\\"bottom\\":4,\\"left\\":4},\\"focusable\\":true,\\"collapsable\\":false,\\"style\\":{\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"center\\",\\"marginTop\\":6,\\"borderWidth\\":1,\\"borderRadius\\":4,\\"minHeight\\":40,\\"backgroundColor\\":\\"#f3f4f5\\",\\"borderLeftColor\\":\\"#CBCED1\\",\\"borderTopColor\\":\\"#e1e5e8\\",\\"borderRightColor\\":\\"#e1e5e8\\",\\"borderBottomColor\\":\\"#e1e5e8\\",\\"borderLeftWidth\\":2,\\"opacity\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"borderRadius\\":4,\\"padding\\":8}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\"}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#6C727A\\"}]},\\"children\\":[\\"Engineering (9 today)\\"]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"width\\":20,\\"height\\":20,\\"right\\":8,\\"top\\":8,\\"justifyContent\\":\\"center\\",\\"alignItems\\":\\"center\\"}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"selectable\\":false,\\"allowFontScaling\\":false,\\"style\\":[{\\"fontSize\\":22,\\"color\\":\\"#6C727A\\"},null,{\\"fontFamily\\":\\"custom\\",\\"fontWeight\\":\\"normal\\",\\"fontStyle\\":\\"normal\\"},{}]},\\"children\\":[\\"\\"]}]}]}]}]}"`;
exports[`Storyshots CollapsibleQuote Item 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"padding\\":10}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessible\\":true,\\"testID\\":\\"collapsibleQuoteTouchable-Engineering (9 today)\\",\\"hitSlop\\":{\\"top\\":4,\\"right\\":4,\\"bottom\\":4,\\"left\\":4},\\"focusable\\":true,\\"collapsable\\":false,\\"style\\":{\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"center\\",\\"marginTop\\":6,\\"borderWidth\\":1,\\"borderRadius\\":4,\\"minHeight\\":40,\\"backgroundColor\\":\\"#f3f4f5\\",\\"borderLeftColor\\":\\"#CBCED1\\",\\"borderTopColor\\":\\"#e1e5e8\\",\\"borderRightColor\\":\\"#e1e5e8\\",\\"borderBottomColor\\":\\"#e1e5e8\\",\\"borderLeftWidth\\":2,\\"opacity\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"borderRadius\\":4,\\"padding\\":8}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\"}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"500\\"},{\\"color\\":\\"#6C727A\\"}]},\\"children\\":[\\"Engineering (9 today)\\"]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"width\\":20,\\"height\\":20,\\"right\\":8,\\"top\\":8,\\"justifyContent\\":\\"center\\",\\"alignItems\\":\\"center\\"}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"selectable\\":false,\\"allowFontScaling\\":false,\\"style\\":[{\\"fontSize\\":22,\\"color\\":\\"#6C727A\\"},null,{\\"fontFamily\\":\\"custom\\",\\"fontWeight\\":\\"normal\\",\\"fontStyle\\":\\"normal\\"},{}]},\\"children\\":[\\"\\"]}]}]}]}]}"`;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,27 +1,27 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.6)
CFPropertyList (3.0.5)
rexml
addressable (2.8.4)
public_suffix (>= 2.0.2, < 6.0)
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.2.0)
aws-partitions (1.750.0)
aws-sdk-core (3.171.0)
aws-partitions (1.600.0)
aws-sdk-core (3.131.2)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.5)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.63.0)
aws-sdk-core (~> 3, >= 3.165.0)
aws-partitions (~> 1, >= 1.525.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.121.0)
aws-sdk-core (~> 3, >= 3.165.0)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.57.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.114.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4)
aws-sigv4 (1.5.2)
aws-sigv4 (1.5.0)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
claide (1.1.0)
@ -34,10 +34,10 @@ GEM
rake (>= 12.0.0, < 14.0.0)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.8.1)
dotenv (2.7.6)
emoji_regex (3.2.3)
excon (0.99.0)
faraday (1.10.3)
excon (0.92.3)
faraday (1.10.0)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
@ -66,7 +66,7 @@ GEM
faraday_middleware (1.2.0)
faraday (~> 1.0)
fastimage (2.2.6)
fastlane (2.212.2)
fastlane (2.206.2)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0)
@ -106,9 +106,9 @@ GEM
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.39.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-core (0.11.0)
google-apis-androidpublisher_v3 (0.22.0)
google-apis-core (>= 0.5, < 2.a)
google-apis-core (0.6.0)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a)
@ -117,27 +117,27 @@ GEM
retriable (>= 2.0, < 4.a)
rexml
webrick
google-apis-iamcredentials_v1 (0.17.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-playcustomapp_v1 (0.13.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-storage_v1 (0.19.0)
google-apis-core (>= 0.9.0, < 2.a)
google-apis-iamcredentials_v1 (0.12.0)
google-apis-core (>= 0.6, < 2.a)
google-apis-playcustomapp_v1 (0.9.0)
google-apis-core (>= 0.6, < 2.a)
google-apis-storage_v1 (0.15.0)
google-apis-core (>= 0.5, < 2.a)
google-cloud-core (1.6.0)
google-cloud-env (~> 1.0)
google-cloud-errors (~> 1.0)
google-cloud-env (1.6.0)
faraday (>= 0.17.3, < 3.0)
google-cloud-errors (1.3.1)
google-cloud-storage (1.44.0)
google-cloud-errors (1.2.0)
google-cloud-storage (1.36.2)
addressable (~> 2.8)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
google-apis-storage_v1 (~> 0.19.0)
google-apis-storage_v1 (~> 0.1)
google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0)
googleauth (1.5.2)
googleauth (1.2.0)
faraday (>= 0.17.3, < 3.a)
jwt (>= 1.4, < 3.0)
memoist (~> 0.16)
@ -148,11 +148,11 @@ GEM
http-cookie (1.0.5)
domain_name (~> 0.5)
httpclient (2.8.3)
jmespath (1.6.2)
json (2.6.3)
jwt (2.7.0)
jmespath (1.6.1)
json (2.6.2)
jwt (2.4.1)
memoist (0.16.2)
mini_magick (4.12.0)
mini_magick (4.11.0)
mini_mime (1.1.2)
multi_json (1.15.0)
multipart-post (2.0.0)
@ -160,8 +160,8 @@ GEM
naturally (2.2.1)
optparse (0.1.1)
os (1.1.4)
plist (3.7.0)
public_suffix (5.0.1)
plist (3.6.0)
public_suffix (4.0.7)
rake (13.0.6)
representable (3.2.0)
declarative (< 0.1.0)
@ -178,7 +178,7 @@ GEM
faraday (>= 0.17.5, < 3.a)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
simctl (1.6.10)
simctl (1.6.8)
CFPropertyList
naturally
terminal-notifier (2.0.0)
@ -193,9 +193,8 @@ GEM
unf (0.1.4)
unf_ext
unf_ext (0.0.8.2)
unf_ext (0.0.8.2-x64-mingw32)
unicode-display_width (1.8.0)
webrick (1.8.1)
webrick (1.7.0)
word_wrap (1.0.0)
xcodeproj (1.22.0)
CFPropertyList (>= 2.3.3, < 4.0)
@ -217,4 +216,4 @@ DEPENDENCIES
fastlane
BUNDLED WITH
2.4.10
2.3.11

55
android/app/_BUCK Normal file
View File

@ -0,0 +1,55 @@
# To learn about Buck see [Docs](https://buckbuild.com/).
# To run your application with Buck:
# - install Buck
# - `npm start` - to start the packager
# - `cd android`
# - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"`
# - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck
# - `buck install -r android/app` - compile, install and run application
#
load(":build_defs.bzl", "create_aar_targets", "create_jar_targets")
lib_deps = []
create_aar_targets(glob(["libs/*.aar"]))
create_jar_targets(glob(["libs/*.jar"]))
android_library(
name = "all-libs",
exported_deps = lib_deps,
)
android_library(
name = "app-code",
srcs = glob([
"src/main/java/**/*.java",
]),
deps = [
":all-libs",
":build_config",
":res",
],
)
android_build_config(
name = "build_config",
package = "chat.rocket.reactnative",
)
android_resource(
name = "res",
package = "chat.rocket.reactnative",
res = "src/main/res",
)
android_binary(
name = "app",
keystore = "//android/keystores:debug",
manifest = "src/main/AndroidManifest.xml",
package_type = "debug",
deps = [
":app-code",
],
)

View File

@ -3,7 +3,6 @@ def isFoss = taskRequests.contains("foss")
apply plugin: "com.android.application"
apply plugin: 'kotlin-android'
apply plugin: "com.facebook.react"
if (!isFoss) {
apply plugin: 'com.google.firebase.crashlytics'
@ -13,88 +12,126 @@ if (!isFoss) {
import com.android.build.OutputFile
/**
* This is the configuration block to customize your React Native Android app.
* By default you don't need to apply any configuration, just uncomment the lines you need.
* The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
* and bundleReleaseJsAndAssets).
* These basically call `react-native bundle` with the correct arguments during the Android build
* cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
* bundle directly from the development server. Below you can see all the possible configurations
* and their defaults. If you decide to add a configuration block, make sure to add it before the
* `apply from: "../../node_modules/react-native/react.gradle"` line.
*
* project.ext.react = [
* // the name of the generated asset file containing your JS bundle
* bundleAssetName: "index.android.bundle",
*
* // the entry file for bundle generation. If none specified and
* // "index.android.js" exists, it will be used. Otherwise "index.tsx" is
* // 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
* bundleCommand: "ram-bundle",
*
* // whether to bundle JS and assets in debug mode
* bundleInDebug: false,
*
* // whether to bundle JS and assets in release mode
* bundleInRelease: true,
*
* // whether to bundle JS and assets in another build variant (if configured).
* // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
* // The configuration property can be in the following formats
* // 'bundleIn${productFlavor}${buildType}'
* // 'bundleIn${buildType}'
* // bundleInFreeDebug: true,
* // bundleInPaidRelease: true,
* // bundleInBeta: true,
*
* // whether to disable dev mode in custom build variants (by default only disabled in release)
* // for example: to disable dev mode in the staging build type (if configured)
* devDisabledInStaging: true,
* // The configuration property can be in the following formats
* // 'devDisabledIn${productFlavor}${buildType}'
* // 'devDisabledIn${buildType}'
*
* // the root of your project, i.e. where "package.json" lives
* root: "../../",
*
* // where to put the JS bundle asset in debug mode
* jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
*
* // where to put the JS bundle asset in release mode
* jsBundleDirRelease: "$buildDir/intermediates/assets/release",
*
* // where to put drawable resources / React Native assets, e.g. the ones you use via
* // require('./image.png')), in debug mode
* resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
*
* // where to put drawable resources / React Native assets, e.g. the ones you use via
* // require('./image.png')), in release mode
* resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
*
* // by default the gradle tasks are skipped if none of the JS files or assets change; this means
* // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
* // date; if you have any other folders that you want to ignore for performance reasons (gradle
* // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
* // for example, you might want to remove it from here.
* inputExcludes: ["android/**", "ios/**"],
*
* // override which node gets called and with what additional arguments
* nodeExecutableAndArgs: ["node"],
*
* // supply additional arguments to the packager
* extraPackagerArgs: []
* ]
*/
react {
/* Folders */
// The root of your project, i.e. where "package.json" lives. Default is '..'
// root = file("../")
// The folder where the react-native NPM package is. Default is ../node_modules/react-native
// reactNativeDir = file("../node_modules/react-native")
// The folder where the react-native Codegen package is. Default is ../node_modules/react-native-codegen
// codegenDir = file("../node_modules/react-native-codegen")
// The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js
// cliFile = file("../node_modules/react-native/cli.js")
/* Variants */
// The list of variants to that are debuggable. For those we're going to
// skip the bundling of the JS bundle and the assets. By default is just 'debug'.
// If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants.
debuggableVariants = ["experimentalPlayDebug", "officialPlayDebug", "experimentalFossDebug", "officialFossDebug"]
/* Bundling */
// A list containing the node command and its flags. Default is just 'node'.
// nodeExecutableAndArgs = ["node"]
//
// The command to run when bundling. By default is 'bundle'
// bundleCommand = "ram-bundle"
//
// The path to the CLI configuration file. Default is empty.
// bundleConfig = file(../rn-cli.config.js)
//
// The name of the generated asset file containing your JS bundle
// bundleAssetName = "MyApplication.android.bundle"
//
// The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
// entryFile = file("../js/MyApplication.android.js")
//
// A list of extra flags to pass to the 'bundle' commands.
// See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle
// extraPackagerArgs = []
/* Hermes Commands */
// The hermes compiler command to run. By default it is 'hermesc'
// hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
//
// The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
// hermesFlags = ["-O", "-output-source-map"]
}
project.ext.react = [
bundleAssetName: "app.bundle",
iconFontNames: [ 'custom.ttf' ],
enableHermes: true, // clean and rebuild if changing
]
// project.ext.react = [
// bundleAssetName: "app.bundle",
// iconFontNames: [ 'custom.ttf' ],
// enableHermes: true, // clean and rebuild if changing
// ]
apply from: "../../node_modules/react-native/react.gradle"
/**
* Set this to true to create four separate APKs instead of one,
* one for each native architecture. This is useful if you don't
* use App Bundles (https://developer.android.com/guide/app-bundle/)
* and want to have separate APKs to upload to the Play Store.
* Set this to true to create two separate APKs instead of one:
* - An APK that only works on ARM devices
* - An APK that only works on x86 devices
* The advantage is the size of the APK is reduced by about 4MB.
* Upload all the APKs to the Play Store and people will download
* the correct one based on the CPU architecture of their device.
*/
def enableSeparateBuildPerCPUArchitecture = false
/**
* Set this to true to Run Proguard on Release builds to minify the Java bytecode.
* Run Proguard to shrink the Java bytecode in release builds.
*/
def enableProguardInReleaseBuilds = false
/**
* The preferred build flavor of JavaScriptCore (JSC)
* The preferred build flavor of JavaScriptCore.
*
* For example, to use the international variant, you can use:
* `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
*
* The international variant includes ICU i18n library and necessary data
* allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
* give correct results when using with locales other than en-US. Note that
* give correct results when using with locales other than en-US. Note that
* this variant is about 6MiB larger per architecture than default.
*/
def jscFlavor = 'org.webkit:android-jsc:+'
/**
* Whether to enable the Hermes VM.
*
* This should be set on project.ext.react and mirrored here. If it is not set
* on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
* and the benefits of using Hermes will therefore be sharply reduced.
*/
def enableHermes = project.ext.react.get("enableHermes", false);
/**
* Private function to get the list of Native Architectures you want to build.
* This reads the value from reactNativeArchitectures in your gradle.properties
* file and works together with the --active-arch-only flag of react-native run-android.
* Architectures to build native code for.
*/
def reactNativeArchitectures() {
def value = project.getProperties().get("reactNativeArchitectures")
@ -105,8 +142,6 @@ android {
ndkVersion rootProject.ext.ndkVersion
compileSdkVersion rootProject.ext.compileSdkVersion
// Can't set this, since it causes issues to Official flavor
// namespace APPLICATION_ID
defaultConfig {
applicationId APPLICATION_ID
minSdkVersion rootProject.ext.minSdkVersion
@ -121,16 +156,78 @@ android {
resValue "string", "rn_config_reader_custom_package", "chat.rocket.reactnative"
testBuildType System.getProperty('testBuildType', 'debug')
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}
splits {
abi {
reset()
enable enableSeparateBuildPerCPUArchitecture
universalApk false // If true, also generate a universal APK
include (*reactNativeArchitectures())
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
if (isNewArchitectureEnabled()) {
// We configure the NDK build only if you decide to opt-in for the New Architecture.
externalNativeBuild {
ndkBuild {
arguments "APP_PLATFORM=android-21",
"APP_STL=c++_shared",
"NDK_TOOLCHAIN_VERSION=clang",
"GENERATED_SRC_DIR=$buildDir/generated/source",
"PROJECT_BUILD_DIR=$buildDir",
"REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
"REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build"
cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1"
cppFlags "-std=c++17"
// Make sure this target name is the same you specify inside the
// src/main/jni/Android.mk file for the `LOCAL_MODULE` variable.
targets "rndiffapp_appmodules"
// Fix for windows limit on number of character in file paths and in command lines
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
arguments "NDK_APP_SHORT_COMMANDS=true"
}
}
}
if (!enableSeparateBuildPerCPUArchitecture) {
ndk {
abiFilters (*reactNativeArchitectures())
}
}
}
}
if (isNewArchitectureEnabled()) {
// We configure the NDK build only if you decide to opt-in for the New Architecture.
externalNativeBuild {
ndkBuild {
path "$projectDir/src/main/jni/Android.mk"
}
}
def reactAndroidProjectDir = project(':ReactAndroid').projectDir
def packageReactNdkDebugLibs = tasks.register("packageReactNdkDebugLibs", Copy) {
dependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck")
from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
into("$buildDir/react-ndk/exported")
}
def packageReactNdkReleaseLibs = tasks.register("packageReactNdkReleaseLibs", Copy) {
dependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck")
from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
into("$buildDir/react-ndk/exported")
}
afterEvaluate {
// If you wish to add a custom TurboModule or component locally,
// you should uncomment this line.
// preBuild.dependsOn("generateCodegenArtifactsFromSchema")
preDebugBuild.dependsOn(packageReactNdkDebugLibs)
preReleaseBuild.dependsOn(packageReactNdkReleaseLibs)
// Due to a bug inside AGP, we have to explicitly set a dependency
// between configureNdkBuild* tasks and the preBuild tasks.
// This can be removed once this is solved: https://issuetracker.google.com/issues/207403732
configureNdkBuildRelease.dependsOn(preReleaseBuild)
configureNdkBuildDebug.dependsOn(preDebugBuild)
reactNativeArchitectures().each { architecture ->
tasks.findByName("configureNdkBuildDebug[${architecture}]")?.configure {
dependsOn("preDebugBuild")
}
tasks.findByName("configureNdkBuildRelease[${architecture}]")?.configure {
dependsOn("preReleaseBuild")
}
}
}
}
signingConfigs {
release {
if (project.hasProperty('KEYSTORE')) {
@ -141,6 +238,14 @@ android {
}
}
}
splits {
abi {
reset()
enable enableSeparateBuildPerCPUArchitecture
universalApk false // If true, also generate a universal APK
include (*reactNativeArchitectures())
}
}
buildTypes {
release {
minifyEnabled enableProguardInReleaseBuilds
@ -157,6 +262,18 @@ android {
}
}
// packagingOptions {
// pickFirst '**/armeabi-v7a/libc++_shared.so'
// pickFirst '**/x86/libc++_shared.so'
// pickFirst '**/arm64-v8a/libc++_shared.so'
// pickFirst '**/x86_64/libc++_shared.so'
// }
// FIXME: Remove when we update RN
packagingOptions {
pickFirst '**/*.so'
}
// applicationVariants are e.g. debug, release
flavorDimensions "app", "type"
@ -225,47 +342,74 @@ android {
}
dependencies {
// The version of react-native is set by the React Native Gradle Plugin
implementation("com.facebook.react:react-android")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0")
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
exclude group:'com.squareup.okhttp3', module:'okhttp'
}
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}")
if (hermesEnabled.toBoolean()) {
implementation("com.facebook.react:hermes-android")
} else {
implementation jscFlavor
}
implementation project(':@react-native-community_viewpager')
implementation "androidx.core:core-splashscreen:1.0.0"
playImplementation project(':react-native-notifications')
playImplementation 'com.google.firebase:firebase-core:16.0.0'
playImplementation project(':@react-native-firebase_app')
playImplementation project(':@react-native-firebase_analytics')
playImplementation project(':@react-native-firebase_crashlytics')
implementation fileTree(dir: "libs", include: ["*.jar"])
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+" // From node_modules
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.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'
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/";
debugImplementation files(hermesPath + "hermes-debug.aar")
releaseImplementation files(hermesPath + "hermes-release.aar")
} else {
implementation jscFlavor
}
implementation "com.google.code.gson:gson:2.8.9"
implementation "com.github.bumptech.glide:glide:4.9.0"
annotationProcessor "com.github.bumptech.glide:compiler:4.9.0"
implementation "com.tencent:mmkv-static:1.2.10"
androidTestImplementation('com.wix:detox:+')
androidTestImplementation 'androidx.test:core:1.4.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.facebook.soloader:soloader:0.10.4'
}
if (isNewArchitectureEnabled()) {
// If new architecture is enabled, we let you build RN from source
// Otherwise we fallback to a prebuilt .aar bundled in the NPM package.
// This will be applied to all the imported transtitive dependency.
configurations.all {
resolutionStrategy.dependencySubstitution {
substitute(module("com.facebook.react:react-native"))
.using(project(":ReactAndroid")).because("On New Architecture we're building React Native from source")
}
}
}
// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
from configurations.implementation
into 'libs'
}
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
if (!isFoss) {
apply plugin: 'com.google.gms.google-services'
}
bugsnag {
uploadReactNativeMappings = false
}
def isNewArchitectureEnabled() {
// To opt-in for the New Architecture, you can either:
// - Set `newArchEnabled` to true inside the `gradle.properties` file
// - Invoke gradle with `-newArchEnabled=true`
// - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
}

View File

@ -0,0 +1,19 @@
"""Helper definitions to glob .aar and .jar targets"""
def create_aar_targets(aarfiles):
for aarfile in aarfiles:
name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")]
lib_deps.append(":" + name)
android_prebuilt_aar(
name = name,
aar = aarfile,
)
def create_jar_targets(jarfiles):
for jarfile in jarfiles:
name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")]
lib_deps.append(":" + name)
prebuilt_jar(
name = name,
binary_jar = jarfile,
)

View File

@ -1,3 +1,9 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
* directory of this source tree.
*/
package chat.rocket.reactnative;
import android.content.Context;
import com.facebook.flipper.android.AndroidFlipperClient;
@ -18,11 +24,6 @@ import com.facebook.react.bridge.ReactContext;
import com.facebook.react.modules.network.NetworkingModule;
import com.facebook.react.modules.network.CustomClientBuilder;
import okhttp3.OkHttpClient;
/**
* Class responsible of loading Flipper inside your React Native application. This is the debug
* flavor of it. Here you can add your own plugins and customize the Flipper setup.
*/
public class ReactNativeFlipper {
public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
if (FlipperUtils.shouldEnableFlipper(context)) {

View File

@ -6,10 +6,9 @@ import android.os.Bundle;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.defaults.DefaultReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.zoontek.rnbootsplash.RNBootSplash;
import expo.modules.ReactActivityDelegateWrapper;
public class MainActivity extends ReactActivity {
@ -44,20 +43,26 @@ public class MainActivity extends ReactActivity {
this.sendBroadcast(intent);
}
/**
* Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link
* DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React
* (aka React 18) with two boolean flags.
/**
* Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and
* you can specify the rendered you wish to use (Fabric or the older renderer).
*/
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new DefaultReactActivityDelegate(
this,
getMainComponentName(),
return new ReactActivityDelegateWrapper(this, new MainActivityDelegate(this, getMainComponentName()));
}
public static class MainActivityDelegate extends ReactActivityDelegate {
public MainActivityDelegate(ReactActivity activity, String mainComponentName) {
super(activity, mainComponentName);
}
@Override
protected ReactRootView createRootView() {
ReactRootView reactRootView = new ReactRootView(getContext());
// If you opted-in for the New Architecture, we enable the Fabric Renderer.
DefaultNewArchitectureEntryPoint.getFabricEnabled(), // fabricEnabled
// If you opted-in for the New Architecture, we enable Concurrent React (i.e. React 18).
DefaultNewArchitectureEntryPoint.getConcurrentReactEnabled() // concurrentRootEnabled
);
reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED);
return reactRootView;
}
}
}

View File

@ -8,70 +8,115 @@ import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.defaults.DefaultReactNativeHost;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.ReactInstanceManager;
import com.facebook.soloader.SoLoader;
import com.reactnativecommunity.viewpager.RNCViewPagerPackage;
import com.facebook.react.bridge.JSIModulePackage;
import com.swmansion.reanimated.ReanimatedJSIModulePackage;
import android.content.Context;
import android.content.res.Configuration;
import expo.modules.ApplicationLifecycleDispatcher;
import expo.modules.ReactNativeHostWrapper;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;
import chat.rocket.reactnative.newarchitecture.MainApplicationReactNativeHost;
import chat.rocket.reactnative.networking.SSLPinningPackage;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost =
new DefaultReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
private final ReactNativeHost mReactNativeHost = new ReactNativeHostWrapper(this, new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
packages.add(new RNCViewPagerPackage());
packages.add(new SSLPinningPackage());
List<ReactPackage> additionalModules = new AdditionalModules().getAdditionalModules(MainApplication.this);
packages.addAll(additionalModules);
return packages;
}
@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
packages.add(new RNCViewPagerPackage());
packages.add(new SSLPinningPackage());
List<ReactPackage> additionalModules = new AdditionalModules().getAdditionalModules(MainApplication.this);
packages.addAll(additionalModules);
return packages;
}
@Override
protected String getJSMainModuleName() {
return "index";
}
@Override
protected String getJSMainModuleName() {
return "index";
}
@Override
protected boolean isNewArchEnabled() {
return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
}
@Override
protected JSIModulePackage getJSIModulePackage() {
return new ReanimatedJSIModulePackage();
}
@Override
protected Boolean isHermesEnabled() {
return BuildConfig.IS_HERMES_ENABLED;
}
};
@Override
protected @Nullable String getBundleAssetName() {
return "app.bundle";
}
});
private final ReactNativeHost mNewArchitectureNativeHost =
new ReactNativeHostWrapper(this, new MainApplicationReactNativeHost(this));
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
return mNewArchitectureNativeHost;
} else {
return mReactNativeHost;
}
}
@Override
public void onCreate() {
super.onCreate();
// If you opted-in for the New Architecture, we enable the TurboModule system
ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
SoLoader.init(this, /* native exopackage */ false);
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
// If you opted-in for the New Architecture, we load the native entry point for this app.
DefaultNewArchitectureEntryPoint.load();
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
ApplicationLifecycleDispatcher.onApplicationCreate(this);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig);
}
/**
* Loads Flipper in React Native templates. Call this in the onCreate method with something like
* initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
*
* @param context
* @param reactInstanceManager
*/
private static void initializeFlipper(
Context context, ReactInstanceManager reactInstanceManager) {
if (BuildConfig.DEBUG) {
try {
/*
We use reflection here to pick up the class that initializes Flipper,
since Flipper library is not available in release mode
*/
Class<?> aClass = Class.forName("chat.rocket.reactnative.ReactNativeFlipper");
aClass
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
.invoke(null, context, reactInstanceManager);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
}
}

View File

@ -0,0 +1,116 @@
package chat.rocket.reactnative.newarchitecture;
import android.app.Application;
import androidx.annotation.NonNull;
import com.facebook.react.PackageList;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
import com.facebook.react.bridge.JSIModulePackage;
import com.facebook.react.bridge.JSIModuleProvider;
import com.facebook.react.bridge.JSIModuleSpec;
import com.facebook.react.bridge.JSIModuleType;
import com.facebook.react.bridge.JavaScriptContextHolder;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.UIManager;
import com.facebook.react.fabric.ComponentFactory;
import com.facebook.react.fabric.CoreComponentsRegistry;
import com.facebook.react.fabric.EmptyReactNativeConfig;
import com.facebook.react.fabric.FabricJSIModuleProvider;
import com.facebook.react.uimanager.ViewManagerRegistry;
import chat.rocket.reactnative.BuildConfig;
import chat.rocket.reactnative.newarchitecture.components.MainComponentsRegistry;
import chat.rocket.reactnative.newarchitecture.modules.MainApplicationTurboModuleManagerDelegate;
import java.util.ArrayList;
import java.util.List;
/**
* A {@link ReactNativeHost} that helps you load everything needed for the New Architecture, both
* TurboModule delegates and the Fabric Renderer.
*
* <p>Please note that this class is used ONLY if you opt-in for the New Architecture (see the
* `newArchEnabled` property). Is ignored otherwise.
*/
public class MainApplicationReactNativeHost extends ReactNativeHost {
public MainApplicationReactNativeHost(Application application) {
super(application);
}
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
// TurboModules must also be loaded here providing a valid TurboReactPackage implementation:
// packages.add(new TurboReactPackage() { ... });
// If you have custom Fabric Components, their ViewManagers should also be loaded here
// inside a ReactPackage.
return packages;
}
@Override
protected String getJSMainModuleName() {
return "index";
}
@NonNull
@Override
protected ReactPackageTurboModuleManagerDelegate.Builder
getReactPackageTurboModuleManagerDelegateBuilder() {
// Here we provide the ReactPackageTurboModuleManagerDelegate Builder. This is necessary
// for the new architecture and to use TurboModules correctly.
return new MainApplicationTurboModuleManagerDelegate.Builder();
}
@Override
protected JSIModulePackage getJSIModulePackage() {
return new JSIModulePackage() {
@Override
public List<JSIModuleSpec> getJSIModules(
final ReactApplicationContext reactApplicationContext,
final JavaScriptContextHolder jsContext) {
final List<JSIModuleSpec> specs = new ArrayList<>();
// Here we provide a new JSIModuleSpec that will be responsible of providing the
// custom Fabric Components.
specs.add(
new JSIModuleSpec() {
@Override
public JSIModuleType getJSIModuleType() {
return JSIModuleType.UIManager;
}
@Override
public JSIModuleProvider<UIManager> getJSIModuleProvider() {
final ComponentFactory componentFactory = new ComponentFactory();
CoreComponentsRegistry.register(componentFactory);
// Here we register a Components Registry.
// The one that is generated with the template contains no components
// and just provides you the one from React Native core.
MainComponentsRegistry.register(componentFactory);
final ReactInstanceManager reactInstanceManager = getReactInstanceManager();
ViewManagerRegistry viewManagerRegistry =
new ViewManagerRegistry(
reactInstanceManager.getOrCreateViewManagers(reactApplicationContext));
return new FabricJSIModuleProvider(
reactApplicationContext,
componentFactory,
new EmptyReactNativeConfig(),
viewManagerRegistry);
}
});
return specs;
}
};
}
}

View File

@ -0,0 +1,36 @@
package chat.rocket.reactnative.newarchitecture.components;
import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.fabric.ComponentFactory;
import com.facebook.soloader.SoLoader;
/**
* Class responsible to load the custom Fabric Components. This class has native methods and needs a
* corresponding C++ implementation/header file to work correctly (already placed inside the jni/
* folder for you).
*
* <p>Please note that this class is used ONLY if you opt-in for the New Architecture (see the
* `newArchEnabled` property). Is ignored otherwise.
*/
@DoNotStrip
public class MainComponentsRegistry {
static {
SoLoader.loadLibrary("fabricjni");
}
@DoNotStrip private final HybridData mHybridData;
@DoNotStrip
private native HybridData initHybrid(ComponentFactory componentFactory);
@DoNotStrip
private MainComponentsRegistry(ComponentFactory componentFactory) {
mHybridData = initHybrid(componentFactory);
}
@DoNotStrip
public static MainComponentsRegistry register(ComponentFactory componentFactory) {
return new MainComponentsRegistry(componentFactory);
}
}

View File

@ -0,0 +1,48 @@
package chat.rocket.reactnative.newarchitecture.modules;
import com.facebook.jni.HybridData;
import com.facebook.react.ReactPackage;
import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.soloader.SoLoader;
import java.util.List;
/**
* Class responsible to load the TurboModules. This class has native methods and needs a
* corresponding C++ implementation/header file to work correctly (already placed inside the jni/
* folder for you).
*
* <p>Please note that this class is used ONLY if you opt-in for the New Architecture (see the
* `newArchEnabled` property). Is ignored otherwise.
*/
public class MainApplicationTurboModuleManagerDelegate
extends ReactPackageTurboModuleManagerDelegate {
private static volatile boolean sIsSoLibraryLoaded;
protected MainApplicationTurboModuleManagerDelegate(
ReactApplicationContext reactApplicationContext, List<ReactPackage> packages) {
super(reactApplicationContext, packages);
}
protected native HybridData initHybrid();
native boolean canCreateTurboModule(String moduleName);
public static class Builder extends ReactPackageTurboModuleManagerDelegate.Builder {
protected MainApplicationTurboModuleManagerDelegate build(
ReactApplicationContext context, List<ReactPackage> packages) {
return new MainApplicationTurboModuleManagerDelegate(context, packages);
}
}
@Override
protected synchronized void maybeLoadOtherSoLibraries() {
if (!sIsSoLibraryLoaded) {
// If you change the name of your application .so file in the Android.mk file,
// make sure you update the name here as well.
SoLoader.loadLibrary("rocketchat_appmodules");
sIsSoLibraryLoaded = true;
}
}
}

View File

@ -0,0 +1,49 @@
THIS_DIR := $(call my-dir)
include $(REACT_ANDROID_DIR)/Android-prebuilt.mk
# If you wish to add a custom TurboModule or Fabric component in your app you
# will have to include the following autogenerated makefile.
# include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk
include $(CLEAR_VARS)
LOCAL_PATH := $(THIS_DIR)
# You can customize the name of your application .so file here.
LOCAL_MODULE := rocketchat_appmodules
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp)
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
# If you wish to add a custom TurboModule or Fabric component in your app you
# will have to uncomment those lines to include the generated source
# files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni)
#
# LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
# LOCAL_SRC_FILES += $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp)
# LOCAL_EXPORT_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
# Here you should add any native library you wish to depend on.
LOCAL_SHARED_LIBRARIES := \
libfabricjni \
libfbjni \
libfolly_futures \
libfolly_json \
libglog \
libjsi \
libreact_codegen_rncore \
libreact_debug \
libreact_nativemodule_core \
libreact_render_componentregistry \
libreact_render_core \
libreact_render_debug \
libreact_render_graphics \
librrc_view \
libruntimeexecutor \
libturbomodulejsijni \
libyoga
LOCAL_CFLAGS := -DLOG_TAG=\"ReactNative\" -fexceptions -frtti -std=c++17 -Wall
include $(BUILD_SHARED_LIBRARY)

View File

@ -0,0 +1,24 @@
#include "MainApplicationModuleProvider.h"
#include <rncore.h>
namespace facebook {
namespace react {
std::shared_ptr<TurboModule> MainApplicationModuleProvider(
const std::string moduleName,
const JavaTurboModule::InitParams &params) {
// Here you can provide your own module provider for TurboModules coming from
// either your application or from external libraries. The approach to follow
// is similar to the following (for a library called `samplelibrary`:
//
// auto module = samplelibrary_ModuleProvider(moduleName, params);
// if (module != nullptr) {
// return module;
// }
// return rncore_ModuleProvider(moduleName, params);
return rncore_ModuleProvider(moduleName, params);
}
} // namespace react
} // namespace facebook

View File

@ -0,0 +1,16 @@
#pragma once
#include <memory>
#include <string>
#include <ReactCommon/JavaTurboModule.h>
namespace facebook {
namespace react {
std::shared_ptr<TurboModule> MainApplicationModuleProvider(
const std::string moduleName,
const JavaTurboModule::InitParams &params);
} // namespace react
} // namespace facebook

View File

@ -0,0 +1,45 @@
#include "MainApplicationTurboModuleManagerDelegate.h"
#include "MainApplicationModuleProvider.h"
namespace facebook {
namespace react {
jni::local_ref<MainApplicationTurboModuleManagerDelegate::jhybriddata>
MainApplicationTurboModuleManagerDelegate::initHybrid(
jni::alias_ref<jhybridobject>) {
return makeCxxInstance();
}
void MainApplicationTurboModuleManagerDelegate::registerNatives() {
registerHybrid({
makeNativeMethod(
"initHybrid", MainApplicationTurboModuleManagerDelegate::initHybrid),
makeNativeMethod(
"canCreateTurboModule",
MainApplicationTurboModuleManagerDelegate::canCreateTurboModule),
});
}
std::shared_ptr<TurboModule>
MainApplicationTurboModuleManagerDelegate::getTurboModule(
const std::string name,
const std::shared_ptr<CallInvoker> jsInvoker) {
// Not implemented yet: provide pure-C++ NativeModules here.
return nullptr;
}
std::shared_ptr<TurboModule>
MainApplicationTurboModuleManagerDelegate::getTurboModule(
const std::string name,
const JavaTurboModule::InitParams &params) {
return MainApplicationModuleProvider(name, params);
}
bool MainApplicationTurboModuleManagerDelegate::canCreateTurboModule(
std::string name) {
return getTurboModule(name, nullptr) != nullptr ||
getTurboModule(name, {.moduleName = name}) != nullptr;
}
} // namespace react
} // namespace facebook

View File

@ -0,0 +1,38 @@
#include <memory>
#include <string>
#include <ReactCommon/TurboModuleManagerDelegate.h>
#include <fbjni/fbjni.h>
namespace facebook {
namespace react {
class MainApplicationTurboModuleManagerDelegate
: public jni::HybridClass<
MainApplicationTurboModuleManagerDelegate,
TurboModuleManagerDelegate> {
public:
// Adapt it to the package you used for your Java class.
static constexpr auto kJavaDescriptor =
"Lchat/rocket/reactnative/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;";
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject>);
static void registerNatives();
std::shared_ptr<TurboModule> getTurboModule(
const std::string name,
const std::shared_ptr<CallInvoker> jsInvoker) override;
std::shared_ptr<TurboModule> getTurboModule(
const std::string name,
const JavaTurboModule::InitParams &params) override;
/**
* Test-only method. Allows user to verify whether a TurboModule can be
* created by instances of this class.
*/
bool canCreateTurboModule(std::string name);
};
} // namespace react
} // namespace facebook

View File

@ -0,0 +1,61 @@
#include "MainComponentsRegistry.h"
#include <CoreComponentsRegistry.h>
#include <fbjni/fbjni.h>
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
#include <react/renderer/components/rncore/ComponentDescriptors.h>
namespace facebook {
namespace react {
MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) {}
std::shared_ptr<ComponentDescriptorProviderRegistry const>
MainComponentsRegistry::sharedProviderRegistry() {
auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry();
// Custom Fabric Components go here. You can register custom
// components coming from your App or from 3rd party libraries here.
//
// providerRegistry->add(concreteComponentDescriptorProvider<
// AocViewerComponentDescriptor>());
return providerRegistry;
}
jni::local_ref<MainComponentsRegistry::jhybriddata>
MainComponentsRegistry::initHybrid(
jni::alias_ref<jclass>,
ComponentFactory *delegate) {
auto instance = makeCxxInstance(delegate);
auto buildRegistryFunction =
[](EventDispatcher::Weak const &eventDispatcher,
ContextContainer::Shared const &contextContainer)
-> ComponentDescriptorRegistry::Shared {
auto registry = MainComponentsRegistry::sharedProviderRegistry()
->createComponentDescriptorRegistry(
{eventDispatcher, contextContainer});
auto mutableRegistry =
std::const_pointer_cast<ComponentDescriptorRegistry>(registry);
mutableRegistry->setFallbackComponentDescriptor(
std::make_shared<UnimplementedNativeViewComponentDescriptor>(
ComponentDescriptorParameters{
eventDispatcher, contextContainer, nullptr}));
return registry;
};
delegate->buildRegistryFunction = buildRegistryFunction;
return instance;
}
void MainComponentsRegistry::registerNatives() {
registerHybrid({
makeNativeMethod("initHybrid", MainComponentsRegistry::initHybrid),
});
}
} // namespace react
} // namespace facebook

View File

@ -0,0 +1,32 @@
#pragma once
#include <ComponentFactory.h>
#include <fbjni/fbjni.h>
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
#include <react/renderer/componentregistry/ComponentDescriptorRegistry.h>
namespace facebook {
namespace react {
class MainComponentsRegistry
: public facebook::jni::HybridClass<MainComponentsRegistry> {
public:
// Adapt it to the package you used for your Java class.
constexpr static auto kJavaDescriptor =
"Lchat/rocket/reactnative/newarchitecture/components/MainComponentsRegistry;";
static void registerNatives();
MainComponentsRegistry(ComponentFactory *delegate);
private:
static std::shared_ptr<ComponentDescriptorProviderRegistry const>
sharedProviderRegistry();
static jni::local_ref<jhybriddata> initHybrid(
jni::alias_ref<jclass>,
ComponentFactory *delegate);
};
} // namespace react
} // namespace facebook

View File

@ -0,0 +1,11 @@
#include <fbjni/fbjni.h>
#include "MainApplicationTurboModuleManagerDelegate.h"
#include "MainComponentsRegistry.h"
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
return facebook::jni::initialize(vm, [] {
facebook::react::MainApplicationTurboModuleManagerDelegate::
registerNatives();
facebook::react::MainComponentsRegistry::registerNatives();
});
}

View File

@ -1,7 +1,6 @@
package chat.rocket.reactnative;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Base64;
import android.util.Log;
@ -81,7 +80,7 @@ class Encryption {
dbName += "-experimental";
}
dbName += ".db";
Database database = new Database(dbName, reactContext, SQLiteDatabase.CREATE_IF_NECESSARY);
Database database = new Database(dbName, reactContext);
String[] query = {ejson.rid};
Cursor cursor = database.rawQuery("select * from subscriptions where id == ? limit 1", query);

View File

@ -1,12 +0,0 @@
package chat.rocket.reactnative;
import android.content.Context;
import com.facebook.react.ReactInstanceManager;
/**
* Class responsible of loading Flipper inside your React Native application. This is the release
* flavor of it so it's empty as we don't want to load Flipper.
*/
public class ReactNativeFlipper {
public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
// Do nothing as we don't want to initialize Flipper on Release.
}
}

View File

@ -1,10 +1,11 @@
import org.apache.tools.ant.taskdefs.condition.Os
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
def taskRequests = getGradle().getStartParameter().getTaskRequests().toString().toLowerCase()
def isPlay = !taskRequests.contains("foss")
ext {
// TODO: target 33
buildToolsVersion = "33.0.0"
minSdkVersion = 23
compileSdkVersion = 33
@ -38,20 +39,75 @@ buildscript {
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.0'
classpath 'com.bugsnag:bugsnag-android-gradle-plugin:7.+'
}
classpath("com.android.tools.build:gradle:7.3.1")
classpath("com.android.tools.build:gradle:7.0.4")
classpath("com.facebook.react:react-native-gradle-plugin")
classpath("de.undercouch:gradle-download-task:4.1.2")
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
mavenLocal()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url("$rootDir/../node_modules/react-native/android")
}
maven {
// Android JSC is installed from npm
url("$rootDir/../node_modules/jsc-android/dist")
}
maven {
url "$rootDir/../node_modules/detox/Detox-android"
}
maven {
// expo-camera bundles a custom com.google.android:cameraview
url "$rootDir/../node_modules/expo-camera/android/maven"
}
mavenCentral {
content {
excludeGroup "com.facebook.react"
}
}
google()
maven { url 'https://maven.google.com' }
maven { url 'https://www.jitpack.io' }
// https://stackoverflow.com/a/74333788/5447468
// TODO: remove once we update RN
exclusiveContent {
// We get React Native's Android binaries exclusively through npm,
// from a local Maven repo inside node_modules/react-native/.
// (The use of exclusiveContent prevents looking elsewhere like Maven Central
// and potentially getting a wrong version.)
filter {
includeGroup "com.facebook.react"
}
forRepository {
maven {
// NOTE: if you are in a monorepo, you may have "$rootDir/../../../node_modules/react-native/android"
url "$rootDir/../node_modules/react-native/android"
}
}
}
}
}
subprojects { subproject ->
afterEvaluate {
if (!project.name.equalsIgnoreCase("app") && project.hasProperty("android")) {
android {
compileSdkVersion 31
buildToolsVersion "31.0.0"
defaultConfig {
minSdkVersion 23
targetSdkVersion 31
}
}
}
}
}

View File

@ -37,10 +37,6 @@ reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
# are providing them.
newArchEnabled=false
# Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead.
hermesEnabled=true
# Application ID
APPLICATION_ID=chat.rocket.reactnative

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@ -11,13 +11,9 @@ apply from: file("../node_modules/@react-native-community/cli-platform-android/n
include ':app'
includeBuild('../node_modules/react-native-gradle-plugin')
includeBuild('../node_modules/react-native') {
dependencySubstitution {
substitute(module("com.facebook.react:react-android")).using(project(":ReactAndroid"))
substitute(module("com.facebook.react:react-native")).using(project(":ReactAndroid"))
substitute(module("com.facebook.react:hermes-android")).using(project(":ReactAndroid:hermes-engine"))
substitute(module("com.facebook.react:hermes-engine")).using(project(":ReactAndroid:hermes-engine"))
}
if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") {
include(":ReactAndroid")
project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid')
}
apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle")

View File

@ -3,15 +3,17 @@ import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { connect } from 'react-redux';
import { SetUsernameStackParamList, StackParamList } from './definitions/navigationTypes';
import Navigation from './lib/navigation/appNavigation';
import { defaultHeader, getActiveRouteName, navigationTheme } from './lib/methods/helpers/navigation';
import { RootEnum } from './definitions';
// Stacks
import AuthLoadingView from './views/AuthLoadingView';
// SetUsername Stack
import SetUsernameView from './views/SetUsernameView';
import OutsideStack from './stacks/OutsideStack';
import InsideStack from './stacks/InsideStack';
import MasterDetailStack from './stacks/MasterDetailStack';
import { SetUsernameStackParamList, StackParamList } from './stacks/types';
import { ThemeContext } from './theme';
import { setCurrentScreen } from './lib/methods/helpers/log';

201
app/commands.ts Normal file
View File

@ -0,0 +1,201 @@
/* eslint-disable no-bitwise */
import { NativeSyntheticEvent } from 'react-native';
import KeyCommands, { constants, KeyCommand } from 'react-native-keycommands';
import I18n from './i18n';
const KEY_TYPING = '\t';
const KEY_PREFERENCES = 'p';
const KEY_SEARCH = 'f';
const KEY_PREVIOUS_ROOM = '[';
const KEY_NEXT_ROOM = ']';
const KEY_NEW_ROOM = __DEV__ ? 'e' : 'n';
const KEY_ROOM_ACTIONS = __DEV__ ? 'b' : 'i';
const KEY_UPLOAD = 'u';
const KEY_REPLY = ';';
const KEY_SERVER_SELECTION = __DEV__ ? 'o' : '`';
const KEY_ADD_SERVER = __DEV__ ? 'l' : 'n';
const KEY_SEND_MESSAGE = '\r';
const KEY_SELECT = '123456789';
const keyCommands = [
{
// Focus messageBox
input: KEY_TYPING,
modifierFlags: 0,
discoverabilityTitle: I18n.t('Type_message')
},
{
// Send message on textInput to current room
input: KEY_SEND_MESSAGE,
modifierFlags: 0,
discoverabilityTitle: I18n.t('Send')
},
{
// Open Preferences Modal
input: KEY_PREFERENCES,
modifierFlags: constants.keyModifierCommand,
discoverabilityTitle: I18n.t('Preferences')
},
{
// Focus Room Search
input: KEY_SEARCH,
modifierFlags: constants.keyModifierCommand | constants.keyModifierAlternate,
discoverabilityTitle: I18n.t('Room_search')
},
{
// Select a room by order using 1-9
input: '1...9',
modifierFlags: constants.keyModifierCommand,
discoverabilityTitle: I18n.t('Room_selection')
},
{
// Change room to next on Rooms List
input: KEY_NEXT_ROOM,
modifierFlags: constants.keyModifierCommand,
discoverabilityTitle: I18n.t('Next_room')
},
{
// Change room to previous on Rooms List
input: KEY_PREVIOUS_ROOM,
modifierFlags: constants.keyModifierCommand,
discoverabilityTitle: I18n.t('Previous_room')
},
{
// Open New Room Modal
input: KEY_NEW_ROOM,
modifierFlags: constants.keyModifierCommand,
discoverabilityTitle: I18n.t('New_room')
},
{
// Open Room Actions
input: KEY_ROOM_ACTIONS,
modifierFlags: constants.keyModifierCommand,
discoverabilityTitle: I18n.t('Room_actions')
},
{
// Upload a file to room
input: KEY_UPLOAD,
modifierFlags: constants.keyModifierCommand,
discoverabilityTitle: I18n.t('Upload_room')
},
{
// Search Messages on current room
input: KEY_SEARCH,
modifierFlags: constants.keyModifierCommand,
discoverabilityTitle: I18n.t('Search_messages')
},
{
// Scroll messages on current room
input: '↑ ↓',
modifierFlags: constants.keyModifierAlternate,
discoverabilityTitle: I18n.t('Scroll_messages')
},
{
// Scroll up messages on current room
input: constants.keyInputUpArrow,
modifierFlags: constants.keyModifierAlternate
},
{
// Scroll down messages on current room
input: constants.keyInputDownArrow,
modifierFlags: constants.keyModifierAlternate
},
{
// Reply latest message with Quote
input: KEY_REPLY,
modifierFlags: constants.keyModifierCommand,
discoverabilityTitle: I18n.t('Reply_latest')
},
{
// Open server dropdown
input: KEY_SERVER_SELECTION,
modifierFlags: constants.keyModifierCommand | constants.keyModifierAlternate,
discoverabilityTitle: I18n.t('Server_selection')
},
{
// Select a server by order using 1-9
input: '1...9',
modifierFlags: constants.keyModifierCommand | constants.keyModifierAlternate,
discoverabilityTitle: I18n.t('Server_selection_numbers')
},
{
// Navigate to add new server
input: KEY_ADD_SERVER,
modifierFlags: constants.keyModifierCommand | constants.keyModifierAlternate,
discoverabilityTitle: I18n.t('Add_server')
},
// Refers to select rooms on list
...[1, 2, 3, 4, 5, 6, 7, 8, 9].map(value => ({
input: `${value}`,
modifierFlags: constants.keyModifierCommand
})),
// Refers to select servers on list
...[1, 2, 3, 4, 5, 6, 7, 8, 9].map(value => ({
input: `${value}`,
modifierFlags: constants.keyModifierCommand | constants.keyModifierAlternate
}))
];
export const setKeyCommands = (): void => KeyCommands.setKeyCommands(keyCommands);
export const deleteKeyCommands = (): void => KeyCommands.deleteKeyCommands(keyCommands);
export const KEY_COMMAND = 'KEY_COMMAND';
export interface IKeyCommandEvent extends NativeSyntheticEvent<typeof KeyCommand> {
input: number & string;
modifierFlags: string | number;
}
export const commandHandle = (event: IKeyCommandEvent, key: string | string[], flags: string[] = []): boolean => {
const { input, modifierFlags } = event;
let _flags = 0;
if (flags.includes('command') && flags.includes('alternate')) {
_flags = constants.keyModifierCommand | constants.keyModifierAlternate;
} else if (flags.includes('command')) {
_flags = constants.keyModifierCommand;
} else if (flags.includes('alternate')) {
_flags = constants.keyModifierAlternate;
}
return key.includes(input) && modifierFlags === _flags;
};
export const handleCommandTyping = (event: IKeyCommandEvent): boolean => commandHandle(event, KEY_TYPING);
export const handleCommandSubmit = (event: IKeyCommandEvent): boolean => commandHandle(event, KEY_SEND_MESSAGE);
export const handleCommandShowUpload = (event: IKeyCommandEvent): boolean => commandHandle(event, KEY_UPLOAD, ['command']);
export const handleCommandScroll = (event: IKeyCommandEvent): boolean =>
commandHandle(event, [constants.keyInputUpArrow, constants.keyInputDownArrow], ['alternate']);
export const handleCommandRoomActions = (event: IKeyCommandEvent): boolean => commandHandle(event, KEY_ROOM_ACTIONS, ['command']);
export const handleCommandSearchMessages = (event: IKeyCommandEvent): boolean => commandHandle(event, KEY_SEARCH, ['command']);
export const handleCommandReplyLatest = (event: IKeyCommandEvent): boolean => commandHandle(event, KEY_REPLY, ['command']);
export const handleCommandSelectServer = (event: IKeyCommandEvent): boolean =>
commandHandle(event, KEY_SELECT, ['command', 'alternate']);
export const handleCommandShowPreferences = (event: IKeyCommandEvent): boolean =>
commandHandle(event, KEY_PREFERENCES, ['command']);
export const handleCommandSearching = (event: IKeyCommandEvent): boolean =>
commandHandle(event, KEY_SEARCH, ['command', 'alternate']);
export const handleCommandSelectRoom = (event: IKeyCommandEvent): boolean => commandHandle(event, KEY_SELECT, ['command']);
export const handleCommandPreviousRoom = (event: IKeyCommandEvent): boolean =>
commandHandle(event, KEY_PREVIOUS_ROOM, ['command']);
export const handleCommandNextRoom = (event: IKeyCommandEvent): boolean => commandHandle(event, KEY_NEXT_ROOM, ['command']);
export const handleCommandShowNewMessage = (event: IKeyCommandEvent): boolean => commandHandle(event, KEY_NEW_ROOM, ['command']);
export const handleCommandAddNewServer = (event: IKeyCommandEvent): boolean =>
commandHandle(event, KEY_ADD_SERVER, ['command', 'alternate']);
export const handleCommandOpenServerDropdown = (event: IKeyCommandEvent): boolean =>
commandHandle(event, KEY_SERVER_SELECTION, ['command', 'alternate']);

View File

@ -4,7 +4,7 @@ import React, { forwardRef, isValidElement, useEffect, useImperativeHandle, useR
import { Keyboard } from 'react-native';
import { Easing } from 'react-native-reanimated';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import BottomSheet, { BottomSheetBackdrop, BottomSheetBackdropProps } from '@gorhom/bottom-sheet';
import BottomSheet, { BottomSheetBackdrop } from '@gorhom/bottom-sheet';
import { useDimensions, useOrientation } from '../../dimensions';
import { useTheme } from '../../theme';
@ -107,7 +107,7 @@ const ActionSheet = React.memo(
};
const renderBackdrop = useCallback(
(props: BottomSheetBackdropProps) => (
props => (
<BottomSheetBackdrop
{...props}
appearsOnIndex={0}

View File

@ -75,7 +75,6 @@ const EmojiPicker = ({
parentWidth={parentWidth}
/>
) : (
// @ts-ignore
<ScrollableTabView
renderTabBar={() => <TabBar />}
contentProps={{

View File

@ -13,6 +13,7 @@ export interface IHeaderButtonItem extends Omit<ICustomIcon, 'name' | 'size' | '
testID?: string;
badge?(): void;
color?: string;
disabled?: boolean;
}
export const BUTTON_HIT_SLOP = {

View File

@ -31,7 +31,7 @@ const MentionItemContent = React.memo(({ trackingType, item }: IMessageBoxMentio
return (
<>
<MentionEmoji item={item} />
<Text style={[styles.mentionText, { color: themes[theme].titleText }]}>:{item.name ?? item}:</Text>
<Text style={[styles.mentionText, { color: themes[theme].titleText }]}>:{item.name || item}:</Text>
</>
);
case MENTIONS_TRACKING_TYPE_COMMANDS:
@ -57,7 +57,7 @@ const MentionItemContent = React.memo(({ trackingType, item }: IMessageBoxMentio
return (
<>
<Avatar style={styles.avatar} text={item.username || item.name} size={30} type={item.t} />
<Text style={[styles.mentionText, { color: themes[theme].titleText }]}>{item.username ?? item.name ?? item}</Text>
<Text style={[styles.mentionText, { color: themes[theme].titleText }]}>{item.username || item.name || item}</Text>
</>
);
}

View File

@ -24,19 +24,19 @@ const RECORDING_EXTENSION = '.m4a';
const RECORDING_SETTINGS = {
android: {
extension: RECORDING_EXTENSION,
outputFormat: Audio.AndroidOutputFormat.MPEG_4,
audioEncoder: Audio.AndroidAudioEncoder.AAC,
sampleRate: Audio.RecordingOptionsPresets.LOW_QUALITY.android.sampleRate,
numberOfChannels: Audio.RecordingOptionsPresets.LOW_QUALITY.android.numberOfChannels,
bitRate: Audio.RecordingOptionsPresets.LOW_QUALITY.android.bitRate
outputFormat: Audio.RECORDING_OPTION_ANDROID_OUTPUT_FORMAT_MPEG_4,
audioEncoder: Audio.RECORDING_OPTION_ANDROID_AUDIO_ENCODER_AAC,
sampleRate: Audio.RECORDING_OPTIONS_PRESET_LOW_QUALITY.android.sampleRate,
numberOfChannels: Audio.RECORDING_OPTIONS_PRESET_LOW_QUALITY.android.numberOfChannels,
bitRate: Audio.RECORDING_OPTIONS_PRESET_LOW_QUALITY.android.bitRate
},
ios: {
extension: RECORDING_EXTENSION,
audioQuality: Audio.IOSAudioQuality.MIN,
sampleRate: Audio.RecordingOptionsPresets.LOW_QUALITY.ios.sampleRate,
numberOfChannels: Audio.RecordingOptionsPresets.LOW_QUALITY.ios.numberOfChannels,
bitRate: Audio.RecordingOptionsPresets.LOW_QUALITY.ios.bitRate,
outputFormat: Audio.IOSOutputFormat.MPEG4AAC
audioQuality: Audio.RECORDING_OPTION_IOS_AUDIO_QUALITY_MIN,
sampleRate: Audio.RECORDING_OPTIONS_PRESET_LOW_QUALITY.ios.sampleRate,
numberOfChannels: Audio.RECORDING_OPTIONS_PRESET_LOW_QUALITY.ios.numberOfChannels,
bitRate: Audio.RECORDING_OPTIONS_PRESET_LOW_QUALITY.ios.bitRate,
outputFormat: Audio.RECORDING_OPTION_IOS_OUTPUT_FORMAT_MPEG4AAC
},
web: {}
};

View File

@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { Alert, NativeModules, Text, View, BackHandler } from 'react-native';
import { Alert, Keyboard, NativeModules, Text, View, BackHandler } from 'react-native';
import { connect } from 'react-redux';
import { KeyboardAccessoryView } from 'react-native-ui-lib/keyboard';
import ImagePicker, { Image, ImageOrVideo, Options } from 'react-native-image-crop-picker';
@ -21,6 +21,8 @@ import { themes, emojis } from '../../lib/constants';
import LeftButtons from './LeftButtons';
import RightButtons from './RightButtons';
import { canUploadFile } from '../../lib/methods/helpers/media';
import EventEmiter from '../../lib/methods/helpers/events';
import { KEY_COMMAND, handleCommandShowUpload, handleCommandSubmit, handleCommandTyping } from '../../commands';
import getMentionRegexp from './getMentionRegexp';
import Mentions from './Mentions';
import MessageboxContext from './Context';
@ -138,6 +140,8 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
private selection: { start: number; end: number };
private focused: boolean;
private imagePickerConfig: Options;
private libraryPickerConfig: Options;
@ -188,6 +192,7 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
};
this.text = '';
this.selection = { start: 0, end: 0 };
this.focused = false;
const libPickerLabels = {
cropperChooseText: I18n.t('Choose'),
@ -263,6 +268,10 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
this.setShowSend(true);
}
if (isTablet) {
EventEmiter.addEventListener(KEY_COMMAND, this.handleCommands);
}
if (usedCannedResponse) {
this.onChangeText(usedCannedResponse);
}
@ -437,6 +446,9 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
if (this.unsubscribeBlur) {
this.unsubscribeBlur();
}
if (isTablet) {
EventEmiter.removeListener(KEY_COMMAND, this.handleCommands);
}
BackHandler.removeEventListener('hardwareBackPress', this.handleBackPress);
}
@ -966,7 +978,7 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
const { showEmojiKeyboard } = this.state;
this.closeEmoji();
setTimeout(() => action && action(params), showEmojiKeyboard && isIOS ? TIMEOUT_CLOSE_EMOJI : undefined);
setTimeout(() => action && action(params), showEmojiKeyboard && isIOS ? TIMEOUT_CLOSE_EMOJI : null);
};
submit = async () => {
@ -1101,6 +1113,21 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
});
};
handleCommands = ({ event }: { event: any }) => {
if (handleCommandTyping(event)) {
if (this.focused) {
Keyboard.dismiss();
} else {
this.component.focus();
}
this.focused = !this.focused;
} else if (handleCommandSubmit(event)) {
this.submit();
} else if (handleCommandShowUpload(event)) {
this.showMessageBoxActions();
}
};
onPressSendToChannel = () => this.setState(({ tshow }) => ({ tshow: !tshow }));
renderSendToChannel = () => {

View File

@ -21,7 +21,6 @@ const ReactionsList = ({ reactions, getCustomEmoji }: IReactionsListProps): Reac
const allTabLabel = { emoji: I18n.t('All'), usernames: [], names: [], _id: 'All' };
return (
<View style={styles.container} testID='reactionsList'>
{/* @ts-ignore */}
<ScrollableTabView renderTabBar={() => <ReactionsTabBar getCustomEmoji={getCustomEmoji} />}>
<AllTab tabLabel={allTabLabel} reactions={sortedReactions} getCustomEmoji={getCustomEmoji} />
{sortedReactions?.map(reaction => (

View File

@ -17,7 +17,7 @@ const SearchBox = ({ onChangeText, onSubmitEditing, testID }: TextInputProps): J
const { colors } = useTheme();
const internalOnChangeText = useCallback((value: string) => {
const internalOnChangeText = useCallback(value => {
setText(value);
onChangeText?.(value);
}, []);

View File

@ -46,7 +46,6 @@ const Toast = (): React.ReactElement => {
ref={getToastRef}
// @ts-ignore
position='center'
// @ts-ignore
style={[styles.toast, { backgroundColor: colors.toastBackground }]}
textStyle={[styles.text, { color: colors.buttonText }]}
opacity={0.9}

View File

@ -93,7 +93,6 @@ export const DatePicker = ({ element, language, action, context, loading, value,
mode='date'
display={isAndroid ? 'default' : 'inline'}
value={currentDate}
// @ts-ignore
onChange={onChange}
textColor={themes[theme].titleText}
/>

View File

@ -1,6 +1,6 @@
import React from 'react';
import { Text, View } from 'react-native';
import Touchable, { PlatformTouchableProps } from 'react-native-platform-touchable';
import Touchable from 'react-native-platform-touchable';
import { CustomIcon } from '../../CustomIcon';
import ActivityIndicator from '../../ActivityIndicator';
@ -9,9 +9,9 @@ import { useTheme } from '../../../theme';
interface IInput {
children?: JSX.Element;
onPress: PlatformTouchableProps['onPress'];
onPress: () => void;
inputStyle?: object;
disabled?: PlatformTouchableProps['disabled'];
disabled?: boolean | null;
placeholder?: string;
loading?: boolean;
innerInputStyle?: object;

View File

@ -36,7 +36,7 @@ interface IMultiSelect {
onClose?: () => void;
inputStyle?: TextStyle;
value?: any[];
disabled?: boolean;
disabled?: boolean | null;
innerInputStyle?: object;
}

View File

@ -71,7 +71,6 @@ export const Select = ({ options = [], placeholder, onChange, loading, disabled,
);
return (
// @ts-ignore lib types issues. We need to fork it and maintain or find another lib
<RNPickerSelect
items={items}
placeholder={placeholderObject}
@ -88,6 +87,8 @@ export const Select = ({ options = [], placeholder, onChange, loading, disabled,
}}
Icon={Icon}
textInputProps={{
// style property was Omitted in lib, but can be used normally
// @ts-ignore
style: { ...styles.pickerText, color: selected ? themes[theme].titleText : themes[theme].auxiliaryText }
}}
/>

View File

@ -121,6 +121,7 @@ Button.displayName = 'MessageAudioButton';
class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioState> {
static contextType = MessageContext;
private sound: Sound;
constructor(props: IMessageAudioProps) {
@ -366,13 +367,7 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
return (
<>
<Markdown
msg={msg}
style={[isReply && style]}
username={user.username}
getCustomEmoji={getCustomEmoji}
theme={theme}
/>
<Markdown msg={msg} style={[isReply && style]} username={user.username} getCustomEmoji={getCustomEmoji} theme={theme} />
<View
style={[
styles.audioContainer,

View File

@ -0,0 +1,6 @@
export interface ICommand {
event: {
input: string;
modifierFlags: number;
};
}

View File

@ -40,6 +40,6 @@ export interface IBaseScreen<T extends Record<string, object | undefined>, S ext
dispatch: Dispatch;
isMasterDetail: boolean;
// TODO: remove after migrating all Class components
theme?: TSupportedThemes;
theme: TSupportedThemes;
colors: TColors;
}

View File

@ -1,5 +1,12 @@
import { NavigatorScreenParams } from '@react-navigation/core';
import { StackNavigationOptions } from '@react-navigation/stack';
import { TSubscriptionModel } from './ISubscription';
import { TServerModel } from './IServer';
import { IAttachment } from './IAttachment';
import { MasterDetailInsideStackParamList } from '../stacks/MasterDetailStack/types';
import { OutsideParamList, InsideStackParamList } from '../stacks/types';
interface INavigationProps {
route?: any;
navigation?: any;
@ -9,3 +16,41 @@ interface INavigationProps {
export type TNavigationOptions = {
navigationOptions?(props: INavigationProps): StackNavigationOptions;
};
export type SetUsernameStackParamList = {
SetUsernameView: {
title: string;
};
};
export type StackParamList = {
AuthLoading: undefined;
OutsideStack: NavigatorScreenParams<OutsideParamList>;
InsideStack: NavigatorScreenParams<InsideStackParamList>;
MasterDetailStack: NavigatorScreenParams<MasterDetailInsideStackParamList>;
SetUsernameStack: NavigatorScreenParams<SetUsernameStackParamList>;
};
export type ShareInsideStackParamList = {
ShareListView: undefined;
ShareView: {
attachments: IAttachment[];
isShareView?: boolean;
isShareExtension: boolean;
serverInfo: TServerModel;
text: string;
room: TSubscriptionModel;
thread?: any; // TODO: Change
};
SelectServerView: undefined;
};
export type ShareOutsideStackParamList = {
WithoutServersView: undefined;
};
export type ShareAppStackParamList = {
AuthLoading?: undefined;
OutsideStack?: NavigatorScreenParams<ShareOutsideStackParamList>;
InsideStack?: NavigatorScreenParams<ShareInsideStackParamList>;
};

View File

@ -6,6 +6,7 @@ declare module 'react-native-image-progress';
declare module 'react-native-ui-lib/keyboard';
declare module '@rocket.chat/sdk';
declare module 'react-native-config-reader';
declare module 'react-native-keycommands';
declare module 'react-native-mime-types';
declare module 'react-native-restart';
declare module 'rn-root-view';

View File

@ -1,5 +1,6 @@
import React from 'react';
import { Dimensions, Linking, EmitterSubscription } from 'react-native';
import { Dimensions, Linking } from 'react-native';
import { KeyCommandsEmitter } from 'react-native-keycommands';
import { initialWindowMetrics, SafeAreaProvider } from 'react-native-safe-area-context';
import RNScreens from 'react-native-screens';
import { Provider } from 'react-redux';
@ -8,11 +9,13 @@ import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { appInit, appInitLocalSettings, setMasterDetail as setMasterDetailAction } from './actions/app';
import { deepLinkingOpen } from './actions/deepLinking';
import AppContainer from './AppContainer';
import { KEY_COMMAND } from './commands';
import { ActionSheetProvider } from './containers/ActionSheet';
import InAppNotification from './containers/InAppNotification';
import Toast from './containers/Toast';
import TwoFactor from './containers/TwoFactor';
import Loading from './containers/Loading';
import { ICommand } from './definitions/ICommand';
import { IThemePreference } from './definitions/ITheme';
import { DimensionsContext } from './dimensions';
import { colors, isFDroidBuild, MIN_WIDTH_MASTER_DETAIL_LAYOUT, themes } from './lib/constants';
@ -23,6 +26,7 @@ import store from './lib/store';
import { initStore } from './lib/store/auxStore';
import { ThemeContext, TSupportedThemes } from './theme';
import { debounce, isTablet } from './lib/methods/helpers';
import EventEmitter from './lib/methods/helpers/events';
import { toggleAnalyticsEventsReport, toggleCrashErrorsReport } from './lib/methods/helpers/log';
import {
getTheme,
@ -79,7 +83,8 @@ const parseDeepLinking = (url: string) => {
export default class Root extends React.Component<{}, IState> {
private listenerTimeout!: any;
private dimensionsListener?: EmitterSubscription;
private onKeyCommands: any;
constructor(props: any) {
super(props);
@ -101,7 +106,6 @@ export default class Root extends React.Component<{}, IState> {
this.initTablet();
}
setNativeTheme(theme);
subscribeTheme(theme, this.state.theme, this.setTheme);
}
componentDidMount() {
@ -113,16 +117,18 @@ export default class Root extends React.Component<{}, IState> {
}
});
}, 5000);
this.dimensionsListener = Dimensions.addEventListener('change', this.onDimensionsChange);
Dimensions.addEventListener('change', this.onDimensionsChange);
}
componentWillUnmount() {
clearTimeout(this.listenerTimeout);
if (this.dimensionsListener) {
this.dimensionsListener.remove();
}
Dimensions.removeEventListener('change', this.onDimensionsChange);
unsubscribeTheme();
if (this.onKeyCommands && this.onKeyCommands.remove) {
this.onKeyCommands.remove();
}
}
init = async () => {
@ -175,9 +181,9 @@ export default class Root extends React.Component<{}, IState> {
this.setState(
prevState => newThemeState(prevState, newTheme as IThemePreference),
() => {
const { themePreferences, theme } = this.state;
const { themePreferences } = this.state;
// subscribe to Appearance changes
subscribeTheme(themePreferences, theme, this.setTheme);
subscribeTheme(themePreferences, this.setTheme);
}
);
};
@ -189,6 +195,9 @@ export default class Root extends React.Component<{}, IState> {
initTablet = () => {
const { width } = this.state;
this.setMasterDetail(width);
this.onKeyCommands = KeyCommandsEmitter.addListener('onKeyCommand', (command: ICommand) => {
EventEmitter.emit(KEY_COMMAND, { event: command });
});
};
initCrashReport = () => {

View File

@ -382,7 +382,7 @@ class Encryption {
}
try {
const batch: (Model | null | void | false)[] = [];
const batch: (Model | null | void | false | Promise<void>)[] = [];
// If the subscription doesn't exists yet
if (!subRecord) {
// Let's create the subscription with the data received

View File

@ -1,4 +1,6 @@
export default class Deferred {
[Symbol.toStringTag]: 'Promise';
private promise: Promise<unknown>;
private _resolve: (value?: unknown) => void;
private _reject: (reason?: any) => void;

View File

@ -17,7 +17,7 @@ export const useFrequentlyUsedEmoji = (
useEffect(() => {
const getFrequentlyUsedEmojis = async () => {
const db = database.active;
const frequentlyUsedRecords = await db.get('frequently_used_emojis').query(Q.sortBy('count', Q.desc)).fetch();
const frequentlyUsedRecords = await db.get('frequently_used_emojis').query(Q.experimentalSortBy('count', Q.desc)).fetch();
let frequentlyUsedEmojis = frequentlyUsedRecords.map(item => {
if (item.isCustom) {
return { name: item.content, extension: item.extension! }; // if isCustom is true, extension is not null

View File

@ -1,4 +1,5 @@
import { IEmitUserInteraction } from '../../../containers/UIKit/interfaces';
import { ICommand } from '../../../definitions/ICommand';
import log from './log';
type TEventEmitterEmmitArgs =
@ -10,6 +11,7 @@ type TEventEmitterEmmitArgs =
| { force: boolean }
| { hasBiometry: boolean }
| { visible: boolean; onCancel?: null | Function }
| { event: string | ICommand }
| { cancel: () => void }
| { submit: (param: string) => void }
| IEmitUserInteraction;

View File

@ -11,10 +11,10 @@ const { add, multiply } = Animated;
* @param fallback Animated Node to use if the condition is `false`
*/
export default function conditional(
condition: Animated.AnimatedInterpolation<0 | 1>,
main: Animated.AnimatedInterpolation<number>,
fallback: Animated.AnimatedInterpolation<number>
) {
condition: Animated.AnimatedInterpolation,
main: Animated.Animated,
fallback: Animated.Animated
): Animated.AnimatedAddition {
// To implement this behavior, we multiply the main node with the condition.
// So if condition is 0, result will be 0, and if condition is 1, result will be main node.
// Then we multiple reverse of the condition (0 if condition is 1) with the fallback.

View File

@ -7,7 +7,6 @@ import { themes, THEME_PREFERENCES_KEY } from '../../constants';
import UserPreferences from '../userPreferences';
import { TSupportedThemes } from '../../../theme';
import { isAndroid } from './deviceInfo';
import { debounce } from './debounce';
let themeListener: { remove: () => void } | null;
@ -69,24 +68,12 @@ export const unsubscribeTheme = () => {
}
};
type AppearancePreferences = {
colorScheme: 'light' | 'dark';
};
export const subscribeTheme = (themePreferences: IThemePreference, theme: TSupportedThemes, setTheme: () => void): void => {
export const subscribeTheme = (themePreferences: IThemePreference, setTheme: () => void): void => {
const { currentTheme } = themePreferences;
if (currentTheme === 'automatic') {
unsubscribeTheme();
themeListener = Appearance.addChangeListener(
// listener issue https://github.com/facebook/react-native/issues/36713
debounce((appearance: AppearancePreferences) => {
const simplifiedTheme = theme === 'black' ? 'dark' : theme;
if (simplifiedTheme !== appearance.colorScheme) {
setTheme();
}
}, 300)
);
} else {
if (!themeListener && currentTheme === 'automatic') {
// not use listener params because we use getTheme
themeListener = Appearance.addChangeListener(() => setTheme());
} else if (currentTheme !== 'automatic') {
// unsubscribe appearance changes when automatic was disabled
unsubscribeTheme();
}

View File

@ -34,7 +34,7 @@ export const localSearchSubscription = async ({
Q.where('name', Q.like(`%${likeString}%`)),
Q.where('fname', Q.like(`%${likeString}%`))
),
Q.sortBy('room_updated_at', Q.desc)
Q.experimentalSortBy('room_updated_at', Q.desc)
)
.fetch();
@ -82,8 +82,8 @@ export const localSearchUsersMessageByRid = async ({ text = '', rid = '' }): Pro
.get('messages')
.query(
Q.and(Q.where('rid', rid), Q.where('u', Q.notLike(`%${userId}%`)), Q.where('t', null)),
Q.sortBy('ts', Q.desc),
Q.take(50)
Q.experimentalSortBy('ts', Q.desc),
Q.experimentalTake(50)
)
.fetch();

View File

@ -213,7 +213,6 @@ const createOrUpdateSubscription = async (subscription: ISubscription, room: ISe
if (messageRecord) {
batch.push(
messageRecord.prepareUpdate(() => {
// @ts-ignore
Object.assign(messageRecord, lastMessage);
})
);

View File

@ -38,7 +38,8 @@ export const pushNotificationConfigure = (onNotification: (notification: INotifi
const notificationCategory = new NotificationCategory('MESSAGE', [notificationAction]);
Notifications.setCategories([notificationCategory]);
} else if (Platform.OS === 'android' && Platform.constants.Version >= 33) {
PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS).then(permissionStatus => {
// @ts-ignore
PermissionsAndroid.request('android.permission.POST_NOTIFICATIONS').then(permissionStatus => {
if (permissionStatus === 'granted') {
Notifications.registerRemoteNotifications();
} else {

View File

@ -1,26 +1,76 @@
import React, { useEffect, useLayoutEffect, useState } from 'react';
import React, { useContext, useEffect, useLayoutEffect, useState } from 'react';
import { Dimensions } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { Provider } from 'react-redux';
import { getTheme, setNativeTheme, initialTheme as initialThemeFunction } from './lib/methods/helpers/theme';
import { getTheme, setNativeTheme, initialTheme as initialThemeFunction, unsubscribeTheme } from './lib/methods/helpers/theme';
import UserPreferences from './lib/methods/userPreferences';
import Navigation from './lib/navigation/shareNavigation';
import store from './lib/store';
import { initStore } from './lib/store/auxStore';
import { closeShareExtension, shareExtensionInit } from './lib/methods/shareExtension';
import { getActiveRouteName, navigationTheme } from './lib/methods/helpers/navigation';
import { defaultHeader, getActiveRouteName, navigationTheme, themedHeader } from './lib/methods/helpers/navigation';
import { ThemeContext } from './theme';
import { localAuthenticate } from './lib/methods/helpers/localAuthentication';
import ScreenLockedView from './views/ScreenLockedView';
// Outside Stack
import WithoutServersView from './views/WithoutServersView';
// Inside Stack
import ShareListView from './views/ShareListView';
import ShareView from './views/ShareView';
import SelectServerView from './views/SelectServerView';
import { setCurrentScreen } from './lib/methods/helpers/log';
import AuthLoadingView from './views/AuthLoadingView';
import { DimensionsContext } from './dimensions';
import { ShareInsideStackParamList, ShareOutsideStackParamList, ShareAppStackParamList } from './definitions/navigationTypes';
import { colors, CURRENT_SERVER } from './lib/constants';
import Loading from './containers/Loading';
import ShareExtensionStack from './stacks/ShareExtensionStack';
initStore(store);
const Inside = createStackNavigator<ShareInsideStackParamList>();
const InsideStack = () => {
const { theme } = useContext(ThemeContext);
const screenOptions = {
...defaultHeader,
...themedHeader(theme)
};
screenOptions.headerStyle = { ...screenOptions.headerStyle, height: 57 };
return (
<Inside.Navigator screenOptions={screenOptions}>
<Inside.Screen name='ShareListView' component={ShareListView} />
<Inside.Screen name='ShareView' component={ShareView} />
<Inside.Screen name='SelectServerView' component={SelectServerView} />
</Inside.Navigator>
);
};
const Outside = createStackNavigator<ShareOutsideStackParamList>();
const OutsideStack = () => {
const { theme } = useContext(ThemeContext);
return (
<Outside.Navigator screenOptions={{ ...defaultHeader, ...themedHeader(theme) }}>
<Outside.Screen name='WithoutServersView' component={WithoutServersView} />
</Outside.Navigator>
);
};
// App
const Stack = createStackNavigator<ShareAppStackParamList>();
export const App = ({ root }: { root: string }): React.ReactElement => (
<Stack.Navigator screenOptions={{ headerShown: false, animationEnabled: false }}>
<>
{!root ? <Stack.Screen name='AuthLoading' component={AuthLoadingView} /> : null}
{root === 'outside' ? <Stack.Screen name='OutsideStack' component={OutsideStack} /> : null}
{root === 'inside' ? <Stack.Screen name='InsideStack' component={InsideStack} /> : null}
</>
</Stack.Navigator>
);
const { width, height, scale, fontScale } = Dimensions.get('screen');
const initialTheme = initialThemeFunction();
const theme = getTheme(initialTheme);
@ -54,6 +104,7 @@ const Root = (): React.ReactElement => {
return () => {
closeShareExtension();
unsubscribeTheme();
};
}, []);
@ -80,7 +131,7 @@ const Root = (): React.ReactElement => {
Navigation.routeNameRef.current = currentRouteName;
}}
>
<ShareExtensionStack root={root} />
<App root={root} />
<Loading />
</NavigationContainer>
<ScreenLockedView />

View File

@ -99,11 +99,9 @@ const ChatsStackNavigator = () => {
<ChatsStack.Screen name='RoomActionsView' component={RoomActionsView} options={RoomActionsView.navigationOptions} />
<ChatsStack.Screen name='SelectListView' component={SelectListView} options={SelectListView.navigationOptions} />
<ChatsStack.Screen name='RoomInfoView' component={RoomInfoView} options={RoomInfoView.navigationOptions} />
{/* @ts-ignore */}
<ChatsStack.Screen name='RoomInfoEditView' component={RoomInfoEditView} options={RoomInfoEditView.navigationOptions} />
<ChatsStack.Screen name='ChangeAvatarView' component={ChangeAvatarView} />
<ChatsStack.Screen name='RoomMembersView' component={RoomMembersView} />
{/* @ts-ignore */}
<ChatsStack.Screen name='DiscussionsView' component={DiscussionsView} />
<ChatsStack.Screen
name='SearchMessagesView'
@ -111,18 +109,14 @@ const ChatsStackNavigator = () => {
options={SearchMessagesView.navigationOptions}
/>
<ChatsStack.Screen name='SelectedUsersView' component={SelectedUsersView} />
{/* @ts-ignore */}
<ChatsStack.Screen name='InviteUsersView' component={InviteUsersView} />
<ChatsStack.Screen name='InviteUsersEditView' component={InviteUsersEditView} />
<ChatsStack.Screen name='MessagesView' component={MessagesView} />
<ChatsStack.Screen name='AutoTranslateView' component={AutoTranslateView} />
<ChatsStack.Screen name='DirectoryView' component={DirectoryView} options={DirectoryView.navigationOptions} />
<ChatsStack.Screen name='NotificationPrefView' component={NotificationPrefView} />
{/* @ts-ignore */}
<ChatsStack.Screen name='ForwardLivechatView' component={ForwardLivechatView} />
{/* @ts-ignore */}
<ChatsStack.Screen name='CloseLivechatView' component={CloseLivechatView} />
{/* @ts-ignore */}
<ChatsStack.Screen name='LivechatEditView' component={LivechatEditView} options={LivechatEditView.navigationOptions} />
<ChatsStack.Screen name='PickerView' component={PickerView} />
{/* @ts-ignore */}
@ -133,14 +127,12 @@ const ChatsStackNavigator = () => {
<ChatsStack.Screen name='AddExistingChannelView' component={AddExistingChannelView} />
{/* @ts-ignore */}
<ChatsStack.Screen name='MarkdownTableView' component={MarkdownTableView} />
{/* @ts-ignore */}
<ChatsStack.Screen name='ReadReceiptsView' component={ReadReceiptsView} options={ReadReceiptsView.navigationOptions} />
<ChatsStack.Screen name='QueueListView' component={QueueListView} />
<ChatsStack.Screen name='CannedResponsesListView' component={CannedResponsesListView} />
<ChatsStack.Screen name='CannedResponseDetail' component={CannedResponseDetail} />
<ChatsStack.Screen
name='JitsiMeetView'
// @ts-ignore
component={JitsiMeetView}
options={{ headerShown: false, animationEnabled: isIOS }}
/>
@ -227,8 +219,7 @@ const DrawerNavigator = () => {
<Drawer.Navigator
// @ts-ignore
drawerContent={({ navigation, state }) => <Sidebar navigation={navigation} state={state} />}
// Performance issues on Android when disabled
useLegacyImplementation
useLegacyImplementation={true}
screenOptions={{
swipeEnabled: false,
headerShown: false,
@ -258,7 +249,6 @@ const NewMessageStackNavigator = () => {
<NewMessageStack.Screen name='NewMessageView' component={NewMessageView} />
<NewMessageStack.Screen name='SelectedUsersViewCreateChannel' component={SelectedUsersView} />
<NewMessageStack.Screen name='CreateChannelView' component={CreateChannelView} />
{/* @ts-ignore */}
<NewMessageStack.Screen name='CreateDiscussionView' component={CreateDiscussionView} />
<NewMessageStack.Screen name='ForwardMessageView' component={ForwardMessageView} />
</NewMessageStack.Navigator>
@ -318,7 +308,6 @@ const InsideStackNavigator = () => {
<InsideStack.Screen name='AttachmentView' component={AttachmentView} />
<InsideStack.Screen name='StatusView' component={StatusView} />
<InsideStack.Screen name='ShareView' component={ShareView} />
{/* @ts-ignore */}
<InsideStack.Screen name='ModalBlockView' component={ModalBlockView} options={ModalBlockView.navigationOptions} />
</InsideStack.Navigator>
);

View File

@ -1,4 +1,5 @@
import React from 'react';
import React, { useEffect } from 'react';
import { useIsFocused } from '@react-navigation/native';
import { createStackNavigator, StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack';
import { createDrawerNavigator } from '@react-navigation/drawer';
@ -61,6 +62,7 @@ import CreateDiscussionView from '../../views/CreateDiscussionView';
import E2ESaveYourPasswordView from '../../views/E2ESaveYourPasswordView';
import E2EHowItWorksView from '../../views/E2EHowItWorksView';
import E2EEnterYourPasswordView from '../../views/E2EEnterYourPasswordView';
import { deleteKeyCommands, setKeyCommands } from '../../commands';
import ShareView from '../../views/ShareView';
import QueueListView from '../../ee/omnichannel/views/QueueListView';
import AddChannelTeamView from '../../views/AddChannelTeamView';
@ -82,6 +84,18 @@ const ChatsStack = createStackNavigator<MasterDetailChatsStackParamList>();
const ChatsStackNavigator = React.memo(() => {
const { theme } = React.useContext(ThemeContext);
const isFocused = useIsFocused();
useEffect(() => {
if (isFocused) {
setKeyCommands();
} else {
deleteKeyCommands();
}
return () => {
deleteKeyCommands();
};
}, [isFocused]);
return (
<ChatsStack.Navigator
screenOptions={{ ...defaultHeader, ...themedHeader(theme), ...StackAnimation } as StackNavigationOptions}
@ -115,11 +129,8 @@ const ModalStackNavigator = React.memo(({ navigation }: INavigation) => {
screenOptions={{ ...defaultHeader, ...themedHeader(theme), ...StackAnimation } as StackNavigationOptions}
>
<ModalStack.Screen name='RoomActionsView' component={RoomActionsView} />
{/* @ts-ignore */}
<ModalStack.Screen name='RoomInfoView' component={RoomInfoView} options={RoomInfoView.navigationOptions} />
{/* @ts-ignore */}
<ModalStack.Screen name='SelectListView' component={SelectListView} />
{/* @ts-ignore */}
<ModalStack.Screen name='RoomInfoEditView' component={RoomInfoEditView} options={RoomInfoEditView.navigationOptions} />
<ModalStack.Screen name='ChangeAvatarView' component={ChangeAvatarView} />
<ModalStack.Screen name='RoomMembersView' component={RoomMembersView} />
@ -129,7 +140,6 @@ const ModalStackNavigator = React.memo(({ navigation }: INavigation) => {
options={SearchMessagesView.navigationOptions}
/>
<ModalStack.Screen name='SelectedUsersView' component={SelectedUsersView} />
{/* @ts-ignore */}
<ModalStack.Screen name='InviteUsersView' component={InviteUsersView} />
<ModalStack.Screen name='AddChannelTeamView' component={AddChannelTeamView} />
<ModalStack.Screen name='AddExistingChannelView' component={AddExistingChannelView} />
@ -146,24 +156,18 @@ const ModalStackNavigator = React.memo(({ navigation }: INavigation) => {
<ModalStack.Screen name='ForwardMessageView' component={ForwardMessageView} />
{/* @ts-ignore */}
<ModalStack.Screen name='ForwardLivechatView' component={ForwardLivechatView} />
{/* @ts-ignore */}
<ModalStack.Screen name='CloseLivechatView' component={CloseLivechatView} />
<ModalStack.Screen name='CannedResponsesListView' component={CannedResponsesListView} />
{/* @ts-ignore */}
<ModalStack.Screen name='CannedResponseDetail' component={CannedResponseDetail} />
{/* @ts-ignore */}
<ModalStack.Screen name='LivechatEditView' component={LivechatEditView} options={LivechatEditView.navigationOptions} />
<ModalStack.Screen name='PickerView' component={PickerView} />
{/* @ts-ignore */}
<ModalStack.Screen name='ThreadMessagesView' component={ThreadMessagesView} />
{/* @ts-ignore */}
<ModalStack.Screen name='DiscussionsView' component={DiscussionsView} />
<ModalStack.Screen name='TeamChannelsView' component={TeamChannelsView} options={TeamChannelsView.navigationOptions} />
{/* @ts-ignore */}
<ModalStack.Screen name='MarkdownTableView' component={MarkdownTableView} />
<ModalStack.Screen
name='ReadReceiptsView'
// @ts-ignore
component={ReadReceiptsView}
options={props => ReadReceiptsView.navigationOptions!({ ...props, isMasterDetail: true })}
/>
@ -183,7 +187,6 @@ const ModalStackNavigator = React.memo(({ navigation }: INavigation) => {
<ModalStack.Screen name='NewMessageView' component={NewMessageView} />
<ModalStack.Screen name='SelectedUsersViewCreateChannel' component={SelectedUsersView} />
<ModalStack.Screen name='CreateChannelView' component={CreateChannelView} />
{/* @ts-ignore */}
<ModalStack.Screen name='CreateDiscussionView' component={CreateDiscussionView} />
<ModalStack.Screen name='E2ESaveYourPasswordView' component={E2ESaveYourPasswordView} />
<ModalStack.Screen name='E2EHowItWorksView' component={E2EHowItWorksView} />
@ -216,11 +219,9 @@ const InsideStackNavigator = React.memo(() => {
<InsideStack.Screen name='DrawerNavigator' component={DrawerNavigator} options={{ headerShown: false }} />
<InsideStack.Screen name='ModalStackNavigator' component={ModalStackNavigator} options={{ headerShown: false }} />
<InsideStack.Screen name='AttachmentView' component={AttachmentView} />
{/* @ts-ignore */}
<InsideStack.Screen name='ModalBlockView' component={ModalBlockView} options={ModalBlockView.navigationOptions} />
<InsideStack.Screen
name='JitsiMeetView'
// @ts-ignore
component={JitsiMeetView}
options={{ headerShown: false, animationEnabled: isIOS }}
/>

View File

@ -1,6 +1,5 @@
import { NavigatorScreenParams } from '@react-navigation/core';
import { TServerModel, TThreadModel } from '../../definitions';
import { IAttachment } from '../../definitions/IAttachment';
import { ILivechatDepartment } from '../../definitions/ILivechatDepartment';
import { ILivechatTag } from '../../definitions/ILivechatTag';
@ -209,18 +208,13 @@ export type MasterDetailInsideStackParamList = {
rid: string;
url: string;
onlyAudio?: boolean;
videoConf?: boolean;
};
ShareView: {
attachments: IAttachment[];
isShareView?: boolean;
isShareExtension: boolean;
serverInfo: TServerModel;
serverInfo: {};
text: string;
room: TSubscriptionModel;
thread?: TThreadModel;
replying?: boolean;
replyingMessage?: IMessage;
closeReply?: Function;
room: ISubscription;
thread: any; // TODO: Change
};
};

View File

@ -22,17 +22,13 @@ const _OutsideStack = () => {
return (
<Outside.Navigator screenOptions={{ ...defaultHeader, ...themedHeader(theme), ...StackAnimation } as StackNavigationOptions}>
{/* @ts-ignore */}
<Outside.Screen name='NewServerView' component={NewServerView} options={NewServerView.navigationOptions} />
<Outside.Screen name='WorkspaceView' component={WorkspaceView} />
{/* @ts-ignore */}
<Outside.Screen name='LoginView' component={LoginView} options={LoginView.navigationOptions} />
<Outside.Screen name='ForgotPasswordView' component={ForgotPasswordView} />
{/* @ts-ignore */}
<Outside.Screen name='SendEmailConfirmationView' component={SendEmailConfirmationView} />
{/* @ts-ignore */}
<Outside.Screen name='RegisterView' component={RegisterView} options={RegisterView.navigationOptions} />
{/* @ts-ignore */}
<Outside.Screen name='LegalView' component={LegalView} />
</Outside.Navigator>
);

View File

@ -1,57 +0,0 @@
import React, { useContext } from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import { defaultHeader, themedHeader } from '../../lib/methods/helpers/navigation';
import { ThemeContext } from '../../theme';
// Outside Stack
import WithoutServersView from '../../views/WithoutServersView';
// Inside Stack
import ShareListView from '../../views/ShareListView';
import ShareView from '../../views/ShareView';
import SelectServerView from '../../views/SelectServerView';
import AuthLoadingView from '../../views/AuthLoadingView';
import { ShareAppStackParamList, ShareInsideStackParamList, ShareOutsideStackParamList } from './types';
const Inside = createStackNavigator<ShareInsideStackParamList>();
const InsideStack = () => {
const { theme } = useContext(ThemeContext);
const screenOptions = {
...defaultHeader,
...themedHeader(theme)
};
screenOptions.headerStyle = { ...screenOptions.headerStyle, height: 57 };
return (
<Inside.Navigator screenOptions={screenOptions}>
<Inside.Screen name='ShareListView' component={ShareListView} />
<Inside.Screen name='ShareView' component={ShareView} />
<Inside.Screen name='SelectServerView' component={SelectServerView} />
</Inside.Navigator>
);
};
const Outside = createStackNavigator<ShareOutsideStackParamList>();
const OutsideStack = () => {
const { theme } = useContext(ThemeContext);
return (
<Outside.Navigator screenOptions={{ ...defaultHeader, ...themedHeader(theme) }}>
<Outside.Screen name='WithoutServersView' component={WithoutServersView} />
</Outside.Navigator>
);
};
// App
const Stack = createStackNavigator<ShareAppStackParamList>();
const ShareExtensionStack = ({ root }: { root: string }): React.ReactElement => (
<Stack.Navigator screenOptions={{ headerShown: false, animationEnabled: false }}>
<>
{!root ? <Stack.Screen name='AuthLoading' component={AuthLoadingView} /> : null}
{root === 'outside' ? <Stack.Screen name='OutsideStack' component={OutsideStack} /> : null}
{root === 'inside' ? <Stack.Screen name='InsideStack' component={InsideStack} /> : null}
</>
</Stack.Navigator>
);
export default ShareExtensionStack;

View File

@ -1,33 +0,0 @@
import { NavigatorScreenParams } from '@react-navigation/core';
import { TSubscriptionModel } from '../../definitions/ISubscription';
import { TServerModel } from '../../definitions/IServer';
import { IAttachment } from '../../definitions/IAttachment';
import { IMessage, TThreadModel } from '../../definitions';
export type ShareInsideStackParamList = {
ShareListView: undefined;
ShareView: {
attachments: IAttachment[];
isShareView?: boolean;
isShareExtension: boolean;
serverInfo: TServerModel;
text: string;
room: TSubscriptionModel;
thread?: TThreadModel;
replying?: boolean;
replyingMessage?: IMessage;
closeReply?: Function;
};
SelectServerView: undefined;
};
export type ShareOutsideStackParamList = {
WithoutServersView: undefined;
};
export type ShareAppStackParamList = {
AuthLoading?: undefined;
OutsideStack?: NavigatorScreenParams<ShareOutsideStackParamList>;
InsideStack?: NavigatorScreenParams<ShareInsideStackParamList>;
};

View File

@ -7,26 +7,12 @@ import { TDataSelect } from '../definitions/IDataSelect';
import { ILivechatDepartment } from '../definitions/ILivechatDepartment';
import { ILivechatTag } from '../definitions/ILivechatTag';
import { IMessage, TAnyMessageModel, TMessageModel } from '../definitions/IMessage';
import { TServerModel } from '../definitions/IServer';
import { IServer } from '../definitions/IServer';
import { ISubscription, SubscriptionType, TSubscriptionModel } from '../definitions/ISubscription';
import { TChangeAvatarViewContext } from '../definitions/TChangeAvatarViewContext';
import { MasterDetailInsideStackParamList, ModalStackParamList } from './MasterDetailStack/types';
import { ModalStackParamList } from './MasterDetailStack/types';
import { TNavigation } from './stackType';
export type SetUsernameStackParamList = {
SetUsernameView: {
title: string;
};
};
export type StackParamList = {
AuthLoading: undefined;
OutsideStack: NavigatorScreenParams<OutsideParamList>;
InsideStack: NavigatorScreenParams<InsideStackParamList>;
MasterDetailStack: NavigatorScreenParams<MasterDetailInsideStackParamList>;
SetUsernameStack: NavigatorScreenParams<SetUsernameStackParamList>;
};
export type ChatsStackParamList = {
ModalStackNavigator: NavigatorScreenParams<ModalStackParamList & TNavigation>;
E2ESaveYourPasswordStackNavigator: NavigatorScreenParams<E2ESaveYourPasswordStackParamList>;
@ -138,7 +124,7 @@ export type ChatsStackParamList = {
};
LivechatEditView: {
room: ISubscription;
roomUser?: any; // TODO: Change
roomUser: any; // TODO: Change
};
ThreadMessagesView: {
rid: string;
@ -259,7 +245,7 @@ export type E2ESaveYourPasswordStackParamList = {
};
export type E2EEnterYourPasswordStackParamList = {
E2EEnterYourPasswordView?: undefined;
E2EEnterYourPasswordView: undefined;
};
export type InsideStackParamList = {
@ -272,10 +258,10 @@ export type InsideStackParamList = {
attachments: IAttachment[];
isShareView?: boolean;
isShareExtension: boolean;
serverInfo: TServerModel;
serverInfo: IServer;
text: string;
room: TSubscriptionModel;
thread?: TThreadModel;
thread: TThreadModel;
replying?: boolean;
replyingMessage?: IMessage;
closeReply?: Function;

View File

@ -79,8 +79,8 @@ const AddExistingChannelView = () => {
Q.where('team_id', ''),
Q.where('t', Q.oneOf(['c', 'p'])),
Q.where('name', Q.like(`%${stringToSearch}%`)),
Q.take(QUERY_SIZE),
Q.sortBy('room_updated_at', Q.desc)
Q.experimentalTake(QUERY_SIZE),
Q.experimentalSortBy('room_updated_at', Q.desc)
)
.fetch();

View File

@ -9,6 +9,7 @@ import { RouteProp } from '@react-navigation/core';
import { OutsideModalParamList } from '../stacks/types';
import StatusBar from '../containers/StatusBar';
import ActivityIndicator from '../containers/ActivityIndicator';
import { TSupportedThemes, withTheme } from '../theme';
import { userAgent } from '../lib/constants';
import { debounce } from '../lib/methods/helpers';
import * as HeaderButton from '../containers/HeaderButton';
@ -48,6 +49,7 @@ interface IAuthenticationWebView extends INavigationOption {
server: string;
Accounts_Iframe_api_url: string;
Accounts_Iframe_api_method: string;
theme: TSupportedThemes;
}
interface IState {
@ -198,9 +200,9 @@ class AuthenticationWebView extends React.PureComponent<IAuthenticationWebView,
}
const mapStateToProps = (state: IApplicationState) => ({
server: state.server.server as string,
server: state.server.server,
Accounts_Iframe_api_url: state.settings.Accounts_Iframe_api_url as string,
Accounts_Iframe_api_method: state.settings.Accounts_Iframe_api_method as string
});
export default connect(mapStateToProps)(AuthenticationWebView);
export default connect(mapStateToProps)(withTheme(AuthenticationWebView));

View File

@ -144,14 +144,14 @@ class CreateChannelView extends React.Component<ICreateChannelViewProps, ICreate
const { server, user, blockUnauthenticatedAccess, theme, serverVersion } = this.props;
return (
<KeyboardView
style={{ backgroundColor: themes[theme!].auxiliaryBackground }}
style={{ backgroundColor: themes[theme].auxiliaryBackground }}
contentContainerStyle={styles.container}
keyboardVerticalOffset={128}
>
<StatusBar />
<SafeAreaView testID='create-discussion-view' style={styles.container}>
<ScrollView {...scrollPersistTaps}>
<Text style={[styles.description, { color: themes[theme!].auxiliaryText }]}>{I18n.t('Discussion_Desc')}</Text>
<Text style={[styles.description, { color: themes[theme].auxiliaryText }]}>{I18n.t('Discussion_Desc')}</Text>
<SelectChannel
server={server}
userId={user.id}
@ -180,7 +180,7 @@ class CreateChannelView extends React.Component<ICreateChannelViewProps, ICreate
/>
{this.isEncryptionEnabled ? (
<>
<Text style={[styles.label, { color: themes[theme!].titleText }]}>{I18n.t('Encrypted')}</Text>
<Text style={[styles.label, { color: themes[theme].titleText }]}>{I18n.t('Encrypted')}</Text>
<Switch value={encrypted} onValueChange={this.onEncryptedChange} trackColor={SWITCH_TRACK_COLOR} />
</>
) : null}

View File

@ -37,7 +37,7 @@ interface IDirectoryViewProps {
baseUrl: string;
isFederationEnabled: boolean;
user: IUser;
theme?: TSupportedThemes;
theme: TSupportedThemes;
directoryDefaultView: string;
isMasterDetail: boolean;
}
@ -218,15 +218,15 @@ class DirectoryView extends React.Component<IDirectoryViewProps, IDirectoryViewS
style={[
sharedStyles.separatorVertical,
styles.toggleDropdownContainer,
{ borderColor: themes[theme!].separatorColor }
{ borderColor: themes[theme].separatorColor }
]}
>
<CustomIcon name={icon} size={20} color={themes[theme!].tintColor} style={styles.toggleDropdownIcon} />
<Text style={[styles.toggleDropdownText, { color: themes[theme!].tintColor }]}>{I18n.t(text)}</Text>
<CustomIcon name={icon} size={20} color={themes[theme].tintColor} style={styles.toggleDropdownIcon} />
<Text style={[styles.toggleDropdownText, { color: themes[theme].tintColor }]}>{I18n.t(text)}</Text>
<CustomIcon
name='chevron-down'
size={20}
color={themes[theme!].auxiliaryTintColor}
color={themes[theme].auxiliaryTintColor}
style={styles.toggleDropdownArrow}
/>
</View>
@ -243,7 +243,7 @@ class DirectoryView extends React.Component<IDirectoryViewProps, IDirectoryViewS
if (index === data.length - 1) {
style = {
...sharedStyles.separatorBottom,
borderColor: themes[theme!].separatorColor
borderColor: themes[theme].separatorColor
};
}
@ -297,7 +297,7 @@ class DirectoryView extends React.Component<IDirectoryViewProps, IDirectoryViewS
const { data, loading, showOptionsDropdown, type, globalUsers } = this.state;
const { isFederationEnabled, theme } = this.props;
return (
<SafeAreaView style={{ backgroundColor: themes[theme!].backgroundColor }} testID='directory-view'>
<SafeAreaView style={{ backgroundColor: themes[theme].backgroundColor }} testID='directory-view'>
<StatusBar />
<FlatList
data={data}
@ -314,7 +314,7 @@ class DirectoryView extends React.Component<IDirectoryViewProps, IDirectoryViewS
/>
{showOptionsDropdown ? (
<Options
theme={theme!}
theme={theme}
type={type}
globalUsers={globalUsers}
close={this.toggleDropdown}

View File

@ -1,4 +1,4 @@
import { activateKeepAwakeAsync, deactivateKeepAwake } from 'expo-keep-awake';
import { activateKeepAwake, deactivateKeepAwake } from 'expo-keep-awake';
import React from 'react';
import { BackHandler, Linking, NativeEventSubscription, SafeAreaView } from 'react-native';
import WebView from 'react-native-webview';
@ -31,7 +31,7 @@ class JitsiMeetView extends React.Component<TJitsiMeetViewProps> {
componentDidMount() {
this.handleJitsiApp();
this.onConferenceJoined();
activateKeepAwakeAsync();
activateKeepAwake();
}
componentWillUnmount() {

View File

@ -47,13 +47,13 @@ interface ILivechatEditViewProps {
user: IUser;
navigation: StackNavigationProp<ChatsStackParamList, 'LivechatEditView'>;
route: RouteProp<ChatsStackParamList, 'LivechatEditView'>;
theme?: TSupportedThemes;
theme: TSupportedThemes;
editOmnichannelContact: string[] | undefined;
editLivechatRoomCustomfields: string[] | undefined;
}
const Title = ({ title, theme }: ITitle) =>
title ? <Text style={[styles.title, { color: themes[theme!].titleText }]}>{title}</Text> : null;
title ? <Text style={[styles.title, { color: themes[theme].titleText }]}>{title}</Text> : null;
const LivechatEditView = ({ user, navigation, route, theme }: ILivechatEditViewProps) => {
const [customFields, setCustomFields] = useState<ICustomFields>({});
@ -183,13 +183,13 @@ const LivechatEditView = ({ user, navigation, route, theme }: ILivechatEditViewP
return (
<KeyboardView
style={{ backgroundColor: themes[theme!].auxiliaryBackground }}
style={{ backgroundColor: themes[theme].auxiliaryBackground }}
contentContainerStyle={sharedStyles.container}
keyboardVerticalOffset={128}
>
<ScrollView {...scrollPersistTaps} style={styles.container}>
<SafeAreaView>
<Title title={visitor?.username} theme={theme!} />
<Title title={visitor?.username} theme={theme} />
<FormTextInput
label={I18n.t('Name')}
defaultValue={visitor?.name}
@ -246,7 +246,7 @@ const LivechatEditView = ({ user, navigation, route, theme }: ILivechatEditViewP
editable={!!editOmnichannelContactPermission}
/>
))}
<Title title={I18n.t('Conversation')} theme={theme!} />
<Title title={I18n.t('Conversation')} theme={theme} />
<FormTextInput
label={I18n.t('Topic')}
inputRef={e => {
@ -257,7 +257,7 @@ const LivechatEditView = ({ user, navigation, route, theme }: ILivechatEditViewP
editable={!!editLivechatRoomCustomFieldsPermission}
/>
<Text style={[styles.label, { color: themes[theme!].titleText }]}>{I18n.t('Tags')}</Text>
<Text style={[styles.label, { color: themes[theme].titleText }]}>{I18n.t('Tags')}</Text>
<MultiSelect
options={tagOptions}
onChange={({ value }: { value: string[] }) => {

View File

@ -159,7 +159,7 @@ class LoginView extends React.Component<ILoginViewProps, ILoginViewState> {
return (
<>
<Text style={[styles.title, sharedStyles.textBold, { color: themes[theme!].titleText }]}>{I18n.t('Login')}</Text>
<Text style={[styles.title, sharedStyles.textBold, { color: themes[theme].titleText }]}>{I18n.t('Login')}</Text>
<FormTextInput
label={I18n.t('Username_or_email')}
containerStyle={styles.inputContainer}
@ -205,17 +205,17 @@ class LoginView extends React.Component<ILoginViewProps, ILoginViewState> {
type='secondary'
onPress={this.forgotPassword}
testID='login-view-forgot-password'
color={themes[theme!].auxiliaryText}
color={themes[theme].auxiliaryText}
fontSize={14}
/>
)}
{this.showRegistrationButton ? (
<View style={styles.bottomContainer}>
<Text style={[styles.bottomContainerText, { color: themes[theme!].auxiliaryText }]}>
<Text style={[styles.bottomContainerText, { color: themes[theme].auxiliaryText }]}>
{I18n.t('Dont_Have_An_Account')}
</Text>
<Text
style={[styles.bottomContainerTextBold, { color: themes[theme!].actionTintColor }]}
style={[styles.bottomContainerTextBold, { color: themes[theme].actionTintColor }]}
onPress={this.register}
testID='login-view-register'
>
@ -223,7 +223,7 @@ class LoginView extends React.Component<ILoginViewProps, ILoginViewState> {
</Text>
</View>
) : (
<Text style={[styles.registerDisabled, { color: themes[theme!].auxiliaryText }]}>
<Text style={[styles.registerDisabled, { color: themes[theme].auxiliaryText }]}>
{Accounts_RegistrationForm_LinkReplacementText}
</Text>
)}

View File

@ -54,7 +54,7 @@ interface IModalBlockViewState {
interface IModalBlockViewProps {
navigation: StackNavigationProp<MasterDetailInsideStackParamList, 'ModalBlockView'>;
route: RouteProp<MasterDetailInsideStackParamList, 'ModalBlockView'>;
theme?: TSupportedThemes;
theme: TSupportedThemes;
language: string;
user: {
id: string;
@ -256,7 +256,7 @@ class ModalBlockView extends React.Component<IModalBlockViewProps, IModalBlockVi
return (
<KeyboardAwareScrollView
style={[styles.container, { backgroundColor: themes[theme!].auxiliaryBackground }]}
style={[styles.container, { backgroundColor: themes[theme].auxiliaryBackground }]}
keyboardShouldPersistTaps='always'
>
<View style={styles.content}>

View File

@ -55,7 +55,7 @@ const NewMessageView = () => {
const db = database.active;
const c = await db
.get('subscriptions')
.query(Q.where('t', 'd'), Q.take(QUERY_SIZE), Q.sortBy('room_updated_at', Q.desc))
.query(Q.where('t', 'd'), Q.experimentalTake(QUERY_SIZE), Q.experimentalSortBy('room_updated_at', Q.desc))
.fetch();
setChats(c);
} catch (e) {

View File

@ -21,7 +21,7 @@ import database from '../../lib/database';
import { sanitizeLikeString } from '../../lib/database/utils';
import UserPreferences from '../../lib/methods/userPreferences';
import { OutsideParamList } from '../../stacks/types';
import { TSupportedThemes, withTheme } from '../../theme';
import { withTheme } from '../../theme';
import { isIOS, isTablet } from '../../lib/methods/helpers';
import EventEmitter from '../../lib/methods/helpers/events';
import { BASIC_AUTH_KEY, setBasicAuth } from '../../lib/methods/helpers/fetch';
@ -67,11 +67,10 @@ const styles = StyleSheet.create({
});
interface INewServerViewProps extends IBaseScreen<OutsideParamList, 'NewServerView'> {
connecting?: boolean;
previousServer?: string | null;
width?: number;
height?: number;
theme?: TSupportedThemes;
connecting: boolean;
previousServer: string | null;
width: number;
height: number;
}
interface INewServerViewState {
@ -158,7 +157,7 @@ class NewServerView extends React.Component<INewServerViewProps, INewServerViewS
const db = database.servers;
try {
const serversHistoryCollection = db.get('servers_history');
let whereClause = [Q.where('username', Q.notEq(null)), Q.sortBy('updated_at', Q.desc), Q.take(3)];
let whereClause = [Q.where('username', Q.notEq(null)), Q.experimentalSortBy('updated_at', Q.desc), Q.experimentalTake(3)];
if (text) {
const likeString = sanitizeLikeString(text);
whereClause = [...whereClause, Q.where('url', Q.like(`%${likeString}%`))];
@ -304,14 +303,14 @@ class NewServerView extends React.Component<INewServerViewProps, INewServerViewS
style={[
styles.certificatePicker,
{
marginBottom: verticalScale({ size: previousServer && !isTablet ? 10 : 30, height: height! })
marginBottom: verticalScale({ size: previousServer && !isTablet ? 10 : 30, height })
}
]}
>
<Text
style={[
styles.chooseCertificateTitle,
{ color: themes[theme!].auxiliaryText, fontSize: moderateScale({ size: 13, width: width! }) }
{ color: themes[theme].auxiliaryText, fontSize: moderateScale({ size: 13, width }) }
]}
>
{certificate ? I18n.t('Your_certificate') : I18n.t('Do_you_have_a_certificate')}
@ -321,10 +320,7 @@ class NewServerView extends React.Component<INewServerViewProps, INewServerViewS
testID='new-server-choose-certificate'
>
<Text
style={[
styles.chooseCertificate,
{ color: themes[theme!].tintColor, fontSize: moderateScale({ size: 13, width: width! }) }
]}
style={[styles.chooseCertificate, { color: themes[theme].tintColor, fontSize: moderateScale({ size: 13, width }) }]}
>
{certificate ?? I18n.t('Apply_Your_Certificate')}
</Text>
@ -338,10 +334,6 @@ class NewServerView extends React.Component<INewServerViewProps, INewServerViewS
const { text, connectingOpen, serversHistory } = this.state;
const marginTop = previousServer ? 0 : 35;
if (!height || !width) {
return null;
}
return (
<FormContainer testID='new-server-view' keyboardShouldPersistTaps='never'>
<FormContainerInner>
@ -362,7 +354,7 @@ class NewServerView extends React.Component<INewServerViewProps, INewServerViewS
style={[
styles.title,
{
color: themes[theme!].titleText,
color: themes[theme].titleText,
fontSize: moderateScale({ size: 22, width }),
marginBottom: verticalScale({ size: 8, height })
}
@ -374,7 +366,7 @@ class NewServerView extends React.Component<INewServerViewProps, INewServerViewS
style={[
styles.subtitle,
{
color: themes[theme!].controlText,
color: themes[theme].controlText,
fontSize: moderateScale({ size: 16, width }),
marginBottom: verticalScale({ size: 30, height })
}
@ -384,7 +376,7 @@ class NewServerView extends React.Component<INewServerViewProps, INewServerViewS
</Text>
<ServerInput
text={text}
theme={theme!}
theme={theme}
serversHistory={serversHistory}
onChangeText={this.onChangeText}
onSubmit={this.submit}
@ -402,12 +394,12 @@ class NewServerView extends React.Component<INewServerViewProps, INewServerViewS
/>
{isIOS ? (
<>
<OrSeparator theme={theme!} />
<OrSeparator theme={theme} />
<Text
style={[
styles.description,
{
color: themes[theme!].auxiliaryText,
color: themes[theme].auxiliaryText,
fontSize: moderateScale({ size: 14, width }),
marginBottom: verticalScale({ size: 16, height })
}
@ -418,7 +410,7 @@ class NewServerView extends React.Component<INewServerViewProps, INewServerViewS
<Button
title={I18n.t('Join_our_open_workspace')}
type='secondary'
backgroundColor={themes[theme!].chatComponentBackground}
backgroundColor={themes[theme].chatComponentBackground}
onPress={this.connectOpen}
disabled={connecting}
loading={connectingOpen && connecting}

View File

@ -32,7 +32,7 @@ interface INavigationOption {
interface IReadReceiptViewProps extends INavigationOption {
Message_TimeAndDateFormat: string;
theme?: TSupportedThemes;
theme: TSupportedThemes;
}
class ReadReceiptView extends React.Component<IReadReceiptViewProps, IReadReceiptViewState> {
@ -106,10 +106,10 @@ class ReadReceiptView extends React.Component<IReadReceiptViewProps, IReadReceip
}
return (
<View
style={[styles.listEmptyContainer, { backgroundColor: themes[theme!].chatComponentBackground }]}
style={[styles.listEmptyContainer, { backgroundColor: themes[theme].chatComponentBackground }]}
testID='read-receipt-view'
>
<Text style={[styles.emptyText, { color: themes[theme!].auxiliaryTintColor }]}>{I18n.t('No_Read_Receipts')}</Text>
<Text style={[styles.emptyText, { color: themes[theme].auxiliaryTintColor }]}>{I18n.t('No_Read_Receipts')}</Text>
</View>
);
};
@ -121,18 +121,18 @@ class ReadReceiptView extends React.Component<IReadReceiptViewProps, IReadReceip
return null;
}
return (
<View style={[styles.itemContainer, { backgroundColor: themes[theme!].backgroundColor }]}>
<View style={[styles.itemContainer, { backgroundColor: themes[theme].backgroundColor }]}>
<Avatar text={item.user.username} size={40} />
<View style={styles.infoContainer}>
<View style={styles.item}>
<Text style={[styles.name, { color: themes[theme!].titleText }]}>{item?.user?.name}</Text>
<Text style={[styles.time, { color: themes[theme!].auxiliaryText }]}>{time}</Text>
<Text style={[styles.name, { color: themes[theme].titleText }]}>{item?.user?.name}</Text>
<Text style={[styles.time, { color: themes[theme].auxiliaryText }]}>{time}</Text>
</View>
<Text
style={[
styles.username,
{
color: themes[theme!].auxiliaryText
color: themes[theme].auxiliaryText
}
]}
>{`@${item.user.username}`}</Text>
@ -157,11 +157,11 @@ class ReadReceiptView extends React.Component<IReadReceiptViewProps, IReadReceip
style={[
styles.list,
{
backgroundColor: themes[theme!].chatComponentBackground,
borderColor: themes[theme!].separatorColor
backgroundColor: themes[theme].chatComponentBackground,
borderColor: themes[theme].separatorColor
}
]}
refreshControl={<RefreshControl refreshing={loading} onRefresh={this.load} tintColor={themes[theme!].auxiliaryText} />}
refreshControl={<RefreshControl refreshing={loading} onRefresh={this.load} tintColor={themes[theme].auxiliaryText} />}
keyExtractor={item => item._id}
/>
</SafeAreaView>

View File

@ -231,7 +231,7 @@ class RegisterView extends React.Component<IProps, any> {
<FormContainer testID='register-view'>
<FormContainerInner>
<LoginServices separator />
<Text style={[styles.title, sharedStyles.textBold, { color: themes[theme!].titleText }]}>{I18n.t('Sign_Up')}</Text>
<Text style={[styles.title, sharedStyles.textBold, { color: themes[theme].titleText }]}>{I18n.t('Sign_Up')}</Text>
<FormTextInput
label={I18n.t('Name')}
containerStyle={styles.inputContainer}
@ -310,10 +310,10 @@ class RegisterView extends React.Component<IProps, any> {
{showLoginButton ? (
<View style={styles.bottomContainer}>
<Text style={[styles.bottomContainerText, { color: themes[theme!].auxiliaryText }]}>
<Text style={[styles.bottomContainerText, { color: themes[theme].auxiliaryText }]}>
{I18n.t('Do_you_have_an_account')}
</Text>
<Text style={[styles.bottomContainerTextBold, { color: themes[theme!].actionTintColor }]} onPress={this.login}>
<Text style={[styles.bottomContainerTextBold, { color: themes[theme].actionTintColor }]} onPress={this.login}>
{I18n.t('Login')}
</Text>
</View>

View File

@ -268,7 +268,6 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
// @ts-ignore
logEvent(events[`RA_GO_${route.replace('View', '').toUpperCase()}${params.name ? params.name.toUpperCase() : ''}`]);
const { navigation } = this.props;
// @ts-ignore
navigation.navigate(route, params);
}
if (event) {
@ -730,8 +729,8 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
.query(
Q.where('team_main', true),
Q.where('name', Q.like(`%${onChangeText}%`)),
Q.take(QUERY_SIZE),
Q.sortBy('room_updated_at', Q.desc)
Q.experimentalTake(QUERY_SIZE),
Q.experimentalSortBy('room_updated_at', Q.desc)
)
.fetch();
@ -780,7 +779,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
}
})
}
style={{ backgroundColor: themes[theme!].backgroundColor }}
style={{ backgroundColor: themes[theme].backgroundColor }}
accessibilityLabel={I18n.t('Room_Info')}
enabled={!isGroupChatHandler}
testID='room-actions-info'
@ -788,14 +787,14 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
<View style={[styles.roomInfoContainer, { height: 72 * fontScale }]}>
<Avatar text={avatar} style={styles.avatar} size={50 * fontScale} type={t} rid={rid}>
{t === 'd' && member._id ? (
<View style={[sharedStyles.status, { backgroundColor: themes[theme!].backgroundColor }]}>
<View style={[sharedStyles.status, { backgroundColor: themes[theme].backgroundColor }]}>
<Status size={16} id={member._id} />
</View>
) : undefined}
</Avatar>
<View style={styles.roomTitleContainer}>
{room.t === 'd' ? (
<Text style={[styles.roomTitle, { color: themes[theme!].titleText }]} numberOfLines={1}>
<Text style={[styles.roomTitle, { color: themes[theme].titleText }]} numberOfLines={1}>
{room.fname}
</Text>
) : (
@ -806,19 +805,19 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
status={room.visitor?.status}
sourceType={source}
/>
<Text style={[styles.roomTitle, { color: themes[theme!].titleText }]} numberOfLines={1}>
<Text style={[styles.roomTitle, { color: themes[theme].titleText }]} numberOfLines={1}>
{getRoomTitle(room)}
</Text>
</View>
)}
<MarkdownPreview
msg={t === 'd' ? `@${name}` : topic}
style={[styles.roomDescription, { color: themes[theme!].auxiliaryText }]}
style={[styles.roomDescription, { color: themes[theme].auxiliaryText }]}
/>
{room.t === 'd' && (
<MarkdownPreview
msg={member.statusText}
style={[styles.roomDescription, { color: themes[theme!].auxiliaryText }]}
style={[styles.roomDescription, { color: themes[theme].auxiliaryText }]}
/>
)}
</View>
@ -874,9 +873,9 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
})
}
testID='room-actions-block-user'
left={() => <List.Icon name='ignore' color={themes[theme!].dangerColor} />}
left={() => <List.Icon name='ignore' color={themes[theme].dangerColor} />}
showActionIndicator
color={themes[theme!].dangerColor}
color={themes[theme].dangerColor}
/>
<List.Separator />
</List.Section>
@ -896,9 +895,9 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
})
}
testID='room-actions-leave-channel'
left={() => <List.Icon name='logout' color={themes[theme!].dangerColor} />}
left={() => <List.Icon name='logout' color={themes[theme].dangerColor} />}
showActionIndicator
color={themes[theme!].dangerColor}
color={themes[theme].dangerColor}
/>
<List.Separator />
</List.Section>
@ -999,7 +998,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
params: { rid }
})
}
left={() => <List.Icon name='chat-forward' color={themes[theme!].titleText} />}
left={() => <List.Icon name='chat-forward' color={themes[theme].titleText} />}
showActionIndicator
/>
<List.Separator />
@ -1015,7 +1014,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
event: this.placeOnHoldLivechat
})
}
left={() => <List.Icon name='pause' color={themes[theme!].titleText} />}
left={() => <List.Icon name='pause' color={themes[theme].titleText} />}
showActionIndicator
/>
<List.Separator />
@ -1031,7 +1030,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
event: this.returnLivechat
})
}
left={() => <List.Icon name='move-to-the-queue' color={themes[theme!].titleText} />}
left={() => <List.Icon name='move-to-the-queue' color={themes[theme].titleText} />}
showActionIndicator
/>
<List.Separator />
@ -1041,13 +1040,13 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
<>
<List.Item
title='Close'
color={themes[theme!].dangerColor}
color={themes[theme].dangerColor}
onPress={() =>
this.onPressTouchable({
event: this.closeLivechat
})
}
left={() => <List.Icon name='chat-close' color={themes[theme!].dangerColor} />}
left={() => <List.Icon name='chat-close' color={themes[theme].dangerColor} />}
showActionIndicator
/>
<List.Separator />

View File

@ -6,7 +6,6 @@ import { SWITCH_TRACK_COLOR, themes } from '../../lib/constants';
import styles from './styles';
interface ISwitchContainer {
children?: JSX.Element | null;
value: boolean;
disabled?: boolean;
leftLabelPrimary: string;
@ -20,7 +19,7 @@ interface ISwitchContainer {
leftLabelStyle?: TextStyle;
}
const SwitchContainer = React.memo(
const SwitchContainer: React.FC<ISwitchContainer> = React.memo(
({
children,
value,
@ -34,7 +33,7 @@ const SwitchContainer = React.memo(
testID,
labelContainerStyle,
leftLabelStyle
}: ISwitchContainer) => (
}) => (
<>
<View key='switch-container' style={[styles.switchContainer, !!children && styles.switchMargin]}>
{leftLabelPrimary && (

View File

@ -517,16 +517,16 @@ class RoomInfoEditView extends React.Component<IRoomInfoEditViewProps, IRoomInfo
encrypted
} = this.state;
const { serverVersion, encryptionEnabled, theme } = this.props;
const { dangerColor } = themes[theme!];
const { dangerColor } = themes[theme];
return (
<KeyboardView
style={{ backgroundColor: themes[theme!].backgroundColor }}
style={{ backgroundColor: themes[theme].backgroundColor }}
contentContainerStyle={sharedStyles.container}
keyboardVerticalOffset={128}
>
<StatusBar />
<SafeAreaView testID='room-info-edit-view' style={{ backgroundColor: themes[theme!].backgroundColor }}>
<SafeAreaView testID='room-info-edit-view' style={{ backgroundColor: themes[theme].backgroundColor }}>
<ScrollView
contentContainerStyle={sharedStyles.containerScrollView}
testID='room-info-edit-view-list'
@ -615,7 +615,7 @@ class RoomInfoEditView extends React.Component<IRoomInfoEditViewProps, IRoomInfo
: I18n.t('Just_invited_people_can_access_this_channel')
}
onValueChange={this.toggleRoomType}
theme={theme!}
theme={theme}
testID='room-info-edit-view-t'
/>
<SwitchContainer
@ -630,7 +630,7 @@ class RoomInfoEditView extends React.Component<IRoomInfoEditViewProps, IRoomInfo
rightLabelSecondary={I18n.t('Only_authorized_users_can_write_new_messages')}
onValueChange={this.toggleReadOnly}
disabled={!permissions['set-readonly'] || room.broadcast}
theme={theme!}
theme={theme}
testID='room-info-edit-view-ro'
/>
{ro && !room.broadcast ? (
@ -642,14 +642,14 @@ class RoomInfoEditView extends React.Component<IRoomInfoEditViewProps, IRoomInfo
rightLabelSecondary={I18n.t('Reactions_are_enabled')}
onValueChange={this.toggleReactions}
disabled={!permissions['set-react-when-readonly']}
theme={theme!}
theme={theme}
testID='room-info-edit-view-react-when-ro'
/>
) : null}
{room.broadcast
? [
<Text style={styles.broadcast}>{I18n.t('Broadcast')}</Text>,
<View style={[styles.divider, { borderColor: themes[theme!].separatorColor }]} />
<View style={[styles.divider, { borderColor: themes[theme].separatorColor }]} />
]
: null}
{serverVersion && !compareServerVersion(serverVersion, 'lowerThan', '3.0.0') ? (
@ -661,7 +661,7 @@ class RoomInfoEditView extends React.Component<IRoomInfoEditViewProps, IRoomInfo
? I18n.t('Overwrites_the_server_configuration_and_use_room_config')
: I18n.t('Uses_server_configuration')
}
theme={theme!}
theme={theme}
testID='room-info-edit-switch-system-messages'
onValueChange={this.toggleHideSystemMessages}
labelContainerStyle={styles.hideSystemMessages}
@ -676,7 +676,7 @@ class RoomInfoEditView extends React.Component<IRoomInfoEditViewProps, IRoomInfo
disabled={!t}
leftLabelPrimary={I18n.t('Encrypted')}
leftLabelSecondary={I18n.t('End_to_end_encrypted_room')}
theme={theme!}
theme={theme}
testID='room-info-edit-switch-encrypted'
onValueChange={this.toggleEncrypted}
labelContainerStyle={styles.hideSystemMessages}
@ -686,14 +686,14 @@ class RoomInfoEditView extends React.Component<IRoomInfoEditViewProps, IRoomInfo
<TouchableOpacity
style={[
styles.buttonContainer,
{ backgroundColor: themes[theme!].buttonBackground },
{ backgroundColor: themes[theme].buttonBackground },
!this.formIsChanged() && styles.buttonContainerDisabled
]}
onPress={this.submit}
disabled={!this.formIsChanged()}
testID='room-info-edit-view-submit'
>
<Text style={[styles.button, { color: themes[theme!].buttonText }]} accessibilityRole='button'>
<Text style={[styles.button, { color: themes[theme].buttonText }]} accessibilityRole='button'>
{I18n.t('SAVE')}
</Text>
</TouchableOpacity>
@ -702,7 +702,7 @@ class RoomInfoEditView extends React.Component<IRoomInfoEditViewProps, IRoomInfo
style={[
styles.buttonContainer_inverted,
styles.buttonInverted,
{ flex: 1, borderColor: themes[theme!].auxiliaryText },
{ flex: 1, borderColor: themes[theme].auxiliaryText },
!this.formIsChanged() && styles.buttonContainerDisabled
]}
onPress={this.reset}
@ -710,7 +710,7 @@ class RoomInfoEditView extends React.Component<IRoomInfoEditViewProps, IRoomInfo
testID='room-info-edit-view-reset'
>
<Text
style={[styles.button, styles.button_inverted, { color: themes[theme!].bodyText }]}
style={[styles.button, styles.button_inverted, { color: themes[theme].bodyText }]}
accessibilityRole='button'
>
{I18n.t('RESET')}
@ -734,7 +734,7 @@ class RoomInfoEditView extends React.Component<IRoomInfoEditViewProps, IRoomInfo
</Text>
</TouchableOpacity>
</View>
<View style={[styles.divider, { borderColor: themes[theme!].separatorColor }]} />
<View style={[styles.divider, { borderColor: themes[theme].separatorColor }]} />
<TouchableOpacity
style={[
styles.buttonContainer_inverted,
@ -760,7 +760,7 @@ class RoomInfoEditView extends React.Component<IRoomInfoEditViewProps, IRoomInfo
const mapStateToProps = (state: IApplicationState) => ({
serverVersion: state.server.version as string,
encryptionEnabled: state.encryption.enabled as boolean,
encryptionEnabled: state.encryption.enabled,
setReadOnlyPermission: state.permissions['set-readonly'] as string[],
setReactWhenReadOnlyPermission: state.permissions['set-react-when-readonly'] as string[],
archiveRoomPermission: state.permissions['archive-room'] as string[],
@ -768,7 +768,7 @@ const mapStateToProps = (state: IApplicationState) => ({
deleteCPermission: state.permissions['delete-c'] as string[],
deletePPermission: state.permissions['delete-p'] as string[],
deleteTeamPermission: state.permissions['delete-team'] as string[],
isMasterDetail: state.app.isMasterDetail as boolean
isMasterDetail: state.app.isMasterDetail
});
export default connect(mapStateToProps)(withTheme(RoomInfoEditView));

View File

@ -53,18 +53,18 @@ interface IGetRoomTitle {
const renderRoomTitle = ({ room, type, name, username, statusText, theme }: IGetRoomTitle) =>
type === SubscriptionType.DIRECT ? (
<>
<Text testID='room-info-view-name' style={[styles.roomTitle, { color: themes[theme!].titleText }]}>
<Text testID='room-info-view-name' style={[styles.roomTitle, { color: themes[theme].titleText }]}>
{name}
</Text>
{username && (
<Text
testID='room-info-view-username'
style={[styles.roomUsername, { color: themes[theme!].auxiliaryText }]}
style={[styles.roomUsername, { color: themes[theme].auxiliaryText }]}
>{`@${username}`}</Text>
)}
{!!statusText && (
<View testID='room-info-view-custom-status'>
<MarkdownPreview msg={statusText} style={[styles.roomUsername, { color: themes[theme!].auxiliaryText }]} />
<MarkdownPreview msg={statusText} style={[styles.roomUsername, { color: themes[theme].auxiliaryText }]} />
</View>
)}
</>
@ -77,7 +77,7 @@ const renderRoomTitle = ({ room, type, name, username, statusText, theme }: IGet
status={room.visitor?.status}
sourceType={room.source}
/>
<Text testID='room-info-view-name' style={[styles.roomTitle, { color: themes[theme!].titleText }]} key='room-info-name'>
<Text testID='room-info-view-name' style={[styles.roomTitle, { color: themes[theme].titleText }]} key='room-info-name'>
{getRoomTitle(room)}
</Text>
</View>
@ -90,7 +90,7 @@ interface IRoomInfoViewProps {
>;
route: RouteProp<ChatsStackParamList, 'RoomInfoView'>;
subscribedRoom: string;
theme?: TSupportedThemes;
theme: TSupportedThemes;
isMasterDetail: boolean;
jitsiEnabled: boolean;
editRoomPermission?: string[];
@ -192,7 +192,6 @@ class RoomInfoView extends React.Component<IRoomInfoViewProps, IRoomInfoViewStat
onPress={() => {
const isLivechat = t === SubscriptionType.OMNICHANNEL;
logEvent(events[`RI_GO_${isLivechat ? 'LIVECHAT' : 'RI'}_EDIT`]);
// @ts-ignore
navigation.navigate(isLivechat ? 'LivechatEditView' : 'RoomInfoEditView', { rid, room, roomUser });
}}
testID='room-info-view-edit-button'
@ -420,7 +419,7 @@ class RoomInfoView extends React.Component<IRoomInfoViewProps, IRoomInfoViewStat
handleEdit={showAvatarEdit ? this.handleEditAvatar : undefined}
>
{this.t === SubscriptionType.DIRECT && roomUser._id ? (
<View style={[sharedStyles.status, { backgroundColor: themes[theme!].auxiliaryBackground }]}>
<View style={[sharedStyles.status, { backgroundColor: themes[theme].auxiliaryBackground }]}>
<Status size={20} id={roomUser._id} />
</View>
) : null}
@ -430,7 +429,7 @@ class RoomInfoView extends React.Component<IRoomInfoViewProps, IRoomInfoViewStat
renderButton = (onPress: () => void, iconName: TIconsName, text: string, danger?: boolean) => {
const { theme } = this.props;
const color = danger ? themes[theme!].dangerColor : themes[theme!].actionTintColor;
const color = danger ? themes[theme].dangerColor : themes[theme].actionTintColor;
return (
<BorderlessButton testID={`room-info-view-${iconName}`} onPress={onPress} style={styles.roomButton}>
<CustomIcon name={iconName} size={30} color={color} />
@ -496,10 +495,10 @@ class RoomInfoView extends React.Component<IRoomInfoViewProps, IRoomInfoViewStat
const roomUserParsed = roomUser as IUserParsed;
return (
<ScrollView style={[styles.scroll, { backgroundColor: themes[theme!].backgroundColor }]}>
<ScrollView style={[styles.scroll, { backgroundColor: themes[theme].backgroundColor }]}>
<StatusBar />
<SafeAreaView style={{ backgroundColor: themes[theme!].backgroundColor }} testID='room-info-view'>
<View style={[styles.avatarContainer, { backgroundColor: themes[theme!].auxiliaryBackground }]}>
<SafeAreaView style={{ backgroundColor: themes[theme].backgroundColor }} testID='room-info-view'>
<View style={[styles.avatarContainer, { backgroundColor: themes[theme].auxiliaryBackground }]}>
{this.renderAvatar(room, roomUserParsed)}
<View style={styles.roomTitleContainer}>
{renderRoomTitle({
@ -508,7 +507,7 @@ class RoomInfoView extends React.Component<IRoomInfoViewProps, IRoomInfoViewStat
name: roomUserParsed?.name,
username: roomUserParsed?.username,
statusText: roomUserParsed?.statusText,
theme: theme!
theme
})}
</View>
{this.renderButtons()}

Some files were not shown because too many files have changed in this diff Show More