diff --git a/native/android/app/build.gradle b/native/android/app/build.gradle
index a73a98eb5..8305a9c9a 100644
--- a/native/android/app/build.gradle
+++ b/native/android/app/build.gradle
@@ -1,585 +1,585 @@
apply plugin: "com.android.application"
apply from: "../../../node_modules/react-native-unimodules/gradle.groovy"
import com.android.build.OutputFile
import de.undercouch.gradle.tasks.download.Download
import app.comm.gradle.tasks.GitModules
/**
* 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.js" is
* // default. Can be overridden with ENTRY_FILE environment variable.
* entryFile: "index.android.js",
*
* // https://reactnative.dev/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: []
* ]
*/
project.ext.react = [
enableHermes: true, // clean and rebuild if changing
hermesCommand: "../../../node_modules/hermes-engine/%OS-BIN%/hermesc",
]
apply from: "../../../node_modules/react-native/react.gradle"
/**
* 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
/**
* Run Proguard to shrink the Java bytecode in release builds.
*/
def enableProguardInReleaseBuilds = false
/**
* 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
* 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 that value will be read 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)
/**
* Architectures to build native code for in debug.
*/
def nativeArchitectures = project.getProperties().get("reactNativeDebugArchitectures")
def customDownloadsDir = System.getenv("REACT_NATIVE_DOWNLOADS_DIR")
def dependenciesPath = System.getenv("REACT_NATIVE_DEPENDENCIES")
def downloadsDir = customDownloadsDir ? new File(customDownloadsDir) : new File("$buildDir/downloads")
def thirdPartyNdkDir = new File("$buildDir/third-party-ndk")
// The Boost library is a very large download (>100MB).
// If Boost is already present on your system, define the REACT_NATIVE_BOOST_PATH env variable
// and the build will use that.
def boostPath = dependenciesPath ?: System.getenv("REACT_NATIVE_BOOST_PATH")
task createNativeDepsDirectories {
downloadsDir.mkdirs()
thirdPartyNdkDir.mkdirs()
}
// GRPC
task downloadGrpc(dependsOn: createNativeDepsDirectories, type: Download) {
src("https://github.com/grpc/grpc/archive/refs/tags/v${GRPC_VERSION}.tar.gz")
onlyIfNewer(true)
overwrite(false)
dest(new File(downloadsDir, "grpc-${GRPC_VERSION}.tar.gz"))
}
task copyGrpc(dependsOn: dependenciesPath ? [] : [downloadGrpc], type: Copy) {
from(tarTree(downloadGrpc.dest))
includeEmptyDirs = true
into("$thirdPartyNdkDir/grpc")
}
def grpcDir = "${thirdPartyNdkDir}/grpc/grpc-${GRPC_VERSION}"
task prepareGrpc(dependsOn: copyGrpc, type: GitModules) {
gitmodulesFile(new File("${grpcDir}/.gitmodules"))
outputDir(new File("${grpcDir}"))
// Skip the boringSSL module as we use OpenSSL
skipModules([
"third_party/boringssl-with-bazel"
])
// Needs to override/provide some module branches
// for the gRPC version compatibility
moduleBranch([
"third_party/cares/cares": "cares-1_13_0",
"third_party/abseil-cpp": "lts_2021_03_24",
"third_party/protobuf": "v3.15.8"
])
// We need to move 'zconf.h' because it modifies on the compilation stage
// and makes the 'outputDir' not as UP-TO-DATE
runAfter([
"mv ${grpcDir}/third_party/zlib/zconf.h ${grpcDir}/third_party/zlib/zconf.h.included"
])
}
// FOLLY
task downloadFolly(dependsOn: createNativeDepsDirectories, type: Download) {
src("https://github.com/facebook/folly/archive/v${FOLLY_VERSION}.tar.gz")
onlyIfNewer(true)
overwrite(false)
dest(new File(downloadsDir, "folly-${FOLLY_VERSION}.tar.gz"))
}
def follyFindWrapNoInt = 'return int\\(wrapNoInt\\(open, name, flags, mode\\)\\);'
def follyReplaceWrapNoInt = '''
ssize_t r;
do {
r = open(name, flags, mode);
} while (r == -1 && errno == EINTR);
return r;
'''
def follyFindTableSize = 'for \\(int fd = getdtablesize\\(\\) - 1'
def follyReplaceTableSize = 'for (int fd = sysconf(_SC_OPEN_MAX) - 1'
task prepareFolly(dependsOn: dependenciesPath ? [] : [downloadFolly], type: Copy) {
inputs.properties([
'findWrapNoInt': follyFindWrapNoInt,
'replaceWrapNoInt': follyReplaceWrapNoInt,
'findTableSize': follyFindTableSize,
'replaceTableSize': follyReplaceTableSize,
])
from(dependenciesPath ?: tarTree(downloadFolly.dest))
include("folly-${FOLLY_VERSION}/folly/**/*")
eachFile { fname -> fname.path = (fname.path - "folly-${FOLLY_VERSION}/") }
// Fixes problem with Folly failing to build on certain systems. See
// https://github.com/facebook/react-native/issues/28298
filter { line -> line.replaceAll(follyFindWrapNoInt, follyReplaceWrapNoInt) }
// fix undeclared identifier 'getdtablesize' in Subprocess.cpp
// https://stackoverflow.com/questions/8225186/portable-equivalent-of-open-max/8225235#8225235
filter { line -> line.replaceAll(follyFindTableSize, follyReplaceTableSize) }
includeEmptyDirs = false
into("$thirdPartyNdkDir/folly")
}
// GLOG
task downloadGlog(dependsOn: createNativeDepsDirectories, type: Download) {
src("https://github.com/google/glog/archive/v${GLOG_VERSION}.tar.gz")
onlyIfNewer(true)
overwrite(false)
dest(new File(downloadsDir, "glog-${GLOG_VERSION}.tar.gz"))
}
task prepareGlog(dependsOn: dependenciesPath ? [] : [downloadGlog], type: Copy) {
from(dependenciesPath ?: tarTree(downloadGlog.dest))
include("glog-${GLOG_VERSION}/**/*")
includeEmptyDirs = false
into("$thirdPartyNdkDir/glog")
}
// BOOST
task downloadBoost(dependsOn: createNativeDepsDirectories, type: Download) {
src("https://github.com/react-native-community/boost-for-react-native/releases/download/v${BOOST_VERSION.replace("_", ".")}-0/boost_${BOOST_VERSION}.tar.gz")
onlyIfNewer(true)
overwrite(false)
dest(new File(downloadsDir, "boost_${BOOST_VERSION}.tar.gz"))
}
task prepareBoost(dependsOn: boostPath ? [] : [downloadBoost]) {
inputs.properties([
'boost.version': BOOST_VERSION
])
outputs.dir("$thirdPartyNdkDir/boost/boost/")
.withPropertyName('boost.output')
doFirst {
copy {
from(boostPath ?: tarTree(resources.gzip(downloadBoost.dest)))
include("boost_${BOOST_VERSION}/boost/**/*.hpp", "boost/boost/**/*.hpp")
include("boost_${BOOST_VERSION}/boost/**/*.ipp", "boost/boost/**/*.ipp")
include("boost_${BOOST_VERSION}/boost/**/*.h", "boost/boost/**/*.h")
includeEmptyDirs = false
into("$thirdPartyNdkDir/boost")
}
}
doLast {
file("$thirdPartyNdkDir/boost/boost_${BOOST_VERSION}").renameTo("$thirdPartyNdkDir/boost/boost")
}
}
// DOUBLE-CONVERSION
task downloadDoubleConversion(dependsOn: createNativeDepsDirectories, type: Download) {
src("https://github.com/google/double-conversion/archive/v${DOUBLE_CONVERSION_VERSION}.tar.gz")
onlyIfNewer(true)
overwrite(false)
dest(new File(downloadsDir, "double-conversion-${DOUBLE_CONVERSION_VERSION}.tar.gz"))
}
task prepareDoubleConversion(dependsOn: dependenciesPath ? [] : [downloadDoubleConversion], type: Copy) {
from(dependenciesPath ?: tarTree(downloadDoubleConversion.dest))
from("src/main/jni/third-party/double-conversion/Android.mk")
include("double-conversion-${DOUBLE_CONVERSION_VERSION}/src/**/*", "Android.mk")
filesMatching("*/src/**/*", { fname -> fname.path = "double-conversion/${fname.name}" })
includeEmptyDirs = false
into("$thirdPartyNdkDir/double-conversion")
}
// OPENSSL
def hostSystem = System.getProperty('os.name').toLowerCase(Locale.ROOT)
def hostTag = hostSystem.contains('mac') ? 'darwin-x86_64' : 'linux-x86_64'
task downloadOpenSSL(dependsOn: createNativeDepsDirectories, type: Download) {
src("https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz")
onlyIfNewer(true)
overwrite(false)
dest(new File(downloadsDir, "openssl-${OPENSSL_VERSION}.tar.gz"))
}
task prepareOpenSSL(
dependsOn: dependenciesPath ? [] : [downloadOpenSSL],
type: Copy
) {
from(dependenciesPath ?: tarTree(downloadOpenSSL.dest))
include("openssl-${OPENSSL_VERSION}/**/*")
includeEmptyDirs = false
into("${thirdPartyNdkDir}/openssl")
}
task prebuildOpenSSL(dependsOn: dependenciesPath ? [] : [prepareOpenSSL]) {
inputs.properties([
'openssl.version': OPENSSL_VERSION,
'openssl.abis': getBuildTypeABIs(nativeArchitectures)
])
outputs.dir("${thirdPartyNdkDir}/openssl/openssl-${OPENSSL_VERSION}/build/")
.withPropertyName('openssl.output')
doFirst {
getBuildTypeABIs(nativeArchitectures).each { buildABI ->
logger.info("Building OpenSSL library for the ${buildABI}")
exec {
commandLine './bash/build_openssl.sh',
// OPENSSL_SUBMODULE_PATH
"${thirdPartyNdkDir}/openssl/openssl-${OPENSSL_VERSION}/",
// HOST_TAG
hostTag,
// ANDROID_ARCH_ABI
"${buildABI}",
// MIN_SDK_VERSION
rootProject.ext.minSdkVersion,
// ANDROID_NDK_HOME
android.ndkDirectory.absolutePath,
// PARALLEL_THREADS
Runtime.getRuntime().availableProcessors()
}
}
}
}
// EXTERNAL LIBS
task prepareExternalLibs {
dependsOn prepareGrpc
dependsOn prepareFolly
dependsOn prepareGlog
dependsOn prepareBoost
dependsOn prepareDoubleConversion
dependsOn prebuildOpenSSL
}
// Removes the '.cxx' directory to prevent running
// ninja clean when the 'clean' command is executed
task removeCXX(type: Exec) {
commandLine 'rm', '-rf', '.cxx'
}
// Bind preBuild dependencies only if not 'clean' running
if (!isCleanRunning()) {
afterEvaluate {
preBuild.dependsOn(prepareExternalLibs)
}
}
// Run removing CXX task before the clean execution
beforeEvaluate {
clean.dependsOn(removeCXX)
}
// Detects are we running the 'clean' commands
def isCleanRunning() {
gradle.startParameter.taskRequests.any {
!it.args.isEmpty() && it.args.first().startsWith('clean')
}
}
// Release keystore via macOS Keychain Access
def getPassword(String keyLabel) {
if (System.getenv('ANDROID_SIGNING_PASSWORD')) {
return System.getenv('ANDROID_SIGNING_PASSWORD')
}
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'security',
'find-generic-password',
'-wl', keyLabel,
'-a', System.properties['user.name']
standardOutput = stdout
ignoreExitValue true
}
return stdout.toString().strip()
}
// Returns all ABIs architectures for the 'bundleRelease'
// or only from 'adb devices' if running debug release.
def getBuildTypeABIs(nativeArchitectures) {
if (System.getenv("BUILDKITE") == "true") {
return ["arm64-v8a"]
}
def isBundleRelease = gradle.startParameter.taskRequests.any {
!it.args.isEmpty() && it.args.first().contains("bundleRelease")
}
if (isBundleRelease) {
// All of the supported ABIs
// https://developer.android.com/ndk/guides/abis.html#sa
final allAbis = ["armeabi-v7a", "x86", "arm64-v8a", "x86_64"]
logger.info("Using all architectures to build: ${allAbis}")
return allAbis
}
if (nativeArchitectures) {
return nativeArchitectures.split(',')
}
// Get current 'adb devices' architectures
def commandOutput = new ByteArrayOutputStream()
exec {
commandLine "./bash/detect_abis.sh"
standardOutput = commandOutput
}
final detectedAbis = commandOutput.toString("UTF-8").trim().tokenize()
logger.info("Detected architectures to build: ${detectedAbis}")
return detectedAbis
}
android {
buildFeatures {
prefab true
}
configurations {
all*.exclude module: 'fbjni-java-only'
}
dependencies {
implementation 'com.facebook.fbjni:fbjni:0.1.0'
}
ndkVersion rootProject.ext.ndkVersion
compileSdkVersion rootProject.ext.compileSdkVersion
defaultConfig {
applicationId 'app.comm.android'
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
- versionCode 128
- versionName '1.0.128'
+ versionCode 129
+ versionName '1.0.129'
missingDimensionStrategy 'react-native-camera', 'general'
multiDexEnabled true
}
splits {
abi {
reset()
enable enableSeparateBuildPerCPUArchitecture
universalApk false // If true, also generate a universal APK
include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
}
}
signingConfigs {
debug {
storeFile file('debug.keystore')
storePassword 'android'
keyAlias 'androiddebugkey'
keyPassword 'android'
}
release {
if (project.hasProperty('COMM_UPLOAD_STORE_FILE')) {
def password = getPassword('CommAndroidKeyPassword')
storeFile file(COMM_UPLOAD_STORE_FILE)
storePassword password
keyAlias COMM_UPLOAD_KEY_ALIAS
keyPassword password
}
}
}
buildTypes {
final buildABIs = getBuildTypeABIs(nativeArchitectures)
release {
if (project.hasProperty('COMM_UPLOAD_STORE_FILE')) {
signingConfig signingConfigs.release
} else {
signingConfig signingConfigs.debug
}
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
ndk {
abiFilters = []
abiFilters.addAll(buildABIs)
}
}
debug {
signingConfig signingConfigs.debug
ndk {
abiFilters = []
abiFilters.addAll(buildABIs)
}
}
}
packagingOptions {
pickFirst "**/libc++_shared.so"
pickFirst "**/libfbjni.so"
}
defaultConfig {
externalNativeBuild {
cmake {
arguments "-DANDROID_STL=c++_shared",
"-DGLOG_VERSION=" + GLOG_VERSION,
"-DOPENSSL_VERSION=" + OPENSSL_VERSION,
"-DGRPC_VERSION=" + GRPC_VERSION
targets "comm_jni_module", "turbomodulejsijni"
}
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
// applicationVariants are e.g. debug, release
applicationVariants.all { variant ->
variant.outputs.each { output ->
// For each separate APK per architecture, set a unique version code as described here:
// https://developer.android.com/studio/build/configure-apk-splits.html
// Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc.
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
def abi = output.getFilter(OutputFile.ABI)
if (abi != null) { // null for the universal-debug, universal-release variants
output.versionCodeOverride =
defaultConfig.versionCode * 1000 + versionCodes.get(abi)
}
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.21"
//noinspection GradleDynamicVersion
implementation("com.facebook.react:react-native:+")
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
addUnimodulesDependencies([ modulesPaths: [ '../../../node_modules' ] ])
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
exclude group:'com.facebook.fbjni'
}
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
exclude group:'com.facebook.flipper'
}
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
exclude group:'com.facebook.flipper'
exclude group:'com.facebook.fresco', module:'stetho'
}
implementation "com.google.android.gms:play-services-base:16.1.0"
implementation "com.google.firebase:firebase-core:16.0.9"
implementation "com.google.firebase:firebase-messaging:18.0.0"
implementation "me.leolin:ShortcutBadger:1.1.21@aar"
implementation project(':reactnativekeyboardinput')
implementation "androidx.multidex:multidex:2.0.1"
implementation "androidx.lifecycle:lifecycle-runtime:2.2.0"
implementation "androidx.lifecycle:lifecycle-process:2.2.0"
implementation 'com.facebook.fresco:fresco:2.2.0'
implementation 'com.facebook.fresco:animated-gif:2.2.0'
implementation 'com.facebook.fresco:animated-webp:2.2.0'
implementation 'com.facebook.fresco:webpsupport:2.2.0'
implementation 'org.conscrypt:conscrypt-android:2.0.0'
if (enableHermes) {
def hermesPath = "../../../node_modules/hermes-engine/android/"
debugImplementation files(hermesPath + "hermes-debug.aar")
releaseImplementation files(hermesPath + "hermes-release.aar")
} else {
implementation jscFlavor
}
}
// 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)
apply plugin: 'com.google.gms.google-services'
diff --git a/native/ios/Comm/Info.debug.plist b/native/ios/Comm/Info.debug.plist
index 5cc0003a0..ea2cdb02b 100644
--- a/native/ios/Comm/Info.debug.plist
+++ b/native/ios/Comm/Info.debug.plist
@@ -1,102 +1,102 @@
ITSAppUsesNonExemptEncryption
CFBundleDevelopmentRegion
en
CFBundleDisplayName
Comm
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundleName
$(PRODUCT_NAME)
CFBundlePackageType
APPL
CFBundleShortVersionString
- 1.0.128
+ 1.0.129
CFBundleSignature
????
CFBundleVersion
- 128
+ 129
LSApplicationQueriesSchemes
org-appextension-feature-password-management
LSRequiresIPhoneOS
NSAppTransportSecurity
NSAllowsArbitraryLoads
NSExceptionDomains
localhost
NSExceptionAllowsInsecureHTTPLoads
NSLocationAlwaysUsageDescription
Allow $(PRODUCT_NAME) to use your location
NSLocationWhenInUseUsageDescription
Allow $(PRODUCT_NAME) to access your location
NSPhotoLibraryUsageDescription
Allow $(PRODUCT_NAME) to access your photo library so you can send images.
NSPhotoLibraryAddUsageDescription
Allow $(PRODUCT_NAME) to save images to your photo library.
NSCameraUsageDescription
Allow $(PRODUCT_NAME) to access the camera so you can capture and send photos.
UIAppFonts
OpenSans-Semibold.ttf
OpenSans-Regular.ttf
Anaheim-Regular.ttf
AntDesign.ttf
Entypo.ttf
EvilIcons.ttf
Feather.ttf
FontAwesome.ttf
FontAwesome5_Brands.ttf
FontAwesome5_Regular.ttf
FontAwesome5_Solid.ttf
Fontisto.ttf
Foundation.ttf
Ionicons.ttf
MaterialCommunityIcons.ttf
MaterialIcons.ttf
Octicons.ttf
SimpleLineIcons.ttf
Zocial.ttf
IBMPlexSans-Regular.ttf
IBMPlexSans-Medium.ttf
IBMPlexSans-Bold.ttf
swmansion.ttf
UIBackgroundModes
fetch
remote-notification
UILaunchStoryboardName
SplashScreen
UIRequiredDeviceCapabilities
armv7
UIStatusBarStyle
UIStatusBarStyleLightContent
UISupportedInterfaceOrientations
UIInterfaceOrientationPortrait
UIViewControllerBasedStatusBarAppearance
diff --git a/native/ios/Comm/Info.release.plist b/native/ios/Comm/Info.release.plist
index b2c437272..5e21ec3e0 100644
--- a/native/ios/Comm/Info.release.plist
+++ b/native/ios/Comm/Info.release.plist
@@ -1,89 +1,89 @@
ITSAppUsesNonExemptEncryption
CFBundleDevelopmentRegion
en
CFBundleDisplayName
Comm
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundleName
$(PRODUCT_NAME)
CFBundlePackageType
APPL
CFBundleShortVersionString
- 1.0.128
+ 1.0.129
CFBundleSignature
????
CFBundleVersion
- 128
+ 129
LSApplicationQueriesSchemes
org-appextension-feature-password-management
LSRequiresIPhoneOS
NSLocationAlwaysUsageDescription
Allow $(PRODUCT_NAME) to use your location
NSLocationWhenInUseUsageDescription
Allow $(PRODUCT_NAME) to access your location
NSPhotoLibraryUsageDescription
Allow $(PRODUCT_NAME) to access your photo library so you can send images.
NSPhotoLibraryAddUsageDescription
Allow $(PRODUCT_NAME) to save images to your photo library.
NSCameraUsageDescription
Allow $(PRODUCT_NAME) to access the camera so you can capture and send photos.
UIAppFonts
OpenSans-Semibold.ttf
OpenSans-Regular.ttf
Anaheim-Regular.ttf
AntDesign.ttf
Entypo.ttf
EvilIcons.ttf
Feather.ttf
FontAwesome.ttf
FontAwesome5_Brands.ttf
FontAwesome5_Regular.ttf
FontAwesome5_Solid.ttf
Fontisto.ttf
Foundation.ttf
Ionicons.ttf
MaterialCommunityIcons.ttf
MaterialIcons.ttf
Octicons.ttf
SimpleLineIcons.ttf
Zocial.ttf
IBMPlexSans-Regular.ttf
IBMPlexSans-Medium.ttf
IBMPlexSans-Bold.ttf
swmansion.ttf
UIBackgroundModes
fetch
remote-notification
UILaunchStoryboardName
SplashScreen
UIRequiredDeviceCapabilities
armv7
UIStatusBarStyle
UIStatusBarStyleLightContent
UISupportedInterfaceOrientations
UIInterfaceOrientationPortrait
UIViewControllerBasedStatusBarAppearance
diff --git a/native/redux/persist.js b/native/redux/persist.js
index e6f1e8fac..c9605d9e0 100644
--- a/native/redux/persist.js
+++ b/native/redux/persist.js
@@ -1,398 +1,398 @@
// @flow
import AsyncStorage from '@react-native-community/async-storage';
import invariant from 'invariant';
import { Platform } from 'react-native';
import Orientation from 'react-native-orientation-locker';
import { createMigrate } from 'redux-persist';
import { highestLocalIDSelector } from 'lib/selectors/local-id-selectors';
import { inconsistencyResponsesToReports } from 'lib/shared/report-utils';
import { getContainingThreadID, getCommunity } from 'lib/shared/thread-utils';
import { unshimMessageStore } from 'lib/shared/unshim-utils';
import { defaultEnabledApps } from 'lib/types/enabled-apps';
import { defaultCalendarFilters } from 'lib/types/filter-types';
import { messageTypes } from 'lib/types/message-types';
import type { ClientDBMessageStoreOperation } from 'lib/types/message-types';
import { defaultConnectionInfo } from 'lib/types/socket-types';
import { translateRawMessageInfoToClientDBMessageInfo } from 'lib/utils/message-ops-utils';
import { convertThreadStoreOperationsToClientDBOperations } from 'lib/utils/thread-ops-utils';
import { defaultNotifPermissionAlertInfo } from '../push/alerts';
import { defaultDeviceCameraInfo } from '../types/camera';
import { defaultGlobalThemeInfo } from '../types/themes';
import { migrateThreadStoreForEditThreadPermissions } from './edit-thread-permission-migration';
import type { AppState } from './state-types';
const migrations = {
[1]: (state: AppState) => ({
...state,
notifPermissionAlertInfo: defaultNotifPermissionAlertInfo,
}),
[2]: (state: AppState) => ({
...state,
messageSentFromRoute: [],
}),
[3]: state => ({
currentUserInfo: state.currentUserInfo,
entryStore: state.entryStore,
threadInfos: state.threadInfos,
userInfos: state.userInfos,
messageStore: {
...state.messageStore,
currentAsOf: state.currentAsOf,
},
updatesCurrentAsOf: state.currentAsOf,
cookie: state.cookie,
deviceToken: state.deviceToken,
urlPrefix: state.urlPrefix,
customServer: state.customServer,
threadIDsToNotifIDs: state.threadIDsToNotifIDs,
notifPermissionAlertInfo: state.notifPermissionAlertInfo,
messageSentFromRoute: state.messageSentFromRoute,
_persist: state._persist,
}),
[4]: (state: AppState) => ({
...state,
pingTimestamps: undefined,
activeServerRequests: undefined,
}),
[5]: (state: AppState) => ({
...state,
calendarFilters: defaultCalendarFilters,
}),
[6]: state => ({
...state,
threadInfos: undefined,
threadStore: {
threadInfos: state.threadInfos,
inconsistencyResponses: [],
},
}),
[7]: state => ({
...state,
lastUserInteraction: undefined,
sessionID: undefined,
entryStore: {
...state.entryStore,
inconsistencyResponses: [],
},
}),
[8]: (state: AppState) => ({
...state,
pingTimestamps: undefined,
activeServerRequests: undefined,
connection: defaultConnectionInfo(Platform.OS),
watchedThreadIDs: [],
entryStore: {
...state.entryStore,
actualizedCalendarQuery: undefined,
},
}),
[9]: (state: AppState) => ({
...state,
connection: {
...state.connection,
lateResponses: [],
},
}),
[10]: (state: AppState) => ({
...state,
nextLocalID: highestLocalIDSelector(state) + 1,
connection: {
...state.connection,
showDisconnectedBar: false,
},
messageStore: {
...state.messageStore,
local: {},
},
}),
[11]: (state: AppState) => ({
...state,
messageStore: unshimMessageStore(state.messageStore, [messageTypes.IMAGES]),
}),
[12]: (state: AppState) => ({
...state,
globalThemeInfo: defaultGlobalThemeInfo,
}),
[13]: (state: AppState) => ({
...state,
deviceCameraInfo: defaultDeviceCameraInfo,
deviceOrientation: Orientation.getInitialOrientation(),
}),
[14]: (state: AppState) => state,
[15]: state => ({
...state,
threadStore: {
...state.threadStore,
inconsistencyReports: inconsistencyResponsesToReports(
state.threadStore.inconsistencyResponses,
),
inconsistencyResponses: undefined,
},
entryStore: {
...state.entryStore,
inconsistencyReports: inconsistencyResponsesToReports(
state.entryStore.inconsistencyResponses,
),
inconsistencyResponses: undefined,
},
queuedReports: [],
}),
[16]: state => {
const result = {
...state,
messageSentFromRoute: undefined,
dataLoaded: !!state.currentUserInfo && !state.currentUserInfo.anonymous,
};
if (state.navInfo) {
result.navInfo = {
...state.navInfo,
navigationState: undefined,
};
}
return result;
},
[17]: state => ({
...state,
userInfos: undefined,
userStore: {
userInfos: state.userInfos,
inconsistencyResponses: [],
},
}),
[18]: state => ({
...state,
userStore: {
userInfos: state.userStore.userInfos,
inconsistencyReports: [],
},
}),
[19]: state => {
const threadInfos = {};
for (const threadID in state.threadStore.threadInfos) {
const threadInfo = state.threadStore.threadInfos[threadID];
const { visibilityRules, ...rest } = threadInfo;
threadInfos[threadID] = rest;
}
return {
...state,
threadStore: {
...state.threadStore,
threadInfos,
},
};
},
[20]: (state: AppState) => ({
...state,
messageStore: unshimMessageStore(state.messageStore, [
messageTypes.UPDATE_RELATIONSHIP,
]),
}),
[21]: (state: AppState) => ({
...state,
messageStore: unshimMessageStore(state.messageStore, [
messageTypes.CREATE_SIDEBAR,
messageTypes.SIDEBAR_SOURCE,
]),
}),
[22]: state => {
for (const key in state.drafts) {
const value = state.drafts[key];
global.CommCoreModule.updateDraft({
key,
text: value,
});
}
return {
...state,
drafts: undefined,
};
},
[23]: state => ({
...state,
globalThemeInfo: defaultGlobalThemeInfo,
}),
[24]: state => ({
...state,
enabledApps: defaultEnabledApps,
}),
[25]: state => ({
...state,
crashReportsEnabled: __DEV__,
}),
[26]: state => {
const { currentUserInfo } = state;
if (currentUserInfo.anonymous) {
return state;
}
return {
...state,
crashReportsEnabled: undefined,
currentUserInfo: {
id: currentUserInfo.id,
username: currentUserInfo.username,
},
enabledReports: {
crashReports: __DEV__,
inconsistencyReports: __DEV__,
mediaReports: __DEV__,
},
};
},
[27]: state => ({
...state,
queuedReports: undefined,
enabledReports: undefined,
threadStore: {
...state.threadStore,
inconsistencyReports: undefined,
},
entryStore: {
...state.entryStore,
inconsistencyReports: undefined,
},
reportStore: {
enabledReports: {
crashReports: __DEV__,
inconsistencyReports: __DEV__,
mediaReports: __DEV__,
},
queuedReports: [
...state.entryStore.inconsistencyReports,
...state.threadStore.inconsistencyReports,
...state.queuedReports,
],
},
}),
[28]: state => {
const threadParentToChildren = {};
for (const threadID in state.threadStore.threadInfos) {
const threadInfo = state.threadStore.threadInfos[threadID];
const parentThreadInfo = threadInfo.parentThreadID
? state.threadStore.threadInfos[threadInfo.parentThreadID]
: null;
const parentIndex = parentThreadInfo ? parentThreadInfo.id : '-1';
if (!threadParentToChildren[parentIndex]) {
threadParentToChildren[parentIndex] = [];
}
threadParentToChildren[parentIndex].push(threadID);
}
const rootIDs = threadParentToChildren['-1'];
if (!rootIDs) {
// This should never happen, but if it somehow does we'll let the state
// check mechanism resolve it...
return state;
}
const threadInfos = {};
const stack = [...rootIDs];
while (stack.length > 0) {
const threadID = stack.shift();
const threadInfo = state.threadStore.threadInfos[threadID];
const parentThreadInfo = threadInfo.parentThreadID
? threadInfos[threadInfo.parentThreadID]
: null;
threadInfos[threadID] = {
...threadInfo,
containingThreadID: getContainingThreadID(
parentThreadInfo,
threadInfo.type,
),
community: getCommunity(parentThreadInfo),
};
const children = threadParentToChildren[threadID];
if (children) {
stack.push(...children);
}
}
return { ...state, threadStore: { ...state.threadStore, threadInfos } };
},
[29]: (state: AppState) => {
const updatedThreadInfos = migrateThreadStoreForEditThreadPermissions(
state.threadStore.threadInfos,
);
return {
...state,
threadStore: {
...state.threadStore,
threadInfos: updatedThreadInfos,
},
};
},
[30]: (state: AppState) => {
const threadInfos = state.threadStore.threadInfos;
const operations = [
{
type: 'remove_all',
},
...Object.keys(threadInfos).map((id: string) => ({
type: 'replace',
payload: { id, threadInfo: threadInfos[id] },
})),
];
const processingResult: boolean = global.CommCoreModule.processThreadStoreOperationsSync(
convertThreadStoreOperationsToClientDBOperations(operations),
);
if (!processingResult) {
return { ...state, cookie: null };
}
return state;
},
[31]: (state: AppState) => {
const messages = state.messageStore.messages;
const operations: $ReadOnlyArray = [
{
type: 'remove_all',
},
...Object.keys(messages).map((id: string) => ({
type: 'replace',
payload: translateRawMessageInfoToClientDBMessageInfo(messages[id]),
})),
];
const processingResult: boolean = global.CommCoreModule.processMessageStoreOperationsSync(
operations,
);
if (!processingResult) {
return { ...state, cookie: null };
}
return state;
},
};
const persistConfig = {
key: 'root',
storage: AsyncStorage,
blacklist: [
'loadingStatuses',
'lifecycleState',
'dimensions',
'connectivity',
'deviceOrientation',
'frozen',
'threadStore',
],
debug: __DEV__,
version: 30,
migrate: (createMigrate(migrations, { debug: __DEV__ }): any),
timeout: ((__DEV__ ? 0 : undefined): number | void),
};
-const codeVersion = 128;
+const codeVersion = 129;
// This local exists to avoid a circular dependency where redux-setup needs to
// import all the navigation and screen stuff, but some of those screens want to
// access the persistor to purge its state.
let storedPersistor = null;
function setPersistor(persistor: *) {
storedPersistor = persistor;
}
function getPersistor(): empty {
invariant(storedPersistor, 'should be set');
return storedPersistor;
}
export { persistConfig, codeVersion, setPersistor, getPersistor };