Compare commits
4 Commits
develop
...
encode-aud
Author | SHA1 | Date |
---|---|---|
Gleidson Daniel | 84db57e405 | |
Gleidson Daniel Silva | a73afa9494 | |
Gleidson Daniel | 36677622e0 | |
Gleidson Daniel | 6d70253766 |
|
@ -1,12 +1,9 @@
|
||||||
defaults: &defaults
|
defaults: &defaults
|
||||||
working_directory: ~/repo
|
working_directory: ~/repo
|
||||||
|
|
||||||
orbs:
|
|
||||||
android: circleci/android@2.1.2
|
|
||||||
|
|
||||||
macos: &macos
|
macos: &macos
|
||||||
macos:
|
macos:
|
||||||
xcode: "14.2.0"
|
xcode: "13.3.0"
|
||||||
resource_class: large
|
resource_class: large
|
||||||
|
|
||||||
bash-env: &bash-env
|
bash-env: &bash-env
|
||||||
|
@ -54,14 +51,14 @@ save-gems-cache: &save-gems-cache
|
||||||
update-fastlane-ios: &update-fastlane-ios
|
update-fastlane-ios: &update-fastlane-ios
|
||||||
name: Update Fastlane
|
name: Update Fastlane
|
||||||
command: |
|
command: |
|
||||||
echo "ruby-2.7.7" > ~/.ruby-version
|
echo "ruby-2.6.4" > ~/.ruby-version
|
||||||
bundle install
|
bundle install
|
||||||
working_directory: ios
|
working_directory: ios
|
||||||
|
|
||||||
update-fastlane-android: &update-fastlane-android
|
update-fastlane-android: &update-fastlane-android
|
||||||
name: Update Fastlane
|
name: Update Fastlane
|
||||||
command: |
|
command: |
|
||||||
echo "ruby-2.7.7" > ~/.ruby-version
|
echo "ruby-2.6.4" > ~/.ruby-version
|
||||||
bundle install
|
bundle install
|
||||||
working_directory: android
|
working_directory: android
|
||||||
|
|
||||||
|
@ -121,26 +118,26 @@ commands:
|
||||||
if [[ $CIRCLE_JOB == "android-build-official" ]]; then
|
if [[ $CIRCLE_JOB == "android-build-official" ]]; then
|
||||||
echo -e "APPLICATION_ID=chat.rocket.android" >> ./gradle.properties
|
echo -e "APPLICATION_ID=chat.rocket.android" >> ./gradle.properties
|
||||||
echo -e "BugsnagAPIKey=$BUGSNAG_KEY_OFFICIAL" >> ./gradle.properties
|
echo -e "BugsnagAPIKey=$BUGSNAG_KEY_OFFICIAL" >> ./gradle.properties
|
||||||
echo $KEYSTORE_OFFICIAL_BASE64 | base64 --decode > ./app/$KEYSTORE_OFFICIAL
|
echo $CHAT_ROCKET_ANDROID_STORE_FILE_BASE64_JKS | base64 --decode > ./app/$KEYSTORE_OFFICIAL
|
||||||
echo -e "KEYSTORE=$KEYSTORE_OFFICIAL" >> ./gradle.properties
|
echo -e "KEYSTORE=$KEYSTORE_OFFICIAL" >> ./gradle.properties
|
||||||
echo -e "KEYSTORE_PASSWORD=$KEYSTORE_OFFICIAL_PASSWORD" >> ./gradle.properties
|
echo -e "KEYSTORE_PASSWORD=$CHAT_ROCKET_ANDROID_STORE_PASSWORD" >> ./gradle.properties
|
||||||
echo -e "KEY_ALIAS=$KEYSTORE_OFFICIAL_ALIAS" >> ./gradle.properties
|
echo -e "KEY_ALIAS=$CHAT_ROCKET_ANDROID_KEY_ALIAS" >> ./gradle.properties
|
||||||
echo -e "KEY_PASSWORD=$KEYSTORE_OFFICIAL_PASSWORD" >> ./gradle.properties
|
echo -e "KEY_PASSWORD=$CHAT_ROCKET_ANDROID_KEY_PASSWORD" >> ./gradle.properties
|
||||||
else
|
else
|
||||||
echo -e "APPLICATION_ID=chat.rocket.reactnative" >> ./gradle.properties
|
echo -e "APPLICATION_ID=chat.rocket.reactnative" >> ./gradle.properties
|
||||||
echo -e "BugsnagAPIKey=$BUGSNAG_KEY" >> ./gradle.properties
|
echo -e "BugsnagAPIKey=$BUGSNAG_KEY" >> ./gradle.properties
|
||||||
echo $KEYSTORE_EXPERIMENTAL_BASE64 | base64 --decode > ./app/$KEYSTORE_EXPERIMENTAL
|
echo $KEYSTORE_BASE64 | base64 --decode > ./app/$KEYSTORE
|
||||||
echo -e "KEYSTORE=$KEYSTORE_EXPERIMENTAL" >> ./gradle.properties
|
echo -e "KEYSTORE=$KEYSTORE" >> ./gradle.properties
|
||||||
echo -e "KEYSTORE_PASSWORD=$KEYSTORE_EXPERIMENTAL_PASSWORD" >> ./gradle.properties
|
echo -e "KEYSTORE_PASSWORD=$KEYSTORE_PASSWORD" >> ./gradle.properties
|
||||||
echo -e "KEY_ALIAS=$KEYSTORE_EXPERIMENTAL_ALIAS" >> ./gradle.properties
|
echo -e "KEY_ALIAS=$KEY_ALIAS" >> ./gradle.properties
|
||||||
echo -e "KEY_PASSWORD=$KEYSTORE_EXPERIMENTAL_PASSWORD" >> ./gradle.properties
|
echo -e "KEY_PASSWORD=$KEYSTORE_PASSWORD" >> ./gradle.properties
|
||||||
fi
|
fi
|
||||||
working_directory: android
|
working_directory: android
|
||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Set Google Services
|
name: Set Google Services
|
||||||
command: |
|
command: |
|
||||||
if [[ $GOOGLE_SERVICES_ANDROID ]]; then
|
if [[ $KEYSTORE ]]; then
|
||||||
echo $GOOGLE_SERVICES_ANDROID | base64 --decode > google-services.json
|
echo $GOOGLE_SERVICES_ANDROID | base64 --decode > google-services.json
|
||||||
fi
|
fi
|
||||||
working_directory: android/app
|
working_directory: android/app
|
||||||
|
@ -154,7 +151,7 @@ commands:
|
||||||
if [[ $CIRCLE_JOB == "android-build-experimental" || "android-automatic-build-experimental" ]]; then
|
if [[ $CIRCLE_JOB == "android-build-experimental" || "android-automatic-build-experimental" ]]; then
|
||||||
./gradlew bundleExperimentalPlayRelease
|
./gradlew bundleExperimentalPlayRelease
|
||||||
fi
|
fi
|
||||||
if [[ ! $GOOGLE_SERVICES_ANDROID ]]; then
|
if [[ ! $KEYSTORE ]]; then
|
||||||
./gradlew assembleExperimentalPlayDebug
|
./gradlew assembleExperimentalPlayDebug
|
||||||
fi
|
fi
|
||||||
working_directory: android
|
working_directory: android
|
||||||
|
@ -203,12 +200,8 @@ commands:
|
||||||
- run:
|
- run:
|
||||||
name: Set Google Services
|
name: Set Google Services
|
||||||
command: |
|
command: |
|
||||||
if [[ $APP_STORE_CONNECT_API_KEY_BASE64 ]]; then
|
if [[ $KEYSTORE ]]; then
|
||||||
if [[ $CIRCLE_JOB == "ios-build-official" ]]; then
|
echo $GOOGLE_SERVICES_IOS | base64 --decode > GoogleService-Info.plist
|
||||||
echo $GOOGLE_SERVICES_IOS | base64 --decode > GoogleService-Info.plist
|
|
||||||
else
|
|
||||||
echo $GOOGLE_SERVICES_IOS_EXPERIMENTAL | base64 --decode > GoogleService-Info.plist
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
working_directory: ios
|
working_directory: ios
|
||||||
- run:
|
- run:
|
||||||
|
@ -230,12 +223,12 @@ commands:
|
||||||
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL NO" ./NotificationService/Info.plist
|
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL NO" ./NotificationService/Info.plist
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $APP_STORE_CONNECT_API_KEY_BASE64 ]]; then
|
if [[ $APP_STORE_CONNECT_API_BASE64 ]]; then
|
||||||
echo $APP_STORE_CONNECT_API_KEY_BASE64 | base64 --decode > ./fastlane/app_store_connect_api_key.p8
|
echo $APP_STORE_CONNECT_API_BASE64 | base64 --decode > ./fastlane/app_store_connect_api_key.p8
|
||||||
if [[ $CIRCLE_JOB == "ios-build-official" ]]; then
|
if [[ $CIRCLE_JOB == "ios-build-official" ]]; then
|
||||||
bundle exec fastlane ios build_official
|
bundle exec fastlane ios build_official
|
||||||
else
|
else
|
||||||
if [[ $APP_STORE_CONNECT_API_KEY_BASE64 ]]; then
|
if [[ $KEYSTORE ]]; then
|
||||||
bundle exec fastlane ios build_experimental
|
bundle exec fastlane ios build_experimental
|
||||||
else
|
else
|
||||||
bundle exec fastlane ios build_fork
|
bundle exec fastlane ios build_fork
|
||||||
|
@ -325,19 +318,11 @@ commands:
|
||||||
- run:
|
- run:
|
||||||
name: Fastlane Tesflight Upload
|
name: Fastlane Tesflight Upload
|
||||||
command: |
|
command: |
|
||||||
echo $APP_STORE_CONNECT_API_KEY_BASE64 | base64 --decode > ./fastlane/app_store_connect_api_key.p8
|
echo $APP_STORE_CONNECT_API_BASE64 | base64 --decode > ./fastlane/app_store_connect_api_key.p8
|
||||||
bundle exec fastlane ios beta official:<< parameters.official >>
|
bundle exec fastlane ios beta official:<< parameters.official >>
|
||||||
working_directory: ios
|
working_directory: ios
|
||||||
- save_cache: *save-gems-cache
|
- save_cache: *save-gems-cache
|
||||||
|
|
||||||
create-e2e-account-file:
|
|
||||||
description: "Create e2e account file"
|
|
||||||
steps:
|
|
||||||
- run:
|
|
||||||
command: |
|
|
||||||
echo $E2E_ACCOUNT | base64 --decode > ./e2e_account.ts
|
|
||||||
working_directory: e2e
|
|
||||||
|
|
||||||
version: 2.1
|
version: 2.1
|
||||||
|
|
||||||
# EXECUTORS
|
# EXECUTORS
|
||||||
|
@ -449,94 +434,6 @@ jobs:
|
||||||
- upload-to-google-play-beta:
|
- upload-to-google-play-beta:
|
||||||
official: true
|
official: true
|
||||||
|
|
||||||
e2e-build-android:
|
|
||||||
<<: *defaults
|
|
||||||
executor:
|
|
||||||
name: android/android-machine
|
|
||||||
resource-class: xlarge
|
|
||||||
tag: 2022.12.1
|
|
||||||
environment:
|
|
||||||
<<: *android-env
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- restore_cache: *restore-npm-cache-linux
|
|
||||||
- run: *install-npm-modules
|
|
||||||
- save_cache: *save-npm-cache-linux
|
|
||||||
- restore_cache: *restore-gradle-cache
|
|
||||||
- run:
|
|
||||||
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 "FLIPPER_VERSION=0.125.0" >> ./gradle.properties
|
|
||||||
echo -e "VERSIONCODE=$CIRCLE_BUILD_NUM" >> ./gradle.properties
|
|
||||||
echo -e "APPLICATION_ID=chat.rocket.reactnative" >> ./gradle.properties
|
|
||||||
echo -e "BugsnagAPIKey=$BUGSNAG_KEY" >> ./gradle.properties
|
|
||||||
echo $KEYSTORE_EXPERIMENTAL_BASE64 | base64 --decode > ./app/$KEYSTORE_EXPERIMENTAL
|
|
||||||
echo -e "KEYSTORE=$KEYSTORE_EXPERIMENTAL" >> ./gradle.properties
|
|
||||||
echo -e "KEYSTORE_PASSWORD=$KEYSTORE_EXPERIMENTAL_PASSWORD" >> ./gradle.properties
|
|
||||||
echo -e "KEY_ALIAS=$KEYSTORE_EXPERIMENTAL_ALIAS" >> ./gradle.properties
|
|
||||||
echo -e "KEY_PASSWORD=$KEYSTORE_EXPERIMENTAL_PASSWORD" >> ./gradle.properties
|
|
||||||
working_directory: android
|
|
||||||
- run:
|
|
||||||
name: Build Android
|
|
||||||
command: |
|
|
||||||
echo "RUNNING_E2E_TESTS=true" > ./.env
|
|
||||||
yarn e2e:android-build
|
|
||||||
- save_cache: *save-gradle-cache
|
|
||||||
- store_artifacts:
|
|
||||||
path: android/app/build/outputs/apk/experimentalPlay/release/app-experimental-play-release.apk
|
|
||||||
- store_artifacts:
|
|
||||||
path: android/app/build/outputs/apk/androidTest/experimentalPlay/release/app-experimental-play-release-androidTest.apk
|
|
||||||
- persist_to_workspace:
|
|
||||||
root: /home/circleci/repo
|
|
||||||
paths:
|
|
||||||
- android/app/build/outputs/apk/
|
|
||||||
|
|
||||||
e2e-test-android:
|
|
||||||
<<: *defaults
|
|
||||||
executor:
|
|
||||||
name: android/android-machine
|
|
||||||
resource-class: xlarge
|
|
||||||
tag: 2022.12.1
|
|
||||||
parallelism: 4
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- attach_workspace:
|
|
||||||
at: /home/circleci/repo
|
|
||||||
- restore_cache: *restore-npm-cache-linux
|
|
||||||
- run: *install-npm-modules
|
|
||||||
- save_cache: *save-npm-cache-linux
|
|
||||||
- run: mkdir ~/junit
|
|
||||||
- create-e2e-account-file
|
|
||||||
- android/create-avd:
|
|
||||||
avd-name: Pixel_API_31_AOSP
|
|
||||||
install: true
|
|
||||||
system-image: system-images;android-31;default;x86_64
|
|
||||||
- run:
|
|
||||||
name: Setup emulator
|
|
||||||
command: |
|
|
||||||
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
|
|
||||||
- run:
|
|
||||||
name: Run Detox Tests
|
|
||||||
command: |
|
|
||||||
TEST=$(circleci tests glob "e2e/tests/**/*.ts" | circleci tests split --split-by=timings)
|
|
||||||
yarn e2e:android-test $TEST
|
|
||||||
- store_artifacts:
|
|
||||||
path: artifacts
|
|
||||||
- run:
|
|
||||||
command: cp junit.xml ~/junit/
|
|
||||||
when: always
|
|
||||||
- store_test_results:
|
|
||||||
path: ~/junit
|
|
||||||
- store_artifacts:
|
|
||||||
path: ~/junit
|
|
||||||
|
|
||||||
# iOS builds
|
# iOS builds
|
||||||
ios-build-experimental:
|
ios-build-experimental:
|
||||||
executor: mac-env
|
executor: mac-env
|
||||||
|
@ -560,89 +457,11 @@ jobs:
|
||||||
- upload-to-testflight:
|
- upload-to-testflight:
|
||||||
official: true
|
official: true
|
||||||
|
|
||||||
e2e-build-ios:
|
|
||||||
executor: mac-env
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- restore_cache: *restore-gems-cache
|
|
||||||
- restore_cache: *restore-npm-cache-mac
|
|
||||||
- run: *install-npm-modules
|
|
||||||
- run: *update-fastlane-ios
|
|
||||||
- save_cache: *save-npm-cache-mac
|
|
||||||
- save_cache: *save-gems-cache
|
|
||||||
- manage-pods
|
|
||||||
- run:
|
|
||||||
name: Configure Detox
|
|
||||||
command: |
|
|
||||||
brew tap wix/brew
|
|
||||||
brew install applesimutils
|
|
||||||
- run:
|
|
||||||
name: Build
|
|
||||||
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
|
|
||||||
yarn detox clean-framework-cache && yarn detox build-framework-cache
|
|
||||||
echo "RUNNING_E2E_TESTS=true" > ./.env
|
|
||||||
yarn e2e:ios-build
|
|
||||||
- persist_to_workspace:
|
|
||||||
root: /Users/distiller/project
|
|
||||||
paths:
|
|
||||||
- ios/build/Build/Products/Release-iphonesimulator/Rocket.Chat Experimental.app
|
|
||||||
|
|
||||||
e2e-test-ios:
|
|
||||||
executor: mac-env
|
|
||||||
parallelism: 5
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- attach_workspace:
|
|
||||||
at: /Users/distiller/project
|
|
||||||
- restore_cache: *restore-npm-cache-mac
|
|
||||||
- run: *install-npm-modules
|
|
||||||
- save_cache: *save-npm-cache-mac
|
|
||||||
- run: mkdir ~/junit
|
|
||||||
- run:
|
|
||||||
name: Configure Detox
|
|
||||||
command: |
|
|
||||||
brew tap wix/brew
|
|
||||||
brew install applesimutils
|
|
||||||
yarn detox clean-framework-cache && yarn detox build-framework-cache
|
|
||||||
- create-e2e-account-file
|
|
||||||
- run:
|
|
||||||
name: Run tests
|
|
||||||
command: |
|
|
||||||
TEST=$(circleci tests glob "e2e/tests/**/*.ts" | circleci tests split --split-by=timings)
|
|
||||||
yarn e2e:ios-test $TEST
|
|
||||||
- store_artifacts:
|
|
||||||
path: artifacts
|
|
||||||
- run:
|
|
||||||
command: cp junit.xml ~/junit/
|
|
||||||
when: always
|
|
||||||
- store_test_results:
|
|
||||||
path: ~/junit
|
|
||||||
- store_artifacts:
|
|
||||||
path: ~/junit
|
|
||||||
|
|
||||||
workflows:
|
workflows:
|
||||||
build-and-test:
|
build-and-test:
|
||||||
jobs:
|
jobs:
|
||||||
- lint-testunit
|
- lint-testunit
|
||||||
|
|
||||||
# E2E tests
|
|
||||||
- e2e-hold:
|
|
||||||
type: approval
|
|
||||||
- e2e-build-ios:
|
|
||||||
requires:
|
|
||||||
- e2e-hold
|
|
||||||
- e2e-test-ios:
|
|
||||||
requires:
|
|
||||||
- e2e-build-ios
|
|
||||||
- e2e-build-android:
|
|
||||||
requires:
|
|
||||||
- e2e-hold
|
|
||||||
- e2e-test-android:
|
|
||||||
requires:
|
|
||||||
- e2e-build-android
|
|
||||||
|
|
||||||
# iOS Experimental
|
# iOS Experimental
|
||||||
- ios-hold-build-experimental:
|
- ios-hold-build-experimental:
|
||||||
type: approval
|
type: approval
|
||||||
|
|
91
.detoxrc.js
91
.detoxrc.js
|
@ -1,91 +0,0 @@
|
||||||
/** @type {Detox.DetoxConfig} */
|
|
||||||
module.exports = {
|
|
||||||
testRunner: {
|
|
||||||
args: {
|
|
||||||
$0: 'jest',
|
|
||||||
config: 'e2e/jest.config.js'
|
|
||||||
},
|
|
||||||
retries: process.env.CI ? 3 : 0
|
|
||||||
},
|
|
||||||
artifacts: {
|
|
||||||
plugins: {
|
|
||||||
screenshot: 'failing',
|
|
||||||
video: 'failing',
|
|
||||||
uiHierarchy: 'enabled'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
apps: {
|
|
||||||
'ios.debug': {
|
|
||||||
type: 'ios.app',
|
|
||||||
binaryPath: 'ios/build/Build/Products/Debug-iphonesimulator/Rocket.Chat Experimental.app',
|
|
||||||
build:
|
|
||||||
'xcodebuild -workspace ios/RocketChatRN.xcworkspace -scheme RocketChatRN -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build'
|
|
||||||
},
|
|
||||||
'ios.release': {
|
|
||||||
type: 'ios.app',
|
|
||||||
binaryPath: 'ios/build/Build/Products/Release-iphonesimulator/Rocket.Chat Experimental.app',
|
|
||||||
build:
|
|
||||||
'xcodebuild -workspace ios/RocketChatRN.xcworkspace -scheme RocketChatRN -configuration Release -sdk iphonesimulator -derivedDataPath ios/build'
|
|
||||||
},
|
|
||||||
'android.debug': {
|
|
||||||
type: 'android.apk',
|
|
||||||
binaryPath: 'android/app/build/outputs/apk/experimentalPlay/debug/app-experimental-play-debug.apk',
|
|
||||||
build:
|
|
||||||
'cd android ; ./gradlew assembleExperimentalPlayDebug assembleExperimentalPlayDebugAndroidTest -DtestBuildType=debug ; cd -',
|
|
||||||
reversePorts: [8081]
|
|
||||||
},
|
|
||||||
'android.release': {
|
|
||||||
type: 'android.apk',
|
|
||||||
binaryPath: 'android/app/build/outputs/apk/experimentalPlay/release/app-experimental-play-release.apk',
|
|
||||||
build:
|
|
||||||
'cd android ; ./gradlew assembleExperimentalPlayRelease assembleExperimentalPlayReleaseAndroidTest -DtestBuildType=release ; cd -'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
devices: {
|
|
||||||
simulator: {
|
|
||||||
type: 'ios.simulator',
|
|
||||||
device: {
|
|
||||||
type: 'iPhone 14'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
attached: {
|
|
||||||
type: 'android.attached',
|
|
||||||
device: {
|
|
||||||
adbName: '.*'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
emulator: {
|
|
||||||
type: 'android.emulator',
|
|
||||||
device: {
|
|
||||||
avdName: 'Pixel_API_31_AOSP'
|
|
||||||
},
|
|
||||||
headless: process.env.CI ? true : false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
configurations: {
|
|
||||||
'ios.sim.debug': {
|
|
||||||
device: 'simulator',
|
|
||||||
app: 'ios.debug'
|
|
||||||
},
|
|
||||||
'ios.sim.release': {
|
|
||||||
device: 'simulator',
|
|
||||||
app: 'ios.release'
|
|
||||||
},
|
|
||||||
'android.att.debug': {
|
|
||||||
device: 'attached',
|
|
||||||
app: 'android.debug'
|
|
||||||
},
|
|
||||||
'android.att.release': {
|
|
||||||
device: 'attached',
|
|
||||||
app: 'android.release'
|
|
||||||
},
|
|
||||||
'android.emu.debug': {
|
|
||||||
device: 'emulator',
|
|
||||||
app: 'android.debug'
|
|
||||||
},
|
|
||||||
'android.emu.release': {
|
|
||||||
device: 'emulator',
|
|
||||||
app: 'android.release'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
15
.eslintrc.js
15
.eslintrc.js
|
@ -2,7 +2,7 @@ module.exports = {
|
||||||
settings: {
|
settings: {
|
||||||
'import/resolver': {
|
'import/resolver': {
|
||||||
node: {
|
node: {
|
||||||
extensions: ['.ts', '.tsx', '.js', '.ios.js', '.android.js', '.native.js', '.ios.tsx', '.android.tsx']
|
extensions: ['.ts', '.tsx', '.js', '.ios.js', '.android.js', '.native.js']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -240,8 +240,19 @@ module.exports = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
files: ['e2e/**'],
|
files: ['e2e/**'],
|
||||||
|
globals: {
|
||||||
|
by: true,
|
||||||
|
detox: true,
|
||||||
|
device: true,
|
||||||
|
element: true,
|
||||||
|
waitFor: true
|
||||||
|
},
|
||||||
rules: {
|
rules: {
|
||||||
'no-await-in-loop': 0
|
'import/no-extraneous-dependencies': 0,
|
||||||
|
'no-await-in-loop': 0,
|
||||||
|
'no-restricted-syntax': 0,
|
||||||
|
// TODO: remove this rule when update Detox to 20 and test if the namespace Detox is available
|
||||||
|
'no-undef': 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,5 +3,5 @@ updates:
|
||||||
- package-ecosystem: "npm"
|
- package-ecosystem: "npm"
|
||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: "daily"
|
||||||
open-pull-requests-limit: 25
|
open-pull-requests-limit: 25
|
|
@ -67,6 +67,5 @@ e2e/docker/rc_test_env/docker-compose.yml
|
||||||
e2e/docker/data/db
|
e2e/docker/data/db
|
||||||
e2e/e2e_account.js
|
e2e/e2e_account.js
|
||||||
e2e/e2e_account.ts
|
e2e/e2e_account.ts
|
||||||
junit.xml
|
|
||||||
|
|
||||||
*.p8
|
*.p8
|
|
@ -1 +1 @@
|
||||||
2.7.7
|
2.7.4
|
||||||
|
|
2
Gemfile
2
Gemfile
|
@ -1,4 +1,4 @@
|
||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
|
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
|
||||||
ruby '2.7.7'
|
ruby '2.7.4'
|
||||||
gem 'cocoapods', '~> 1.11', '>= 1.11.2'
|
gem 'cocoapods', '~> 1.11', '>= 1.11.2'
|
|
@ -1,13 +1,13 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
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 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\\":2,\\"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},\\"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\\":2,\\"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},\\"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\\":2,\\"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},\\"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\\":2,\\"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},\\"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\\":2,\\"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},\\"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\\":2,\\"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!\\"]}]}"`;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// 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,\\"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\\":2,\\"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,\\"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\\":2,\\"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,\\"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\\":2,\\"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,\\"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\\":2,\\"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,\\"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\\":2,\\"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\\"]}]}]}]}]}"`;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
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 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\\":2,\\"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\\":2,\\"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\\"]}]}]}]"`;
|
exports[`Storyshots Login Services Service List 1`] = `"[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"borderRadius\\":2,\\"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\\":2,\\"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\\":2,\\"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\\":2,\\"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
|
@ -1,3 +1,3 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`Storyshots SearchBox Basic 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"testID\\":\\"searchbox\\",\\"style\\":{\\"backgroundColor\\":\\"#ffffff\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"marginBottom\\":10},{\\"margin\\":16,\\"marginBottom\\":16}]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"position\\":\\"relative\\",\\"justifyContent\\":\\"center\\"}},\\"children\\":[{\\"type\\":\\"TextInput\\",\\"props\\":{\\"style\\":[{\\"color\\":\\"#0d0e12\\"},[{\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"400\\",\\"height\\":48,\\"fontSize\\":16,\\"paddingHorizontal\\":16,\\"paddingVertical\\":10,\\"borderWidth\\":1,\\"borderRadius\\":4},null,{\\"paddingRight\\":45},{\\"backgroundColor\\":\\"#ffffff\\",\\"borderColor\\":\\"#cbcbcc\\",\\"color\\":\\"#0d0e12\\"},null,null],{\\"textAlign\\":\\"auto\\"}],\\"placeholderTextColor\\":\\"#9ca2a8\\",\\"keyboardAppearance\\":\\"light\\",\\"autoCorrect\\":false,\\"autoCapitalize\\":\\"none\\",\\"underlineColorAndroid\\":\\"transparent\\",\\"accessibilityLabel\\":\\"Search\\",\\"placeholder\\":\\"Search\\",\\"value\\":\\"\\",\\"blurOnSubmit\\":true,\\"returnKeyType\\":\\"search\\"},\\"children\\":null},{\\"type\\":\\"Text\\",\\"props\\":{\\"selectable\\":false,\\"allowFontScaling\\":false,\\"style\\":[{\\"fontSize\\":20,\\"color\\":\\"#2f343d\\"},[{\\"position\\":\\"absolute\\"},{\\"right\\":12}],{\\"fontFamily\\":\\"custom\\",\\"fontWeight\\":\\"normal\\",\\"fontStyle\\":\\"normal\\"},{}]},\\"children\\":[\\"\\"]}]}]}]}"`;
|
exports[`Storyshots SearchBox Basic 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"testID\\":\\"searchbox\\",\\"style\\":{\\"backgroundColor\\":\\"#ffffff\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"marginBottom\\":10},{\\"margin\\":16,\\"marginBottom\\":16}]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"position\\":\\"relative\\",\\"justifyContent\\":\\"center\\"}},\\"children\\":[{\\"type\\":\\"TextInput\\",\\"props\\":{\\"style\\":[{\\"color\\":\\"#0d0e12\\"},[{\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Inter\\",\\"fontWeight\\":\\"400\\",\\"height\\":48,\\"fontSize\\":16,\\"paddingHorizontal\\":16,\\"paddingVertical\\":10,\\"borderWidth\\":2,\\"borderRadius\\":2},null,{\\"paddingRight\\":45},{\\"backgroundColor\\":\\"#ffffff\\",\\"borderColor\\":\\"#cbcbcc\\",\\"color\\":\\"#0d0e12\\"},null,null],{\\"textAlign\\":\\"auto\\"}],\\"placeholderTextColor\\":\\"#9ca2a8\\",\\"keyboardAppearance\\":\\"light\\",\\"autoCorrect\\":false,\\"autoCapitalize\\":\\"none\\",\\"underlineColorAndroid\\":\\"transparent\\",\\"accessibilityLabel\\":\\"Search\\",\\"placeholder\\":\\"Search\\",\\"value\\":\\"\\",\\"blurOnSubmit\\":true,\\"returnKeyType\\":\\"search\\"},\\"children\\":null},{\\"type\\":\\"Text\\",\\"props\\":{\\"selectable\\":false,\\"allowFontScaling\\":false,\\"style\\":[{\\"fontSize\\":20,\\"color\\":\\"#2f343d\\"},[{\\"position\\":\\"absolute\\"},{\\"right\\":12}],{\\"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
File diff suppressed because one or more lines are too long
|
@ -147,7 +147,7 @@ android {
|
||||||
minSdkVersion rootProject.ext.minSdkVersion
|
minSdkVersion rootProject.ext.minSdkVersion
|
||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||||
versionCode VERSIONCODE as Integer
|
versionCode VERSIONCODE as Integer
|
||||||
versionName "4.37.0"
|
versionName "4.33.0"
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
if (!isFoss) {
|
if (!isFoss) {
|
||||||
manifestPlaceholders = [BugsnagAPIKey: BugsnagAPIKey as String]
|
manifestPlaceholders = [BugsnagAPIKey: BugsnagAPIKey as String]
|
||||||
|
@ -250,7 +250,6 @@ android {
|
||||||
release {
|
release {
|
||||||
minifyEnabled enableProguardInReleaseBuilds
|
minifyEnabled enableProguardInReleaseBuilds
|
||||||
setProguardFiles([getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'])
|
setProguardFiles([getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'])
|
||||||
proguardFile "${rootProject.projectDir}/../node_modules/detox/android/detox/proguard-rules-app.pro"
|
|
||||||
signingConfig signingConfigs.release
|
signingConfig signingConfigs.release
|
||||||
if (!isFoss) {
|
if (!isFoss) {
|
||||||
firebaseCrashlytics {
|
firebaseCrashlytics {
|
||||||
|
@ -269,11 +268,6 @@ android {
|
||||||
// pickFirst '**/x86_64/libc++_shared.so'
|
// pickFirst '**/x86_64/libc++_shared.so'
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// FIXME: Remove when we update RN
|
|
||||||
packagingOptions {
|
|
||||||
pickFirst '**/*.so'
|
|
||||||
}
|
|
||||||
|
|
||||||
// applicationVariants are e.g. debug, release
|
// applicationVariants are e.g. debug, release
|
||||||
|
|
||||||
flavorDimensions "app", "type"
|
flavorDimensions "app", "type"
|
||||||
|
@ -286,6 +280,10 @@ android {
|
||||||
dimension = "app"
|
dimension = "app"
|
||||||
buildConfigField "boolean", "IS_OFFICIAL", "false"
|
buildConfigField "boolean", "IS_OFFICIAL", "false"
|
||||||
}
|
}
|
||||||
|
e2e {
|
||||||
|
dimension = "app"
|
||||||
|
buildConfigField "boolean", "IS_OFFICIAL", "false"
|
||||||
|
}
|
||||||
foss {
|
foss {
|
||||||
dimension = "type"
|
dimension = "type"
|
||||||
buildConfigField "boolean", "FDROID_BUILD", "true"
|
buildConfigField "boolean", "FDROID_BUILD", "true"
|
||||||
|
@ -313,6 +311,16 @@ android {
|
||||||
java.srcDirs = ['src/main/java', 'src/play/java']
|
java.srcDirs = ['src/main/java', 'src/play/java']
|
||||||
manifest.srcFile 'src/play/AndroidManifest.xml'
|
manifest.srcFile 'src/play/AndroidManifest.xml'
|
||||||
}
|
}
|
||||||
|
e2ePlayDebug {
|
||||||
|
java.srcDirs = ['src/main/java', 'src/play/java']
|
||||||
|
res.srcDirs = ['src/experimental/res']
|
||||||
|
manifest.srcFile 'src/play/AndroidManifest.xml'
|
||||||
|
}
|
||||||
|
e2ePlayRelease {
|
||||||
|
java.srcDirs = ['src/main/java', 'src/play/java']
|
||||||
|
res.srcDirs = ['src/experimental/res']
|
||||||
|
manifest.srcFile 'src/play/AndroidManifest.xml'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
applicationVariants.all { variant ->
|
applicationVariants.all { variant ->
|
||||||
|
@ -349,6 +357,9 @@ dependencies {
|
||||||
playImplementation project(':@react-native-firebase_app')
|
playImplementation project(':@react-native-firebase_app')
|
||||||
playImplementation project(':@react-native-firebase_analytics')
|
playImplementation project(':@react-native-firebase_analytics')
|
||||||
playImplementation project(':@react-native-firebase_crashlytics')
|
playImplementation project(':@react-native-firebase_crashlytics')
|
||||||
|
implementation(project(':react-native-jitsi-meet')) { // https://github.com/skrafft/react-native-jitsi-meet#side-note
|
||||||
|
exclude group: 'com.facebook.react',module:'react-native-svg'
|
||||||
|
}
|
||||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||||
|
|
||||||
//noinspection GradleDynamicVersion
|
//noinspection GradleDynamicVersion
|
||||||
|
@ -377,9 +388,8 @@ dependencies {
|
||||||
implementation "com.github.bumptech.glide:glide:4.9.0"
|
implementation "com.github.bumptech.glide:glide:4.9.0"
|
||||||
annotationProcessor "com.github.bumptech.glide:compiler:4.9.0"
|
annotationProcessor "com.github.bumptech.glide:compiler:4.9.0"
|
||||||
implementation "com.tencent:mmkv-static:1.2.10"
|
implementation "com.tencent:mmkv-static:1.2.10"
|
||||||
androidTestImplementation('com.wix:detox:+')
|
androidTestImplementation('com.wix:detox:+') { transitive = true }
|
||||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
androidTestImplementation 'junit:junit:4.12'
|
||||||
implementation 'com.facebook.soloader:soloader:0.10.4'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNewArchitectureEnabled()) {
|
if (isNewArchitectureEnabled()) {
|
||||||
|
|
|
@ -18,7 +18,7 @@ public class DetoxTest {
|
||||||
@Rule
|
@Rule
|
||||||
// Replace 'MainActivity' with the value of android:name entry in
|
// Replace 'MainActivity' with the value of android:name entry in
|
||||||
// <activity> in AndroidManifest.xml
|
// <activity> in AndroidManifest.xml
|
||||||
public ActivityTestRule<chat.rocket.reactnative.MainActivity> mActivityRule = new ActivityTestRule<>(chat.rocket.reactnative.MainActivity.class, false, false);
|
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class, false, false);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void runDetoxTests() {
|
public void runDetoxTests() {
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package chat.rocket.reactnative;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.facebook.react.ReactInstanceManager;
|
||||||
|
|
||||||
|
public class MainDebugApplication extends MainApplication {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
||||||
|
ReactNativeFlipper.initializeFlipper(context, reactInstanceManager);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<network-security-config xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
<base-config cleartextTrafficPermitted="true">
|
||||||
|
<trust-anchors>
|
||||||
|
<certificates src="system" />
|
||||||
|
<certificates src="user"
|
||||||
|
tools:ignore="AcceptsUserCertificates" />
|
||||||
|
</trust-anchors>
|
||||||
|
</base-config>
|
||||||
|
</network-security-config>
|
|
@ -5,15 +5,6 @@
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
|
||||||
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
|
|
||||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
|
||||||
<uses-permission android:name="android.permission.VIDEO_CAPTURE" />
|
|
||||||
<uses-permission android:name="android.permission.AUDIO_CAPTURE" />
|
|
||||||
|
|
||||||
<!-- permissions related to jitsi call -->
|
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name="chat.rocket.reactnative.MainApplication"
|
android:name="chat.rocket.reactnative.MainApplication"
|
||||||
android:allowBackup="false"
|
android:allowBackup="false"
|
||||||
|
@ -23,7 +14,6 @@
|
||||||
android:requestLegacyExternalStorage="true"
|
android:requestLegacyExternalStorage="true"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/BootTheme"
|
android:theme="@style/BootTheme"
|
||||||
android:hardwareAccelerated="true"
|
|
||||||
tools:replace="android:allowBackup">
|
tools:replace="android:allowBackup">
|
||||||
<activity
|
<activity
|
||||||
android:name="chat.rocket.reactnative.MainActivity"
|
android:name="chat.rocket.reactnative.MainActivity"
|
||||||
|
@ -79,10 +69,5 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
</application>
|
</application>
|
||||||
<queries>
|
|
||||||
<package android:name="org.jitsi.meet" />
|
|
||||||
<intent>
|
|
||||||
<action android:name="android.intent.action.SEND" />
|
|
||||||
</intent>
|
|
||||||
</queries>
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
Binary file not shown.
|
@ -9,16 +9,13 @@ import com.facebook.react.ReactApplication;
|
||||||
import com.facebook.react.ReactNativeHost;
|
import com.facebook.react.ReactNativeHost;
|
||||||
import com.facebook.react.ReactPackage;
|
import com.facebook.react.ReactPackage;
|
||||||
import com.facebook.react.config.ReactFeatureFlags;
|
import com.facebook.react.config.ReactFeatureFlags;
|
||||||
import com.facebook.react.ReactInstanceManager;
|
|
||||||
import com.facebook.soloader.SoLoader;
|
import com.facebook.soloader.SoLoader;
|
||||||
import com.reactnativecommunity.viewpager.RNCViewPagerPackage;
|
import com.reactnativecommunity.viewpager.RNCViewPagerPackage;
|
||||||
import com.facebook.react.bridge.JSIModulePackage;
|
import com.facebook.react.bridge.JSIModulePackage;
|
||||||
import com.swmansion.reanimated.ReanimatedJSIModulePackage;
|
import com.swmansion.reanimated.ReanimatedJSIModulePackage;
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import expo.modules.ApplicationLifecycleDispatcher;
|
import expo.modules.ApplicationLifecycleDispatcher;
|
||||||
import expo.modules.ReactNativeHostWrapper;
|
import expo.modules.ReactNativeHostWrapper;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -79,7 +76,6 @@ public class MainApplication extends Application implements ReactApplication {
|
||||||
// If you opted-in for the New Architecture, we enable the TurboModule system
|
// If you opted-in for the New Architecture, we enable the TurboModule system
|
||||||
ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
|
ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
|
||||||
SoLoader.init(this, /* native exopackage */ false);
|
SoLoader.init(this, /* native exopackage */ false);
|
||||||
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
|
||||||
ApplicationLifecycleDispatcher.onApplicationCreate(this);
|
ApplicationLifecycleDispatcher.onApplicationCreate(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,35 +84,4 @@ public class MainApplication extends Application implements ReactApplication {
|
||||||
super.onConfigurationChanged(newConfig);
|
super.onConfigurationChanged(newConfig);
|
||||||
ApplicationLifecycleDispatcher.onConfigurationChanged(this, 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,4 @@
|
||||||
tools:ignore="AcceptsUserCertificates" />
|
tools:ignore="AcceptsUserCertificates" />
|
||||||
</trust-anchors>
|
</trust-anchors>
|
||||||
</base-config>
|
</base-config>
|
||||||
<domain-config cleartextTrafficPermitted="true">
|
|
||||||
<domain includeSubdomains="true">10.0.2.2</domain>
|
|
||||||
<domain includeSubdomains="true">localhost</domain>
|
|
||||||
</domain-config>
|
|
||||||
</network-security-config>
|
</network-security-config>
|
|
@ -1,5 +1,9 @@
|
||||||
import org.apache.tools.ant.taskdefs.condition.Os
|
import org.apache.tools.ant.taskdefs.condition.Os
|
||||||
|
|
||||||
|
def safeExtGet(prop, fallback) {
|
||||||
|
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
||||||
|
}
|
||||||
|
|
||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
buildscript {
|
buildscript {
|
||||||
def taskRequests = getGradle().getStartParameter().getTaskRequests().toString().toLowerCase()
|
def taskRequests = getGradle().getStartParameter().getTaskRequests().toString().toLowerCase()
|
||||||
|
@ -7,7 +11,7 @@ buildscript {
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
buildToolsVersion = "31.0.0"
|
buildToolsVersion = "31.0.0"
|
||||||
minSdkVersion = 23
|
minSdkVersion = 24
|
||||||
compileSdkVersion = 31
|
compileSdkVersion = 31
|
||||||
targetSdkVersion = 31
|
targetSdkVersion = 31
|
||||||
if (System.properties['os.arch'] == "aarch64") {
|
if (System.properties['os.arch'] == "aarch64") {
|
||||||
|
@ -22,6 +26,9 @@ buildscript {
|
||||||
kotlinVersion = '1.6.10'
|
kotlinVersion = '1.6.10'
|
||||||
supportLibVersion = "28.0.0"
|
supportLibVersion = "28.0.0"
|
||||||
libre_build = !(isPlay.toBoolean())
|
libre_build = !(isPlay.toBoolean())
|
||||||
|
jitsi_url = "https://github.com/RocketChat/jitsi-maven-repository/raw/master/releases"
|
||||||
|
jitsi_version = "3.7.0"
|
||||||
|
ffmpegKitPackage = "audio"
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
@ -62,6 +69,9 @@ allprojects {
|
||||||
url "$rootDir/../node_modules/detox/Detox-android"
|
url "$rootDir/../node_modules/detox/Detox-android"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maven {
|
||||||
|
url jitsi_url
|
||||||
|
}
|
||||||
mavenCentral {
|
mavenCentral {
|
||||||
content {
|
content {
|
||||||
excludeGroup "com.facebook.react"
|
excludeGroup "com.facebook.react"
|
||||||
|
@ -71,38 +81,5 @@ allprojects {
|
||||||
google()
|
google()
|
||||||
maven { url 'https://maven.google.com' }
|
maven { url 'https://maven.google.com' }
|
||||||
maven { url 'https://www.jitpack.io' }
|
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -23,7 +23,7 @@ android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
|
|
||||||
# Version of flipper SDK to use with React Native
|
# Version of flipper SDK to use with React Native
|
||||||
FLIPPER_VERSION=0.175.0
|
FLIPPER_VERSION=0.125.0
|
||||||
|
|
||||||
# Use this property to specify which architecture you want to build.
|
# Use this property to specify which architecture you want to build.
|
||||||
# You can also override it from the CLI using
|
# You can also override it from the CLI using
|
||||||
|
|
|
@ -28,9 +28,7 @@ export const ROOM = createRequestTypes('ROOM', [
|
||||||
'DELETE',
|
'DELETE',
|
||||||
'REMOVED',
|
'REMOVED',
|
||||||
'FORWARD',
|
'FORWARD',
|
||||||
'USER_TYPING',
|
'USER_TYPING'
|
||||||
'HISTORY_REQUEST',
|
|
||||||
'HISTORY_FINISHED'
|
|
||||||
]);
|
]);
|
||||||
export const INQUIRY = createRequestTypes('INQUIRY', [
|
export const INQUIRY = createRequestTypes('INQUIRY', [
|
||||||
...defaultTypes,
|
...defaultTypes,
|
||||||
|
@ -40,14 +38,7 @@ export const INQUIRY = createRequestTypes('INQUIRY', [
|
||||||
'QUEUE_UPDATE',
|
'QUEUE_UPDATE',
|
||||||
'QUEUE_REMOVE'
|
'QUEUE_REMOVE'
|
||||||
]);
|
]);
|
||||||
export const APP = createRequestTypes('APP', [
|
export const APP = createRequestTypes('APP', ['START', 'READY', 'INIT', 'INIT_LOCAL_SETTINGS', 'SET_MASTER_DETAIL']);
|
||||||
'START',
|
|
||||||
'READY',
|
|
||||||
'INIT',
|
|
||||||
'INIT_LOCAL_SETTINGS',
|
|
||||||
'SET_MASTER_DETAIL',
|
|
||||||
'SET_NOTIFICATION_PRESENCE_CAP'
|
|
||||||
]);
|
|
||||||
export const MESSAGES = createRequestTypes('MESSAGES', ['REPLY_BROADCAST']);
|
export const MESSAGES = createRequestTypes('MESSAGES', ['REPLY_BROADCAST']);
|
||||||
export const CREATE_CHANNEL = createRequestTypes('CREATE_CHANNEL', [...defaultTypes]);
|
export const CREATE_CHANNEL = createRequestTypes('CREATE_CHANNEL', [...defaultTypes]);
|
||||||
export const CREATE_DISCUSSION = createRequestTypes('CREATE_DISCUSSION', [...defaultTypes]);
|
export const CREATE_DISCUSSION = createRequestTypes('CREATE_DISCUSSION', [...defaultTypes]);
|
||||||
|
|
|
@ -12,11 +12,7 @@ interface ISetMasterDetail extends Action {
|
||||||
isMasterDetail: boolean;
|
isMasterDetail: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ISetNotificationPresenceCap extends Action {
|
export type TActionApp = IAppStart & ISetMasterDetail;
|
||||||
show: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TActionApp = IAppStart & ISetMasterDetail & ISetNotificationPresenceCap;
|
|
||||||
|
|
||||||
interface Params {
|
interface Params {
|
||||||
root: RootEnum;
|
root: RootEnum;
|
||||||
|
@ -55,10 +51,3 @@ export function setMasterDetail(isMasterDetail: boolean): ISetMasterDetail {
|
||||||
isMasterDetail
|
isMasterDetail
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setNotificationPresenceCap(show: boolean): ISetNotificationPresenceCap {
|
|
||||||
return {
|
|
||||||
type: APP.SET_NOTIFICATION_PRESENCE_CAP,
|
|
||||||
show
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Action } from 'redux';
|
import { Action } from 'redux';
|
||||||
|
|
||||||
import { ERoomType, RoomType } from '../definitions';
|
import { ERoomType } from '../definitions/ERoomType';
|
||||||
import { ROOM } from './actionsTypes';
|
import { ROOM } from './actionsTypes';
|
||||||
|
|
||||||
// TYPE RETURN RELATED
|
// TYPE RETURN RELATED
|
||||||
|
@ -44,24 +44,7 @@ interface IUserTyping extends Action {
|
||||||
status: boolean;
|
status: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IRoomHistoryRequest extends Action {
|
export type TActionsRoom = TSubscribeRoom & TUnsubscribeRoom & ILeaveRoom & IDeleteRoom & IForwardRoom & IUserTyping;
|
||||||
rid: string;
|
|
||||||
t: RoomType;
|
|
||||||
loaderId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IRoomHistoryFinished extends Action {
|
|
||||||
loaderId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TActionsRoom = TSubscribeRoom &
|
|
||||||
TUnsubscribeRoom &
|
|
||||||
ILeaveRoom &
|
|
||||||
IDeleteRoom &
|
|
||||||
IForwardRoom &
|
|
||||||
IUserTyping &
|
|
||||||
IRoomHistoryRequest &
|
|
||||||
IRoomHistoryFinished;
|
|
||||||
|
|
||||||
export function subscribeRoom(rid: string): TSubscribeRoom {
|
export function subscribeRoom(rid: string): TSubscribeRoom {
|
||||||
return {
|
return {
|
||||||
|
@ -116,19 +99,3 @@ export function userTyping(rid: string, status = true): IUserTyping {
|
||||||
status
|
status
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function roomHistoryRequest({ rid, t, loaderId }: { rid: string; t: RoomType; loaderId: string }): IRoomHistoryRequest {
|
|
||||||
return {
|
|
||||||
type: ROOM.HISTORY_REQUEST,
|
|
||||||
rid,
|
|
||||||
t,
|
|
||||||
loaderId
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function roomHistoryFinished({ loaderId }: { loaderId: string }): IRoomHistoryFinished {
|
|
||||||
return {
|
|
||||||
type: ROOM.HISTORY_FINISHED,
|
|
||||||
loaderId
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
@ -122,6 +122,7 @@ const ActionSheetContentWithInputAndSubmit = ({
|
||||||
}}
|
}}
|
||||||
testID={testID}
|
testID={testID}
|
||||||
secureTextEntry={secureTextEntry}
|
secureTextEntry={secureTextEntry}
|
||||||
|
inputStyle={{ borderWidth: 2 }}
|
||||||
bottomSheet={isIOS}
|
bottomSheet={isIOS}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
|
@ -52,7 +52,7 @@ export default StyleSheet.create({
|
||||||
paddingHorizontal: 14,
|
paddingHorizontal: 14,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
height: ITEM_HEIGHT,
|
height: ITEM_HEIGHT,
|
||||||
borderRadius: 4,
|
borderRadius: 2,
|
||||||
marginBottom: 12
|
marginBottom: 12
|
||||||
},
|
},
|
||||||
text: {
|
text: {
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ViewStyle } from 'react-native';
|
|
||||||
|
|
||||||
import { TGetCustomEmoji } from '../../definitions/IEmoji';
|
import { TGetCustomEmoji } from '../../definitions/IEmoji';
|
||||||
|
|
||||||
export interface IAvatar {
|
export interface IAvatar {
|
||||||
server?: string;
|
server?: string;
|
||||||
style?: ViewStyle;
|
style?: any;
|
||||||
text?: string;
|
text?: string;
|
||||||
avatar?: string;
|
avatar?: string;
|
||||||
emoji?: string;
|
emoji?: string;
|
||||||
|
|
|
@ -22,7 +22,7 @@ const styles = StyleSheet.create({
|
||||||
paddingHorizontal: 14,
|
paddingHorizontal: 14,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
height: 48,
|
height: 48,
|
||||||
borderRadius: 4,
|
borderRadius: 2,
|
||||||
marginBottom: 12
|
marginBottom: 12
|
||||||
},
|
},
|
||||||
text: {
|
text: {
|
||||||
|
|
|
@ -10,7 +10,7 @@ const styles = StyleSheet.create({
|
||||||
pressable: {
|
pressable: {
|
||||||
paddingHorizontal: 8,
|
paddingHorizontal: 8,
|
||||||
marginRight: 8,
|
marginRight: 8,
|
||||||
borderRadius: 4,
|
borderRadius: 2,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
maxWidth: 192
|
maxWidth: 192
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
export const mappedIcons = {
|
export const mappedIcons = {
|
||||||
'status-disabled': 59837,
|
'lamp-bulb': 59812,
|
||||||
'lamp-bulb': 59836,
|
|
||||||
'phone-in': 59835,
|
|
||||||
'basketball': 59776,
|
'basketball': 59776,
|
||||||
'percentage': 59777,
|
'percentage': 59777,
|
||||||
'glasses': 59812,
|
|
||||||
'burger': 59813,
|
'burger': 59813,
|
||||||
'leaf': 59814,
|
'leaf': 59814,
|
||||||
'airplane': 59815,
|
'airplane': 59815,
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,31 +1,34 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { useWindowDimensions } from 'react-native';
|
||||||
import { FlatList } from 'react-native-gesture-handler';
|
import { FlatList } from 'react-native-gesture-handler';
|
||||||
|
|
||||||
import { IEmoji } from '../../definitions/IEmoji';
|
|
||||||
import scrollPersistTaps from '../../lib/methods/helpers/scrollPersistTaps';
|
|
||||||
import { PressableEmoji } from './PressableEmoji';
|
|
||||||
import { EMOJI_BUTTON_SIZE } from './styles';
|
import { EMOJI_BUTTON_SIZE } from './styles';
|
||||||
|
import scrollPersistTaps from '../../lib/methods/helpers/scrollPersistTaps';
|
||||||
|
import { IEmoji } from '../../definitions/IEmoji';
|
||||||
|
import { PressableEmoji } from './PressableEmoji';
|
||||||
|
|
||||||
interface IEmojiCategoryProps {
|
interface IEmojiCategoryProps {
|
||||||
emojis: IEmoji[];
|
emojis: IEmoji[];
|
||||||
onEmojiSelected: (emoji: IEmoji) => void;
|
onEmojiSelected: (emoji: IEmoji) => void;
|
||||||
tabLabel?: string; // needed for react-native-scrollable-tab-view only
|
tabLabel?: string; // needed for react-native-scrollable-tab-view only
|
||||||
parentWidth: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const EmojiCategory = ({ onEmojiSelected, emojis, parentWidth }: IEmojiCategoryProps): React.ReactElement | null => {
|
const EmojiCategory = ({ onEmojiSelected, emojis }: IEmojiCategoryProps): React.ReactElement | null => {
|
||||||
if (!parentWidth) {
|
const { width } = useWindowDimensions();
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const numColumns = Math.trunc(parentWidth / EMOJI_BUTTON_SIZE);
|
const numColumns = Math.trunc(width / EMOJI_BUTTON_SIZE);
|
||||||
const marginHorizontal = (parentWidth % EMOJI_BUTTON_SIZE) / 2;
|
const marginHorizontal = (width % EMOJI_BUTTON_SIZE) / 2;
|
||||||
|
|
||||||
const renderItem = ({ item }: { item: IEmoji }) => <PressableEmoji emoji={item} onPress={onEmojiSelected} />;
|
const renderItem = ({ item }: { item: IEmoji }) => <PressableEmoji emoji={item} onPress={onEmojiSelected} />;
|
||||||
|
|
||||||
|
if (!width) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FlatList
|
<FlatList
|
||||||
key={`emoji-category-${parentWidth}`}
|
// needed to update the numColumns when the width changes
|
||||||
|
key={`emoji-category-${width}`}
|
||||||
keyExtractor={item => (typeof item === 'string' ? item : item.name)}
|
keyExtractor={item => (typeof item === 'string' ? item : item.name)}
|
||||||
data={emojis}
|
data={emojis}
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState } from 'react';
|
import React from 'react';
|
||||||
import { View } from 'react-native';
|
import { View } from 'react-native';
|
||||||
import ScrollableTabView from 'react-native-scrollable-tab-view';
|
import ScrollableTabView from 'react-native-scrollable-tab-view';
|
||||||
|
|
||||||
|
@ -20,8 +20,6 @@ const EmojiPicker = ({
|
||||||
searchedEmojis = []
|
searchedEmojis = []
|
||||||
}: IEmojiPickerProps): React.ReactElement | null => {
|
}: IEmojiPickerProps): React.ReactElement | null => {
|
||||||
const { colors } = useTheme();
|
const { colors } = useTheme();
|
||||||
const [parentWidth, setParentWidth] = useState(0);
|
|
||||||
|
|
||||||
const { frequentlyUsed, loaded } = useFrequentlyUsedEmoji();
|
const { frequentlyUsed, loaded } = useFrequentlyUsedEmoji();
|
||||||
|
|
||||||
const allCustomEmojis: ICustomEmojis = useAppSelector(
|
const allCustomEmojis: ICustomEmojis = useAppSelector(
|
||||||
|
@ -52,14 +50,7 @@ const EmojiPicker = ({
|
||||||
if (!emojis.length) {
|
if (!emojis.length) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (
|
return <EmojiCategory emojis={emojis} onEmojiSelected={(emoji: IEmoji) => handleEmojiSelect(emoji)} tabLabel={label} />;
|
||||||
<EmojiCategory
|
|
||||||
parentWidth={parentWidth}
|
|
||||||
emojis={emojis}
|
|
||||||
onEmojiSelected={(emoji: IEmoji) => handleEmojiSelect(emoji)}
|
|
||||||
tabLabel={label}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!loaded) {
|
if (!loaded) {
|
||||||
|
@ -67,13 +58,9 @@ const EmojiPicker = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.emojiPickerContainer} onLayout={e => setParentWidth(e.nativeEvent.layout.width)}>
|
<View style={styles.emojiPickerContainer}>
|
||||||
{searching ? (
|
{searching ? (
|
||||||
<EmojiCategory
|
<EmojiCategory emojis={searchedEmojis} onEmojiSelected={(emoji: IEmoji) => handleEmojiSelect(emoji)} />
|
||||||
emojis={searchedEmojis}
|
|
||||||
onEmojiSelected={(emoji: IEmoji) => handleEmojiSelect(emoji)}
|
|
||||||
parentWidth={parentWidth}
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
<ScrollableTabView
|
<ScrollableTabView
|
||||||
renderTabBar={() => <TabBar />}
|
renderTabBar={() => <TabBar />}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { StyleSheet, View } from 'react-native';
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
import { STATUS_COLORS } from '../../lib/constants';
|
|
||||||
import UnreadBadge from '../UnreadBadge';
|
import UnreadBadge from '../UnreadBadge';
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
|
@ -16,8 +15,6 @@ const styles = StyleSheet.create({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export const BadgeUnread = ({ ...props }): React.ReactElement => <UnreadBadge {...props} style={styles.badgeContainer} small />;
|
export const Badge = ({ ...props }): React.ReactElement => <UnreadBadge {...props} style={styles.badgeContainer} small />;
|
||||||
|
|
||||||
export const BadgeWarn = (): React.ReactElement => (
|
export default Badge;
|
||||||
<View style={[styles.badgeContainer, { width: 10, height: 10, backgroundColor: STATUS_COLORS.disabled }]} />
|
|
||||||
);
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { View } from 'react-native';
|
|
||||||
import { Header, HeaderBackground } from '@react-navigation/elements';
|
import { Header, HeaderBackground } from '@react-navigation/elements';
|
||||||
import { NavigationContainer } from '@react-navigation/native';
|
import { NavigationContainer } from '@react-navigation/native';
|
||||||
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
||||||
|
@ -104,10 +103,9 @@ export const Badge = () => (
|
||||||
<HeaderExample
|
<HeaderExample
|
||||||
left={() => (
|
left={() => (
|
||||||
<HeaderButton.Container left>
|
<HeaderButton.Container left>
|
||||||
<HeaderButton.Item iconName='threads' badge={() => <HeaderButton.BadgeUnread tunread={[1]} />} />
|
<HeaderButton.Item iconName='threads' badge={() => <HeaderButton.Badge tunread={[1]} />} />
|
||||||
<HeaderButton.Item iconName='threads' badge={() => <HeaderButton.BadgeUnread tunread={[1]} tunreadUser={[1]} />} />
|
<HeaderButton.Item iconName='threads' badge={() => <HeaderButton.Badge tunread={[1]} tunreadUser={[1]} />} />
|
||||||
<HeaderButton.Item iconName='threads' badge={() => <HeaderButton.BadgeUnread tunread={[1]} tunreadGroup={[1]} />} />
|
<HeaderButton.Item iconName='threads' badge={() => <HeaderButton.Badge tunread={[1]} tunreadGroup={[1]} />} />
|
||||||
<HeaderButton.Drawer badge={() => <HeaderButton.BadgeWarn />} />
|
|
||||||
</HeaderButton.Container>
|
</HeaderButton.Container>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -116,23 +114,20 @@ export const Badge = () => (
|
||||||
|
|
||||||
const ThemeStory = ({ theme }: { theme: TSupportedThemes }) => (
|
const ThemeStory = ({ theme }: { theme: TSupportedThemes }) => (
|
||||||
<ThemeContext.Provider value={{ theme, colors: colors[theme] }}>
|
<ThemeContext.Provider value={{ theme, colors: colors[theme] }}>
|
||||||
<View style={{ flexDirection: 'column' }}>
|
<HeaderExample
|
||||||
<HeaderExample
|
left={() => (
|
||||||
left={() => (
|
<HeaderButton.Container left>
|
||||||
<HeaderButton.Container left>
|
<HeaderButton.Item iconName='threads' />
|
||||||
<HeaderButton.Drawer badge={() => <HeaderButton.BadgeWarn />} />
|
</HeaderButton.Container>
|
||||||
<HeaderButton.Item iconName='threads' />
|
)}
|
||||||
</HeaderButton.Container>
|
right={() => (
|
||||||
)}
|
<HeaderButton.Container>
|
||||||
right={() => (
|
<HeaderButton.Item title='Threads' />
|
||||||
<HeaderButton.Container>
|
<HeaderButton.Item iconName='threads' badge={() => <HeaderButton.Badge tunread={[1]} />} />
|
||||||
<HeaderButton.Item title='Threads' />
|
</HeaderButton.Container>
|
||||||
<HeaderButton.Item iconName='threads' badge={() => <HeaderButton.BadgeUnread tunread={[1]} />} />
|
)}
|
||||||
</HeaderButton.Container>
|
colors={colors[theme]}
|
||||||
)}
|
/>
|
||||||
colors={colors[theme]}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
</ThemeContext.Provider>
|
</ThemeContext.Provider>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export { default as Container } from './HeaderButtonContainer';
|
export { default as Container } from './HeaderButtonContainer';
|
||||||
export { default as Item } from './HeaderButtonItem';
|
export { default as Item } from './HeaderButtonItem';
|
||||||
export * from './HeaderButtonItemBadge';
|
export { default as Badge } from './HeaderButtonItemBadge';
|
||||||
export * from './Common';
|
export * from './Common';
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { themes } from '../../lib/constants';
|
||||||
import { useTheme } from '../../theme';
|
import { useTheme } from '../../theme';
|
||||||
import { ROW_HEIGHT } from '../RoomItem';
|
import { ROW_HEIGHT } from '../RoomItem';
|
||||||
import { goRoom } from '../../lib/methods/helpers/goRoom';
|
import { goRoom } from '../../lib/methods/helpers/goRoom';
|
||||||
|
import Navigation from '../../lib/navigation/appNavigation';
|
||||||
import { useOrientation } from '../../dimensions';
|
import { useOrientation } from '../../dimensions';
|
||||||
import { IApplicationState, ISubscription, SubscriptionType } from '../../definitions';
|
import { IApplicationState, ISubscription, SubscriptionType } from '../../definitions';
|
||||||
|
|
||||||
|
@ -97,7 +98,12 @@ const NotifierComponent = React.memo(({ notification, isMasterDetail }: INotifie
|
||||||
prid
|
prid
|
||||||
};
|
};
|
||||||
|
|
||||||
goRoom({ item, isMasterDetail, jumpToMessageId: _id, popToRoot: true });
|
if (isMasterDetail) {
|
||||||
|
Navigation.navigate('DrawerNavigator');
|
||||||
|
} else {
|
||||||
|
Navigation.navigate('RoomsListView');
|
||||||
|
}
|
||||||
|
goRoom({ item, isMasterDetail, jumpToMessageId: _id });
|
||||||
hideNotification();
|
hideNotification();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -118,7 +124,6 @@ const NotifierComponent = React.memo(({ notification, isMasterDetail }: INotifie
|
||||||
onPress={onPress}
|
onPress={onPress}
|
||||||
hitSlop={BUTTON_HIT_SLOP}
|
hitSlop={BUTTON_HIT_SLOP}
|
||||||
background={Touchable.SelectableBackgroundBorderless()}
|
background={Touchable.SelectableBackgroundBorderless()}
|
||||||
testID={`in-app-notification-${text}`}
|
|
||||||
>
|
>
|
||||||
<>
|
<>
|
||||||
<Avatar text={avatar} size={AVATAR_SIZE} type={type} rid={rid} style={styles.avatar} />
|
<Avatar text={avatar} size={AVATAR_SIZE} type={type} rid={rid} style={styles.avatar} />
|
||||||
|
|
|
@ -1,50 +1,56 @@
|
||||||
import React, { memo, useEffect } from 'react';
|
import React, { memo, useEffect } from 'react';
|
||||||
import { Easing, Notifier, NotifierRoot } from 'react-native-notifier';
|
import { Easing, Notifier, NotifierRoot } from 'react-native-notifier';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { dequal } from 'dequal';
|
||||||
|
|
||||||
import NotifierComponent, { INotifierComponent } from './NotifierComponent';
|
import NotifierComponent, { INotifierComponent } from './NotifierComponent';
|
||||||
import EventEmitter from '../../lib/methods/helpers/events';
|
import EventEmitter from '../../lib/methods/helpers/events';
|
||||||
import Navigation from '../../lib/navigation/appNavigation';
|
import Navigation from '../../lib/navigation/appNavigation';
|
||||||
import { getActiveRoute } from '../../lib/methods/helpers/navigation';
|
import { getActiveRoute } from '../../lib/methods/helpers/navigation';
|
||||||
import { useAppSelector } from '../../lib/hooks';
|
import { IApplicationState } from '../../definitions';
|
||||||
|
import { IRoom } from '../../reducers/room';
|
||||||
|
|
||||||
export const INAPP_NOTIFICATION_EMITTER = 'NotificationInApp';
|
export const INAPP_NOTIFICATION_EMITTER = 'NotificationInApp';
|
||||||
|
|
||||||
const InAppNotification = memo(() => {
|
const InAppNotification = memo(
|
||||||
const { appState, subscribedRoom } = useAppSelector(state => ({
|
({ rooms, appState }: { rooms: IRoom['rooms']; appState: string }) => {
|
||||||
subscribedRoom: state.room.subscribedRoom,
|
const show = (notification: INotifierComponent['notification']) => {
|
||||||
appState: state.app.ready && state.app.foreground ? 'foreground' : 'background'
|
if (appState !== 'foreground') {
|
||||||
}));
|
|
||||||
|
|
||||||
const show = (notification: INotifierComponent['notification']) => {
|
|
||||||
if (appState !== 'foreground') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { payload } = notification;
|
|
||||||
const state = Navigation.navigationRef.current?.getRootState();
|
|
||||||
const route = getActiveRoute(state);
|
|
||||||
if (payload.rid) {
|
|
||||||
if (payload.rid === subscribedRoom || route?.name === 'JitsiMeetView') {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Notifier.showNotification({
|
|
||||||
showEasing: Easing.inOut(Easing.quad),
|
const { payload } = notification;
|
||||||
Component: NotifierComponent,
|
const state = Navigation.navigationRef.current?.getRootState();
|
||||||
componentProps: {
|
const route = getActiveRoute(state);
|
||||||
notification
|
if (payload.rid) {
|
||||||
|
if (rooms.includes(payload.rid) || route?.name === 'JitsiMeetView') {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
});
|
Notifier.showNotification({
|
||||||
}
|
showEasing: Easing.inOut(Easing.quad),
|
||||||
};
|
Component: NotifierComponent,
|
||||||
|
componentProps: {
|
||||||
useEffect(() => {
|
notification
|
||||||
const listener = EventEmitter.addEventListener(INAPP_NOTIFICATION_EMITTER, show);
|
}
|
||||||
return () => {
|
});
|
||||||
EventEmitter.removeListener(INAPP_NOTIFICATION_EMITTER, listener);
|
}
|
||||||
};
|
};
|
||||||
}, [subscribedRoom, appState]);
|
|
||||||
|
|
||||||
return <NotifierRoot />;
|
useEffect(() => {
|
||||||
|
const listener = EventEmitter.addEventListener(INAPP_NOTIFICATION_EMITTER, show);
|
||||||
|
return () => {
|
||||||
|
EventEmitter.removeListener(INAPP_NOTIFICATION_EMITTER, listener);
|
||||||
|
};
|
||||||
|
}, [rooms]);
|
||||||
|
|
||||||
|
return <NotifierRoot />;
|
||||||
|
},
|
||||||
|
(prevProps, nextProps) => dequal(prevProps.rooms, nextProps.rooms)
|
||||||
|
);
|
||||||
|
|
||||||
|
const mapStateToProps = (state: IApplicationState) => ({
|
||||||
|
rooms: state.room.rooms,
|
||||||
|
appState: state.app.ready && state.app.foreground ? 'foreground' : 'background'
|
||||||
});
|
});
|
||||||
|
|
||||||
export default InAppNotification;
|
export default connect(mapStateToProps)(InAppNotification);
|
||||||
|
|
|
@ -4,7 +4,7 @@ import sharedStyles from '../../views/Styles';
|
||||||
|
|
||||||
export const BUTTON_HEIGHT = 48;
|
export const BUTTON_HEIGHT = 48;
|
||||||
export const SERVICE_HEIGHT = 58;
|
export const SERVICE_HEIGHT = 58;
|
||||||
export const BORDER_RADIUS = 4;
|
export const BORDER_RADIUS = 2;
|
||||||
export const SERVICES_COLLAPSED_HEIGHT = 174;
|
export const SERVICES_COLLAPSED_HEIGHT = 174;
|
||||||
|
|
||||||
export default StyleSheet.create({
|
export default StyleSheet.create({
|
||||||
|
|
|
@ -14,12 +14,12 @@ import { IEmoji, TAnyMessageModel } from '../../definitions';
|
||||||
import Touch from '../Touch';
|
import Touch from '../Touch';
|
||||||
|
|
||||||
export interface IHeader {
|
export interface IHeader {
|
||||||
handleReaction: (emoji: IEmoji | null, message: TAnyMessageModel) => void;
|
handleReaction: (emoji: IEmoji, message: TAnyMessageModel) => void;
|
||||||
message: TAnyMessageModel;
|
message: TAnyMessageModel;
|
||||||
isMasterDetail: boolean;
|
isMasterDetail: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
type TOnReaction = ({ emoji }: { emoji?: IEmoji }) => void;
|
type TOnReaction = ({ emoji }: { emoji: IEmoji }) => void;
|
||||||
|
|
||||||
interface THeaderItem {
|
interface THeaderItem {
|
||||||
item: IEmoji;
|
item: IEmoji;
|
||||||
|
@ -94,10 +94,8 @@ const Header = React.memo(({ handleReaction, message, isMasterDetail }: IHeader)
|
||||||
const quantity = Math.trunc(size / (ITEM_SIZE + ITEM_MARGIN * 2) - 1);
|
const quantity = Math.trunc(size / (ITEM_SIZE + ITEM_MARGIN * 2) - 1);
|
||||||
|
|
||||||
const onReaction: TOnReaction = ({ emoji }) => {
|
const onReaction: TOnReaction = ({ emoji }) => {
|
||||||
handleReaction(emoji || null, message);
|
handleReaction(emoji, message);
|
||||||
if (emoji) {
|
addFrequentlyUsed(emoji);
|
||||||
addFrequentlyUsed(emoji);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderItem = ({ item }: { item: IEmoji }) => <HeaderItem item={item} onReaction={onReaction} theme={theme} />;
|
const renderItem = ({ item }: { item: IEmoji }) => <HeaderItem item={item} onReaction={onReaction} theme={theme} />;
|
||||||
|
|
|
@ -40,7 +40,6 @@ export interface IMessageActionsProps {
|
||||||
editMessagePermission?: string[];
|
editMessagePermission?: string[];
|
||||||
deleteMessagePermission?: string[];
|
deleteMessagePermission?: string[];
|
||||||
forceDeleteMessagePermission?: string[];
|
forceDeleteMessagePermission?: string[];
|
||||||
deleteOwnMessagePermission?: string[];
|
|
||||||
pinMessagePermission?: string[];
|
pinMessagePermission?: string[];
|
||||||
createDirectMessagePermission?: string[];
|
createDirectMessagePermission?: string[];
|
||||||
}
|
}
|
||||||
|
@ -72,7 +71,6 @@ const MessageActions = React.memo(
|
||||||
editMessagePermission,
|
editMessagePermission,
|
||||||
deleteMessagePermission,
|
deleteMessagePermission,
|
||||||
forceDeleteMessagePermission,
|
forceDeleteMessagePermission,
|
||||||
deleteOwnMessagePermission,
|
|
||||||
pinMessagePermission,
|
pinMessagePermission,
|
||||||
createDirectMessagePermission
|
createDirectMessagePermission
|
||||||
},
|
},
|
||||||
|
@ -82,27 +80,19 @@ const MessageActions = React.memo(
|
||||||
hasEditPermission: false,
|
hasEditPermission: false,
|
||||||
hasDeletePermission: false,
|
hasDeletePermission: false,
|
||||||
hasForceDeletePermission: false,
|
hasForceDeletePermission: false,
|
||||||
hasPinPermission: false,
|
hasPinPermission: false
|
||||||
hasDeleteOwnPermission: false
|
|
||||||
};
|
};
|
||||||
const { showActionSheet, hideActionSheet } = useActionSheet();
|
const { showActionSheet, hideActionSheet } = useActionSheet();
|
||||||
|
|
||||||
const getPermissions = async () => {
|
const getPermissions = async () => {
|
||||||
try {
|
try {
|
||||||
const permission = [
|
const permission = [editMessagePermission, deleteMessagePermission, forceDeleteMessagePermission, pinMessagePermission];
|
||||||
editMessagePermission,
|
|
||||||
deleteMessagePermission,
|
|
||||||
forceDeleteMessagePermission,
|
|
||||||
pinMessagePermission,
|
|
||||||
deleteOwnMessagePermission
|
|
||||||
];
|
|
||||||
const result = await hasPermission(permission, room.rid);
|
const result = await hasPermission(permission, room.rid);
|
||||||
permissions = {
|
permissions = {
|
||||||
hasEditPermission: result[0],
|
hasEditPermission: result[0],
|
||||||
hasDeletePermission: result[1],
|
hasDeletePermission: result[1],
|
||||||
hasForceDeletePermission: result[2],
|
hasForceDeletePermission: result[2],
|
||||||
hasPinPermission: result[3],
|
hasPinPermission: result[3]
|
||||||
hasDeleteOwnPermission: result[4]
|
|
||||||
};
|
};
|
||||||
} catch {
|
} catch {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
|
@ -144,7 +134,7 @@ const MessageActions = React.memo(
|
||||||
if (tmid === message.id) {
|
if (tmid === message.id) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const deleteOwn = isOwn(message) && permissions.hasDeleteOwnPermission;
|
const deleteOwn = isOwn(message);
|
||||||
if (!(permissions.hasDeletePermission || (Message_AllowDeleting && deleteOwn) || permissions.hasForceDeletePermission)) {
|
if (!(permissions.hasDeletePermission || (Message_AllowDeleting && deleteOwn) || permissions.hasForceDeletePermission)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -285,10 +275,10 @@ const MessageActions = React.memo(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleReaction: IHeader['handleReaction'] = (emoji, message) => {
|
const handleReaction: IHeader['handleReaction'] = (shortname, message) => {
|
||||||
logEvent(events.ROOM_MSG_ACTION_REACTION);
|
logEvent(events.ROOM_MSG_ACTION_REACTION);
|
||||||
if (emoji) {
|
if (shortname) {
|
||||||
onReactionPress(emoji, message.id);
|
onReactionPress(shortname, message.id);
|
||||||
} else {
|
} else {
|
||||||
setTimeout(() => reactionInit(message), ACTION_SHEET_ANIMATION_DURATION);
|
setTimeout(() => reactionInit(message), ACTION_SHEET_ANIMATION_DURATION);
|
||||||
}
|
}
|
||||||
|
@ -352,11 +342,21 @@ const MessageActions = React.memo(
|
||||||
};
|
};
|
||||||
|
|
||||||
const getOptions = (message: TAnyMessageModel) => {
|
const getOptions = (message: TAnyMessageModel) => {
|
||||||
const options: TActionSheetOptionsItem[] = [];
|
let options: TActionSheetOptionsItem[] = [];
|
||||||
const videoConfBlock = message.t === 'videoconf';
|
|
||||||
|
// Reply
|
||||||
|
if (!isReadOnly && !tmid) {
|
||||||
|
options = [
|
||||||
|
{
|
||||||
|
title: I18n.t('Reply_in_Thread'),
|
||||||
|
icon: 'threads',
|
||||||
|
onPress: () => handleReply(message)
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
// Quote
|
// Quote
|
||||||
if (!isReadOnly && !videoConfBlock) {
|
if (!isReadOnly) {
|
||||||
options.push({
|
options.push({
|
||||||
title: I18n.t('Quote'),
|
title: I18n.t('Quote'),
|
||||||
icon: 'quote',
|
icon: 'quote',
|
||||||
|
@ -364,17 +364,8 @@ const MessageActions = React.memo(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reply
|
|
||||||
if (!isReadOnly && !tmid) {
|
|
||||||
options.push({
|
|
||||||
title: I18n.t('Reply_in_Thread'),
|
|
||||||
icon: 'threads',
|
|
||||||
onPress: () => handleReply(message)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reply in DM
|
// Reply in DM
|
||||||
if (room.t !== 'd' && room.t !== 'l' && createDirectMessagePermission && !videoConfBlock) {
|
if (room.t !== 'd' && room.t !== 'l' && createDirectMessagePermission) {
|
||||||
options.push({
|
options.push({
|
||||||
title: I18n.t('Reply_in_direct_message'),
|
title: I18n.t('Reply_in_direct_message'),
|
||||||
icon: 'arrow-back',
|
icon: 'arrow-back',
|
||||||
|
@ -382,6 +373,22 @@ const MessageActions = React.memo(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Edit
|
||||||
|
if (allowEdit(message)) {
|
||||||
|
options.push({
|
||||||
|
title: I18n.t('Edit'),
|
||||||
|
icon: 'edit',
|
||||||
|
onPress: () => handleEdit(message)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Permalink
|
||||||
|
options.push({
|
||||||
|
title: I18n.t('Permalink'),
|
||||||
|
icon: 'link',
|
||||||
|
onPress: () => handlePermalink(message)
|
||||||
|
});
|
||||||
|
|
||||||
// Create Discussion
|
// Create Discussion
|
||||||
options.push({
|
options.push({
|
||||||
title: I18n.t('Start_a_Discussion'),
|
title: I18n.t('Start_a_Discussion'),
|
||||||
|
@ -389,22 +396,22 @@ const MessageActions = React.memo(
|
||||||
onPress: () => handleCreateDiscussion(message)
|
onPress: () => handleCreateDiscussion(message)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Permalink
|
// Mark as unread
|
||||||
options.push({
|
if (message.u && message.u._id !== user.id) {
|
||||||
title: I18n.t('Get_link'),
|
|
||||||
icon: 'link',
|
|
||||||
onPress: () => handlePermalink(message)
|
|
||||||
});
|
|
||||||
|
|
||||||
// Copy
|
|
||||||
if (!videoConfBlock) {
|
|
||||||
options.push({
|
options.push({
|
||||||
title: I18n.t('Copy'),
|
title: I18n.t('Mark_unread'),
|
||||||
icon: 'copy',
|
icon: 'flag',
|
||||||
onPress: () => handleCopy(message)
|
onPress: () => handleUnread(message)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy
|
||||||
|
options.push({
|
||||||
|
title: I18n.t('Copy'),
|
||||||
|
icon: 'copy',
|
||||||
|
onPress: () => handleCopy(message)
|
||||||
|
});
|
||||||
|
|
||||||
// Share
|
// Share
|
||||||
options.push({
|
options.push({
|
||||||
title: I18n.t('Share'),
|
title: I18n.t('Share'),
|
||||||
|
@ -412,26 +419,8 @@ const MessageActions = React.memo(
|
||||||
onPress: () => handleShare(message)
|
onPress: () => handleShare(message)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Edit
|
|
||||||
if (allowEdit(message) && !videoConfBlock) {
|
|
||||||
options.push({
|
|
||||||
title: I18n.t('Edit'),
|
|
||||||
icon: 'edit',
|
|
||||||
onPress: () => handleEdit(message)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pin
|
|
||||||
if (Message_AllowPinning && permissions?.hasPinPermission && !videoConfBlock) {
|
|
||||||
options.push({
|
|
||||||
title: I18n.t(message.pinned ? 'Unpin' : 'Pin'),
|
|
||||||
icon: 'pin',
|
|
||||||
onPress: () => handlePin(message)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Star
|
// Star
|
||||||
if (Message_AllowStarring && !videoConfBlock) {
|
if (Message_AllowStarring) {
|
||||||
options.push({
|
options.push({
|
||||||
title: I18n.t(message.starred ? 'Unstar' : 'Star'),
|
title: I18n.t(message.starred ? 'Unstar' : 'Star'),
|
||||||
icon: message.starred ? 'star-filled' : 'star',
|
icon: message.starred ? 'star-filled' : 'star',
|
||||||
|
@ -439,12 +428,12 @@ const MessageActions = React.memo(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark as unread
|
// Pin
|
||||||
if (message.u && message.u._id !== user.id) {
|
if (Message_AllowPinning && permissions?.hasPinPermission) {
|
||||||
options.push({
|
options.push({
|
||||||
title: I18n.t('Mark_unread'),
|
title: I18n.t(message.pinned ? 'Unpin' : 'Pin'),
|
||||||
icon: 'flag',
|
icon: 'pin',
|
||||||
onPress: () => handleUnread(message)
|
onPress: () => handlePin(message)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,7 +507,6 @@ const mapStateToProps = (state: IApplicationState) => ({
|
||||||
isMasterDetail: state.app.isMasterDetail,
|
isMasterDetail: state.app.isMasterDetail,
|
||||||
editMessagePermission: state.permissions['edit-message'],
|
editMessagePermission: state.permissions['edit-message'],
|
||||||
deleteMessagePermission: state.permissions['delete-message'],
|
deleteMessagePermission: state.permissions['delete-message'],
|
||||||
deleteOwnMessagePermission: state.permissions['delete-own-message'],
|
|
||||||
forceDeleteMessagePermission: state.permissions['force-delete-message'],
|
forceDeleteMessagePermission: state.permissions['force-delete-message'],
|
||||||
pinMessagePermission: state.permissions['pin-message'],
|
pinMessagePermission: state.permissions['pin-message'],
|
||||||
createDirectMessagePermission: state.permissions['create-d']
|
createDirectMessagePermission: state.permissions['create-d']
|
||||||
|
|
|
@ -37,7 +37,7 @@ const styles = StyleSheet.create({
|
||||||
height: 32,
|
height: 32,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
borderRadius: 4
|
borderRadius: 10
|
||||||
},
|
},
|
||||||
emptyContainer: {
|
emptyContainer: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import { Text, TouchableOpacity, View } from 'react-native';
|
import { Text, TouchableOpacity } from 'react-native';
|
||||||
|
|
||||||
import { themes } from '../../../lib/constants';
|
import { themes } from '../../../lib/constants';
|
||||||
import { IEmoji } from '../../../definitions/IEmoji';
|
import { IEmoji } from '../../../definitions/IEmoji';
|
||||||
|
@ -37,9 +37,7 @@ const MentionItemContent = React.memo(({ trackingType, item }: IMessageBoxMentio
|
||||||
case MENTIONS_TRACKING_TYPE_COMMANDS:
|
case MENTIONS_TRACKING_TYPE_COMMANDS:
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<View style={[styles.slash, { backgroundColor: themes[theme].borderColor }]}>
|
<Text style={[styles.slash, { backgroundColor: themes[theme].borderColor, color: themes[theme].tintColor }]}>/</Text>
|
||||||
<Text style={{ color: themes[theme].tintColor }}>/</Text>
|
|
||||||
</View>
|
|
||||||
<Text style={[styles.mentionText, { color: themes[theme].titleText }]}>{item.id}</Text>
|
<Text style={[styles.mentionText, { color: themes[theme].titleText }]}>{item.id}</Text>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,9 +8,10 @@ import { activateKeepAwake, deactivateKeepAwake } from 'expo-keep-awake';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import { themes } from '../../lib/constants';
|
import { themes } from '../../lib/constants';
|
||||||
import { CustomIcon } from '../CustomIcon';
|
import { encodeAudio } from '../../lib/methods/audioFile';
|
||||||
import { events, logEvent } from '../../lib/methods/helpers/log';
|
import { events, logEvent } from '../../lib/methods/helpers/log';
|
||||||
import { TSupportedThemes } from '../../theme';
|
import { TSupportedThemes } from '../../theme';
|
||||||
|
import { CustomIcon } from '../CustomIcon';
|
||||||
|
|
||||||
interface IMessageBoxRecordAudioProps {
|
interface IMessageBoxRecordAudioProps {
|
||||||
theme: TSupportedThemes;
|
theme: TSupportedThemes;
|
||||||
|
@ -157,16 +158,16 @@ export default class RecordAudio extends React.PureComponent<IMessageBoxRecordAu
|
||||||
await this.recording.stopAndUnloadAsync();
|
await this.recording.stopAndUnloadAsync();
|
||||||
|
|
||||||
const fileURI = this.recording.getURI();
|
const fileURI = this.recording.getURI();
|
||||||
const fileData = await getInfoAsync(fileURI as string);
|
const audioEncodedPath = await encodeAudio(fileURI!);
|
||||||
|
const fileData = await getInfoAsync(audioEncodedPath);
|
||||||
const fileInfo = {
|
const fileInfo = {
|
||||||
name: `${Date.now()}.m4a`,
|
name: `${Date.now()}.mp3`,
|
||||||
mime: 'audio/aac',
|
mime: 'audio/mpeg',
|
||||||
type: 'audio/aac',
|
type: 'audio/mpeg',
|
||||||
store: 'Uploads',
|
store: 'Uploads',
|
||||||
path: fileURI,
|
path: fileData.uri,
|
||||||
size: fileData.size
|
size: fileData.size
|
||||||
};
|
};
|
||||||
|
|
||||||
onFinish(fileInfo);
|
onFinish(fileInfo);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logEvent(events.ROOM_AUDIO_FINISH_F);
|
logEvent(events.ROOM_AUDIO_FINISH_F);
|
||||||
|
|
|
@ -237,7 +237,7 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
const db = database.active;
|
const db = database.active;
|
||||||
const { rid, tmid, navigation, sharing, usedCannedResponse } = this.props;
|
const { rid, tmid, navigation, sharing, usedCannedResponse, isMasterDetail } = this.props;
|
||||||
let msg;
|
let msg;
|
||||||
try {
|
try {
|
||||||
const threadsCollection = db.get('threads');
|
const threadsCollection = db.get('threads');
|
||||||
|
@ -272,7 +272,7 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
|
||||||
EventEmiter.addEventListener(KEY_COMMAND, this.handleCommands);
|
EventEmiter.addEventListener(KEY_COMMAND, this.handleCommands);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usedCannedResponse) {
|
if (isMasterDetail && usedCannedResponse) {
|
||||||
this.onChangeText(usedCannedResponse);
|
this.onChangeText(usedCannedResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +302,7 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
|
||||||
if (usedCannedResponse !== nextProps.usedCannedResponse) {
|
if (usedCannedResponse !== nextProps.usedCannedResponse) {
|
||||||
this.onChangeText(nextProps.usedCannedResponse ?? '');
|
this.onChangeText(nextProps.usedCannedResponse ?? '');
|
||||||
}
|
}
|
||||||
if (sharing && !replying) {
|
if (sharing) {
|
||||||
this.setInput(nextProps.message.msg ?? '');
|
this.setInput(nextProps.message.msg ?? '');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -857,21 +857,14 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
|
||||||
};
|
};
|
||||||
|
|
||||||
openShareView = (attachments: any) => {
|
openShareView = (attachments: any) => {
|
||||||
const { message, replyCancel, replyWithMention, replying } = this.props;
|
const { message, replyCancel, replyWithMention } = this.props;
|
||||||
// Start a thread with an attachment
|
// Start a thread with an attachment
|
||||||
let value: TThreadModel | IMessage = this.thread;
|
let value: TThreadModel | IMessage = this.thread;
|
||||||
if (replyWithMention) {
|
if (replyWithMention) {
|
||||||
value = message;
|
value = message;
|
||||||
replyCancel();
|
replyCancel();
|
||||||
}
|
}
|
||||||
Navigation.navigate('ShareView', {
|
Navigation.navigate('ShareView', { room: this.room, thread: value, attachments });
|
||||||
room: this.room,
|
|
||||||
thread: value,
|
|
||||||
attachments,
|
|
||||||
replying,
|
|
||||||
replyingMessage: message,
|
|
||||||
closeReply: replyCancel
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
createDiscussion = () => {
|
createDiscussion = () => {
|
||||||
|
@ -1049,7 +1042,16 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
|
||||||
|
|
||||||
// Legacy reply or quote (quote is a reply without mention)
|
// Legacy reply or quote (quote is a reply without mention)
|
||||||
} else {
|
} else {
|
||||||
const msg = await this.formatReplyMessage(replyingMessage, message);
|
const { user, roomType } = this.props;
|
||||||
|
const permalink = await this.getPermalink(replyingMessage);
|
||||||
|
let msg = `[ ](${permalink}) `;
|
||||||
|
|
||||||
|
// if original message wasn't sent by current user and neither from a direct room
|
||||||
|
if (user.username !== replyingMessage?.u?.username && roomType !== 'd' && replyWithMention) {
|
||||||
|
msg += `@${replyingMessage?.u?.username} `;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = `${msg} ${message}`;
|
||||||
onSubmit(msg);
|
onSubmit(msg);
|
||||||
}
|
}
|
||||||
replyCancel();
|
replyCancel();
|
||||||
|
@ -1061,20 +1063,6 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
formatReplyMessage = async (replyingMessage: IMessage, message = '') => {
|
|
||||||
const { user, roomType, replyWithMention, serverVersion } = this.props;
|
|
||||||
const permalink = await this.getPermalink(replyingMessage);
|
|
||||||
let msg = `[ ](${permalink}) `;
|
|
||||||
|
|
||||||
// if original message wasn't sent by current user and neither from a direct room
|
|
||||||
if (user.username !== replyingMessage?.u?.username && roomType !== 'd' && replyWithMention) {
|
|
||||||
msg += `@${replyingMessage?.u?.username} `;
|
|
||||||
}
|
|
||||||
|
|
||||||
const connectionString = compareServerVersion(serverVersion, 'lowerThan', '5.0.0') ? ' ' : '\n';
|
|
||||||
return `${msg}${connectionString}${message}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
updateMentions = (keyword: any, type: string) => {
|
updateMentions = (keyword: any, type: string) => {
|
||||||
if (type === MENTIONS_TRACKING_TYPE_USERS) {
|
if (type === MENTIONS_TRACKING_TYPE_USERS) {
|
||||||
this.getUsers(keyword);
|
this.getUsers(keyword);
|
||||||
|
|
|
@ -113,7 +113,7 @@ export default StyleSheet.create({
|
||||||
padding: 5,
|
padding: 5,
|
||||||
paddingHorizontal: 12,
|
paddingHorizontal: 12,
|
||||||
marginHorizontal: 10,
|
marginHorizontal: 10,
|
||||||
borderRadius: 4
|
borderRadius: 2
|
||||||
},
|
},
|
||||||
commandPreviewImage: {
|
commandPreviewImage: {
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
|
|
|
@ -46,7 +46,6 @@ const RoomHeaderContainer = React.memo(
|
||||||
const connecting = useSelector((state: IApplicationState) => state.meteor.connecting || state.server.loading);
|
const connecting = useSelector((state: IApplicationState) => state.meteor.connecting || state.server.loading);
|
||||||
const usersTyping = useSelector((state: IApplicationState) => state.usersTyping, shallowEqual);
|
const usersTyping = useSelector((state: IApplicationState) => state.usersTyping, shallowEqual);
|
||||||
const connected = useSelector((state: IApplicationState) => state.meteor.connected);
|
const connected = useSelector((state: IApplicationState) => state.meteor.connected);
|
||||||
const presenceDisabled = useSelector((state: IApplicationState) => state.settings.Presence_broadcast_disabled);
|
|
||||||
const activeUser = useSelector(
|
const activeUser = useSelector(
|
||||||
(state: IApplicationState) => (roomUserId ? state.activeUsers?.[roomUserId] : undefined),
|
(state: IApplicationState) => (roomUserId ? state.activeUsers?.[roomUserId] : undefined),
|
||||||
shallowEqual
|
shallowEqual
|
||||||
|
@ -62,13 +61,9 @@ const RoomHeaderContainer = React.memo(
|
||||||
|
|
||||||
if (connected) {
|
if (connected) {
|
||||||
if ((type === 'd' || (tmid && roomUserId)) && activeUser) {
|
if ((type === 'd' || (tmid && roomUserId)) && activeUser) {
|
||||||
if (presenceDisabled) {
|
const { status: statusActiveUser, statusText: statusTextActiveUser } = activeUser;
|
||||||
status = 'disabled';
|
status = statusActiveUser;
|
||||||
} else {
|
statusText = statusTextActiveUser;
|
||||||
const { status: statusActiveUser, statusText: statusTextActiveUser } = activeUser;
|
|
||||||
status = statusActiveUser;
|
|
||||||
statusText = statusTextActiveUser;
|
|
||||||
}
|
|
||||||
} else if (type === 'l' && visitor?.status) {
|
} else if (type === 'l' && visitor?.status) {
|
||||||
const { status: statusVisitor } = visitor;
|
const { status: statusVisitor } = visitor;
|
||||||
status = statusVisitor;
|
status = statusVisitor;
|
||||||
|
|
|
@ -65,7 +65,6 @@ export const UserStatus = () => (
|
||||||
<RoomItem status='busy' />
|
<RoomItem status='busy' />
|
||||||
<RoomItem status='offline' />
|
<RoomItem status='offline' />
|
||||||
<RoomItem status='loading' />
|
<RoomItem status='loading' />
|
||||||
<RoomItem status='disabled' />
|
|
||||||
<RoomItem status='wrong' />
|
<RoomItem status='wrong' />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,13 +2,13 @@ import React, { useEffect, useReducer, useRef } from 'react';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
|
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
|
import { useAppSelector } from '../../lib/hooks';
|
||||||
import { getUserPresence } from '../../lib/methods';
|
import { getUserPresence } from '../../lib/methods';
|
||||||
import { isGroupChat } from '../../lib/methods/helpers';
|
import { isGroupChat } from '../../lib/methods/helpers';
|
||||||
import { formatDate } from '../../lib/methods/helpers/room';
|
import { formatDate } from '../../lib/methods/helpers/room';
|
||||||
import { IRoomItemContainerProps } from './interfaces';
|
import { IRoomItemContainerProps } from './interfaces';
|
||||||
import RoomItem from './RoomItem';
|
import RoomItem from './RoomItem';
|
||||||
import { ROW_HEIGHT, ROW_HEIGHT_CONDENSED } from './styles';
|
import { ROW_HEIGHT, ROW_HEIGHT_CONDENSED } from './styles';
|
||||||
import { useUserStatus } from './useUserStatus';
|
|
||||||
|
|
||||||
export { ROW_HEIGHT, ROW_HEIGHT_CONDENSED };
|
export { ROW_HEIGHT, ROW_HEIGHT_CONDENSED };
|
||||||
|
|
||||||
|
@ -42,11 +42,11 @@ const RoomItemContainer = React.memo(
|
||||||
const isRead = getIsRead(item);
|
const isRead = getIsRead(item);
|
||||||
const date = item.roomUpdatedAt && formatDate(item.roomUpdatedAt);
|
const date = item.roomUpdatedAt && formatDate(item.roomUpdatedAt);
|
||||||
const alert = item.alert || item.tunread?.length;
|
const alert = item.alert || item.tunread?.length;
|
||||||
|
const connected = useAppSelector(state => state.meteor.connected);
|
||||||
|
const userStatus = useAppSelector(state => state.activeUsers[id || '']?.status);
|
||||||
const [_, forceUpdate] = useReducer(x => x + 1, 1);
|
const [_, forceUpdate] = useReducer(x => x + 1, 1);
|
||||||
const roomSubscription = useRef<Subscription | null>(null);
|
const roomSubscription = useRef<Subscription | null>(null);
|
||||||
|
|
||||||
const { connected, status } = useUserStatus(item.t, item?.visitor?.status, id);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const init = () => {
|
const init = () => {
|
||||||
if (item?.observe) {
|
if (item?.observe) {
|
||||||
|
@ -85,6 +85,8 @@ const RoomItemContainer = React.memo(
|
||||||
accessibilityLabel = `, ${I18n.t('last_message')} ${date}`;
|
accessibilityLabel = `, ${I18n.t('last_message')} ${date}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const status = item.t === 'l' ? item.visitor?.status || item.v?.status : userStatus;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RoomItem
|
<RoomItem
|
||||||
name={name}
|
name={name}
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
import { TUserStatus } from '../../definitions';
|
|
||||||
import { useAppSelector } from '../../lib/hooks';
|
|
||||||
import { RoomTypes } from '../../lib/methods';
|
|
||||||
|
|
||||||
export const useUserStatus = (
|
|
||||||
type: RoomTypes,
|
|
||||||
liveChatStatus?: TUserStatus,
|
|
||||||
id?: string
|
|
||||||
): { connected: boolean; status: TUserStatus } => {
|
|
||||||
const connected = useAppSelector(state => state.meteor.connected);
|
|
||||||
const presenceDisabled = useAppSelector(state => state.settings.Presence_broadcast_disabled);
|
|
||||||
const userStatus = useAppSelector(state => state.activeUsers[id || '']?.status);
|
|
||||||
|
|
||||||
let status = 'loading';
|
|
||||||
if (connected) {
|
|
||||||
if (type === 'd') {
|
|
||||||
if (presenceDisabled) {
|
|
||||||
status = 'disabled';
|
|
||||||
} else {
|
|
||||||
status = userStatus || 'loading';
|
|
||||||
}
|
|
||||||
} else if (type === 'l' && liveChatStatus) {
|
|
||||||
status = liveChatStatus;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
connected,
|
|
||||||
status: status as TUserStatus
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState } from 'react';
|
import React from 'react';
|
||||||
import { StyleProp, ViewStyle } from 'react-native';
|
import { StyleProp, ViewStyle } from 'react-native';
|
||||||
import { SvgUri } from 'react-native-svg';
|
import { SvgUri } from 'react-native-svg';
|
||||||
|
|
||||||
|
@ -29,12 +29,22 @@ interface IOmnichannelRoomIconProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const OmnichannelRoomIcon = ({ size, style, sourceType, status }: IOmnichannelRoomIconProps) => {
|
export const OmnichannelRoomIcon = ({ size, style, sourceType, status }: IOmnichannelRoomIconProps) => {
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
const [svgError, setSvgError] = useState(false);
|
|
||||||
const baseUrl = useAppSelector(state => state.server?.server);
|
const baseUrl = useAppSelector(state => state.server?.server);
|
||||||
const connected = useAppSelector(state => state.meteor?.connected);
|
const connected = useAppSelector(state => state.meteor?.connected);
|
||||||
|
|
||||||
const customIcon = (
|
if (sourceType?.type === OmnichannelSourceType.APP && sourceType.id && sourceType.sidebarIcon && connected) {
|
||||||
|
return (
|
||||||
|
<SvgUri
|
||||||
|
height={size}
|
||||||
|
width={size}
|
||||||
|
color={STATUS_COLORS[status || 'offline']}
|
||||||
|
uri={`${baseUrl}/api/apps/public/${sourceType.id}/get-sidebar-icon?icon=${sourceType.sidebarIcon}`}
|
||||||
|
style={style}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
<CustomIcon
|
<CustomIcon
|
||||||
name={iconMap[sourceType?.type || 'other']}
|
name={iconMap[sourceType?.type || 'other']}
|
||||||
size={size}
|
size={size}
|
||||||
|
@ -42,23 +52,4 @@ export const OmnichannelRoomIcon = ({ size, style, sourceType, status }: IOmnich
|
||||||
color={STATUS_COLORS[status || 'offline']}
|
color={STATUS_COLORS[status || 'offline']}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!svgError && sourceType?.type === OmnichannelSourceType.APP && sourceType.id && sourceType.sidebarIcon && connected) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<SvgUri
|
|
||||||
height={size}
|
|
||||||
width={size}
|
|
||||||
color={STATUS_COLORS[status || 'offline']}
|
|
||||||
uri={`${baseUrl}/api/apps/public/${sourceType.id}/get-sidebar-icon?icon=${sourceType.sidebarIcon}`}
|
|
||||||
style={style}
|
|
||||||
onError={() => setSvgError(true)}
|
|
||||||
onLoad={() => setLoading(false)}
|
|
||||||
/>
|
|
||||||
{loading ? customIcon : null}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return customIcon;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,15 +6,9 @@ import { IStatus } from './definition';
|
||||||
import { useAppSelector } from '../../lib/hooks';
|
import { useAppSelector } from '../../lib/hooks';
|
||||||
|
|
||||||
const StatusContainer = ({ id, style, size = 32, ...props }: Omit<IStatus, 'status'>): React.ReactElement => {
|
const StatusContainer = ({ id, style, size = 32, ...props }: Omit<IStatus, 'status'>): React.ReactElement => {
|
||||||
const status = useAppSelector(state => {
|
const status = useAppSelector(state =>
|
||||||
if (state.settings.Presence_broadcast_disabled) {
|
state.meteor.connected ? state.activeUsers[id] && state.activeUsers[id].status : 'loading'
|
||||||
return 'disabled';
|
) as TUserStatus;
|
||||||
}
|
|
||||||
if (state.meteor.connected) {
|
|
||||||
return state.activeUsers[id] && state.activeUsers[id].status;
|
|
||||||
}
|
|
||||||
return 'loading';
|
|
||||||
}) as TUserStatus;
|
|
||||||
return <Status size={size} style={style} status={status} {...props} />;
|
return <Status size={size} style={style} status={status} {...props} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,8 @@ const styles = StyleSheet.create({
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
paddingHorizontal: 16,
|
paddingHorizontal: 16,
|
||||||
paddingVertical: 10,
|
paddingVertical: 10,
|
||||||
borderWidth: 1,
|
borderWidth: 2,
|
||||||
borderRadius: 4
|
borderRadius: 2
|
||||||
},
|
},
|
||||||
inputIconLeft: {
|
inputIconLeft: {
|
||||||
paddingLeft: 45
|
paddingLeft: 45
|
||||||
|
|
|
@ -19,8 +19,8 @@ const styles = StyleSheet.create({
|
||||||
input: {
|
input: {
|
||||||
height: 48,
|
height: 48,
|
||||||
paddingLeft: 16,
|
paddingLeft: 16,
|
||||||
borderWidth: 1,
|
borderWidth: 2,
|
||||||
borderRadius: 4,
|
borderRadius: 2,
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
flexDirection: 'row'
|
flexDirection: 'row'
|
||||||
},
|
},
|
||||||
|
|
|
@ -22,11 +22,11 @@ const Input = ({ children, onPress, loading, inputStyle, placeholder, disabled,
|
||||||
return (
|
return (
|
||||||
<Touchable
|
<Touchable
|
||||||
onPress={onPress}
|
onPress={onPress}
|
||||||
style={[{ backgroundColor: colors.backgroundColor }, styles.inputBorder, inputStyle]}
|
style={[{ backgroundColor: colors.backgroundColor }, inputStyle]}
|
||||||
background={Touchable.Ripple(colors.bannerBackground)}
|
background={Touchable.Ripple(colors.bannerBackground)}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
<View style={[styles.input, styles.inputBorder, { borderColor: colors.separatorColor }, innerInputStyle]}>
|
<View style={[styles.input, { borderColor: colors.separatorColor }, innerInputStyle]}>
|
||||||
{placeholder ? <Text style={[styles.pickerText, { color: colors.auxiliaryText }]}>{placeholder}</Text> : children}
|
{placeholder ? <Text style={[styles.pickerText, { color: colors.auxiliaryText }]}>{placeholder}</Text> : children}
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<ActivityIndicator style={styles.icon} />
|
<ActivityIndicator style={styles.icon} />
|
||||||
|
|
|
@ -31,14 +31,12 @@ export default StyleSheet.create({
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
flex: 1
|
flex: 1
|
||||||
},
|
},
|
||||||
inputBorder: {
|
|
||||||
borderRadius: 4
|
|
||||||
},
|
|
||||||
input: {
|
input: {
|
||||||
minHeight: 48,
|
minHeight: 48,
|
||||||
paddingHorizontal: 8,
|
paddingHorizontal: 8,
|
||||||
paddingBottom: 0,
|
paddingBottom: 0,
|
||||||
borderWidth: 1,
|
borderWidth: 2,
|
||||||
|
borderRadius: 2,
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
flexDirection: 'row'
|
flexDirection: 'row'
|
||||||
},
|
},
|
||||||
|
|
|
@ -19,8 +19,8 @@ const styles = StyleSheet.create({
|
||||||
viewContainer: {
|
viewContainer: {
|
||||||
marginBottom: 16,
|
marginBottom: 16,
|
||||||
paddingHorizontal: 16,
|
paddingHorizontal: 16,
|
||||||
borderWidth: 1,
|
borderWidth: 2,
|
||||||
borderRadius: 4,
|
borderRadius: 2,
|
||||||
justifyContent: 'center'
|
justifyContent: 'center'
|
||||||
},
|
},
|
||||||
pickerText: {
|
pickerText: {
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { Text, View } from 'react-native';
|
|
||||||
|
|
||||||
import i18n from '../../../../i18n';
|
|
||||||
import useStyle from './styles';
|
|
||||||
import AvatarContainer from '../../../Avatar';
|
|
||||||
|
|
||||||
const MAX_USERS = 3;
|
|
||||||
|
|
||||||
export type TCallUsers = { _id: string; username: string; name: string; avatarETag: string }[];
|
|
||||||
|
|
||||||
export const CallParticipants = ({ users }: { users: TCallUsers }): React.ReactElement => {
|
|
||||||
const style = useStyle();
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{users.map(({ username }, index) =>
|
|
||||||
index < MAX_USERS ? <AvatarContainer style={{ marginRight: 4 }} key={index} size={28} text={username} /> : null
|
|
||||||
)}
|
|
||||||
{users.length > MAX_USERS ? (
|
|
||||||
<View style={style.plusUsers}>
|
|
||||||
<Text style={style.plusUsersText}>{users.length > 9 ? '+9' : `+${users.length}`}</Text>
|
|
||||||
</View>
|
|
||||||
) : null}
|
|
||||||
<Text style={style.joined}>{i18n.t('Joined')}</Text>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
|
@ -1,81 +0,0 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
|
||||||
import { Text, View } from 'react-native';
|
|
||||||
import Touchable from 'react-native-platform-touchable';
|
|
||||||
|
|
||||||
import i18n from '../../../../i18n';
|
|
||||||
import { getSubscriptionByRoomId } from '../../../../lib/database/services/Subscription';
|
|
||||||
import { useAppSelector } from '../../../../lib/hooks';
|
|
||||||
import { getRoomAvatar, getUidDirectMessage } from '../../../../lib/methods/helpers';
|
|
||||||
import { useTheme } from '../../../../theme';
|
|
||||||
import { useActionSheet } from '../../../ActionSheet';
|
|
||||||
import AvatarContainer from '../../../Avatar';
|
|
||||||
import Button from '../../../Button';
|
|
||||||
import { CustomIcon } from '../../../CustomIcon';
|
|
||||||
import { BUTTON_HIT_SLOP } from '../../../message/utils';
|
|
||||||
import StatusContainer from '../../../Status';
|
|
||||||
import useStyle from './styles';
|
|
||||||
|
|
||||||
export default function StartACallActionSheet({ rid, initCall }: { rid: string; initCall: Function }): React.ReactElement {
|
|
||||||
const style = useStyle();
|
|
||||||
const { colors } = useTheme();
|
|
||||||
const [user, setUser] = useState({ username: '', avatar: '', uid: '' });
|
|
||||||
const [mic, setMic] = useState(true);
|
|
||||||
const [cam, setCam] = useState(false);
|
|
||||||
const username = useAppSelector(state => state.login.user.username);
|
|
||||||
|
|
||||||
const { hideActionSheet } = useActionSheet();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
(async () => {
|
|
||||||
const room = await getSubscriptionByRoomId(rid);
|
|
||||||
const uid = (await getUidDirectMessage(room)) as string;
|
|
||||||
const avt = getRoomAvatar(room);
|
|
||||||
setUser({ uid, username: room?.name || '', avatar: avt });
|
|
||||||
})();
|
|
||||||
}, [rid]);
|
|
||||||
|
|
||||||
const handleColor = (enabled: boolean) => (enabled ? colors.conferenceCallEnabledIcon : colors.conferenceCallDisabledIcon);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<View style={style.actionSheetContainer}>
|
|
||||||
<View style={style.actionSheetHeader}>
|
|
||||||
<Text style={style.actionSheetHeaderTitle}>{i18n.t('Start_a_call')}</Text>
|
|
||||||
<View style={style.actionSheetHeaderButtons}>
|
|
||||||
<Touchable
|
|
||||||
onPress={() => setCam(!cam)}
|
|
||||||
style={[style.iconCallContainer, cam && style.enabledBackground, { marginRight: 6 }]}
|
|
||||||
hitSlop={BUTTON_HIT_SLOP}
|
|
||||||
>
|
|
||||||
<CustomIcon name={cam ? 'camera' : 'camera-disabled'} size={20} color={handleColor(cam)} />
|
|
||||||
</Touchable>
|
|
||||||
<Touchable
|
|
||||||
onPress={() => setMic(!mic)}
|
|
||||||
style={[style.iconCallContainer, mic && style.enabledBackground]}
|
|
||||||
hitSlop={BUTTON_HIT_SLOP}
|
|
||||||
>
|
|
||||||
<CustomIcon name={mic ? 'microphone' : 'microphone-disabled'} size={20} color={handleColor(mic)} />
|
|
||||||
</Touchable>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
<View style={style.actionSheetUsernameContainer}>
|
|
||||||
<AvatarContainer text={user.avatar} size={36} />
|
|
||||||
<StatusContainer size={16} id={user.uid} style={{ marginLeft: 8, marginRight: 6 }} />
|
|
||||||
<Text style={style.actionSheetUsername} numberOfLines={1}>
|
|
||||||
{user.username}
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
<View style={style.actionSheetPhotoContainer}>
|
|
||||||
<AvatarContainer size={62} text={username} />
|
|
||||||
</View>
|
|
||||||
<Button
|
|
||||||
onPress={() => {
|
|
||||||
hideActionSheet();
|
|
||||||
setTimeout(() => {
|
|
||||||
initCall({ cam, mic });
|
|
||||||
}, 100);
|
|
||||||
}}
|
|
||||||
title={i18n.t('Call')}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { View, Text } from 'react-native';
|
|
||||||
|
|
||||||
import i18n from '../../../../i18n';
|
|
||||||
import { useTheme } from '../../../../theme';
|
|
||||||
import { CustomIcon, TIconsName } from '../../../CustomIcon';
|
|
||||||
import useStyle from './styles';
|
|
||||||
|
|
||||||
type VideoConfMessageIconProps = {
|
|
||||||
variant: 'ended' | 'incoming' | 'outgoing';
|
|
||||||
children: React.ReactElement | React.ReactElement[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const VideoConferenceBaseContainer = ({ variant, children }: VideoConfMessageIconProps): React.ReactElement => {
|
|
||||||
const { colors } = useTheme();
|
|
||||||
const style = useStyle();
|
|
||||||
|
|
||||||
const iconStyle: { [key: string]: { icon: TIconsName; color: string; backgroundColor: string; label: string } } = {
|
|
||||||
ended: {
|
|
||||||
icon: 'phone-end',
|
|
||||||
color: colors.conferenceCallEndedPhoneIcon,
|
|
||||||
backgroundColor: colors.conferenceCallEndedPhoneBackground,
|
|
||||||
label: i18n.t('Call_ended')
|
|
||||||
},
|
|
||||||
incoming: {
|
|
||||||
icon: 'phone-in',
|
|
||||||
color: colors.conferenceCallIncomingPhoneIcon,
|
|
||||||
backgroundColor: colors.conferenceCallIncomingPhoneBackground,
|
|
||||||
label: i18n.t('Calling')
|
|
||||||
},
|
|
||||||
outgoing: {
|
|
||||||
icon: 'phone',
|
|
||||||
color: colors.conferenceCallOngoingPhoneIcon,
|
|
||||||
backgroundColor: colors.conferenceCallOngoingPhoneBackground,
|
|
||||||
label: i18n.t('Call_ongoing')
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<View style={style.container}>
|
|
||||||
<View style={style.callInfoContainer}>
|
|
||||||
<View
|
|
||||||
style={{
|
|
||||||
...style.iconContainer,
|
|
||||||
backgroundColor: iconStyle[variant].backgroundColor
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<CustomIcon name={iconStyle[variant].icon} size={variant === 'incoming' ? 16 : 24} color={iconStyle[variant].color} />
|
|
||||||
</View>
|
|
||||||
<Text style={style.infoContainerText}>{iconStyle[variant].label}</Text>
|
|
||||||
</View>
|
|
||||||
<View style={style.callToActionContainer}>{children}</View>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
};
|
|
|
@ -1,23 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { Text } from 'react-native';
|
|
||||||
import Touchable from 'react-native-platform-touchable';
|
|
||||||
|
|
||||||
import i18n from '../../../../i18n';
|
|
||||||
import { videoConfJoin } from '../../../../lib/methods/videoConf';
|
|
||||||
import useStyle from './styles';
|
|
||||||
import { VideoConferenceBaseContainer } from './VideoConferenceBaseContainer';
|
|
||||||
|
|
||||||
const VideoConferenceDirect = React.memo(({ blockId }: { blockId: string }) => {
|
|
||||||
const style = useStyle();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<VideoConferenceBaseContainer variant='incoming'>
|
|
||||||
<Touchable style={style.callToActionButton} onPress={() => videoConfJoin(blockId)}>
|
|
||||||
<Text style={style.callToActionButtonText}>{i18n.t('Join')}</Text>
|
|
||||||
</Touchable>
|
|
||||||
<Text style={style.callBack}>{i18n.t('Waiting_for_answer')}</Text>
|
|
||||||
</VideoConferenceBaseContainer>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
export default VideoConferenceDirect;
|
|
|
@ -1,53 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { Text } from 'react-native';
|
|
||||||
import Touchable from 'react-native-platform-touchable';
|
|
||||||
|
|
||||||
import { IUser } from '../../../../definitions';
|
|
||||||
import { VideoConferenceType } from '../../../../definitions/IVideoConference';
|
|
||||||
import i18n from '../../../../i18n';
|
|
||||||
import { useAppSelector } from '../../../../lib/hooks';
|
|
||||||
import { useVideoConf } from '../../../../lib/hooks/useVideoConf';
|
|
||||||
import { CallParticipants, TCallUsers } from './CallParticipants';
|
|
||||||
import useStyle from './styles';
|
|
||||||
import { VideoConferenceBaseContainer } from './VideoConferenceBaseContainer';
|
|
||||||
|
|
||||||
export default function VideoConferenceEnded({
|
|
||||||
users,
|
|
||||||
type,
|
|
||||||
createdBy,
|
|
||||||
rid
|
|
||||||
}: {
|
|
||||||
users: TCallUsers;
|
|
||||||
type: VideoConferenceType;
|
|
||||||
createdBy: Pick<IUser, '_id' | 'username' | 'name'>;
|
|
||||||
rid: string;
|
|
||||||
}): React.ReactElement {
|
|
||||||
const style = useStyle();
|
|
||||||
const username = useAppSelector(state => state.login.user.username);
|
|
||||||
const { showInitCallActionSheet } = useVideoConf(rid);
|
|
||||||
|
|
||||||
const onlyAuthorOnCall = users.length === 1 && users.some(user => user.username === createdBy.username);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<VideoConferenceBaseContainer variant='ended'>
|
|
||||||
{type === 'direct' ? (
|
|
||||||
<>
|
|
||||||
<Touchable style={style.callToActionCallBack} onPress={showInitCallActionSheet}>
|
|
||||||
<Text style={style.callToActionCallBackText}>
|
|
||||||
{createdBy.username === username ? i18n.t('Call_back') : i18n.t('Call_again')}
|
|
||||||
</Text>
|
|
||||||
</Touchable>
|
|
||||||
<Text style={style.callBack}>{i18n.t('Call_was_not_answered')}</Text>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
{users.length && !onlyAuthorOnCall ? (
|
|
||||||
<CallParticipants users={users} />
|
|
||||||
) : (
|
|
||||||
<Text style={style.notAnswered}>{i18n.t('Call_was_not_answered')}</Text>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</VideoConferenceBaseContainer>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { Text } from 'react-native';
|
|
||||||
import Touchable from 'react-native-platform-touchable';
|
|
||||||
|
|
||||||
import i18n from '../../../../i18n';
|
|
||||||
import { videoConfJoin } from '../../../../lib/methods/videoConf';
|
|
||||||
import { CallParticipants, TCallUsers } from './CallParticipants';
|
|
||||||
import useStyle from './styles';
|
|
||||||
import { VideoConferenceBaseContainer } from './VideoConferenceBaseContainer';
|
|
||||||
|
|
||||||
export default function VideoConferenceOutgoing({ users, blockId }: { users: TCallUsers; blockId: string }): React.ReactElement {
|
|
||||||
const style = useStyle();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<VideoConferenceBaseContainer variant='outgoing'>
|
|
||||||
<Touchable style={style.callToActionButton} onPress={() => videoConfJoin(blockId)}>
|
|
||||||
<Text style={style.callToActionButtonText}>{i18n.t('Join')}</Text>
|
|
||||||
</Touchable>
|
|
||||||
<CallParticipants users={users} />
|
|
||||||
</VideoConferenceBaseContainer>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import SkeletonPlaceholder from 'react-native-skeleton-placeholder';
|
|
||||||
|
|
||||||
import { useTheme } from '../../../../theme';
|
|
||||||
|
|
||||||
export default function VideoConferenceSkeletonLoading(): React.ReactElement {
|
|
||||||
const { colors } = useTheme();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<SkeletonPlaceholder backgroundColor={colors.conferenceCallBackground}>
|
|
||||||
<SkeletonPlaceholder.Item borderWidth={1} borderColor={colors.conferenceCallBorder} borderRadius={4} marginTop={8}>
|
|
||||||
<SkeletonPlaceholder.Item alignItems={'center'} flexDirection='row' marginTop={16} marginLeft={16}>
|
|
||||||
<SkeletonPlaceholder.Item width={28} height={26} />
|
|
||||||
<SkeletonPlaceholder.Item width={75} height={16} marginLeft={8} borderRadius={0} />
|
|
||||||
</SkeletonPlaceholder.Item>
|
|
||||||
<SkeletonPlaceholder.Item
|
|
||||||
width={'100%'}
|
|
||||||
height={48}
|
|
||||||
marginTop={16}
|
|
||||||
borderBottomLeftRadius={4}
|
|
||||||
borderBottomRightRadius={4}
|
|
||||||
borderTopLeftRadius={0}
|
|
||||||
borderTopRightRadius={0}
|
|
||||||
/>
|
|
||||||
</SkeletonPlaceholder.Item>
|
|
||||||
</SkeletonPlaceholder>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,127 +0,0 @@
|
||||||
import { StyleSheet } from 'react-native';
|
|
||||||
|
|
||||||
import { useTheme } from '../../../../theme';
|
|
||||||
import sharedStyles from '../../../../views/Styles';
|
|
||||||
|
|
||||||
export default function useStyle() {
|
|
||||||
const { colors } = useTheme();
|
|
||||||
return StyleSheet.create({
|
|
||||||
container: { height: 108, flex: 1, borderWidth: 1, borderRadius: 4, marginTop: 8, borderColor: colors.conferenceCallBorder },
|
|
||||||
callInfoContainer: { flex: 1, alignItems: 'center', paddingLeft: 16, flexDirection: 'row' },
|
|
||||||
infoContainerText: {
|
|
||||||
fontSize: 12,
|
|
||||||
marginLeft: 8,
|
|
||||||
...sharedStyles.textBold,
|
|
||||||
color: colors.auxiliaryTintColor
|
|
||||||
},
|
|
||||||
iconContainer: {
|
|
||||||
width: 28,
|
|
||||||
height: 28,
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
borderRadius: 4
|
|
||||||
},
|
|
||||||
callToActionContainer: {
|
|
||||||
height: 48,
|
|
||||||
backgroundColor: colors.conferenceCallBackground,
|
|
||||||
flexDirection: 'row',
|
|
||||||
alignItems: 'center',
|
|
||||||
paddingLeft: 16
|
|
||||||
},
|
|
||||||
callToActionButtonText: {
|
|
||||||
fontSize: 12,
|
|
||||||
...sharedStyles.textSemibold,
|
|
||||||
color: colors.buttonText
|
|
||||||
},
|
|
||||||
callToActionCallBackText: {
|
|
||||||
fontSize: 12,
|
|
||||||
...sharedStyles.textSemibold,
|
|
||||||
color: colors.conferenceCallCallBackText
|
|
||||||
},
|
|
||||||
callToActionButton: {
|
|
||||||
backgroundColor: colors.tintColor,
|
|
||||||
minWidth: 50,
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
height: 32,
|
|
||||||
borderRadius: 4,
|
|
||||||
marginRight: 8,
|
|
||||||
paddingHorizontal: 8
|
|
||||||
},
|
|
||||||
joined: {
|
|
||||||
fontSize: 12,
|
|
||||||
...sharedStyles.textRegular,
|
|
||||||
color: colors.passcodeSecondary,
|
|
||||||
marginLeft: 8
|
|
||||||
},
|
|
||||||
plusUsers: {
|
|
||||||
width: 28,
|
|
||||||
height: 28,
|
|
||||||
backgroundColor: colors.conferenceCallPlusUsersButton,
|
|
||||||
borderRadius: 4,
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center'
|
|
||||||
},
|
|
||||||
plusUsersText: {
|
|
||||||
fontSize: 14,
|
|
||||||
...sharedStyles.textSemibold,
|
|
||||||
color: colors.conferenceCallPlusUsersText,
|
|
||||||
alignSelf: 'center'
|
|
||||||
},
|
|
||||||
callBack: {
|
|
||||||
fontSize: 12,
|
|
||||||
...sharedStyles.textRegular,
|
|
||||||
color: colors.passcodeSecondary
|
|
||||||
},
|
|
||||||
callToActionCallBack: {
|
|
||||||
backgroundColor: colors.conferenceCallPlusUsersButton,
|
|
||||||
minWidth: 50,
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
height: 32,
|
|
||||||
borderRadius: 4,
|
|
||||||
marginRight: 8,
|
|
||||||
paddingHorizontal: 8
|
|
||||||
},
|
|
||||||
notAnswered: {
|
|
||||||
fontSize: 12,
|
|
||||||
...sharedStyles.textRegular,
|
|
||||||
color: colors.passcodeSecondary
|
|
||||||
},
|
|
||||||
actionSheetContainer: {
|
|
||||||
paddingHorizontal: 24,
|
|
||||||
flex: 1
|
|
||||||
},
|
|
||||||
actionSheetHeaderTitle: {
|
|
||||||
fontSize: 14,
|
|
||||||
...sharedStyles.textBold,
|
|
||||||
color: colors.passcodePrimary
|
|
||||||
},
|
|
||||||
actionSheetUsername: {
|
|
||||||
fontSize: 16,
|
|
||||||
...sharedStyles.textBold,
|
|
||||||
color: colors.passcodePrimary,
|
|
||||||
flexShrink: 1
|
|
||||||
},
|
|
||||||
enabledBackground: {
|
|
||||||
backgroundColor: colors.conferenceCallEnabledIconBackground
|
|
||||||
},
|
|
||||||
iconCallContainer: {
|
|
||||||
padding: 6,
|
|
||||||
borderRadius: 4
|
|
||||||
},
|
|
||||||
actionSheetHeader: { flexDirection: 'row', alignItems: 'center' },
|
|
||||||
actionSheetHeaderButtons: { flex: 1, alignItems: 'center', flexDirection: 'row', justifyContent: 'flex-end' },
|
|
||||||
actionSheetUsernameContainer: { flexDirection: 'row', paddingTop: 8, alignItems: 'center' },
|
|
||||||
actionSheetPhotoContainer: {
|
|
||||||
height: 220,
|
|
||||||
width: 148,
|
|
||||||
backgroundColor: colors.conferenceCallPhotoBackground,
|
|
||||||
borderRadius: 8,
|
|
||||||
margin: 24,
|
|
||||||
alignSelf: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
alignItems: 'center'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { useEndpointData } from '../../../lib/hooks/useEndpointData';
|
|
||||||
import VideoConferenceDirect from './components/VideoConferenceDirect';
|
|
||||||
import VideoConferenceEnded from './components/VideoConferenceEnded';
|
|
||||||
import VideoConferenceOutgoing from './components/VideoConferenceOutgoing';
|
|
||||||
import VideoConferenceSkeletonLoading from './components/VideoConferenceSkeletonLoading';
|
|
||||||
|
|
||||||
export default function VideoConferenceBlock({ callId, blockId }: { callId: string; blockId: string }): React.ReactElement {
|
|
||||||
const { result } = useEndpointData('video-conference.info', { callId });
|
|
||||||
|
|
||||||
if (result?.success) {
|
|
||||||
const { users, type, status, createdBy, rid } = result;
|
|
||||||
|
|
||||||
if ('endedAt' in result) return <VideoConferenceEnded createdBy={createdBy} rid={rid} type={type} users={users} />;
|
|
||||||
|
|
||||||
if (type === 'direct' && status === 0) return <VideoConferenceDirect blockId={blockId} />;
|
|
||||||
|
|
||||||
return <VideoConferenceOutgoing blockId={blockId} users={users} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <VideoConferenceSkeletonLoading />;
|
|
||||||
}
|
|
|
@ -29,7 +29,6 @@ import { DatePicker } from './DatePicker';
|
||||||
import { Overflow } from './Overflow';
|
import { Overflow } from './Overflow';
|
||||||
import { ThemeContext } from '../../theme';
|
import { ThemeContext } from '../../theme';
|
||||||
import { IActions, IButton, IElement, IInputIndex, IParser, ISection } from './interfaces';
|
import { IActions, IButton, IElement, IInputIndex, IParser, ISection } from './interfaces';
|
||||||
import VideoConferenceBlock from './VideoConferenceBlock';
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
input: {
|
input: {
|
||||||
|
@ -150,10 +149,6 @@ class MessageParser extends UiKitParserMessage<React.ReactElement> {
|
||||||
const [{ loading, value }, action] = useBlockContext(element, context);
|
const [{ loading, value }, action] = useBlockContext(element, context);
|
||||||
return <MultiSelect {...element} value={value} onChange={action} context={context} loading={loading} />;
|
return <MultiSelect {...element} value={value} onChange={action} context={context} loading={loading} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
video_conf(element: IElement & { callId: string }) {
|
|
||||||
return <VideoConferenceBlock callId={element.callId} blockId={element.blockId!} />;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// plain_text and mrkdwn functions are created in MessageParser and the ModalParser's constructor use the same functions
|
// plain_text and mrkdwn functions are created in MessageParser and the ModalParser's constructor use the same functions
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
/* eslint-disable no-shadow */
|
/* eslint-disable no-shadow */
|
||||||
import { BlockContext } from '@rocket.chat/ui-kit';
|
|
||||||
import React, { useContext, useState } from 'react';
|
import React, { useContext, useState } from 'react';
|
||||||
|
import { BlockContext } from '@rocket.chat/ui-kit';
|
||||||
|
|
||||||
import { videoConfJoin } from '../../lib/methods/videoConf';
|
|
||||||
import { IText } from './interfaces';
|
import { IText } from './interfaces';
|
||||||
|
import { videoConfJoin } from '../../lib/methods/videoConf';
|
||||||
|
import { TActionSheetOptionsItem, useActionSheet } from '../ActionSheet';
|
||||||
|
import i18n from '../../i18n';
|
||||||
|
|
||||||
export const textParser = ([{ text }]: IText[]) => text;
|
export const textParser = ([{ text }]: IText[]) => text;
|
||||||
|
|
||||||
|
@ -40,6 +42,7 @@ export const useBlockContext = ({ blockId, actionId, appId, initialValue }: IUse
|
||||||
const { action, appId: appIdFromContext, viewId, state, language, errors, values = {} } = useContext(KitContext);
|
const { action, appId: appIdFromContext, viewId, state, language, errors, values = {} } = useContext(KitContext);
|
||||||
const { value = initialValue } = values[actionId] || {};
|
const { value = initialValue } = values[actionId] || {};
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
const { showActionSheet } = useActionSheet();
|
||||||
|
|
||||||
const error = errors && actionId && errors[actionId];
|
const error = errors && actionId && errors[actionId];
|
||||||
|
|
||||||
|
@ -57,7 +60,20 @@ export const useBlockContext = ({ blockId, actionId, appId, initialValue }: IUse
|
||||||
try {
|
try {
|
||||||
if (appId === 'videoconf-core' && blockId) {
|
if (appId === 'videoconf-core' && blockId) {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
return videoConfJoin(blockId);
|
const options: TActionSheetOptionsItem[] = [
|
||||||
|
{
|
||||||
|
title: i18n.t('Video_call'),
|
||||||
|
icon: 'camera',
|
||||||
|
onPress: () => videoConfJoin(blockId, true)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18n.t('Voice_call'),
|
||||||
|
icon: 'microphone',
|
||||||
|
onPress: () => videoConfJoin(blockId, false)
|
||||||
|
}
|
||||||
|
];
|
||||||
|
showActionSheet({ options });
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
await action({
|
await action({
|
||||||
blockId,
|
blockId,
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { View, StyleSheet, Text, ViewStyle } from 'react-native';
|
|
||||||
|
|
||||||
import sharedStyles from '../views/Styles';
|
|
||||||
import { useTheme } from '../theme';
|
|
||||||
import openLink from '../lib/methods/helpers/openLink';
|
|
||||||
import { useAppSelector } from '../lib/hooks';
|
|
||||||
import I18n from '../i18n';
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
bottomContainer: {
|
|
||||||
flexDirection: 'column',
|
|
||||||
alignItems: 'center',
|
|
||||||
marginBottom: 32,
|
|
||||||
marginHorizontal: 30
|
|
||||||
},
|
|
||||||
bottomContainerText: {
|
|
||||||
...sharedStyles.textRegular,
|
|
||||||
fontSize: 13,
|
|
||||||
textAlign: 'center'
|
|
||||||
},
|
|
||||||
bottomContainerTextBold: {
|
|
||||||
...sharedStyles.textSemibold,
|
|
||||||
fontSize: 13,
|
|
||||||
textAlign: 'center'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const UGCRules = ({ styleContainer }: { styleContainer?: ViewStyle }) => {
|
|
||||||
const { colors, theme } = useTheme();
|
|
||||||
const { server } = useAppSelector(state => ({
|
|
||||||
server: state.server.server
|
|
||||||
}));
|
|
||||||
|
|
||||||
const openContract = (route: string) => {
|
|
||||||
if (!server) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
openLink(`${server}/${route}`, theme);
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<View style={[styles.bottomContainer, styleContainer]}>
|
|
||||||
<Text style={[styles.bottomContainerText, { color: colors.auxiliaryText }]}>
|
|
||||||
{`${I18n.t('Onboarding_agree_terms')}\n`}
|
|
||||||
<Text
|
|
||||||
style={[styles.bottomContainerTextBold, { color: colors.actionTintColor }]}
|
|
||||||
onPress={() => openContract('terms-of-service')}
|
|
||||||
>
|
|
||||||
{I18n.t('Terms_of_Service')}
|
|
||||||
</Text>{' '}
|
|
||||||
{I18n.t('and')}
|
|
||||||
<Text
|
|
||||||
style={[styles.bottomContainerTextBold, { color: colors.actionTintColor }]}
|
|
||||||
onPress={() => openContract('privacy-policy')}
|
|
||||||
>
|
|
||||||
{' '}
|
|
||||||
{I18n.t('Privacy_Policy')}
|
|
||||||
</Text>
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default UGCRules;
|
|
|
@ -1,11 +1,14 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { StyleProp, Text, TextStyle } from 'react-native';
|
import { StyleProp, Text, TextStyle } from 'react-native';
|
||||||
|
import { useNavigation } from '@react-navigation/native';
|
||||||
|
import { StackNavigationProp } from '@react-navigation/stack';
|
||||||
|
|
||||||
import { themes } from '../../lib/constants';
|
import { themes } from '../../lib/constants';
|
||||||
import { useTheme } from '../../theme';
|
import { useTheme } from '../../theme';
|
||||||
import { IUserChannel } from './interfaces';
|
import { IUserChannel } from './interfaces';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import { getSubscriptionByRoomId } from '../../lib/database/services/Subscription';
|
import { getSubscriptionByRoomId } from '../../lib/database/services/Subscription';
|
||||||
|
import { ChatsStackParamList } from '../../stacks/types';
|
||||||
import { useAppSelector } from '../../lib/hooks';
|
import { useAppSelector } from '../../lib/hooks';
|
||||||
import { goRoom } from '../../lib/methods/helpers/goRoom';
|
import { goRoom } from '../../lib/methods/helpers/goRoom';
|
||||||
|
|
||||||
|
@ -19,6 +22,7 @@ interface IHashtag {
|
||||||
const Hashtag = React.memo(({ hashtag, channels, navToRoomInfo, style = [] }: IHashtag) => {
|
const Hashtag = React.memo(({ hashtag, channels, navToRoomInfo, style = [] }: IHashtag) => {
|
||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
const isMasterDetail = useAppSelector(state => state.app.isMasterDetail);
|
const isMasterDetail = useAppSelector(state => state.app.isMasterDetail);
|
||||||
|
const navigation = useNavigation<StackNavigationProp<ChatsStackParamList, 'RoomView'>>();
|
||||||
|
|
||||||
const handlePress = async () => {
|
const handlePress = async () => {
|
||||||
const index = channels?.findIndex(channel => channel.name === hashtag);
|
const index = channels?.findIndex(channel => channel.name === hashtag);
|
||||||
|
@ -29,7 +33,7 @@ const Hashtag = React.memo(({ hashtag, channels, navToRoomInfo, style = [] }: IH
|
||||||
};
|
};
|
||||||
const room = navParam.rid && (await getSubscriptionByRoomId(navParam.rid));
|
const room = navParam.rid && (await getSubscriptionByRoomId(navParam.rid));
|
||||||
if (room) {
|
if (room) {
|
||||||
goRoom({ item: room, isMasterDetail });
|
goRoom({ item: room, isMasterDetail, navigationMethod: isMasterDetail ? navigation.replace : navigation.push });
|
||||||
} else {
|
} else {
|
||||||
navToRoomInfo(navParam);
|
navToRoomInfo(navParam);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,6 @@ interface IMarkdownProps {
|
||||||
testID?: string;
|
testID?: string;
|
||||||
style?: StyleProp<TextStyle>[];
|
style?: StyleProp<TextStyle>[];
|
||||||
onLinkPress?: TOnLinkPress;
|
onLinkPress?: TOnLinkPress;
|
||||||
isTranslated?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type TLiteral = {
|
type TLiteral = {
|
||||||
|
@ -94,7 +93,9 @@ class Markdown extends PureComponent<IMarkdownProps, any> {
|
||||||
|
|
||||||
constructor(props: IMarkdownProps) {
|
constructor(props: IMarkdownProps) {
|
||||||
super(props);
|
super(props);
|
||||||
this.renderer = this.createRenderer();
|
if (!this.isNewMarkdown) {
|
||||||
|
this.renderer = this.createRenderer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createRenderer = () =>
|
createRenderer = () =>
|
||||||
|
@ -309,24 +310,13 @@ class Markdown extends PureComponent<IMarkdownProps, any> {
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const { msg, md, mentions, channels, navToRoomInfo, useRealName, username = '', getCustomEmoji, onLinkPress } = this.props;
|
||||||
msg,
|
|
||||||
md,
|
|
||||||
mentions,
|
|
||||||
channels,
|
|
||||||
navToRoomInfo,
|
|
||||||
useRealName,
|
|
||||||
username = '',
|
|
||||||
getCustomEmoji,
|
|
||||||
onLinkPress,
|
|
||||||
isTranslated
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
if (!msg) {
|
if (!msg) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isNewMarkdown && !isTranslated) {
|
if (this.isNewMarkdown) {
|
||||||
return (
|
return (
|
||||||
<NewMarkdown
|
<NewMarkdown
|
||||||
username={username}
|
username={username}
|
||||||
|
|
|
@ -18,29 +18,13 @@ import MarkdownContext from './MarkdownContext';
|
||||||
|
|
||||||
interface IParagraphProps {
|
interface IParagraphProps {
|
||||||
value: ParagraphProps['value'];
|
value: ParagraphProps['value'];
|
||||||
forceTrim?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Inline = ({ value, forceTrim }: IParagraphProps): React.ReactElement | null => {
|
const Inline = ({ value }: IParagraphProps): React.ReactElement | null => {
|
||||||
const { useRealName, username, navToRoomInfo, mentions, channels } = useContext(MarkdownContext);
|
const { useRealName, username, navToRoomInfo, mentions, channels } = useContext(MarkdownContext);
|
||||||
return (
|
return (
|
||||||
<Text style={styles.inline}>
|
<Text style={styles.inline}>
|
||||||
{value.map((block, index) => {
|
{value.map(block => {
|
||||||
// We are forcing trim when is a `[ ](https://https://open.rocket.chat/) plain_text`
|
|
||||||
// to clean the empty spaces
|
|
||||||
if (forceTrim) {
|
|
||||||
if (index === 0 && block.type === 'LINK') {
|
|
||||||
block.value.label.value =
|
|
||||||
// Need to update the @rocket.chat/message-parser to understand that the label can be a Markup | Markup[]
|
|
||||||
// https://github.com/RocketChat/fuselage/blob/461ecf661d9ff4a46390957c915e4352fa942a7c/packages/message-parser/src/definitions.ts#L141
|
|
||||||
// @ts-ignore
|
|
||||||
block.value?.label?.value?.toString().trimLeft() || block?.value?.label?.[0]?.value?.toString().trimLeft();
|
|
||||||
}
|
|
||||||
if (index === 1 && block.type !== 'LINK') {
|
|
||||||
block.value = block.value?.toString().trimLeft();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (block.type) {
|
switch (block.type) {
|
||||||
case 'IMAGE':
|
case 'IMAGE':
|
||||||
return <Image value={block.value} />;
|
return <Image value={block.value} />;
|
||||||
|
|
|
@ -381,6 +381,27 @@ export const BlockQuote = () => (
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const rocketChatLink = [
|
||||||
|
{
|
||||||
|
type: 'PARAGRAPH',
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
type: 'LINK',
|
||||||
|
value: {
|
||||||
|
src: {
|
||||||
|
type: 'PLAIN_TEXT',
|
||||||
|
value: 'https://rocket.chat'
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: 'PLAIN_TEXT',
|
||||||
|
value: 'https://rocket.chat'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
const markdownLink = [
|
const markdownLink = [
|
||||||
{
|
{
|
||||||
type: 'PARAGRAPH',
|
type: 'PARAGRAPH',
|
||||||
|
@ -466,6 +487,7 @@ const markdownLinkWithEmphasis = [
|
||||||
|
|
||||||
export const Links = () => (
|
export const Links = () => (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
|
<NewMarkdown tokens={rocketChatLink} />
|
||||||
<NewMarkdown tokens={markdownLink} />
|
<NewMarkdown tokens={markdownLink} />
|
||||||
<NewMarkdown tokens={markdownLinkWithEmphasis} />
|
<NewMarkdown tokens={markdownLinkWithEmphasis} />
|
||||||
</View>
|
</View>
|
||||||
|
@ -784,128 +806,3 @@ export const InlineKatex = () => (
|
||||||
<NewMarkdown tokens={inlineKatex} />
|
<NewMarkdown tokens={inlineKatex} />
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|
||||||
const messageQuote = {
|
|
||||||
/**
|
|
||||||
# Hello head 1
|
|
||||||
[ ](https://google.com)
|
|
||||||
*/
|
|
||||||
headAndLink: [
|
|
||||||
{ type: 'HEADING', level: 1, value: [{ type: 'PLAIN_TEXT', value: 'Hello head 1' }] },
|
|
||||||
{ type: 'LINE_BREAK' },
|
|
||||||
{
|
|
||||||
type: 'PARAGRAPH',
|
|
||||||
value: [
|
|
||||||
{
|
|
||||||
type: 'LINK',
|
|
||||||
value: { src: { type: 'PLAIN_TEXT', value: 'https://google.com' }, label: { type: 'PLAIN_TEXT', value: ' ' } }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
/**
|
|
||||||
# Head 1 as the first line then line break and after paragraph
|
|
||||||
bla bla bla bla bla bla
|
|
||||||
bla bla bla bla bla bla
|
|
||||||
[ ](https://google.com)
|
|
||||||
*/
|
|
||||||
headTextAndLink: [
|
|
||||||
{
|
|
||||||
type: 'HEADING',
|
|
||||||
level: 1,
|
|
||||||
value: [{ type: 'PLAIN_TEXT', value: 'Head 1 as the first line then line break and after paragraph' }]
|
|
||||||
},
|
|
||||||
{ type: 'LINE_BREAK' },
|
|
||||||
{ type: 'PARAGRAPH', value: [{ type: 'PLAIN_TEXT', value: 'bla bla bla bla bla bla ' }] },
|
|
||||||
{ type: 'PARAGRAPH', value: [{ type: 'PLAIN_TEXT', value: 'bla bla bla bla bla bla ' }] },
|
|
||||||
{
|
|
||||||
type: 'PARAGRAPH',
|
|
||||||
value: [
|
|
||||||
{
|
|
||||||
type: 'LINK',
|
|
||||||
value: { src: { type: 'PLAIN_TEXT', value: 'https://google.com' }, label: { type: 'PLAIN_TEXT', value: ' ' } }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
/**
|
|
||||||
[ ](permalink from message)\n# Head 1 after a forced line break
|
|
||||||
asdas asd asd asd
|
|
||||||
*/
|
|
||||||
headTextAndQuote: [
|
|
||||||
{
|
|
||||||
type: 'PARAGRAPH',
|
|
||||||
value: [
|
|
||||||
{
|
|
||||||
type: 'LINK',
|
|
||||||
value: {
|
|
||||||
src: { type: 'PLAIN_TEXT', value: 'https://open.rocket.chat/direct/subaru123?msg=QB42gWcaO6BgqtLTo' },
|
|
||||||
label: { type: 'PLAIN_TEXT', value: ' ' }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ type: 'PLAIN_TEXT', value: ' ' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{ type: 'HEADING', level: 1, value: [{ type: 'PLAIN_TEXT', value: 'Head 1 after a forced line break' }] },
|
|
||||||
{ type: 'LINE_BREAK' },
|
|
||||||
{ type: 'PARAGRAPH', value: [{ type: 'PLAIN_TEXT', value: 'Description' }] }
|
|
||||||
],
|
|
||||||
/**
|
|
||||||
[ ](https://google.com) *There is a link before this bold separated by single space*
|
|
||||||
*/
|
|
||||||
linkAndBoldText: [
|
|
||||||
{
|
|
||||||
type: 'PARAGRAPH',
|
|
||||||
value: [
|
|
||||||
{
|
|
||||||
type: 'LINK',
|
|
||||||
value: { src: { type: 'PLAIN_TEXT', value: 'https://google.com' }, label: { type: 'PLAIN_TEXT', value: ' ' } }
|
|
||||||
},
|
|
||||||
{ type: 'PLAIN_TEXT', value: ' ' },
|
|
||||||
{ type: 'BOLD', value: [{ type: 'PLAIN_TEXT', value: 'There is a link before this bold separated by single space' }] }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
simpleQuote: [
|
|
||||||
{
|
|
||||||
type: 'PARAGRAPH',
|
|
||||||
value: [
|
|
||||||
{
|
|
||||||
type: 'LINK',
|
|
||||||
value: {
|
|
||||||
src: {
|
|
||||||
type: 'PLAIN_TEXT',
|
|
||||||
value: 'https://open.rocket.chat/group/quoteeee9798789?msg=ZZp6t2dCRX4TqExht'
|
|
||||||
},
|
|
||||||
// format of label for servers greater or equal than 6.0
|
|
||||||
label: [
|
|
||||||
{
|
|
||||||
type: 'PLAIN_TEXT',
|
|
||||||
value: ' '
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'PARAGRAPH',
|
|
||||||
value: [
|
|
||||||
{
|
|
||||||
type: 'PLAIN_TEXT',
|
|
||||||
value: 'Quoting a message wrote before'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
export const MessageQuote = () => (
|
|
||||||
<View style={styles.container}>
|
|
||||||
<NewMarkdown tokens={messageQuote.headAndLink} />
|
|
||||||
<NewMarkdown tokens={messageQuote.headTextAndLink} />
|
|
||||||
<NewMarkdown tokens={messageQuote.headTextAndQuote} />
|
|
||||||
<NewMarkdown tokens={messageQuote.linkAndBoldText} />
|
|
||||||
<NewMarkdown tokens={messageQuote.simpleQuote} />
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
|
|
|
@ -17,9 +17,7 @@ const OrderedList = ({ value }: IOrderedListProps): React.ReactElement => {
|
||||||
{value.map(item => (
|
{value.map(item => (
|
||||||
<View style={styles.row} key={item.number?.toString()}>
|
<View style={styles.row} key={item.number?.toString()}>
|
||||||
<Text style={[styles.text, { color: colors.bodyText }]}>{item.number}. </Text>
|
<Text style={[styles.text, { color: colors.bodyText }]}>{item.number}. </Text>
|
||||||
<Text style={{ color: colors.bodyText }}>
|
<Inline value={item.value} />
|
||||||
<Inline value={item.value} />
|
|
||||||
</Text>
|
|
||||||
</View>
|
</View>
|
||||||
))}
|
))}
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -12,28 +12,10 @@ interface IParagraphProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
const Paragraph = ({ value }: IParagraphProps) => {
|
const Paragraph = ({ value }: IParagraphProps) => {
|
||||||
let forceTrim = false;
|
|
||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
if (
|
|
||||||
value?.[0]?.type === 'LINK' &&
|
|
||||||
// Need to update the @rocket.chat/message-parser to understand that the label can be a Markup | Markup[]
|
|
||||||
// https://github.com/RocketChat/fuselage/blob/461ecf661d9ff4a46390957c915e4352fa942a7c/packages/message-parser/src/definitions.ts#L141
|
|
||||||
// @ts-ignore
|
|
||||||
(value?.[0]?.value?.label?.value?.toString().trim() === '' || value?.[0]?.value?.label?.[0]?.value?.toString().trim() === '')
|
|
||||||
) {
|
|
||||||
// We are returning null when we receive a message like this: `[ ](https://open.rocket.chat/)\nplain_text`
|
|
||||||
// to avoid render a line empty above the the message
|
|
||||||
if (value.length === 1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (value.length === 2 && value?.[1]?.type === 'PLAIN_TEXT' && value?.[1]?.value?.toString().trim() === '') {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
forceTrim = true;
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<Text style={[styles.text, { color: themes[theme].bodyText }]}>
|
<Text style={[styles.text, { color: themes[theme].bodyText }]}>
|
||||||
<Inline value={value} forceTrim={forceTrim} />
|
<Inline value={value} />
|
||||||
</Text>
|
</Text>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,7 +8,7 @@ interface IPlainProps {
|
||||||
value: PlainProps['value'];
|
value: PlainProps['value'];
|
||||||
}
|
}
|
||||||
|
|
||||||
const Plain = ({ value }: IPlainProps): React.ReactElement => (
|
const Plain = ({ value }: IPlainProps) => (
|
||||||
<Text accessibilityLabel={value} style={styles.plainText}>
|
<Text accessibilityLabel={value} style={styles.plainText}>
|
||||||
{value}
|
{value}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { Tasks as TasksProps } from '@rocket.chat/message-parser';
|
||||||
|
|
||||||
import Inline from './Inline';
|
import Inline from './Inline';
|
||||||
import styles from '../styles';
|
import styles from '../styles';
|
||||||
|
import { themes } from '../../../lib/constants';
|
||||||
import { useTheme } from '../../../theme';
|
import { useTheme } from '../../../theme';
|
||||||
|
|
||||||
interface ITasksProps {
|
interface ITasksProps {
|
||||||
|
@ -11,15 +12,13 @@ interface ITasksProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
const TaskList = ({ value = [] }: ITasksProps) => {
|
const TaskList = ({ value = [] }: ITasksProps) => {
|
||||||
const { colors } = useTheme();
|
const { theme } = useTheme();
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
{value.map(item => (
|
{value.map(item => (
|
||||||
<View style={styles.row}>
|
<View style={styles.row}>
|
||||||
<Text style={[styles.text, { color: colors.bodyText }]}>{item.status ? '- [x] ' : '- [ ] '}</Text>
|
<Text style={[styles.text, { color: themes[theme].bodyText }]}>{item.status ? '- [x] ' : '- [ ] '}</Text>
|
||||||
<Text style={[styles.inline, { color: colors.bodyText }]}>
|
<Inline value={item.value} />
|
||||||
<Inline value={item.value} />
|
|
||||||
</Text>
|
|
||||||
</View>
|
</View>
|
||||||
))}
|
))}
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -18,9 +18,7 @@ const UnorderedList = ({ value }: IUnorderedListProps) => {
|
||||||
{value.map(item => (
|
{value.map(item => (
|
||||||
<View style={styles.row}>
|
<View style={styles.row}>
|
||||||
<Text style={[styles.text, { color: themes[theme].bodyText }]}>- </Text>
|
<Text style={[styles.text, { color: themes[theme].bodyText }]}>- </Text>
|
||||||
<Text style={{ color: themes[theme].bodyText }}>
|
<Inline value={item.value} />
|
||||||
<Inline value={item.value} />
|
|
||||||
</Text>
|
|
||||||
</View>
|
</View>
|
||||||
))}
|
))}
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -20,8 +20,6 @@ import { TGetCustomEmoji } from '../../definitions/IEmoji';
|
||||||
import { IAttachment } from '../../definitions';
|
import { IAttachment } from '../../definitions';
|
||||||
import { TSupportedThemes } from '../../theme';
|
import { TSupportedThemes } from '../../theme';
|
||||||
import { downloadAudioFile } from '../../lib/methods/audioFile';
|
import { downloadAudioFile } from '../../lib/methods/audioFile';
|
||||||
import EventEmitter from '../../lib/methods/helpers/events';
|
|
||||||
import { PAUSE_AUDIO } from './constants';
|
|
||||||
|
|
||||||
interface IButton {
|
interface IButton {
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
|
@ -130,11 +128,6 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
|
||||||
this.sound.setOnPlaybackStatusUpdate(this.onPlaybackStatusUpdate);
|
this.sound.setOnPlaybackStatusUpdate(this.onPlaybackStatusUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
pauseSound = () => {
|
|
||||||
EventEmitter.removeListener(PAUSE_AUDIO, this.pauseSound);
|
|
||||||
this.togglePlayPause();
|
|
||||||
};
|
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
const { file, messageId } = this.props;
|
const { file, messageId } = this.props;
|
||||||
const { baseUrl, user } = this.context;
|
const { baseUrl, user } = this.context;
|
||||||
|
@ -190,7 +183,6 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentWillUnmount() {
|
async componentWillUnmount() {
|
||||||
EventEmitter.removeListener(PAUSE_AUDIO, this.pauseSound);
|
|
||||||
try {
|
try {
|
||||||
await this.sound.stopAsync();
|
await this.sound.stopAsync();
|
||||||
} catch {
|
} catch {
|
||||||
|
@ -229,7 +221,6 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
|
||||||
try {
|
try {
|
||||||
await this.sound.stopAsync();
|
await this.sound.stopAsync();
|
||||||
this.setState({ paused: true, currentTime: 0 });
|
this.setState({ paused: true, currentTime: 0 });
|
||||||
EventEmitter.removeListener(PAUSE_AUDIO, this.pauseSound);
|
|
||||||
} catch {
|
} catch {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
@ -252,10 +243,7 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
|
||||||
try {
|
try {
|
||||||
if (paused) {
|
if (paused) {
|
||||||
await this.sound.pauseAsync();
|
await this.sound.pauseAsync();
|
||||||
EventEmitter.removeListener(PAUSE_AUDIO, this.pauseSound);
|
|
||||||
} else {
|
} else {
|
||||||
EventEmitter.emit(PAUSE_AUDIO);
|
|
||||||
EventEmitter.addEventListener(PAUSE_AUDIO, this.pauseSound);
|
|
||||||
await Audio.setAudioModeAsync(mode);
|
await Audio.setAudioModeAsync(mode);
|
||||||
await this.sound.playAsync();
|
await this.sound.playAsync();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useRef } from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { messageBlockWithContext } from '../UIKit/MessageBlock';
|
import { messageBlockWithContext } from '../UIKit/MessageBlock';
|
||||||
import { IMessageBlocks } from './interfaces';
|
import { IMessageBlocks } from './interfaces';
|
||||||
|
@ -6,29 +6,25 @@ import { IMessageBlocks } from './interfaces';
|
||||||
const Blocks = React.memo(({ blocks, id: mid, rid, blockAction }: IMessageBlocks) => {
|
const Blocks = React.memo(({ blocks, id: mid, rid, blockAction }: IMessageBlocks) => {
|
||||||
if (blocks && blocks.length > 0) {
|
if (blocks && blocks.length > 0) {
|
||||||
const appId = blocks[0]?.appId || '';
|
const appId = blocks[0]?.appId || '';
|
||||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
return React.createElement(
|
||||||
const comp = useRef(
|
messageBlockWithContext({
|
||||||
React.createElement(
|
action: async ({ actionId, value, blockId }: { actionId: string; value: string; blockId: string }) => {
|
||||||
messageBlockWithContext({
|
if (blockAction) {
|
||||||
action: async ({ actionId, value, blockId }: { actionId: string; value: string; blockId: string }) => {
|
await blockAction({
|
||||||
if (blockAction) {
|
actionId,
|
||||||
await blockAction({
|
appId,
|
||||||
actionId,
|
value,
|
||||||
appId,
|
blockId,
|
||||||
value,
|
rid,
|
||||||
blockId,
|
mid
|
||||||
rid,
|
});
|
||||||
mid
|
}
|
||||||
});
|
},
|
||||||
}
|
appId,
|
||||||
},
|
rid
|
||||||
appId,
|
}),
|
||||||
rid
|
{ blocks }
|
||||||
}),
|
|
||||||
{ blocks }
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
return comp.current;
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,12 +10,12 @@ import { themes } from '../../lib/constants';
|
||||||
import { IMessageCallButton } from './interfaces';
|
import { IMessageCallButton } from './interfaces';
|
||||||
import { useTheme } from '../../theme';
|
import { useTheme } from '../../theme';
|
||||||
|
|
||||||
const CallButton = React.memo(({ handleEnterCall }: IMessageCallButton) => {
|
const CallButton = React.memo(({ callJitsi }: IMessageCallButton) => {
|
||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
return (
|
return (
|
||||||
<View style={styles.buttonContainer}>
|
<View style={styles.buttonContainer}>
|
||||||
<Touchable
|
<Touchable
|
||||||
onPress={handleEnterCall}
|
onPress={callJitsi}
|
||||||
background={Touchable.Ripple(themes[theme].bannerBackground)}
|
background={Touchable.Ripple(themes[theme].bannerBackground)}
|
||||||
style={[styles.button, { backgroundColor: themes[theme].tintColor }]}
|
style={[styles.button, { backgroundColor: themes[theme].tintColor }]}
|
||||||
hitSlop={BUTTON_HIT_SLOP}
|
hitSlop={BUTTON_HIT_SLOP}
|
||||||
|
|
|
@ -1,20 +1,14 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import { themes } from '../../../../lib/constants';
|
||||||
import { CustomIcon } from '../../../CustomIcon';
|
import { CustomIcon } from '../../../CustomIcon';
|
||||||
import styles from '../../styles';
|
import styles from '../../styles';
|
||||||
import { useTheme } from '../../../../theme';
|
import { useTheme } from '../../../../theme';
|
||||||
|
|
||||||
const ReadReceipt = React.memo(({ isReadReceiptEnabled, unread }: { isReadReceiptEnabled?: boolean; unread?: boolean }) => {
|
const ReadReceipt = React.memo(({ isReadReceiptEnabled, unread }: { isReadReceiptEnabled?: boolean; unread?: boolean }) => {
|
||||||
const { colors } = useTheme();
|
const { theme } = useTheme();
|
||||||
if (isReadReceiptEnabled) {
|
if (isReadReceiptEnabled && !unread && unread !== null) {
|
||||||
return (
|
return <CustomIcon name='check' color={themes[theme].tintColor} size={16} style={styles.rightIcons} />;
|
||||||
<CustomIcon
|
|
||||||
name='check'
|
|
||||||
color={!unread && unread !== null ? colors.tintColor : colors.auxiliaryTintColor}
|
|
||||||
size={16}
|
|
||||||
style={styles.rightIcons}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
|
@ -53,7 +53,7 @@ const Content = React.memo(
|
||||||
content = (
|
content = (
|
||||||
<Markdown
|
<Markdown
|
||||||
msg={props.msg}
|
msg={props.msg}
|
||||||
md={props.type !== 'e2e' ? props.md : undefined}
|
md={props.md}
|
||||||
getCustomEmoji={props.getCustomEmoji}
|
getCustomEmoji={props.getCustomEmoji}
|
||||||
enableMessageParser={user.enableMessageParserEarlyAdoption}
|
enableMessageParser={user.enableMessageParserEarlyAdoption}
|
||||||
username={user.username}
|
username={user.username}
|
||||||
|
@ -64,7 +64,6 @@ const Content = React.memo(
|
||||||
useRealName={props.useRealName}
|
useRealName={props.useRealName}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
onLinkPress={onLinkPress}
|
onLinkPress={onLinkPress}
|
||||||
isTranslated={props.isTranslated}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ const MessageAvatar = React.memo(({ isHeader, avatar, author, small, navToRoomIn
|
||||||
style={small ? styles.avatarSmall : styles.avatar}
|
style={small ? styles.avatarSmall : styles.avatar}
|
||||||
text={avatar ? '' : author.username}
|
text={avatar ? '' : author.username}
|
||||||
size={small ? 20 : 36}
|
size={small ? 20 : 36}
|
||||||
borderRadius={4}
|
borderRadius={small ? 2 : 4}
|
||||||
onPress={author._id === user.id ? undefined : () => navToRoomInfo(navParam)}
|
onPress={author._id === user.id ? undefined : () => navToRoomInfo(navParam)}
|
||||||
getCustomEmoji={getCustomEmoji}
|
getCustomEmoji={getCustomEmoji}
|
||||||
avatar={avatar}
|
avatar={avatar}
|
||||||
|
|
|
@ -247,8 +247,6 @@ const Reply = React.memo(
|
||||||
>
|
>
|
||||||
<View style={styles.attachmentContainer}>
|
<View style={styles.attachmentContainer}>
|
||||||
<Title attachment={attachment} timeFormat={timeFormat} theme={theme} />
|
<Title attachment={attachment} timeFormat={timeFormat} theme={theme} />
|
||||||
<Description attachment={attachment} getCustomEmoji={getCustomEmoji} theme={theme} />
|
|
||||||
<UrlImage image={attachment.thumb_url} />
|
|
||||||
<Attachments
|
<Attachments
|
||||||
attachments={attachment.attachments}
|
attachments={attachment.attachments}
|
||||||
getCustomEmoji={getCustomEmoji}
|
getCustomEmoji={getCustomEmoji}
|
||||||
|
@ -257,6 +255,8 @@ const Reply = React.memo(
|
||||||
isReply
|
isReply
|
||||||
id={messageId}
|
id={messageId}
|
||||||
/>
|
/>
|
||||||
|
<UrlImage image={attachment.thumb_url} />
|
||||||
|
<Description attachment={attachment} getCustomEmoji={getCustomEmoji} theme={theme} />
|
||||||
<Fields attachment={attachment} getCustomEmoji={getCustomEmoji} theme={theme} />
|
<Fields attachment={attachment} getCustomEmoji={getCustomEmoji} theme={theme} />
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<View style={[styles.backdrop]}>
|
<View style={[styles.backdrop]}>
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
export const DISCUSSION = 'discussion';
|
export const DISCUSSION = 'discussion';
|
||||||
export const THREAD = 'thread';
|
export const THREAD = 'thread';
|
||||||
export const PAUSE_AUDIO = 'pause_audio';
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ interface IMessageContainerProps {
|
||||||
showAttachment: (file: IAttachment) => void;
|
showAttachment: (file: IAttachment) => void;
|
||||||
onReactionLongPress?: (item: TAnyMessageModel) => void;
|
onReactionLongPress?: (item: TAnyMessageModel) => void;
|
||||||
navToRoomInfo: (navParam: IRoomInfoParam) => void;
|
navToRoomInfo: (navParam: IRoomInfoParam) => void;
|
||||||
handleEnterCall?: () => void;
|
callJitsi?: () => void;
|
||||||
blockAction?: (params: { actionId: string; appId: string; value: string; blockId: string; rid: string; mid: string }) => void;
|
blockAction?: (params: { actionId: string; appId: string; value: string; blockId: string; rid: string; mid: string }) => void;
|
||||||
onAnswerButtonPress?: (message: string, tmid?: string, tshow?: boolean) => void;
|
onAnswerButtonPress?: (message: string, tmid?: string, tshow?: boolean) => void;
|
||||||
threadBadgeColor?: string;
|
threadBadgeColor?: string;
|
||||||
|
@ -69,6 +69,7 @@ class MessageContainer extends React.Component<IMessageContainerProps, IMessageC
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
getCustomEmoji: () => null,
|
getCustomEmoji: () => null,
|
||||||
onLongPress: () => {},
|
onLongPress: () => {},
|
||||||
|
callJitsi: () => {},
|
||||||
blockAction: () => {},
|
blockAction: () => {},
|
||||||
archived: false,
|
archived: false,
|
||||||
broadcast: false,
|
broadcast: false,
|
||||||
|
@ -232,9 +233,7 @@ class MessageContainer extends React.Component<IMessageContainerProps, IMessageC
|
||||||
!(previousItem.groupable === false || item.groupable === false || broadcast === true) &&
|
!(previousItem.groupable === false || item.groupable === false || broadcast === true) &&
|
||||||
// @ts-ignore TODO: IMessage vs IMessageFromServer non-sense
|
// @ts-ignore TODO: IMessage vs IMessageFromServer non-sense
|
||||||
item.ts - previousItem.ts < Message_GroupingPeriod * 1000 &&
|
item.ts - previousItem.ts < Message_GroupingPeriod * 1000 &&
|
||||||
previousItem.tmid === item.tmid &&
|
previousItem.tmid === item.tmid
|
||||||
item.t !== 'rm' &&
|
|
||||||
previousItem.t !== 'rm'
|
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -271,7 +270,7 @@ class MessageContainer extends React.Component<IMessageContainerProps, IMessageC
|
||||||
|
|
||||||
get isInfo(): string | boolean {
|
get isInfo(): string | boolean {
|
||||||
const { item } = this.props;
|
const { item } = this.props;
|
||||||
if (['e2e', 'discussion-created', 'jitsi_call_started', 'videoconf'].includes(item.t)) {
|
if (['e2e', 'discussion-created', 'jitsi_call_started'].includes(item.t)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return item.t;
|
return item.t;
|
||||||
|
@ -337,7 +336,7 @@ class MessageContainer extends React.Component<IMessageContainerProps, IMessageC
|
||||||
navToRoomInfo,
|
navToRoomInfo,
|
||||||
getCustomEmoji,
|
getCustomEmoji,
|
||||||
isThreadRoom,
|
isThreadRoom,
|
||||||
handleEnterCall,
|
callJitsi,
|
||||||
blockAction,
|
blockAction,
|
||||||
rid,
|
rid,
|
||||||
threadBadgeColor,
|
threadBadgeColor,
|
||||||
|
@ -377,13 +376,10 @@ class MessageContainer extends React.Component<IMessageContainerProps, IMessageC
|
||||||
} = item;
|
} = item;
|
||||||
|
|
||||||
let message = msg;
|
let message = msg;
|
||||||
let isTranslated = false;
|
|
||||||
// "autoTranslateRoom" and "autoTranslateLanguage" are properties from the subscription
|
// "autoTranslateRoom" and "autoTranslateLanguage" are properties from the subscription
|
||||||
// "autoTranslateMessage" is a toggle between "View Original" and "Translate" state
|
// "autoTranslateMessage" is a toggle between "View Original" and "Translate" state
|
||||||
if (autoTranslateRoom && autoTranslateMessage && autoTranslateLanguage) {
|
if (autoTranslateRoom && autoTranslateMessage && autoTranslateLanguage) {
|
||||||
const messageTranslated = getMessageTranslation(item, autoTranslateLanguage);
|
message = getMessageTranslation(item, autoTranslateLanguage) || message;
|
||||||
isTranslated = !!messageTranslated;
|
|
||||||
message = messageTranslated || message;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -455,11 +451,10 @@ class MessageContainer extends React.Component<IMessageContainerProps, IMessageC
|
||||||
showAttachment={showAttachment}
|
showAttachment={showAttachment}
|
||||||
getCustomEmoji={getCustomEmoji}
|
getCustomEmoji={getCustomEmoji}
|
||||||
navToRoomInfo={navToRoomInfo}
|
navToRoomInfo={navToRoomInfo}
|
||||||
handleEnterCall={handleEnterCall}
|
callJitsi={callJitsi}
|
||||||
blockAction={blockAction}
|
blockAction={blockAction}
|
||||||
highlighted={highlighted}
|
highlighted={highlighted}
|
||||||
comment={comment}
|
comment={comment}
|
||||||
isTranslated={isTranslated}
|
|
||||||
/>
|
/>
|
||||||
</MessageContext.Provider>
|
</MessageContext.Provider>
|
||||||
);
|
);
|
||||||
|
|
|
@ -40,7 +40,7 @@ export interface IMessageBroadcast {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IMessageCallButton {
|
export interface IMessageCallButton {
|
||||||
handleEnterCall?: () => void;
|
callJitsi?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IMessageContent {
|
export interface IMessageContent {
|
||||||
|
@ -63,7 +63,6 @@ export interface IMessageContent {
|
||||||
comment?: string;
|
comment?: string;
|
||||||
hasError: boolean;
|
hasError: boolean;
|
||||||
isHeader: boolean;
|
isHeader: boolean;
|
||||||
isTranslated: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IMessageEmoji {
|
export interface IMessageEmoji {
|
||||||
|
|
|
@ -41,13 +41,13 @@ export default StyleSheet.create({
|
||||||
reactionButton: {
|
reactionButton: {
|
||||||
marginRight: 8,
|
marginRight: 8,
|
||||||
marginBottom: 8,
|
marginBottom: 8,
|
||||||
borderRadius: 4
|
borderRadius: 2
|
||||||
},
|
},
|
||||||
reactionContainer: {
|
reactionContainer: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
borderRadius: 4,
|
borderRadius: 2,
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
height: 28,
|
height: 28,
|
||||||
minWidth: 46.3
|
minWidth: 46.3
|
||||||
|
@ -85,7 +85,7 @@ export default StyleSheet.create({
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
borderRadius: 4
|
borderRadius: 2
|
||||||
},
|
},
|
||||||
buttonIcon: {
|
buttonIcon: {
|
||||||
marginRight: 8
|
marginRight: 8
|
||||||
|
|
|
@ -65,7 +65,6 @@ const messagesWithAuthorName: MessageTypesValues[] = [
|
||||||
'room_changed_avatar',
|
'room_changed_avatar',
|
||||||
'room_e2e_disabled',
|
'room_e2e_disabled',
|
||||||
'room_e2e_enabled',
|
'room_e2e_enabled',
|
||||||
'room-allowed-reacting',
|
|
||||||
'room-disallowed-reacting',
|
'room-disallowed-reacting',
|
||||||
'room-set-read-only',
|
'room-set-read-only',
|
||||||
'room-removed-read-only',
|
'room-removed-read-only',
|
||||||
|
|
|
@ -8,15 +8,7 @@ import { TThreadMessageModel } from './IThreadMessage';
|
||||||
import { TThreadModel } from './IThread';
|
import { TThreadModel } from './IThread';
|
||||||
import { IUrl, IUrlFromServer } from './IUrl';
|
import { IUrl, IUrlFromServer } from './IUrl';
|
||||||
|
|
||||||
export type MessageType =
|
export type MessageType = 'jitsi_call_started' | 'discussion-created' | 'e2e' | 'load_more' | 'rm' | 'uj' | MessageTypeLoad | MessageTypesValues;
|
||||||
| 'jitsi_call_started'
|
|
||||||
| 'discussion-created'
|
|
||||||
| 'e2e'
|
|
||||||
| 'load_more'
|
|
||||||
| 'rm'
|
|
||||||
| 'uj'
|
|
||||||
| MessageTypeLoad
|
|
||||||
| MessageTypesValues;
|
|
||||||
|
|
||||||
export interface IUserMessage {
|
export interface IUserMessage {
|
||||||
_id: string;
|
_id: string;
|
||||||
|
@ -230,7 +222,6 @@ export type MessageTypesValues =
|
||||||
| 'room-allowed-reacting'
|
| 'room-allowed-reacting'
|
||||||
| 'room-disallowed-reacting'
|
| 'room-disallowed-reacting'
|
||||||
| 'command'
|
| 'command'
|
||||||
| 'videoconf'
|
|
||||||
| LivechatMessageTypes
|
| LivechatMessageTypes
|
||||||
| TeamMessageTypes
|
| TeamMessageTypes
|
||||||
| VoipMessageTypesValues
|
| VoipMessageTypesValues
|
||||||
|
|
|
@ -91,7 +91,6 @@ export interface ISubscription {
|
||||||
livechatData?: any;
|
livechatData?: any;
|
||||||
tags?: string[];
|
tags?: string[];
|
||||||
E2EKey?: string;
|
E2EKey?: string;
|
||||||
E2ESuggestedKey?: string;
|
|
||||||
encrypted?: boolean;
|
encrypted?: boolean;
|
||||||
e2eKeyId?: string;
|
e2eKeyId?: string;
|
||||||
avatarETag?: string;
|
avatarETag?: string;
|
||||||
|
@ -146,7 +145,6 @@ export interface IServerSubscription extends IRocketChatRecord {
|
||||||
onHold?: boolean;
|
onHold?: boolean;
|
||||||
encrypted?: boolean;
|
encrypted?: boolean;
|
||||||
E2EKey?: string;
|
E2EKey?: string;
|
||||||
E2ESuggestedKey?: string;
|
|
||||||
unreadAlert?: 'default' | 'all' | 'mentions' | 'nothing';
|
unreadAlert?: 'default' | 'all' | 'mentions' | 'nothing';
|
||||||
|
|
||||||
fname?: unknown;
|
fname?: unknown;
|
||||||
|
|
|
@ -5,7 +5,6 @@ export interface IUpload {
|
||||||
rid?: string;
|
rid?: string;
|
||||||
path: string;
|
path: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
tmid?: string;
|
|
||||||
description?: string;
|
description?: string;
|
||||||
size: number;
|
size: number;
|
||||||
type?: string;
|
type?: string;
|
||||||
|
@ -13,7 +12,6 @@ export interface IUpload {
|
||||||
progress?: number;
|
progress?: number;
|
||||||
error?: boolean;
|
error?: boolean;
|
||||||
subscription?: { id: string };
|
subscription?: { id: string };
|
||||||
msg?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TUploadModel = IUpload & Model;
|
export type TUploadModel = IUpload & Model;
|
||||||
|
|
|
@ -1,109 +0,0 @@
|
||||||
import type { AtLeast } from './utils';
|
|
||||||
import type { IRocketChatRecord } from './IRocketChatRecord';
|
|
||||||
import type { IRoom } from './IRoom';
|
|
||||||
import type { IUser } from './IUser';
|
|
||||||
import type { IMessage } from './IMessage';
|
|
||||||
|
|
||||||
export declare enum VideoConferenceStatus {
|
|
||||||
CALLING = 0,
|
|
||||||
STARTED = 1,
|
|
||||||
EXPIRED = 2,
|
|
||||||
ENDED = 3,
|
|
||||||
DECLINED = 4
|
|
||||||
}
|
|
||||||
export declare type DirectCallInstructions = {
|
|
||||||
type: 'direct';
|
|
||||||
calleeId: IUser['_id'];
|
|
||||||
callId: string;
|
|
||||||
};
|
|
||||||
export declare type ConferenceInstructions = {
|
|
||||||
type: 'videoconference';
|
|
||||||
callId: string;
|
|
||||||
rid: IRoom['_id'];
|
|
||||||
};
|
|
||||||
export declare type LivechatInstructions = {
|
|
||||||
type: 'livechat';
|
|
||||||
callId: string;
|
|
||||||
};
|
|
||||||
export declare type VideoConferenceType =
|
|
||||||
| DirectCallInstructions['type']
|
|
||||||
| ConferenceInstructions['type']
|
|
||||||
| LivechatInstructions['type'];
|
|
||||||
export interface IVideoConferenceUser extends Pick<Required<IUser>, '_id' | 'username' | 'name' | 'avatarETag'> {
|
|
||||||
ts: Date;
|
|
||||||
}
|
|
||||||
export interface IVideoConference extends IRocketChatRecord {
|
|
||||||
type: VideoConferenceType;
|
|
||||||
rid: string;
|
|
||||||
users: IVideoConferenceUser[];
|
|
||||||
status: VideoConferenceStatus;
|
|
||||||
messages: {
|
|
||||||
started?: IMessage['_id'];
|
|
||||||
ended?: IMessage['_id'];
|
|
||||||
};
|
|
||||||
url?: string;
|
|
||||||
createdBy: Pick<Required<IUser>, '_id' | 'username' | 'name'>;
|
|
||||||
createdAt: Date;
|
|
||||||
endedBy?: Pick<Required<IUser>, '_id' | 'username' | 'name'>;
|
|
||||||
endedAt?: Date;
|
|
||||||
providerName: string;
|
|
||||||
providerData?: Record<string, any>;
|
|
||||||
ringing?: boolean;
|
|
||||||
}
|
|
||||||
export interface IDirectVideoConference extends IVideoConference {
|
|
||||||
type: 'direct';
|
|
||||||
}
|
|
||||||
export interface IGroupVideoConference extends IVideoConference {
|
|
||||||
type: 'videoconference';
|
|
||||||
anonymousUsers: number;
|
|
||||||
title: string;
|
|
||||||
}
|
|
||||||
export interface ILivechatVideoConference extends IVideoConference {
|
|
||||||
type: 'livechat';
|
|
||||||
}
|
|
||||||
export declare type VideoConference = IDirectVideoConference | IGroupVideoConference | ILivechatVideoConference;
|
|
||||||
export declare type VideoConferenceInstructions = DirectCallInstructions | ConferenceInstructions | LivechatInstructions;
|
|
||||||
export declare const isDirectVideoConference: (call: VideoConference | undefined | null) => call is IDirectVideoConference;
|
|
||||||
export declare const isGroupVideoConference: (call: VideoConference | undefined | null) => call is IGroupVideoConference;
|
|
||||||
export declare const isLivechatVideoConference: (call: VideoConference | undefined | null) => call is ILivechatVideoConference;
|
|
||||||
declare type GroupVideoConferenceCreateData = Omit<IGroupVideoConference, 'createdBy'> & {
|
|
||||||
createdBy: IUser['_id'];
|
|
||||||
};
|
|
||||||
declare type DirectVideoConferenceCreateData = Omit<IDirectVideoConference, 'createdBy'> & {
|
|
||||||
createdBy: IUser['_id'];
|
|
||||||
};
|
|
||||||
declare type LivechatVideoConferenceCreateData = Omit<ILivechatVideoConference, 'createdBy'> & {
|
|
||||||
createdBy: IUser['_id'];
|
|
||||||
};
|
|
||||||
export declare type VideoConferenceCreateData = AtLeast<
|
|
||||||
DirectVideoConferenceCreateData | GroupVideoConferenceCreateData | LivechatVideoConferenceCreateData,
|
|
||||||
'createdBy' | 'type' | 'rid' | 'providerName' | 'providerData'
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type VideoConferenceCapabilities = {
|
|
||||||
mic?: boolean;
|
|
||||||
cam?: boolean;
|
|
||||||
title?: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type VideoConfStartProps = { roomId: string; title?: string; allowRinging?: boolean };
|
|
||||||
|
|
||||||
export type VideoConfJoinProps = {
|
|
||||||
callId: string;
|
|
||||||
state?: {
|
|
||||||
mic?: boolean;
|
|
||||||
cam?: boolean;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export type VideoConfCancelProps = {
|
|
||||||
callId: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type VideoConfListProps = {
|
|
||||||
roomId: string;
|
|
||||||
count?: number;
|
|
||||||
offset?: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type VideoConfInfoProps = { callId: string };
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue