From 11ddd66809d71f4425e185f19b3a4b13f72a0b03 Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Mon, 4 Nov 2019 18:59:23 -0300 Subject: [PATCH 1/4] MM-19853 Fix iOS SafeAreaView for Server URL screen (#3513) --- app/initial_state.js | 16 ---------------- app/screens/select_server/select_server.js | 5 ++--- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/app/initial_state.js b/app/initial_state.js index 9eb364b38..dfc0220c8 100644 --- a/app/initial_state.js +++ b/app/initial_state.js @@ -73,22 +73,6 @@ const state = { }, }, general: { - server: { - status: 'not_started', - error: null, - }, - config: { - status: 'not_started', - error: null, - }, - dataRetentionPolicy: { - status: 'not_started', - error: null, - }, - license: { - status: 'not_started', - error: null, - }, websocket: { status: 'not_started', error: null, diff --git a/app/screens/select_server/select_server.js b/app/screens/select_server/select_server.js index dd63b80cf..476405070 100644 --- a/app/screens/select_server/select_server.js +++ b/app/screens/select_server/select_server.js @@ -12,6 +12,7 @@ import { Keyboard, KeyboardAvoidingView, Platform, + SafeAreaView, StatusBar, StyleSheet, Text, @@ -28,7 +29,6 @@ import {Client4} from 'mattermost-redux/client'; import ErrorText from 'app/components/error_text'; import FormattedText from 'app/components/formatted_text'; -import SafeAreaView from 'app/components/safe_area_view'; import fetchConfig from 'app/init/fetch'; import mattermostBucket from 'app/mattermost_bucket'; import {GlobalStyles} from 'app/styles'; @@ -416,8 +416,7 @@ export default class SelectServer extends PureComponent { return ( Date: Mon, 4 Nov 2019 19:29:50 -0500 Subject: [PATCH 2/4] MM-19599 Updated Channel Nav Bar height (#3509) During the landscape changes from the previous release, I had added 8px of padding to the iOS landscape, which caused this issue to occur. This change reverts the added padding so that the height matches across the screens for the navigation bar. To note, react-native-navigation is used for the info/thread headers and there is no way to adjust the height of this without replacing the header entirley. --- app/constants/view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/constants/view.js b/app/constants/view.js index e148c0bb8..9bb077a31 100644 --- a/app/constants/view.js +++ b/app/constants/view.js @@ -110,7 +110,7 @@ export default { MAX_CHANNELNAME_LENGTH: 64, ANDROID_TOP_LANDSCAPE: 46, ANDROID_TOP_PORTRAIT: 56, - IOS_TOP_LANDSCAPE: 40, + IOS_TOP_LANDSCAPE: 32, IOS_TOP_PORTRAIT: 64, IOS_INSETS_TOP_PORTRAIT: 88, STATUS_BAR_HEIGHT: 20, From 5540c99a289b40119672305719bea44efd6a389d Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Mon, 4 Nov 2019 22:29:02 -0300 Subject: [PATCH 3/4] Bump app build number to 243 (#3522) --- android/app/build.gradle | 2 +- ios/Mattermost.xcodeproj/project.pbxproj | 4 ++-- ios/Mattermost/Info.plist | 2 +- ios/MattermostShare/Info.plist | 2 +- ios/MattermostTests/Info.plist | 2 +- ios/NotificationService/Info.plist | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index c913cd3a4..a1d5039a6 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -140,7 +140,7 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion missingDimensionStrategy "RNN.reactNativeVersion", "reactNative60" - versionCode 242 + versionCode 243 versionName "1.25.0" multiDexEnabled = true ndk { diff --git a/ios/Mattermost.xcodeproj/project.pbxproj b/ios/Mattermost.xcodeproj/project.pbxproj index bef59d0e7..29bc87906 100644 --- a/ios/Mattermost.xcodeproj/project.pbxproj +++ b/ios/Mattermost.xcodeproj/project.pbxproj @@ -1060,7 +1060,7 @@ CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 242; + CURRENT_PROJECT_VERSION = 243; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = UQ8HT4Q2XM; ENABLE_BITCODE = NO; @@ -1098,7 +1098,7 @@ CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 242; + CURRENT_PROJECT_VERSION = 243; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = UQ8HT4Q2XM; ENABLE_BITCODE = NO; diff --git a/ios/Mattermost/Info.plist b/ios/Mattermost/Info.plist index 088daeb8b..4fd49fdc3 100644 --- a/ios/Mattermost/Info.plist +++ b/ios/Mattermost/Info.plist @@ -34,7 +34,7 @@ CFBundleVersion - 242 + 243 ITSAppUsesNonExemptEncryption LSRequiresIPhoneOS diff --git a/ios/MattermostShare/Info.plist b/ios/MattermostShare/Info.plist index 062a64deb..2aa2a57c8 100644 --- a/ios/MattermostShare/Info.plist +++ b/ios/MattermostShare/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString 1.25.0 CFBundleVersion - 242 + 243 NSAppTransportSecurity NSAllowsArbitraryLoads diff --git a/ios/MattermostTests/Info.plist b/ios/MattermostTests/Info.plist index 8a3571d2b..ae0cd033f 100644 --- a/ios/MattermostTests/Info.plist +++ b/ios/MattermostTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 242 + 243 diff --git a/ios/NotificationService/Info.plist b/ios/NotificationService/Info.plist index 1d21bc3d6..47766f21b 100644 --- a/ios/NotificationService/Info.plist +++ b/ios/NotificationService/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString 1.25.0 CFBundleVersion - 242 + 243 NSExtension NSExtensionPointIdentifier From e848d8ea6e266b2ef3493294e0d2bcb6654e1cce Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Tue, 5 Nov 2019 08:44:36 -0300 Subject: [PATCH 4/4] Update unsigned android and ios builds (#3508) * Update unsigned android and ios builds * Fix attach_workspace path * attach_workspace to ~/ * Remove unnecessary exit 1 --- .circleci/config.yml | 83 ++++++++++++++++++++++++++++++- Makefile | 12 ----- android/app/build.gradle | 2 +- fastlane/Fastfile | 64 ++++++++++++++++-------- fastlane/Gemfile.lock | 22 ++++---- fastlane/metadata/changelog | 5 ++ patches/react-native+0.59.9.patch | 25 ---------- patches/react-native+0.61.2.patch | 78 +++++++++++++++++++++++++++++ 8 files changed, 219 insertions(+), 72 deletions(-) create mode 100644 fastlane/metadata/changelog delete mode 100644 patches/react-native+0.59.9.patch diff --git a/.circleci/config.yml b/.circleci/config.yml index 3225b8f63..d2b61f1fb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -141,7 +141,7 @@ commands: working_directory: fastlane name: Run fastlane to build android no_output_timeout: 30m - command: bundle exec fastlane android build || exit 1 + command: bundle exec fastlane android build build-ios: description: "Build the iOS app" @@ -157,7 +157,7 @@ commands: working_directory: fastlane name: Run fastlane to build iOS no_output_timeout: 30m - command: bundle exec fastlane ios build || exit 1 + command: bundle exec fastlane ios build deploy-to-store: description: "Deploy build to store" @@ -238,6 +238,25 @@ jobs: - save: filename: "Mattermost_Beta.apk" + build-android-unsigned: + executor: android + steps: + - checkout: + path: ~/mattermost-mobile + - npm-dependencies + - assets + - fastlane-dependencies: + for: android + - gradle-dependencies + - run: + working_directory: fastlane + name: Run fastlane to build unsigned android + no_output_timeout: 30m + command: bundle exec fastlane android unsigned + - persist + - save: + filename: "Mattermost-unsigned.apk" + build-ios-beta: executor: ios steps: @@ -263,6 +282,25 @@ jobs: - save: filename: "Mattermost_Beta.ipa" + build-ios-unsigned: + executor: ios + steps: + - checkout: + path: ~/mattermost-mobile + - npm-dependencies + - pods-dependencies + - assets + - fastlane-dependencies: + for: ios + - run: + working_directory: fastlane + name: Run fastlane to build unsigned iOS + no_output_timeout: 30m + command: bundle exec fastlane ios unsigned + - persist + - save: + filename: "Mattermost-unsigned.ipa" + deploy-android-release: executor: name: android @@ -299,6 +337,18 @@ jobs: target: ios file: Mattermost_Beta.ipa + github-release: + executor: + name: android + resource_class: medium + steps: + - attach_workspace: + at: ~/ + - run: + name: Create GitHub release + working_directory: fastlane + command: bundle exec fastlane github + workflows: version: 2 build: @@ -403,3 +453,32 @@ workflows: filters: branches: only: /^build-pr-.*/ + + - build-android-unsigned: + context: mattermost-mobile-unsigned + requires: + - test + filters: + tags: + only: /^v(\d+\.)(\d+\.)(\d+)(.*)?$/ + branches: + ignore: /.*/ + - build-ios-unsigned: + context: mattermost-mobile-unsigned + requires: + - test + filters: + tags: + only: /^v(\d+\.)(\d+\.)(\d+)(.*)?$/ + branches: + ignore: /.*/ + - github-release: + context: mattermost-mobile-unsigned + requires: + - build-android-unsigned + - build-ios-unsigned + filters: + tags: + only: /^v(\d+\.)(\d+\.)(\d+)(.*)?$/ + branches: + ignore: /.*/ \ No newline at end of file diff --git a/Makefile b/Makefile index af3a95c2b..33549d57c 100644 --- a/Makefile +++ b/Makefile @@ -186,14 +186,7 @@ build-android: | stop pre-build check-style i18n-extract-ci prepare-android-buil unsigned-ios: stop pre-build check-style ## Build an unsigned version of the iOS app $(call start_packager) - @echo "Building unsigned iOS app" @cd fastlane && NODE_ENV=production bundle exec fastlane ios unsigned - @mkdir -p build-ios - @cd ios/ && xcodebuild -workspace Mattermost.xcworkspace/ -scheme Mattermost -sdk iphoneos -configuration Release -parallelizeTargets -resultBundlePath ../build-ios/result -derivedDataPath ../build-ios/ CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO - @cd build-ios/ && mkdir -p Payload && cp -R Build/Products/Release-iphoneos/Mattermost.app Payload/ && zip -r Mattermost-unsigned.ipa Payload/ - @mv build-ios/Mattermost-unsigned.ipa . - @cd fastlane && bundle exec fastlane upload_file_to_s3 file:Mattermost-unsigned.ipa os_type:iOS - @rm -rf build-ios/ $(call stop_packager) ios-sim-x86_64: stop pre-build check-style ## Build an unsigned x86_64 version of the iOS app for iPhone simulator @@ -209,12 +202,7 @@ ios-sim-x86_64: stop pre-build check-style ## Build an unsigned x86_64 version o $(call stop_packager) unsigned-android: stop pre-build check-style prepare-android-build ## Build an unsigned version of the Android app - $(call start_packager) - @echo "Building unsigned Android app" @cd fastlane && NODE_ENV=production bundle exec fastlane android unsigned - @mv android/app/build/outputs/apk/unsigned/app-unsigned-unsigned.apk ./Mattermost-unsigned.apk - @cd fastlane && bundle exec fastlane upload_file_to_s3 file:Mattermost-unsigned.apk os_type:Android - $(call stop_packager) test: | pre-run check-style ## Runs tests @npm test diff --git a/android/app/build.gradle b/android/app/build.gradle index a1d5039a6..35cd1ccb1 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -179,7 +179,7 @@ android { unsigned.initWith(buildTypes.release) unsigned { signingConfig null - matchingFallbacks = ['debug', 'release'] + matchingFallbacks = ['release'] } } // applicationVariants are e.g. debug, release diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 7de9d94d8..26d1a3e01 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -17,8 +17,6 @@ before_all do ENV['BRANCH_TO_BUILD'] = ENV['CIRCLE_BRANCH'] end - UI.success("Building for release #{ENV['BUILD_FOR_RELEASE']}") - if ENV['CIRCLECI'] != 'true' # Raises an error is git is not clean if ENV['COMMIT_CHANGES_TO_GIT'] == 'true' @@ -187,19 +185,6 @@ lane :build do |options| build end -desc 'Build the app for Android and iOS unsigned' -lane :unsigned do - configure - - # Build the android app - self.runner.current_platform = :android - unsigned - - # Build the ios app - self.runner.current_platform = :ios - unsigned -end - desc 'Upload file to s3' lane :upload_file_to_s3 do |options| os_type = options[:os_type] @@ -288,6 +273,29 @@ lane :upload_file_to_s3 do |options| end end +desc 'Create GitHub release' +lane :github do + tag = ENV['CIRCLE_TAG'] || ENV['TAG'] + + if tag + version = get_version_number(xcodeproj: './ios/Mattermost.xcodeproj', target: 'Mattermost') + build = get_build_number(xcodeproj: './ios/Mattermost.xcodeproj') + changelog = File.read("metadata/changelog") + changelog.concat("* Android [Mattermost.apk](https://releases.mattermost.com/mattermost-mobile/#{version}/#{build}/Mattermost.apk)\n") + changelog.concat("* iOS [Mattermost.ipa](https://releases.mattermost.com/mattermost-mobile/#{version}/#{build}/Mattermost.ipa)") + + github_release = set_github_release( + repository_name: "mattermost/mattermost-mobile", + api_token: ENV["GITHUB_TOKEN"], + name: "Mobile Version #{version}", + tag_name: tag, + description: changelog, + upload_assets: ["./Mattermost-unsigned.ipa", "./Mattermost-unsigned.apk"], + is_draft: true + ) + end +end + platform :ios do before_all do if ENV['CIRCLECI'] == 'true' @@ -317,11 +325,20 @@ platform :ios do desc 'Build an unsigned ipa' lane :unsigned do - unless configured - configure - end + UI.success('Building unsigned iOS app') + + ENV['APP_NAME'] = 'Mattermost' + ENV['REPLACE_ASSETS'] = 'true' + ENV['BUILD_FOR_RELEASE'] = 'true' + update_identifiers replace_assets + + sh 'mkdir -p ../build-ios' + sh 'cd ../ios/ && xcodebuild -workspace Mattermost.xcworkspace/ -scheme Mattermost -sdk iphoneos -configuration Release -parallelizeTargets -resultBundlePath ../build-ios/result -derivedDataPath ../build-ios/ CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO' + sh 'cd ../build-ios/ && mkdir -p Payload && cp -R Build/Products/Release-iphoneos/Mattermost.app Payload/ && zip -r Mattermost-unsigned.ipa Payload/' + sh 'mv ../build-ios/Mattermost-unsigned.ipa ../' + sh 'rm -rf ../build-ios/' end lane :update_identifiers do @@ -516,9 +533,12 @@ platform :android do desc 'Build an unsigned apk' lane :unsigned do - unless configured - configure - end + UI.success('Building unsigned Android app') + + ENV['APP_NAME'] = 'Mattermost' + ENV['REPLACE_ASSETS'] = 'true' + ENV['BUILD_FOR_RELEASE'] = 'true' + update_identifiers replace_assets @@ -527,6 +547,8 @@ platform :android do build_type: 'Unsigned', project_dir: 'android/' ) + + sh "mv #{lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]} #{Pathname.new(File.expand_path(File.dirname(__FILE__))).parent.to_s}/Mattermost-unsigned.apk" end desc 'Update config and module/listener for Android telemetry' diff --git a/fastlane/Gemfile.lock b/fastlane/Gemfile.lock index b487cd04b..b1a6653c8 100644 --- a/fastlane/Gemfile.lock +++ b/fastlane/Gemfile.lock @@ -6,17 +6,17 @@ GEM public_suffix (>= 2.0.2, < 5.0) atomos (0.1.3) aws-eventstream (1.0.3) - aws-partitions (1.223.0) - aws-sdk-core (3.68.1) + aws-partitions (1.228.0) + aws-sdk-core (3.72.0) aws-eventstream (~> 1.0, >= 1.0.2) - aws-partitions (~> 1.0) + aws-partitions (~> 1, >= 1.228.0) aws-sigv4 (~> 1.1) jmespath (~> 1.0) - aws-sdk-kms (1.24.0) - aws-sdk-core (~> 3, >= 3.61.1) + aws-sdk-kms (1.25.0) + aws-sdk-core (~> 3, >= 3.71.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.49.0) - aws-sdk-core (~> 3, >= 3.61.1) + aws-sdk-s3 (1.51.0) + aws-sdk-core (~> 3, >= 3.71.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.1) aws-sigv4 (1.1.0) @@ -34,7 +34,7 @@ GEM unf (>= 0.0.5, < 1.0.0) dotenv (2.7.5) emoji_regex (1.0.1) - excon (0.67.0) + excon (0.68.0) faraday (0.17.0) multipart-post (>= 1.2, < 3) faraday-cookie_jar (0.0.6) @@ -94,9 +94,9 @@ GEM representable (~> 3.0) retriable (>= 2.0, < 4.0) signet (~> 0.9) - google-cloud-core (1.3.1) + google-cloud-core (1.4.0) google-cloud-env (~> 1.0) - google-cloud-env (1.2.1) + google-cloud-env (1.3.0) faraday (~> 0.11) google-cloud-storage (1.16.0) digest-crc (~> 0.4) @@ -163,7 +163,7 @@ GEM unf_ext (0.0.7.6) unicode-display_width (1.6.0) word_wrap (1.0.0) - xcodeproj (1.12.0) + xcodeproj (1.13.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) diff --git a/fastlane/metadata/changelog b/fastlane/metadata/changelog new file mode 100644 index 000000000..b3b7c8322 --- /dev/null +++ b/fastlane/metadata/changelog @@ -0,0 +1,5 @@ +This version is compatible with Mattermost servers v5.9+. + +Please see [changelog](https://github.com/mattermost/mattermost-mobile/blob/master/CHANGELOG.md) for full release notes. If you're interested in helping beta test upcoming versions before they are released, please see our [documentation](https://github.com/mattermost/mattermost-mobile#testing). + +### Downloads diff --git a/patches/react-native+0.59.9.patch b/patches/react-native+0.59.9.patch deleted file mode 100644 index a846cd491..000000000 --- a/patches/react-native+0.59.9.patch +++ /dev/null @@ -1,25 +0,0 @@ -diff --git a/node_modules/react-native/Libraries/Text/Text/RCTTextShadowView.m b/node_modules/react-native/Libraries/Text/Text/RCTTextShadowView.m -index d464e6a..6c397c5 100644 ---- a/node_modules/react-native/Libraries/Text/Text/RCTTextShadowView.m -+++ b/node_modules/react-native/Libraries/Text/Text/RCTTextShadowView.m -@@ -170,6 +170,12 @@ - (void)postprocessAttributedText:(NSMutableAttributedString *)attributedText - - - (NSAttributedString *)attributedTextWithMeasuredAttachmentsThatFitSize:(CGSize)size - { -+ static UIImage *placeholderImage; -+ static dispatch_once_t onceToken; -+ dispatch_once(&onceToken, ^{ -+ placeholderImage = [UIImage new]; -+ }); -+ - NSMutableAttributedString *attributedText = - [[NSMutableAttributedString alloc] initWithAttributedString:[self attributedTextWithBaseTextAttributes:nil]]; - -@@ -188,6 +194,7 @@ - (NSAttributedString *)attributedTextWithMeasuredAttachmentsThatFitSize:(CGSize - maximumSize:size]; - NSTextAttachment *attachment = [NSTextAttachment new]; - attachment.bounds = (CGRect){CGPointZero, fittingSize}; -+ attachment.image = placeholderImage; - [attributedText addAttribute:NSAttachmentAttributeName value:attachment range:range]; - } - ]; diff --git a/patches/react-native+0.61.2.patch b/patches/react-native+0.61.2.patch index fffcc60b3..78a6a06fa 100644 --- a/patches/react-native+0.61.2.patch +++ b/patches/react-native+0.61.2.patch @@ -1,3 +1,43 @@ +diff --git a/node_modules/react-native/react.gradle b/node_modules/react-native/react.gradle +index 14f0746..054f652 100644 +--- a/node_modules/react-native/react.gradle ++++ b/node_modules/react-native/react.gradle +@@ -116,7 +116,7 @@ afterEvaluate { + + // Set up dev mode + def devEnabled = !(config."devDisabledIn${targetName}" +- || targetName.toLowerCase().contains("release")) ++ || targetName.toLowerCase().contains("release") || targetName.toLowerCase().contains("unsigned")) + + def extraArgs = extraPackagerArgs; + +@@ -141,7 +141,7 @@ afterEvaluate { + def hermesFlags; + def hbcTempFile = file("${jsBundleFile}.hbc") + exec { +- if (targetName.toLowerCase().contains("release")) { ++ if (targetName.toLowerCase().contains("release") || targetName.toLowerCase().contains("unsigned")) { + // Can't use ?: since that will also substitute valid empty lists + hermesFlags = config.hermesFlagsRelease + if (hermesFlags == null) hermesFlags = ["-O", "-output-source-map"] +@@ -180,7 +180,7 @@ afterEvaluate { + ? config."bundleIn${targetName}" + : config."bundleIn${variant.buildType.name.capitalize()}" != null + ? config."bundleIn${variant.buildType.name.capitalize()}" +- : targetName.toLowerCase().contains("release") ++ : (targetName.toLowerCase().contains("release") || targetName.toLowerCase().contains("unsigned")) + } + + // Expose a minimal interface on the application variant and the task itself: +@@ -272,7 +272,7 @@ afterEvaluate { + // This should really be done by packaging all Hermes releated libs into + // two separate HermesDebug and HermesRelease AARs, but until then we'll + // kludge it by deleting the .so files out of the /transforms/ directory. +- def isRelease = targetName.toLowerCase().contains("release") ++ def isRelease = targetName.toLowerCase().contains("release") || targetName.toLowerCase().contains("unsigned") + def libDir = "$buildDir/intermediates/transforms/" + def vmSelectionAction = { + fileTree(libDir).matching { diff --git a/node_modules/react-native/Libraries/Lists/VirtualizedList.js b/node_modules/react-native/Libraries/Lists/VirtualizedList.js index 7dffc17..548e7bb 100644 --- a/node_modules/react-native/Libraries/Lists/VirtualizedList.js @@ -19,6 +59,31 @@ index 7dffc17..548e7bb 100644 }, horizontallyInverted: { transform: [{scaleX: -1}], +diff --git a/node_modules/react-native/Libraries/Text/Text/RCTTextShadowView.m b/node_modules/react-native/Libraries/Text/Text/RCTTextShadowView.m +index 1543bca..a4502b7 100644 +--- a/node_modules/react-native/Libraries/Text/Text/RCTTextShadowView.m ++++ b/node_modules/react-native/Libraries/Text/Text/RCTTextShadowView.m +@@ -177,6 +177,12 @@ - (void)postprocessAttributedText:(NSMutableAttributedString *)attributedText + + - (NSAttributedString *)attributedTextWithMeasuredAttachmentsThatFitSize:(CGSize)size + { ++ static UIImage *placeholderImage; ++ static dispatch_once_t onceToken; ++ dispatch_once(&onceToken, ^{ ++ placeholderImage = [UIImage new]; ++ }); ++ + NSMutableAttributedString *attributedText = + [[NSMutableAttributedString alloc] initWithAttributedString:[self attributedTextWithBaseTextAttributes:nil]]; + +@@ -195,6 +201,7 @@ - (NSAttributedString *)attributedTextWithMeasuredAttachmentsThatFitSize:(CGSize + maximumSize:size]; + NSTextAttachment *attachment = [NSTextAttachment new]; + attachment.bounds = (CGRect){CGPointZero, fittingSize}; ++ attachment.image = placeholderImage; + [attributedText addAttribute:NSAttachmentAttributeName value:attachment range:range]; + } + ]; diff --git a/node_modules/react-native/Libraries/WebSocket/RCTSRWebSocket.h b/node_modules/react-native/Libraries/WebSocket/RCTSRWebSocket.h index 1b17cff..9efa98e 100644 --- a/node_modules/react-native/Libraries/WebSocket/RCTSRWebSocket.h @@ -150,3 +215,16 @@ index 35f0757..a0205fc 100644 } get binaryType(): ?BinaryType { +diff --git a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java +index ef2ae93..2795802 100644 +--- a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java ++++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java +@@ -92,7 +92,7 @@ public class AndroidInfoModule extends ReactContextBaseJavaModule implements Tur + + private Boolean isRunningScreenshotTest() { + try { +- Class.forName("android.support.test.rule.ActivityTestRule"); ++ Class.forName("androidx.test.rule.ActivityTestRule"); + return true; + } catch (ClassNotFoundException ignored) { + return false;