feat(conference) added React Navigation
Introduce navigation for all in-conference screens.
This commit is contained in:
parent
a5129ef291
commit
9df59b4a6f
|
@ -82,7 +82,7 @@ public class MainActivity extends JitsiMeetActivity {
|
|||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
JitsiMeet.showSplashScreen(this);
|
||||
super.onCreate(savedInstanceState);
|
||||
super.onCreate(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -110,7 +110,7 @@ allprojects {
|
|||
|
||||
project.version = "${json.version}-jitsi-${versionQualifierNumber}"
|
||||
|
||||
task androidSourcesJar(type: Jar) {
|
||||
task jitsiAndroidSourcesJar(type: Jar) {
|
||||
classifier = 'sources'
|
||||
from android.sourceSets.main.java.source
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ allprojects {
|
|||
artifact("${project.buildDir}/outputs/aar/${project.name}-release.aar") {
|
||||
extension "aar"
|
||||
}
|
||||
artifact(androidSourcesJar)
|
||||
artifact(jitsiAndroidSourcesJar)
|
||||
pom.withXml {
|
||||
def pomXml = asNode()
|
||||
pomXml.appendNode('name', project.name)
|
||||
|
|
|
@ -70,9 +70,14 @@ dependencies {
|
|||
implementation project(':react-native-calendar-events')
|
||||
implementation project(':react-native-community_netinfo')
|
||||
implementation project(':react-native-default-preference')
|
||||
implementation project(':react-native-gesture-handler')
|
||||
implementation project(':react-native-immersive')
|
||||
implementation project(':react-native-keep-awake')
|
||||
implementation project(':react-native-masked-view_masked-view')
|
||||
implementation project(':react-native-performance')
|
||||
implementation project(':react-native-reanimated')
|
||||
implementation project(':react-native-safe-area-context')
|
||||
implementation project(':react-native-screens')
|
||||
implementation project(':react-native-slider')
|
||||
implementation project(':react-native-sound')
|
||||
implementation project(':react-native-splash-screen')
|
||||
|
|
|
@ -24,7 +24,7 @@ import android.net.Uri;
|
|||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import com.facebook.react.modules.core.PermissionListener;
|
||||
|
@ -38,7 +38,7 @@ import android.app.Activity;
|
|||
* A base activity for SDK users to embed. It uses {@link JitsiMeetFragment} to do the heavy
|
||||
* lifting and wires the remaining Activity lifecycle methods so it works out of the box.
|
||||
*/
|
||||
public class JitsiMeetActivity extends FragmentActivity
|
||||
public class JitsiMeetActivity extends AppCompatActivity
|
||||
implements JitsiMeetActivityInterface {
|
||||
|
||||
protected static final String TAG = JitsiMeetActivity.class.getSimpleName();
|
||||
|
|
|
@ -175,21 +175,26 @@ class ReactInstanceManagerHolder {
|
|||
|
||||
List<ReactPackage> packages
|
||||
= new ArrayList<>(Arrays.asList(
|
||||
new com.reactnativecommunity.asyncstorage.AsyncStoragePackage(),
|
||||
new com.ocetnik.timer.BackgroundTimerPackage(),
|
||||
new com.calendarevents.CalendarEventsPackage(),
|
||||
new com.corbt.keepawake.KCKeepAwakePackage(),
|
||||
new com.facebook.react.shell.MainReactPackage(),
|
||||
new com.horcrux.svg.SvgPackage(),
|
||||
new com.reactnativecommunity.netinfo.NetInfoPackage(),
|
||||
new com.oblador.performance.PerformancePackage(),
|
||||
new com.reactnativecommunity.slider.ReactSliderPackage(),
|
||||
new com.brentvatne.react.ReactVideoPackage(),
|
||||
new com.swmansion.reanimated.ReanimatedPackage(),
|
||||
new org.reactnative.maskedview.RNCMaskedViewPackage(),
|
||||
new com.reactnativecommunity.webview.RNCWebViewPackage(),
|
||||
new com.kevinresol.react_native_default_preference.RNDefaultPreferencePackage(),
|
||||
new com.learnium.RNDeviceInfo.RNDeviceInfo(),
|
||||
new com.oblador.performance.PerformancePackage(),
|
||||
new com.ocetnik.timer.BackgroundTimerPackage(),
|
||||
new com.reactnativecommunity.asyncstorage.AsyncStoragePackage(),
|
||||
new com.reactnativecommunity.netinfo.NetInfoPackage(),
|
||||
new com.reactnativecommunity.slider.ReactSliderPackage(),
|
||||
new com.reactnativecommunity.webview.RNCWebViewPackage(),
|
||||
new com.swmansion.gesturehandler.react.RNGestureHandlerPackage(),
|
||||
new com.rnimmersive.RNImmersivePackage(),
|
||||
new com.swmansion.rnscreens.RNScreensPackage(),
|
||||
new com.zmxv.RNSound.RNSoundPackage(),
|
||||
new com.brentvatne.react.ReactVideoPackage(),
|
||||
new com.th3rdwave.safeareacontext.SafeAreaContextPackage(),
|
||||
new com.horcrux.svg.SvgPackage(),
|
||||
new ReactPackageAdapter() {
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
||||
|
|
|
@ -15,14 +15,24 @@ include ':react-native-default-preference'
|
|||
project(':react-native-default-preference').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-default-preference/android')
|
||||
include ':react-native-device-info'
|
||||
project(':react-native-device-info').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-device-info/android')
|
||||
include ':react-native-gesture-handler'
|
||||
project(':react-native-gesture-handler').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-gesture-handler/android')
|
||||
include ':react-native-google-signin'
|
||||
project(':react-native-google-signin').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/google-signin/android')
|
||||
include ':react-native-immersive'
|
||||
project(':react-native-immersive').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-immersive/android')
|
||||
include ':react-native-keep-awake'
|
||||
project(':react-native-keep-awake').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-keep-awake/android')
|
||||
include ':react-native-masked-view_masked-view'
|
||||
project(':react-native-masked-view_masked-view').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-masked-view/masked-view/android')
|
||||
include ':react-native-performance'
|
||||
project(':react-native-performance').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-performance/android')
|
||||
include ':react-native-reanimated'
|
||||
project(':react-native-reanimated').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-reanimated/android')
|
||||
include ':react-native-safe-area-context'
|
||||
project(':react-native-safe-area-context').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-safe-area-context/android')
|
||||
include ':react-native-screens'
|
||||
project(':react-native-screens').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-screens/android')
|
||||
include ':react-native-slider'
|
||||
project(':react-native-slider').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/slider/android')
|
||||
include ':react-native-sound'
|
||||
|
|
|
@ -72,6 +72,11 @@ target 'JitsiMeetSDK' do
|
|||
pod 'RNSVG', :path => '../node_modules/react-native-svg'
|
||||
pod 'RNWatch', :path => '../node_modules/react-native-watch-connectivity'
|
||||
pod 'RNDefaultPreference', :path => '../node_modules/react-native-default-preference'
|
||||
pod 'RNGestureHandler', :path => '../node_modules/react-native-gesture-handler'
|
||||
pod 'RNReanimated', :path => '../node_modules/react-native-reanimated'
|
||||
pod 'RNScreens', :path => '../node_modules/react-native-screens'
|
||||
pod 'react-native-safe-area-context', :path => '../node_modules/react-native-safe-area-context'
|
||||
pod 'RNCMaskedView', :path => '../node_modules/@react-native-masked-view/masked-view'
|
||||
|
||||
# Native pod dependencies
|
||||
#
|
||||
|
|
|
@ -109,7 +109,7 @@ PODS:
|
|||
- GTMAppAuth (1.2.2):
|
||||
- AppAuth/Core (~> 1.4)
|
||||
- GTMSessionFetcher/Core (~> 1.5)
|
||||
- GTMSessionFetcher/Core (1.6.1)
|
||||
- GTMSessionFetcher/Core (1.7.0)
|
||||
- nanopb (1.30906.0):
|
||||
- nanopb/decode (= 1.30906.0)
|
||||
- nanopb/encode (= 1.30906.0)
|
||||
|
@ -290,6 +290,8 @@ PODS:
|
|||
- React
|
||||
- react-native-performance (2.0.0):
|
||||
- React-Core
|
||||
- react-native-safe-area-context (3.3.2):
|
||||
- React-Core
|
||||
- react-native-slider (3.0.3):
|
||||
- React
|
||||
- react-native-splash-screen (3.2.0):
|
||||
|
@ -359,13 +361,21 @@ PODS:
|
|||
- ReactCommon/turbomodule/core (= 0.61.5-jitsi.2)
|
||||
- RNCAsyncStorage (1.15.5):
|
||||
- React-Core
|
||||
- RNCMaskedView (0.2.6):
|
||||
- React-Core
|
||||
- RNDefaultPreference (1.4.2):
|
||||
- React
|
||||
- RNDeviceInfo (8.0.0):
|
||||
- React-Core
|
||||
- RNGestureHandler (1.10.3):
|
||||
- React-Core
|
||||
- RNGoogleSignin (3.0.1):
|
||||
- GoogleSignIn (~> 5.0.0)
|
||||
- React
|
||||
- RNReanimated (1.13.3):
|
||||
- React-Core
|
||||
- RNScreens (2.18.1):
|
||||
- React-Core
|
||||
- RNSound (0.11.0):
|
||||
- React
|
||||
- RNSound/Core (= 0.11.0)
|
||||
|
@ -405,6 +415,7 @@ DEPENDENCIES:
|
|||
- react-native-keep-awake (from `../node_modules/react-native-keep-awake`)
|
||||
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
|
||||
- react-native-performance (from `../node_modules/react-native-performance/ios`)
|
||||
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
|
||||
- "react-native-slider (from `../node_modules/@react-native-community/slider`)"
|
||||
- react-native-splash-screen (from `../node_modules/react-native-splash-screen`)
|
||||
- react-native-video (from `../node_modules/react-native-video/react-native-video.podspec`)
|
||||
|
@ -421,9 +432,13 @@ DEPENDENCIES:
|
|||
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
|
||||
- ReactCommon/turbomodule (from `../node_modules/react-native/ReactCommon`)
|
||||
- "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)"
|
||||
- "RNCMaskedView (from `../node_modules/@react-native-masked-view/masked-view`)"
|
||||
- RNDefaultPreference (from `../node_modules/react-native-default-preference`)
|
||||
- RNDeviceInfo (from `../node_modules/react-native-device-info`)
|
||||
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
|
||||
- "RNGoogleSignin (from `../node_modules/@react-native-community/google-signin`)"
|
||||
- RNReanimated (from `../node_modules/react-native-reanimated`)
|
||||
- RNScreens (from `../node_modules/react-native-screens`)
|
||||
- RNSound (from `../node_modules/react-native-sound`)
|
||||
- RNSVG (from `../node_modules/react-native-svg`)
|
||||
- RNWatch (from `../node_modules/react-native-watch-connectivity`)
|
||||
|
@ -493,6 +508,8 @@ EXTERNAL SOURCES:
|
|||
:path: "../node_modules/@react-native-community/netinfo"
|
||||
react-native-performance:
|
||||
:path: "../node_modules/react-native-performance/ios"
|
||||
react-native-safe-area-context:
|
||||
:path: "../node_modules/react-native-safe-area-context"
|
||||
react-native-slider:
|
||||
:path: "../node_modules/@react-native-community/slider"
|
||||
react-native-splash-screen:
|
||||
|
@ -525,12 +542,20 @@ EXTERNAL SOURCES:
|
|||
:path: "../node_modules/react-native/ReactCommon"
|
||||
RNCAsyncStorage:
|
||||
:path: "../node_modules/@react-native-async-storage/async-storage"
|
||||
RNCMaskedView:
|
||||
:path: "../node_modules/@react-native-masked-view/masked-view"
|
||||
RNDefaultPreference:
|
||||
:path: "../node_modules/react-native-default-preference"
|
||||
RNDeviceInfo:
|
||||
:path: "../node_modules/react-native-device-info"
|
||||
RNGestureHandler:
|
||||
:path: "../node_modules/react-native-gesture-handler"
|
||||
RNGoogleSignin:
|
||||
:path: "../node_modules/@react-native-community/google-signin"
|
||||
RNReanimated:
|
||||
:path: "../node_modules/react-native-reanimated"
|
||||
RNScreens:
|
||||
:path: "../node_modules/react-native-screens"
|
||||
RNSound:
|
||||
:path: "../node_modules/react-native-sound"
|
||||
RNSVG:
|
||||
|
@ -563,7 +588,7 @@ SPEC CHECKSUMS:
|
|||
GoogleSignIn: 7137d297ddc022a7e0aa4619c86d72c909fa7213
|
||||
GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3
|
||||
GTMAppAuth: ad5c2b70b9a8689e1a04033c9369c4915bfcbe89
|
||||
GTMSessionFetcher: 36689134877faeb055b27dfa4ccc9ceaa42e029e
|
||||
GTMSessionFetcher: 43748f93435c2aa068b1cbe39655aaf600652e91
|
||||
nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc
|
||||
ObjectiveDropboxOfficial: b4765572e334d6fc6214b43a7595510324bbbbaa
|
||||
PromisesObjC: 3113f7f76903778cf4a0586bd1ab89329a0b7b97
|
||||
|
@ -581,6 +606,7 @@ SPEC CHECKSUMS:
|
|||
react-native-keep-awake: afad8a51dfef9fe9655a6344771be32c8596d774
|
||||
react-native-netinfo: 0e563248a4b9a99c33ec29bd03c2d50767db22a6
|
||||
react-native-performance: 6bd6cfac80594775fb782405fceaaf206becf53b
|
||||
react-native-safe-area-context: 584dc04881deb49474363f3be89e4ca0e854c057
|
||||
react-native-slider: e99fc201cefe81270fc9d81714a7a0f5e566b168
|
||||
react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865
|
||||
react-native-video: 0bb76b6d6b77da3009611586c7dbf817b947f30e
|
||||
|
@ -597,14 +623,18 @@ SPEC CHECKSUMS:
|
|||
React-RCTVibration: c1041024893fdfdb8371e7c720c437751b711676
|
||||
ReactCommon: 18014e1d98dbeb9141e935cfe35fc93bd511ffb6
|
||||
RNCAsyncStorage: 56a3355a10b5d660c48c6e37325ac85ebfd09885
|
||||
RNCMaskedView: c298b644a10c0c142055b3ae24d83879ecb13ccd
|
||||
RNDefaultPreference: 1f8133ec0bc0f9453cdada578564ba1ef551fb44
|
||||
RNDeviceInfo: 87d2d175c760f6bcf58acd036f887e8b2392802c
|
||||
RNGestureHandler: a479ebd5ed4221a810967000735517df0d2db211
|
||||
RNGoogleSignin: 39336070b35fc4cea6a98cf111e00480317be0ae
|
||||
RNReanimated: 514a11da3a2bcc6c3dfd9de32b38e2b9bf101926
|
||||
RNScreens: f7ad633b2e0190b77b6a7aab7f914fad6f198d8d
|
||||
RNSound: da030221e6ac7e8290c6b43f2b5f2133a8e225b0
|
||||
RNSVG: ce9d996113475209013317e48b05c21ee988d42e
|
||||
RNWatch: a5320c959c75e72845c07985f3e935e58998f1d3
|
||||
Yoga: 96b469c5e81ff51b917b92e8c3390642d4ded30c
|
||||
|
||||
PODFILE CHECKSUM: 3cc305fd6ee83fff506c10c4805471fa72b61c9a
|
||||
PODFILE CHECKSUM: 42be6796ba6ac039dae5c02125677728ecd0df0d
|
||||
|
||||
COCOAPODS: 1.10.1
|
||||
|
|
|
@ -37,6 +37,10 @@
|
|||
"@react-native-community/google-signin": "3.0.1",
|
||||
"@react-native-community/netinfo": "4.1.5",
|
||||
"@react-native-community/slider": "3.0.3",
|
||||
"@react-native-masked-view/masked-view": "0.2.6",
|
||||
"@react-navigation/material-top-tabs": "5.3.19",
|
||||
"@react-navigation/native": "5.9.8",
|
||||
"@react-navigation/stack": "5.14.9",
|
||||
"@svgr/webpack": "4.3.2",
|
||||
"amplitude-js": "8.2.1",
|
||||
"base64-js": "1.3.1",
|
||||
|
@ -76,14 +80,19 @@
|
|||
"react-native-collapsible": "1.5.1",
|
||||
"react-native-default-preference": "1.4.2",
|
||||
"react-native-device-info": "8.0.0",
|
||||
"react-native-gesture-handler": "1.10.3",
|
||||
"react-native-immersive": "2.0.0",
|
||||
"react-native-keep-awake": "4.0.0",
|
||||
"react-native-paper": "4.8.1",
|
||||
"react-native-performance": "2.0.0",
|
||||
"react-native-reanimated": "1.13.3",
|
||||
"react-native-safe-area-context": "3.3.2",
|
||||
"react-native-screens": "2.18.1",
|
||||
"react-native-sound": "github:jitsi/react-native-sound#3fe5480fce935e888d5089d94a191c7c7e3aa190",
|
||||
"react-native-splash-screen": "3.2.0",
|
||||
"react-native-svg": "12.1.0",
|
||||
"react-native-svg-transformer": "0.14.3",
|
||||
"react-native-tab-view": "2.16.0",
|
||||
"react-native-url-polyfill": "1.2.0",
|
||||
"react-native-video": "5.1.1",
|
||||
"react-native-watch-connectivity": "0.4.3",
|
||||
|
@ -2929,6 +2938,17 @@
|
|||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@egjs/hammerjs": {
|
||||
"version": "2.0.17",
|
||||
"resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz",
|
||||
"integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==",
|
||||
"dependencies": {
|
||||
"@types/hammerjs": "^2.0.36"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/cache": {
|
||||
"version": "10.0.29",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.29.tgz",
|
||||
|
@ -4036,6 +4056,133 @@
|
|||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native-masked-view/masked-view": {
|
||||
"version": "0.2.6",
|
||||
"resolved": "https://registry.npmjs.org/@react-native-masked-view/masked-view/-/masked-view-0.2.6.tgz",
|
||||
"integrity": "sha512-303CxmetUmgiX9NSUxatZkNh9qTYYdiM8xkGf9I3Uj20U3eGY3M78ljeNQ4UVCJA+FNGS5nC1dtS9GjIqvB4dg==",
|
||||
"peerDependencies": {
|
||||
"react": "16 || 17",
|
||||
"react-native": ">=0.57"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-navigation/core": {
|
||||
"version": "5.16.1",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-5.16.1.tgz",
|
||||
"integrity": "sha512-3AToC7vPNeSNcHFLd1h71L6u34hfXoRAS1CxF9Fc4uC8uOrVqcNvphpeFbE0O9Bw6Zpl0BnMFl7E5gaL3KGzNA==",
|
||||
"dependencies": {
|
||||
"@react-navigation/routers": "^5.7.4",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"nanoid": "^3.1.15",
|
||||
"query-string": "^6.13.6",
|
||||
"react-is": "^16.13.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-navigation/core/node_modules/escape-string-regexp": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-navigation/core/node_modules/query-string": {
|
||||
"version": "6.14.1",
|
||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-6.14.1.tgz",
|
||||
"integrity": "sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==",
|
||||
"dependencies": {
|
||||
"decode-uri-component": "^0.2.0",
|
||||
"filter-obj": "^1.1.0",
|
||||
"split-on-first": "^1.0.0",
|
||||
"strict-uri-encode": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-navigation/core/node_modules/strict-uri-encode": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
|
||||
"integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-navigation/material-top-tabs": {
|
||||
"version": "5.3.19",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/material-top-tabs/-/material-top-tabs-5.3.19.tgz",
|
||||
"integrity": "sha512-I7bEF99THxxcY7kCUZ5pPmwXr6kgo6L2sg3P1YJo+CcBWSGvGiHyNbZXNs15HuKRuFvEuueChNV9n8QuKBWbDA==",
|
||||
"dependencies": {
|
||||
"color": "^3.1.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@react-navigation/native": "^5.0.5",
|
||||
"react": "*",
|
||||
"react-native": "*",
|
||||
"react-native-gesture-handler": ">= 1.0.0",
|
||||
"react-native-reanimated": ">= 1.0.0",
|
||||
"react-native-tab-view": ">= 2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-navigation/native": {
|
||||
"version": "5.9.8",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-5.9.8.tgz",
|
||||
"integrity": "sha512-DNbcDHXQPSFDLn51kkVVJjT3V7jJy2GztNYZe/2bEg29mi5QEcHHcpifjMCtyFKntAOWzKlG88UicIQ17UEghg==",
|
||||
"dependencies": {
|
||||
"@react-navigation/core": "^5.16.1",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"nanoid": "^3.1.15"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-navigation/native/node_modules/escape-string-regexp": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-navigation/routers": {
|
||||
"version": "5.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-5.7.4.tgz",
|
||||
"integrity": "sha512-0N202XAqsU/FlE53Nmh6GHyMtGm7g6TeC93mrFAFJOqGRKznT0/ail+cYlU6tNcPA9AHzZu1Modw1eoDINSliQ==",
|
||||
"dependencies": {
|
||||
"nanoid": "^3.1.15"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-navigation/stack": {
|
||||
"version": "5.14.9",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-5.14.9.tgz",
|
||||
"integrity": "sha512-DuvrT9P+Tz8ezZLQYxORZqOGqO+vEufaxlW1hSLw1knLD4jNxkz8TJDXtfKwaz//9gb43UhTNccNM02vm7iPqQ==",
|
||||
"dependencies": {
|
||||
"color": "^3.1.3",
|
||||
"react-native-iphone-x-helper": "^1.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@react-native-community/masked-view": ">= 0.1.0",
|
||||
"@react-navigation/native": "^5.0.5",
|
||||
"react": "*",
|
||||
"react-native": "*",
|
||||
"react-native-gesture-handler": ">= 1.0.0",
|
||||
"react-native-safe-area-context": ">= 0.6.0",
|
||||
"react-native-screens": ">= 2.0.0-alpha.0 || >= 2.0.0-beta.0 || >= 2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@svgr/babel-plugin-add-jsx-attribute": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz",
|
||||
|
@ -5045,6 +5192,11 @@
|
|||
"integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/hammerjs": {
|
||||
"version": "2.0.40",
|
||||
"resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.40.tgz",
|
||||
"integrity": "sha512-VbjwR1fhsn2h2KXAY4oy1fm7dCxaKy0D+deTb8Ilc3Eo3rc5+5eA4rfYmZaHgNJKxVyI0f6WIXzO2zLkVmQPHA=="
|
||||
},
|
||||
"node_modules/@types/http-proxy": {
|
||||
"version": "1.17.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.7.tgz",
|
||||
|
@ -7651,6 +7803,22 @@
|
|||
"object-assign": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-fetch": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz",
|
||||
"integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==",
|
||||
"dependencies": {
|
||||
"node-fetch": "2.6.1"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-fetch/node_modules/node-fetch": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
|
||||
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-os": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/cross-os/-/cross-os-1.4.0.tgz",
|
||||
|
@ -10014,6 +10182,14 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/filter-obj": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
|
||||
"integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs=",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/finalhandler": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
|
||||
|
@ -10582,12 +10758,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/fsevents/node_modules/mkdirp": {
|
||||
"version": "0.5.5",
|
||||
"version": "0.5.1",
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.5"
|
||||
"minimist": "0.0.8"
|
||||
},
|
||||
"bin": {
|
||||
"mkdirp": "bin/cmd.js"
|
||||
|
@ -10764,7 +10940,7 @@
|
|||
}
|
||||
},
|
||||
"node_modules/fsevents/node_modules/rc/node_modules/minimist": {
|
||||
"version": "1.2.5",
|
||||
"version": "1.2.0",
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
|
@ -11812,9 +11988,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/invariant": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.3.tgz",
|
||||
"integrity": "sha512-7Z5PPegwDTyjbaeCnV0efcyS6vdKAU51kpEmS7QFib3P4822l8ICYyMn7qvJnc+WzLoDsuI9gPMKbJ8pCu8XtA==",
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
|
@ -12382,14 +12558,6 @@
|
|||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
|
||||
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ=="
|
||||
},
|
||||
"node_modules/jest-haste-map/node_modules/invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-message-util": {
|
||||
"version": "24.9.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz",
|
||||
|
@ -13641,14 +13809,6 @@
|
|||
"vlq": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/metro-source-map/node_modules/invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/metro-symbolicate": {
|
||||
"version": "0.56.4",
|
||||
"resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.56.4.tgz",
|
||||
|
@ -13667,14 +13827,6 @@
|
|||
"node": ">=8.3"
|
||||
}
|
||||
},
|
||||
"node_modules/metro-symbolicate/node_modules/invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/metro/node_modules/@babel/helper-plugin-utils": {
|
||||
"version": "7.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
|
||||
|
@ -13759,14 +13911,6 @@
|
|||
"klaw": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/metro/node_modules/invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/metro/node_modules/jsonfile": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
|
||||
|
@ -14124,6 +14268,17 @@
|
|||
"integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.1.30",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz",
|
||||
"integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==",
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/nanomatch": {
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
|
||||
|
@ -16558,6 +16713,32 @@
|
|||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-gesture-handler": {
|
||||
"version": "1.10.3",
|
||||
"resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-1.10.3.tgz",
|
||||
"integrity": "sha512-cBGMi1IEsIVMgoox4RvMx7V2r6bNKw0uR1Mu1o7NbuHS6BRSVLq0dP34l2ecnPlC+jpWd3le6Yg1nrdCjby2Mw==",
|
||||
"dependencies": {
|
||||
"@egjs/hammerjs": "^2.0.17",
|
||||
"fbjs": "^3.0.0",
|
||||
"hoist-non-react-statics": "^3.3.0",
|
||||
"invariant": "^2.2.4",
|
||||
"prop-types": "^15.7.2"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-gesture-handler/node_modules/fbjs": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.0.tgz",
|
||||
"integrity": "sha512-dJd4PiDOFuhe7vk4F80Mba83Vr2QuK86FoxtgPmzBqEJahncp+13YCmfoa53KHCo6OnlXLG7eeMWPfB5CrpVKg==",
|
||||
"dependencies": {
|
||||
"cross-fetch": "^3.0.4",
|
||||
"fbjs-css-vars": "^1.0.0",
|
||||
"loose-envify": "^1.0.0",
|
||||
"object-assign": "^4.1.0",
|
||||
"promise": "^7.1.1",
|
||||
"setimmediate": "^1.0.5",
|
||||
"ua-parser-js": "^0.7.18"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-immersive": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-immersive/-/react-native-immersive-2.0.0.tgz",
|
||||
|
@ -16602,6 +16783,51 @@
|
|||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-reanimated": {
|
||||
"version": "1.13.3",
|
||||
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-1.13.3.tgz",
|
||||
"integrity": "sha512-i714H24dv6ncpFO7/SZ0PfAMbvjgVbF8Ow2NPtowoZAz8osS54DmTMrkgJ9Za+uEku/s0AEaxqiXG2Xgntvv2g==",
|
||||
"dependencies": {
|
||||
"fbjs": "^1.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-reanimated/node_modules/fbjs": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-1.0.0.tgz",
|
||||
"integrity": "sha512-MUgcMEJaFhCaF1QtWGnmq9ZDRAzECTCRAF7O6UZIlAlkTs1SasiX9aP0Iw7wfD2mJ7wDTNfg2w7u5fSCwJk1OA==",
|
||||
"dependencies": {
|
||||
"core-js": "^2.4.1",
|
||||
"fbjs-css-vars": "^1.0.0",
|
||||
"isomorphic-fetch": "^2.1.1",
|
||||
"loose-envify": "^1.0.0",
|
||||
"object-assign": "^4.1.0",
|
||||
"promise": "^7.1.1",
|
||||
"setimmediate": "^1.0.5",
|
||||
"ua-parser-js": "^0.7.18"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-safe-area-context": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-3.3.2.tgz",
|
||||
"integrity": "sha512-yOwiiPJ1rk+/nfK13eafbpW6sKW0jOnsRem2C1LPJjM3tfTof6hlvV5eWHATye3XOpu2cJ7N+HdkUvUDGwFD2Q==",
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-screens": {
|
||||
"version": "2.18.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-2.18.1.tgz",
|
||||
"integrity": "sha512-r5WZLpmx2hHjC1RgMdPq5YpSU9tEhBpUaZ5M1SUtNIONyiLqQVxabhRCINdebIk4depJiIl7yw2Q85zJyeX6fw==",
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-sound": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "git+ssh://git@github.com/jitsi/react-native-sound.git#3fe5480fce935e888d5089d94a191c7c7e3aa190",
|
||||
|
@ -16734,6 +16960,17 @@
|
|||
"semver": "bin/semver"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-tab-view": {
|
||||
"version": "2.16.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-tab-view/-/react-native-tab-view-2.16.0.tgz",
|
||||
"integrity": "sha512-ac2DmT7+l13wzIFqtbfXn4wwfgtPoKzWjjZyrK1t+T8sdemuUvD4zIt+UImg03fu3s3VD8Wh/fBrIdcqQyZJWg==",
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": "*",
|
||||
"react-native-gesture-handler": "*",
|
||||
"react-native-reanimated": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-url-polyfill": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-url-polyfill/-/react-native-url-polyfill-1.2.0.tgz",
|
||||
|
@ -16809,14 +17046,6 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-webview/node_modules/invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-youtube-iframe": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-youtube-iframe/-/react-native-youtube-iframe-2.1.1.tgz",
|
||||
|
@ -16854,14 +17083,6 @@
|
|||
"ua-parser-js": "^0.7.18"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native/node_modules/invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native/node_modules/whatwg-fetch": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz",
|
||||
|
@ -16902,14 +17123,6 @@
|
|||
"redux": "^2.0.0 || ^3.0.0 || ^4.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-redux/node_modules/invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-redux/node_modules/loose-envify": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
|
@ -18275,6 +18488,14 @@
|
|||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/split-on-first": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
|
||||
"integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/split-string": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
|
||||
|
@ -24126,6 +24347,14 @@
|
|||
"integrity": "sha512-6nFkfkmSeV/rqSaS4oWHgmpnYw194f6hmWF5is6b0J1naJZoiD0NTc9AiUwPHvWsowkjuHErCZT1wa0jg+BLIA==",
|
||||
"dev": true
|
||||
},
|
||||
"@egjs/hammerjs": {
|
||||
"version": "2.0.17",
|
||||
"resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz",
|
||||
"integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==",
|
||||
"requires": {
|
||||
"@types/hammerjs": "^2.0.36"
|
||||
}
|
||||
},
|
||||
"@emotion/cache": {
|
||||
"version": "10.0.29",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.29.tgz",
|
||||
|
@ -24988,6 +25217,88 @@
|
|||
"resolved": "https://registry.npmjs.org/@react-native-community/slider/-/slider-3.0.3.tgz",
|
||||
"integrity": "sha512-8IeHfDwJ9/CTUwFs6x90VlobV3BfuPgNLjTgC6dRZovfCWigaZwVNIFFJnHBakK3pW2xErAPwhdvNR4JeNoYbw=="
|
||||
},
|
||||
"@react-native-masked-view/masked-view": {
|
||||
"version": "0.2.6",
|
||||
"resolved": "https://registry.npmjs.org/@react-native-masked-view/masked-view/-/masked-view-0.2.6.tgz",
|
||||
"integrity": "sha512-303CxmetUmgiX9NSUxatZkNh9qTYYdiM8xkGf9I3Uj20U3eGY3M78ljeNQ4UVCJA+FNGS5nC1dtS9GjIqvB4dg=="
|
||||
},
|
||||
"@react-navigation/core": {
|
||||
"version": "5.16.1",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-5.16.1.tgz",
|
||||
"integrity": "sha512-3AToC7vPNeSNcHFLd1h71L6u34hfXoRAS1CxF9Fc4uC8uOrVqcNvphpeFbE0O9Bw6Zpl0BnMFl7E5gaL3KGzNA==",
|
||||
"requires": {
|
||||
"@react-navigation/routers": "^5.7.4",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"nanoid": "^3.1.15",
|
||||
"query-string": "^6.13.6",
|
||||
"react-is": "^16.13.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"escape-string-regexp": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
|
||||
},
|
||||
"query-string": {
|
||||
"version": "6.14.1",
|
||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-6.14.1.tgz",
|
||||
"integrity": "sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==",
|
||||
"requires": {
|
||||
"decode-uri-component": "^0.2.0",
|
||||
"filter-obj": "^1.1.0",
|
||||
"split-on-first": "^1.0.0",
|
||||
"strict-uri-encode": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"strict-uri-encode": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
|
||||
"integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@react-navigation/material-top-tabs": {
|
||||
"version": "5.3.19",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/material-top-tabs/-/material-top-tabs-5.3.19.tgz",
|
||||
"integrity": "sha512-I7bEF99THxxcY7kCUZ5pPmwXr6kgo6L2sg3P1YJo+CcBWSGvGiHyNbZXNs15HuKRuFvEuueChNV9n8QuKBWbDA==",
|
||||
"requires": {
|
||||
"color": "^3.1.3"
|
||||
}
|
||||
},
|
||||
"@react-navigation/native": {
|
||||
"version": "5.9.8",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-5.9.8.tgz",
|
||||
"integrity": "sha512-DNbcDHXQPSFDLn51kkVVJjT3V7jJy2GztNYZe/2bEg29mi5QEcHHcpifjMCtyFKntAOWzKlG88UicIQ17UEghg==",
|
||||
"requires": {
|
||||
"@react-navigation/core": "^5.16.1",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"nanoid": "^3.1.15"
|
||||
},
|
||||
"dependencies": {
|
||||
"escape-string-regexp": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@react-navigation/routers": {
|
||||
"version": "5.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-5.7.4.tgz",
|
||||
"integrity": "sha512-0N202XAqsU/FlE53Nmh6GHyMtGm7g6TeC93mrFAFJOqGRKznT0/ail+cYlU6tNcPA9AHzZu1Modw1eoDINSliQ==",
|
||||
"requires": {
|
||||
"nanoid": "^3.1.15"
|
||||
}
|
||||
},
|
||||
"@react-navigation/stack": {
|
||||
"version": "5.14.9",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-5.14.9.tgz",
|
||||
"integrity": "sha512-DuvrT9P+Tz8ezZLQYxORZqOGqO+vEufaxlW1hSLw1knLD4jNxkz8TJDXtfKwaz//9gb43UhTNccNM02vm7iPqQ==",
|
||||
"requires": {
|
||||
"color": "^3.1.3",
|
||||
"react-native-iphone-x-helper": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"@svgr/babel-plugin-add-jsx-attribute": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz",
|
||||
|
@ -25801,6 +26112,11 @@
|
|||
"integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/hammerjs": {
|
||||
"version": "2.0.40",
|
||||
"resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.40.tgz",
|
||||
"integrity": "sha512-VbjwR1fhsn2h2KXAY4oy1fm7dCxaKy0D+deTb8Ilc3Eo3rc5+5eA4rfYmZaHgNJKxVyI0f6WIXzO2zLkVmQPHA=="
|
||||
},
|
||||
"@types/http-proxy": {
|
||||
"version": "1.17.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.7.tgz",
|
||||
|
@ -27871,6 +28187,21 @@
|
|||
"object-assign": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"cross-fetch": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz",
|
||||
"integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==",
|
||||
"requires": {
|
||||
"node-fetch": "2.6.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"node-fetch": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
|
||||
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"cross-os": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/cross-os/-/cross-os-1.4.0.tgz",
|
||||
|
@ -29761,6 +30092,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"filter-obj": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
|
||||
"integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs="
|
||||
},
|
||||
"finalhandler": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
|
||||
|
@ -30184,11 +30520,11 @@
|
|||
}
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.5",
|
||||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.5"
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
|
@ -30316,7 +30652,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.5",
|
||||
"version": "1.2.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
}
|
||||
|
@ -31156,9 +31492,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"invariant": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.3.tgz",
|
||||
"integrity": "sha512-7Z5PPegwDTyjbaeCnV0efcyS6vdKAU51kpEmS7QFib3P4822l8ICYyMn7qvJnc+WzLoDsuI9gPMKbJ8pCu8XtA==",
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
|
@ -31559,14 +31895,6 @@
|
|||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
|
||||
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ=="
|
||||
},
|
||||
"invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -32390,14 +32718,6 @@
|
|||
"klaw": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
|
||||
|
@ -32840,16 +33160,6 @@
|
|||
"ob1": "^0.56.4",
|
||||
"source-map": "^0.5.6",
|
||||
"vlq": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"metro-symbolicate": {
|
||||
|
@ -32862,16 +33172,6 @@
|
|||
"source-map": "^0.5.6",
|
||||
"through2": "^2.0.1",
|
||||
"vlq": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"micromatch": {
|
||||
|
@ -33046,6 +33346,11 @@
|
|||
"integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
|
||||
"optional": true
|
||||
},
|
||||
"nanoid": {
|
||||
"version": "3.1.30",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz",
|
||||
"integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ=="
|
||||
},
|
||||
"nanomatch": {
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
|
||||
|
@ -34896,14 +35201,6 @@
|
|||
"ua-parser-js": "^0.7.18"
|
||||
}
|
||||
},
|
||||
"invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"whatwg-fetch": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz",
|
||||
|
@ -34948,6 +35245,34 @@
|
|||
"resolved": "https://registry.npmjs.org/react-native-device-info/-/react-native-device-info-8.0.0.tgz",
|
||||
"integrity": "sha512-7/DOEhg8GtyW1hpVtWf8F6RvGLaFaOGmex+IkmiBWQC2uW4NFDcfXm+lMMZnduFavTyUTX7AF6lAM3y286cEfA=="
|
||||
},
|
||||
"react-native-gesture-handler": {
|
||||
"version": "1.10.3",
|
||||
"resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-1.10.3.tgz",
|
||||
"integrity": "sha512-cBGMi1IEsIVMgoox4RvMx7V2r6bNKw0uR1Mu1o7NbuHS6BRSVLq0dP34l2ecnPlC+jpWd3le6Yg1nrdCjby2Mw==",
|
||||
"requires": {
|
||||
"@egjs/hammerjs": "^2.0.17",
|
||||
"fbjs": "^3.0.0",
|
||||
"hoist-non-react-statics": "^3.3.0",
|
||||
"invariant": "^2.2.4",
|
||||
"prop-types": "^15.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"fbjs": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.0.tgz",
|
||||
"integrity": "sha512-dJd4PiDOFuhe7vk4F80Mba83Vr2QuK86FoxtgPmzBqEJahncp+13YCmfoa53KHCo6OnlXLG7eeMWPfB5CrpVKg==",
|
||||
"requires": {
|
||||
"cross-fetch": "^3.0.4",
|
||||
"fbjs-css-vars": "^1.0.0",
|
||||
"loose-envify": "^1.0.0",
|
||||
"object-assign": "^4.1.0",
|
||||
"promise": "^7.1.1",
|
||||
"setimmediate": "^1.0.5",
|
||||
"ua-parser-js": "^0.7.18"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"react-native-immersive": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-immersive/-/react-native-immersive-2.0.0.tgz",
|
||||
|
@ -34978,6 +35303,41 @@
|
|||
"resolved": "https://registry.npmjs.org/react-native-performance/-/react-native-performance-2.0.0.tgz",
|
||||
"integrity": "sha512-jKM9Qg0SkL9D9ad377nxb1VV+OXJSyYyIrBHKmM6CABNxfrLVA5xkQMEibjmZQde7b0ndJOZoQAiObgJjjc4VQ=="
|
||||
},
|
||||
"react-native-reanimated": {
|
||||
"version": "1.13.3",
|
||||
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-1.13.3.tgz",
|
||||
"integrity": "sha512-i714H24dv6ncpFO7/SZ0PfAMbvjgVbF8Ow2NPtowoZAz8osS54DmTMrkgJ9Za+uEku/s0AEaxqiXG2Xgntvv2g==",
|
||||
"requires": {
|
||||
"fbjs": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"fbjs": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-1.0.0.tgz",
|
||||
"integrity": "sha512-MUgcMEJaFhCaF1QtWGnmq9ZDRAzECTCRAF7O6UZIlAlkTs1SasiX9aP0Iw7wfD2mJ7wDTNfg2w7u5fSCwJk1OA==",
|
||||
"requires": {
|
||||
"core-js": "^2.4.1",
|
||||
"fbjs-css-vars": "^1.0.0",
|
||||
"isomorphic-fetch": "^2.1.1",
|
||||
"loose-envify": "^1.0.0",
|
||||
"object-assign": "^4.1.0",
|
||||
"promise": "^7.1.1",
|
||||
"setimmediate": "^1.0.5",
|
||||
"ua-parser-js": "^0.7.18"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"react-native-safe-area-context": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-3.3.2.tgz",
|
||||
"integrity": "sha512-yOwiiPJ1rk+/nfK13eafbpW6sKW0jOnsRem2C1LPJjM3tfTof6hlvV5eWHATye3XOpu2cJ7N+HdkUvUDGwFD2Q=="
|
||||
},
|
||||
"react-native-screens": {
|
||||
"version": "2.18.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-2.18.1.tgz",
|
||||
"integrity": "sha512-r5WZLpmx2hHjC1RgMdPq5YpSU9tEhBpUaZ5M1SUtNIONyiLqQVxabhRCINdebIk4depJiIl7yw2Q85zJyeX6fw=="
|
||||
},
|
||||
"react-native-sound": {
|
||||
"version": "git+ssh://git@github.com/jitsi/react-native-sound.git#3fe5480fce935e888d5089d94a191c7c7e3aa190",
|
||||
"integrity": "sha512-364A1CvMgh5MnzI4iJgg+AqpePO63Jmf1ESvkTlW+VK3S513fM3092+5mupmGO8KIP77PuYpuNjTYpjZukbgkw==",
|
||||
|
@ -35076,6 +35436,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"react-native-tab-view": {
|
||||
"version": "2.16.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-tab-view/-/react-native-tab-view-2.16.0.tgz",
|
||||
"integrity": "sha512-ac2DmT7+l13wzIFqtbfXn4wwfgtPoKzWjjZyrK1t+T8sdemuUvD4zIt+UImg03fu3s3VD8Wh/fBrIdcqQyZJWg=="
|
||||
},
|
||||
"react-native-url-polyfill": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-url-polyfill/-/react-native-url-polyfill-1.2.0.tgz",
|
||||
|
@ -35131,14 +35496,6 @@
|
|||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
|
||||
"integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w=="
|
||||
},
|
||||
"invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -35177,14 +35534,6 @@
|
|||
"react-is": "^16.8.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"loose-envify": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
|
@ -36283,6 +36632,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"split-on-first": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
|
||||
"integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw=="
|
||||
},
|
||||
"split-string": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
|
||||
|
|
|
@ -42,6 +42,10 @@
|
|||
"@react-native-community/google-signin": "3.0.1",
|
||||
"@react-native-community/netinfo": "4.1.5",
|
||||
"@react-native-community/slider": "3.0.3",
|
||||
"@react-native-masked-view/masked-view": "0.2.6",
|
||||
"@react-navigation/material-top-tabs": "5.3.19",
|
||||
"@react-navigation/native": "5.9.8",
|
||||
"@react-navigation/stack": "5.14.9",
|
||||
"@svgr/webpack": "4.3.2",
|
||||
"amplitude-js": "8.2.1",
|
||||
"base64-js": "1.3.1",
|
||||
|
@ -81,14 +85,19 @@
|
|||
"react-native-collapsible": "1.5.1",
|
||||
"react-native-default-preference": "1.4.2",
|
||||
"react-native-device-info": "8.0.0",
|
||||
"react-native-gesture-handler": "1.10.3",
|
||||
"react-native-immersive": "2.0.0",
|
||||
"react-native-keep-awake": "4.0.0",
|
||||
"react-native-paper": "4.8.1",
|
||||
"react-native-performance": "2.0.0",
|
||||
"react-native-reanimated": "1.13.3",
|
||||
"react-native-safe-area-context": "3.3.2",
|
||||
"react-native-screens": "2.18.1",
|
||||
"react-native-sound": "github:jitsi/react-native-sound#3fe5480fce935e888d5089d94a191c7c7e3aa190",
|
||||
"react-native-splash-screen": "3.2.0",
|
||||
"react-native-svg": "12.1.0",
|
||||
"react-native-svg-transformer": "0.14.3",
|
||||
"react-native-tab-view": "2.16.0",
|
||||
"react-native-url-polyfill": "1.2.0",
|
||||
"react-native-video": "5.1.1",
|
||||
"react-native-watch-connectivity": "0.4.3",
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
|
||||
import { isRoomValid } from '../base/conference';
|
||||
import { toState } from '../base/redux';
|
||||
import { ConferenceNavigationContainer } from '../conference';
|
||||
import { isWelcomePageAppEnabled } from '../welcome';
|
||||
import { BlankPage, WelcomePage } from '../welcome/components';
|
||||
|
||||
/**
|
||||
* Determines which route is to be rendered in order to depict a specific Redux
|
||||
* store.
|
||||
*
|
||||
* @param {(Function|Object)} stateful - THe redux store, state, or
|
||||
* {@code getState} function.
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
export function _getRouteToRender(stateful) {
|
||||
const state = toState(stateful);
|
||||
|
||||
return _getMobileRoute(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code Route} to display on the React Native app.
|
||||
*
|
||||
* @param {Object} state - The redux state.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
function _getMobileRoute(state) {
|
||||
const route = _getEmptyRoute();
|
||||
|
||||
if (isRoomValid(state['features/base/conference'].room)) {
|
||||
route.component = ConferenceNavigationContainer;
|
||||
} else if (isWelcomePageAppEnabled(state)) {
|
||||
route.component = WelcomePage;
|
||||
} else {
|
||||
route.component = BlankPage;
|
||||
}
|
||||
|
||||
return Promise.resolve(route);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default {@code Route}.
|
||||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
function _getEmptyRoute() {
|
||||
return {
|
||||
component: BlankPage,
|
||||
href: undefined
|
||||
};
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
// @flow
|
||||
|
||||
import { generateRoomWithoutSeparator } from '@jitsi/js-utils/random';
|
||||
import type { Component } from 'react';
|
||||
|
||||
import { isRoomValid } from '../base/conference';
|
||||
import { isSupportedBrowser } from '../base/environment';
|
||||
|
@ -9,25 +7,9 @@ import { toState } from '../base/redux';
|
|||
import { Conference } from '../conference';
|
||||
import { getDeepLinkingPage } from '../deep-linking';
|
||||
import { UnsupportedDesktopBrowser } from '../unsupported-browser';
|
||||
import {
|
||||
BlankPage,
|
||||
WelcomePage,
|
||||
isWelcomePageAppEnabled,
|
||||
isWelcomePageUserEnabled
|
||||
} from '../welcome';
|
||||
import { isWelcomePageUserEnabled } from '../welcome';
|
||||
import { BlankPage, WelcomePage } from '../welcome/components';
|
||||
|
||||
/**
|
||||
* Object describing application route.
|
||||
*
|
||||
* @typedef {Object} Route
|
||||
* @property {Component} component - React Component constructor.
|
||||
* @property {string|undefined} href - New location, in case navigation involves
|
||||
* a location change.
|
||||
*/
|
||||
export type Route = {
|
||||
component: Class<Component<*>>,
|
||||
href: ?string
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines which route is to be rendered in order to depict a specific Redux
|
||||
|
@ -35,46 +17,22 @@ export type Route = {
|
|||
*
|
||||
* @param {(Function|Object)} stateful - THe redux store, state, or
|
||||
* {@code getState} function.
|
||||
* @returns {Promise<Route>}
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
export function _getRouteToRender(stateful: Function | Object): Promise<Route> {
|
||||
export function _getRouteToRender(stateful) {
|
||||
const state = toState(stateful);
|
||||
|
||||
if (navigator.product === 'ReactNative') {
|
||||
return _getMobileRoute(state);
|
||||
}
|
||||
|
||||
return _getWebConferenceRoute(state) || _getWebWelcomePageRoute(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code Route} to display on the React Native app.
|
||||
*
|
||||
* @param {Object} state - The redux state.
|
||||
* @returns {Promise<Route>}
|
||||
*/
|
||||
function _getMobileRoute(state): Promise<Route> {
|
||||
const route = _getEmptyRoute();
|
||||
|
||||
if (isRoomValid(state['features/base/conference'].room)) {
|
||||
route.component = Conference;
|
||||
} else if (isWelcomePageAppEnabled(state)) {
|
||||
route.component = WelcomePage;
|
||||
} else {
|
||||
route.component = BlankPage;
|
||||
}
|
||||
|
||||
return Promise.resolve(route);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code Route} to display when trying to access a conference if
|
||||
* a valid conference is being joined.
|
||||
*
|
||||
* @param {Object} state - The redux state.
|
||||
* @returns {Promise<Route>|undefined}
|
||||
* @returns {Promise|undefined}
|
||||
*/
|
||||
function _getWebConferenceRoute(state): ?Promise<Route> {
|
||||
function _getWebConferenceRoute(state) {
|
||||
if (!isRoomValid(state['features/base/conference'].room)) {
|
||||
return;
|
||||
}
|
||||
|
@ -111,9 +69,9 @@ function _getWebConferenceRoute(state): ?Promise<Route> {
|
|||
* Returns the {@code Route} to display when trying to access the welcome page.
|
||||
*
|
||||
* @param {Object} state - The redux state.
|
||||
* @returns {Promise<Route>}
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
function _getWebWelcomePageRoute(state): Promise<Route> {
|
||||
function _getWebWelcomePageRoute(state) {
|
||||
const route = _getEmptyRoute();
|
||||
|
||||
if (isWelcomePageUserEnabled(state)) {
|
||||
|
@ -137,9 +95,9 @@ function _getWebWelcomePageRoute(state): Promise<Route> {
|
|||
/**
|
||||
* Returns the default {@code Route}.
|
||||
*
|
||||
* @returns {Route}
|
||||
* @returns {Object}
|
||||
*/
|
||||
function _getEmptyRoute(): Route {
|
||||
function _getEmptyRoute() {
|
||||
return {
|
||||
component: BlankPage,
|
||||
href: undefined
|
|
@ -0,0 +1,83 @@
|
|||
// @flow
|
||||
|
||||
import { useHeaderHeight } from '@react-navigation/stack';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import {
|
||||
Keyboard,
|
||||
KeyboardAvoidingView,
|
||||
Platform,
|
||||
TouchableWithoutFeedback
|
||||
} from 'react-native';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
|
||||
import { StyleType } from '../../styles';
|
||||
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* The children component(s) of the Modal, to be rendered.
|
||||
*/
|
||||
children: React$Node,
|
||||
|
||||
/**
|
||||
* Additional style to be appended to the KeyboardAvoidingView content container.
|
||||
*/
|
||||
contentContainerStyle?: StyleType,
|
||||
|
||||
/**
|
||||
* Is the screen rendering a tab navigator?
|
||||
*/
|
||||
hasTabNavigator: boolean,
|
||||
|
||||
/**
|
||||
* Additional style to be appended to the KeyboardAvoidingView.
|
||||
*/
|
||||
style?: StyleType
|
||||
}
|
||||
|
||||
const JitsiKeyboardAvoidingView = (
|
||||
{
|
||||
children,
|
||||
contentContainerStyle,
|
||||
hasTabNavigator,
|
||||
style
|
||||
}: Props) => {
|
||||
const headerHeight = useHeaderHeight();
|
||||
const insets = useSafeAreaInsets();
|
||||
const [ bottomPadding, setBottomPadding ] = useState(insets.bottom);
|
||||
|
||||
useEffect(() => {
|
||||
// This useEffect is needed because insets are undefined at first for some reason
|
||||
// https://github.com/th3rdwave/react-native-safe-area-context/issues/54
|
||||
setBottomPadding(insets.bottom);
|
||||
|
||||
}, [ insets.bottom ]);
|
||||
|
||||
const tabNavigatorPadding
|
||||
= hasTabNavigator ? headerHeight : 0;
|
||||
const noNotchDevicePadding = bottomPadding || 10;
|
||||
const iosVerticalOffset = headerHeight + noNotchDevicePadding + tabNavigatorPadding;
|
||||
const androidVerticalOffset = headerHeight;
|
||||
|
||||
return (
|
||||
<TouchableWithoutFeedback
|
||||
/* eslint-disable-next-line react/jsx-handler-names */
|
||||
onPress = { Keyboard.dismiss }>
|
||||
<KeyboardAvoidingView
|
||||
behavior = { Platform.OS === 'ios' ? 'padding' : 'height' }
|
||||
contentContainerStyle = { contentContainerStyle }
|
||||
enabled = { true }
|
||||
keyboardVerticalOffset = {
|
||||
Platform.OS === 'ios'
|
||||
? iosVerticalOffset
|
||||
: androidVerticalOffset
|
||||
}
|
||||
style = { style }>
|
||||
{ children }
|
||||
</KeyboardAvoidingView>
|
||||
</TouchableWithoutFeedback>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
export default JitsiKeyboardAvoidingView;
|
|
@ -0,0 +1,69 @@
|
|||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
|
||||
import { StyleType } from '../../styles';
|
||||
|
||||
import JitsiKeyboardAvoidingView from './JitsiKeyboardAvoidingView';
|
||||
import styles from './styles';
|
||||
|
||||
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* Additional style to be appended to the KeyboardAvoidingView content container.
|
||||
*/
|
||||
contentContainerStyle?: StyleType,
|
||||
|
||||
/**
|
||||
* The children component(s) of the Modal, to be rendered.
|
||||
*/
|
||||
children: React$Node,
|
||||
|
||||
/**
|
||||
* Optional function that renders a footer component, if needed.
|
||||
*/
|
||||
footerComponent?: Function,
|
||||
|
||||
/**
|
||||
* Is the screen rendering a tab navigator?
|
||||
*/
|
||||
hasTabNavigator: boolean,
|
||||
|
||||
/**
|
||||
* Additional style to be appended to the KeyboardAvoidingView containing the content of the modal.
|
||||
*/
|
||||
style?: StyleType
|
||||
}
|
||||
|
||||
const JitsiScreen = ({
|
||||
contentContainerStyle,
|
||||
children,
|
||||
footerComponent,
|
||||
hasTabNavigator,
|
||||
style
|
||||
}: Props) => (
|
||||
<View
|
||||
style = { styles.jitsiScreenContainer }>
|
||||
<JitsiKeyboardAvoidingView
|
||||
contentContainerStyle = { contentContainerStyle }
|
||||
hasTabNavigator = { hasTabNavigator }
|
||||
style = { style }>
|
||||
<SafeAreaView
|
||||
edges = { [
|
||||
'bottom',
|
||||
'left',
|
||||
'right'
|
||||
] }
|
||||
style = { styles.safeArea }>
|
||||
{ children }
|
||||
</SafeAreaView>
|
||||
{ footerComponent && footerComponent() }
|
||||
</JitsiKeyboardAvoidingView>
|
||||
</View>
|
||||
);
|
||||
|
||||
|
||||
export default JitsiScreen;
|
|
@ -0,0 +1,60 @@
|
|||
// @flow
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Keyboard } from 'react-native';
|
||||
|
||||
import { toState } from '../../redux';
|
||||
|
||||
export const useKeyboardHeight = () => {
|
||||
const [ keyboardHeight, setKeyboardHeight ] = useState(0);
|
||||
|
||||
const onKeyboardDidShow = e => {
|
||||
setKeyboardHeight(e.endCoordinates.height);
|
||||
};
|
||||
|
||||
const onKeyboardDidHide = () => {
|
||||
setKeyboardHeight(0);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const keyboardShow = Keyboard.addListener('keyboardDidShow', onKeyboardDidShow);
|
||||
const keyboardHide = Keyboard.addListener('keyboardDidHide', onKeyboardDidHide);
|
||||
|
||||
return () => {
|
||||
keyboardShow.remove();
|
||||
keyboardHide.remove();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return keyboardHeight;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns the client width.
|
||||
*
|
||||
* @param {(Function|Object)} stateful - The (whole) redux state, or redux's
|
||||
* {@code getState} function to be used to retrieve the state
|
||||
* features/base/config.
|
||||
* @returns {number}.
|
||||
*/
|
||||
export function getClientWidth(stateful: Object) {
|
||||
const state = toState(stateful['features/base/responsive-ui']);
|
||||
|
||||
return state.clientWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns the client height.
|
||||
*
|
||||
* @param {(Function|Object)} stateful - The (whole) redux state, or redux's
|
||||
* {@code getState} function to be used to retrieve the state
|
||||
* features/base/config.
|
||||
* @returns {number}.
|
||||
*/
|
||||
export function getClientHeight(stateful: Object) {
|
||||
const state = toState(stateful['features/base/responsive-ui']);
|
||||
|
||||
return state.clientHeight;
|
||||
}
|
|
@ -3,6 +3,11 @@
|
|||
import { ColorSchemeRegistry, schemeColor } from '../../color-scheme';
|
||||
|
||||
export default {
|
||||
|
||||
jitsiScreenContainer: {
|
||||
flex: 1
|
||||
},
|
||||
|
||||
safeArea: {
|
||||
flex: 1
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ export const colors = {
|
|||
primary07: '#669AEC',
|
||||
primary08: '#99BBF3',
|
||||
primary09: '#CCDDF9',
|
||||
primary10: '#17A0DB',
|
||||
|
||||
surface00: '#111111',
|
||||
surface01: '#040404',
|
||||
|
@ -54,6 +55,9 @@ export const colorMap = {
|
|||
// Primary buttons
|
||||
action01: 'primary05',
|
||||
|
||||
// Screen header
|
||||
screen01Header: 'primary10',
|
||||
|
||||
// Hover state for primary buttons
|
||||
action01Hover: 'primary06',
|
||||
|
||||
|
@ -226,7 +230,8 @@ export const shape = {
|
|||
boxShadow: 'inset 0px -1px 0px rgba(255, 255, 255, 0.15)'
|
||||
};
|
||||
|
||||
export const spacing = [ 0, 4, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80 ];
|
||||
export const spacing
|
||||
= [ 0, 4, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128 ];
|
||||
|
||||
export const typography = {
|
||||
labelRegular: {
|
||||
|
|
|
@ -6,7 +6,8 @@ import { IconMessage, IconReply } from '../../base/icons';
|
|||
import { getParticipantById } from '../../base/participants';
|
||||
import { connect } from '../../base/redux';
|
||||
import { AbstractButton, type AbstractButtonProps } from '../../base/toolbox/components';
|
||||
import { openChat } from '../actions';
|
||||
import { navigate } from '../../conference/components/native/ConferenceNavigationContainerRef';
|
||||
import { screen } from '../../conference/components/native/routes';
|
||||
|
||||
export type Props = AbstractButtonProps & {
|
||||
|
||||
|
@ -30,6 +31,11 @@ export type Props = AbstractButtonProps & {
|
|||
*/
|
||||
dispatch: Function,
|
||||
|
||||
/**
|
||||
* True if the polls feature is disabled.
|
||||
*/
|
||||
_isPollsDisabled: boolean,
|
||||
|
||||
/**
|
||||
* The participant object retrieved from Redux.
|
||||
*/
|
||||
|
@ -52,9 +58,16 @@ class PrivateMessageButton extends AbstractButton<Props, any> {
|
|||
* @returns {void}
|
||||
*/
|
||||
_handleClick() {
|
||||
const { dispatch, _participant } = this.props;
|
||||
|
||||
dispatch(openChat(_participant));
|
||||
this.props._isPollsDisabled
|
||||
? navigate(screen.conference.chat, {
|
||||
privateMessageRecipient: this.props._participant
|
||||
})
|
||||
: navigate(screen.conference.chatandpolls.main, {
|
||||
screen: screen.conference.chatandpolls.tab.chat,
|
||||
params: {
|
||||
privateMessageRecipient: this.props._participant
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -79,9 +92,11 @@ class PrivateMessageButton extends AbstractButton<Props, any> {
|
|||
*/
|
||||
export function _mapStateToProps(state: Object, ownProps: Props): $Shape<Props> {
|
||||
const enabled = getFeatureFlag(state, CHAT_ENABLED, true);
|
||||
const { disablePolls } = state['features/base/config'];
|
||||
const { visible = enabled } = ownProps;
|
||||
|
||||
return {
|
||||
_isPollsDisabled: disablePolls,
|
||||
_participant: getParticipantById(state, ownProps.participantID),
|
||||
visible
|
||||
};
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
import { useIsFocused } from '@react-navigation/native';
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { JitsiModal } from '../../../base/modal';
|
||||
import JitsiScreen from '../../../base/modal/components/JitsiScreen';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { PollsPane } from '../../../polls/components';
|
||||
import { closeChat } from '../../actions.any';
|
||||
import { BUTTON_MODES, CHAT_VIEW_MODAL_ID } from '../../constants';
|
||||
import { screen } from '../../../conference/components/native/routes';
|
||||
import { closeChat, openChat } from '../../actions.native';
|
||||
import AbstractChat, {
|
||||
_mapStateToProps,
|
||||
type Props
|
||||
type Props as AbstractProps
|
||||
} from '../AbstractChat';
|
||||
|
||||
import ChatInputBar from './ChatInputBar';
|
||||
|
@ -20,21 +18,30 @@ import MessageContainer from './MessageContainer';
|
|||
import MessageRecipient from './MessageRecipient';
|
||||
import styles from './styles';
|
||||
|
||||
|
||||
type Props = AbstractProps & {
|
||||
|
||||
/**
|
||||
* Is this screen focused or not(React Navigation)
|
||||
*/
|
||||
isChatScreenFocused: boolean,
|
||||
|
||||
/**
|
||||
* Default prop for navigating between screen components(React Navigation)
|
||||
*/
|
||||
navigation: Object,
|
||||
|
||||
/**
|
||||
* Default prop for navigating between screen components(React Navigation)
|
||||
*/
|
||||
route: Object
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements a React native component that renders the chat window (modal) of
|
||||
* the mobile client.
|
||||
*/
|
||||
class Chat extends AbstractChat<Props> {
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
this._onClose = this._onClose.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements React's {@link Component#render()}.
|
||||
|
@ -42,77 +49,50 @@ class Chat extends AbstractChat<Props> {
|
|||
* @inheritdoc
|
||||
*/
|
||||
render() {
|
||||
const { _messages, route } = this.props;
|
||||
const privateMessageRecipient = route.params?.privateMessageRecipient;
|
||||
|
||||
return (
|
||||
<JitsiModal
|
||||
headerProps = {{
|
||||
headerLabelKey: this.props._isPollsEnabled ? 'chat.titleWithPolls' : 'chat.title'
|
||||
}}
|
||||
modalId = { CHAT_VIEW_MODAL_ID }
|
||||
onClose = { this._onClose }>
|
||||
{this.props._isPollsEnabled && <View style = { styles.tabContainer }>
|
||||
<Button
|
||||
color = '#17a0db'
|
||||
mode = {
|
||||
this.props._isPollsTabFocused
|
||||
? BUTTON_MODES.CONTAINED
|
||||
: BUTTON_MODES.TEXT
|
||||
}
|
||||
onPress = { this._onToggleChatTab }
|
||||
style = { styles.tabLeftButton }
|
||||
uppercase = { false }>
|
||||
{`${this.props.t('chat.tabs.chat')}${this.props._isPollsTabFocused
|
||||
&& this.props._nbUnreadMessages > 0
|
||||
? `(${this.props._nbUnreadMessages})`
|
||||
: ''
|
||||
}`}
|
||||
</Button>
|
||||
<Button
|
||||
color = '#17a0db'
|
||||
mode = {
|
||||
this.props._isPollsTabFocused
|
||||
? BUTTON_MODES.TEXT
|
||||
: BUTTON_MODES.CONTAINED
|
||||
}
|
||||
onPress = { this._onTogglePollsTab }
|
||||
style = { styles.tabRightButton }
|
||||
uppercase = { false }>
|
||||
{`${this.props.t('chat.tabs.polls')}${!this.props._isPollsTabFocused
|
||||
&& this.props._nbUnreadPolls > 0
|
||||
? `(${this.props._nbUnreadPolls})`
|
||||
: ''
|
||||
}`}
|
||||
</Button>
|
||||
</View>}
|
||||
{this.props._isPollsTabFocused
|
||||
? <PollsPane />
|
||||
: (
|
||||
<>
|
||||
<MessageContainer messages = { this.props._messages } />
|
||||
<MessageRecipient />
|
||||
<ChatInputBar onSend = { this._onSendMessage } />
|
||||
</>
|
||||
)}
|
||||
</JitsiModal>
|
||||
<JitsiScreen
|
||||
hasTabNavigator = { true }
|
||||
style = { styles.chatContainer }>
|
||||
<MessageContainer messages = { _messages } />
|
||||
<MessageRecipient privateMessageRecipient = { privateMessageRecipient } />
|
||||
<ChatInputBar onSend = { this._onSendMessage } />
|
||||
</JitsiScreen>
|
||||
);
|
||||
}
|
||||
|
||||
_onSendMessage: (string) => void;
|
||||
|
||||
_onClose: () => boolean
|
||||
|
||||
_onTogglePollsTab: () => void;
|
||||
_onToggleChatTab: () => void;
|
||||
|
||||
/**
|
||||
* Closes the modal.
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
_onClose() {
|
||||
this.props.dispatch(closeChat());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(connect(_mapStateToProps)(Chat));
|
||||
export default translate(connect(_mapStateToProps)(props => {
|
||||
const {
|
||||
_nbUnreadMessages,
|
||||
dispatch,
|
||||
navigation,
|
||||
route
|
||||
} = props;
|
||||
const isChatScreenFocused = useIsFocused();
|
||||
const privateMessageRecipient = route.params?.privateMessageRecipient;
|
||||
|
||||
const nrUnreadMessages
|
||||
= !isChatScreenFocused && _nbUnreadMessages > 0
|
||||
? `(${_nbUnreadMessages})` : '';
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(openChat(privateMessageRecipient));
|
||||
|
||||
navigation.setOptions({
|
||||
tabBarLabel: `${screen.conference.chatandpolls.tab.chat} ${nrUnreadMessages}`
|
||||
});
|
||||
|
||||
return () => dispatch(closeChat());
|
||||
}, [ nrUnreadMessages ]);
|
||||
|
||||
return (
|
||||
<Chat
|
||||
{ ...props }
|
||||
isChatScreenFocused = { isChatScreenFocused } />
|
||||
);
|
||||
}));
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
// @flow
|
||||
|
||||
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import {
|
||||
getClientHeight,
|
||||
getClientWidth
|
||||
} from '../../../base/modal/components/functions.native';
|
||||
import { Chat } from '../../../chat';
|
||||
import { chatTabBarOptions } from '../../../conference/components/native/ConferenceNavigatorScreenOptions';
|
||||
import { screen } from '../../../conference/components/native/routes';
|
||||
import { PollsPane } from '../../../polls/components';
|
||||
|
||||
const ChatTab = createMaterialTopTabNavigator();
|
||||
|
||||
|
||||
const ChatAndPolls = () => {
|
||||
const clientHeight = useSelector(getClientHeight);
|
||||
const clientWidth = useSelector(getClientWidth);
|
||||
|
||||
return (
|
||||
<ChatTab.Navigator
|
||||
backBehavior = 'none'
|
||||
initialLayout = {{
|
||||
height: clientHeight,
|
||||
width: clientWidth
|
||||
}}
|
||||
tabBarOptions = {{
|
||||
...chatTabBarOptions
|
||||
}}>
|
||||
<ChatTab.Screen
|
||||
component = { Chat }
|
||||
name = { screen.conference.chatandpolls.tab.chat } />
|
||||
<ChatTab.Screen
|
||||
component = { PollsPane }
|
||||
name = { screen.conference.chatandpolls.tab.polls } />
|
||||
</ChatTab.Navigator>
|
||||
);
|
||||
};
|
||||
|
||||
export default ChatAndPolls;
|
|
@ -7,17 +7,22 @@ import {
|
|||
AbstractButton,
|
||||
type AbstractButtonProps
|
||||
} from '../../../base/toolbox/components';
|
||||
import { openChat } from '../../actions.native';
|
||||
import { navigate } from '../../../conference/components/native/ConferenceNavigationContainerRef';
|
||||
import { screen } from '../../../conference/components/native/routes';
|
||||
import { getUnreadCount } from '../../functions';
|
||||
|
||||
|
||||
type Props = AbstractButtonProps & {
|
||||
|
||||
/**
|
||||
* True if the polls feature is disabled.
|
||||
*/
|
||||
_isPollsDisabled: boolean,
|
||||
|
||||
/**
|
||||
* The unread message count.
|
||||
*/
|
||||
_unreadMessageCount: number,
|
||||
|
||||
dispatch: Function
|
||||
_unreadMessageCount: number
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -36,7 +41,9 @@ class ChatButton extends AbstractButton<Props, *> {
|
|||
* @returns {void}
|
||||
*/
|
||||
_handleClick() {
|
||||
this.props.dispatch(openChat());
|
||||
this.props._isPollsDisabled
|
||||
? navigate(screen.conference.chat)
|
||||
: navigate(screen.conference.chatandpolls.main);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -59,9 +66,11 @@ class ChatButton extends AbstractButton<Props, *> {
|
|||
*/
|
||||
function _mapStateToProps(state, ownProps) {
|
||||
const enabled = getFeatureFlag(state, CHAT_ENABLED, true);
|
||||
const { disablePolls } = state['features/base/config'];
|
||||
const { visible = enabled } = ownProps;
|
||||
|
||||
return {
|
||||
_isPollsDisabled: disablePolls,
|
||||
_unreadMessageCount: getUnreadCount(state),
|
||||
visible
|
||||
};
|
||||
|
|
|
@ -58,7 +58,6 @@ class ChatInputBar extends Component<Props, State> {
|
|||
};
|
||||
|
||||
this._onChangeText = this._onChangeText.bind(this);
|
||||
this._onFieldReferenceAvailable = this._onFieldReferenceAvailable.bind(this);
|
||||
this._onFocused = this._onFocused.bind(this);
|
||||
this._onSubmit = this._onSubmit.bind(this);
|
||||
}
|
||||
|
@ -83,7 +82,6 @@ class ChatInputBar extends Component<Props, State> {
|
|||
onFocus = { this._onFocused(true) }
|
||||
onSubmitEditing = { this._onSubmit }
|
||||
placeholder = { this.props.t('chat.fieldPlaceHolder') }
|
||||
ref = { this._onFieldReferenceAvailable }
|
||||
returnKeyType = 'send'
|
||||
style = { styles.inputField }
|
||||
value = { this.state.message } />
|
||||
|
@ -113,18 +111,6 @@ class ChatInputBar extends Component<Props, State> {
|
|||
});
|
||||
}
|
||||
|
||||
_onFieldReferenceAvailable: Object => void;
|
||||
|
||||
/**
|
||||
* Callback to be invoked when the field reference is available.
|
||||
*
|
||||
* @param {Object} field - The reference to the field.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onFieldReferenceAvailable(field) {
|
||||
field && field.focus();
|
||||
}
|
||||
|
||||
_onFocused: boolean => Function;
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,9 +8,11 @@ import { translate } from '../../../base/i18n';
|
|||
import { Icon, IconCancelSelection } from '../../../base/icons';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { type StyleType } from '../../../base/styles';
|
||||
import {
|
||||
setParams
|
||||
} from '../../../conference/components/native/ConferenceNavigationContainerRef';
|
||||
import { setPrivateMessageRecipient } from '../../actions.any';
|
||||
import AbstractMessageRecipient, {
|
||||
_mapDispatchToProps,
|
||||
_mapStateToProps as _abstractMapStateToProps,
|
||||
type Props as AbstractProps
|
||||
} from '../AbstractMessageRecipient';
|
||||
|
||||
|
@ -19,35 +21,74 @@ type Props = AbstractProps & {
|
|||
/**
|
||||
* The color-schemed stylesheet of the feature.
|
||||
*/
|
||||
_styles: StyleType
|
||||
_styles: StyleType,
|
||||
|
||||
/**
|
||||
* The Redux dispatch function.
|
||||
*/
|
||||
dispatch: Function,
|
||||
|
||||
/**
|
||||
* The participant object set for private messaging.
|
||||
*/
|
||||
privateMessageRecipient: Object,
|
||||
};
|
||||
|
||||
/**
|
||||
* Class to implement the displaying of the recipient of the next message.
|
||||
*/
|
||||
class MessageRecipient extends AbstractMessageRecipient<Props> {
|
||||
|
||||
/**
|
||||
* Constructor of the component.
|
||||
*
|
||||
* @param {Props} props - The props of the component.
|
||||
*/
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
this._onResetPrivateMessageRecipient = this._onResetPrivateMessageRecipient.bind(this);
|
||||
}
|
||||
|
||||
_onResetPrivateMessageRecipient: () => void;
|
||||
|
||||
/**
|
||||
* Resets private message recipient from state.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_onResetPrivateMessageRecipient() {
|
||||
const { dispatch } = this.props;
|
||||
|
||||
dispatch(setPrivateMessageRecipient());
|
||||
|
||||
setParams({
|
||||
privateMessageRecipient: undefined
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements {@code PureComponent#render}.
|
||||
*
|
||||
* @inheritdoc
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const { _privateMessageRecipient, _styles } = this.props;
|
||||
const { _styles, privateMessageRecipient, t } = this.props;
|
||||
|
||||
if (!_privateMessageRecipient) {
|
||||
if (!privateMessageRecipient) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { t } = this.props;
|
||||
|
||||
return (
|
||||
<View style = { _styles.messageRecipientContainer }>
|
||||
<Text style = { _styles.messageRecipientText }>
|
||||
{ t('chat.messageTo', {
|
||||
recipient: _privateMessageRecipient
|
||||
recipient: privateMessageRecipient.name
|
||||
}) }
|
||||
</Text>
|
||||
<TouchableHighlight onPress = { this.props._onRemovePrivateMessageRecipient }>
|
||||
<TouchableHighlight
|
||||
onPress = { this._onResetPrivateMessageRecipient }>
|
||||
<Icon
|
||||
src = { IconCancelSelection }
|
||||
style = { _styles.messageRecipientCancelIcon } />
|
||||
|
@ -65,9 +106,8 @@ class MessageRecipient extends AbstractMessageRecipient<Props> {
|
|||
*/
|
||||
function _mapStateToProps(state) {
|
||||
return {
|
||||
..._abstractMapStateToProps(state),
|
||||
_styles: ColorSchemeRegistry.get(state, 'Chat')
|
||||
};
|
||||
}
|
||||
|
||||
export default translate(connect(_mapStateToProps, _mapDispatchToProps)(MessageRecipient));
|
||||
export default translate(connect(_mapStateToProps)(MessageRecipient));
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
|
||||
export { default as Chat } from './Chat';
|
||||
export { default as ChatAndPolls } from './ChatAndPolls';
|
||||
export { default as ChatButton } from './ChatButton';
|
||||
export { default as ChatPrivacyDialog } from './ChatPrivacyDialog';
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import { ColorSchemeRegistry, schemeColor } from '../../../base/color-scheme';
|
||||
import { BoxModel, ColorPalette } from '../../../base/styles';
|
||||
import BaseTheme from '../../../base/ui/components/BaseTheme.native';
|
||||
|
||||
const BUBBLE_RADIUS = 8;
|
||||
|
||||
|
@ -40,7 +41,7 @@ export default {
|
|||
alignSelf: 'center',
|
||||
flex: 1,
|
||||
padding: BoxModel.padding,
|
||||
paddingTop: '10%'
|
||||
paddingTop: '8%'
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -126,6 +127,10 @@ export default {
|
|||
fontSize: 13
|
||||
},
|
||||
|
||||
chatContainer: {
|
||||
flex: 1
|
||||
},
|
||||
|
||||
tabContainer: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center'
|
||||
|
@ -164,7 +169,7 @@ ColorSchemeRegistry.register('Chat', {
|
|||
},
|
||||
|
||||
emptyComponentText: {
|
||||
color: schemeColor('displayName'),
|
||||
color: BaseTheme.palette.ui05,
|
||||
textAlign: 'center'
|
||||
},
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// @flow
|
||||
|
||||
export const CHAT_VIEW_MODAL_ID = 'chatView';
|
||||
|
||||
/**
|
||||
* The size of the chat.
|
||||
*/
|
||||
|
|
|
@ -10,7 +10,6 @@ import {
|
|||
JitsiConferenceErrors,
|
||||
JitsiConferenceEvents
|
||||
} from '../base/lib-jitsi-meet';
|
||||
import { setActiveModalId } from '../base/modal';
|
||||
import {
|
||||
getLocalParticipant,
|
||||
getParticipantById,
|
||||
|
@ -18,7 +17,6 @@ import {
|
|||
} from '../base/participants';
|
||||
import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux';
|
||||
import { playSound, registerSound, unregisterSound } from '../base/sounds';
|
||||
import { openDisplayNamePrompt } from '../display-name';
|
||||
import { resetNbUnreadPollsMessages } from '../polls/actions';
|
||||
import { ADD_REACTION_MESSAGE } from '../reactions/actionTypes';
|
||||
import { pushReactions } from '../reactions/actions.any';
|
||||
|
@ -35,7 +33,6 @@ import { addMessage, clearMessages } from './actions';
|
|||
import { closeChat } from './actions.any';
|
||||
import { ChatPrivacyDialog } from './components';
|
||||
import {
|
||||
CHAT_VIEW_MODAL_ID,
|
||||
INCOMING_MSG_SOUND_ID,
|
||||
MESSAGE_TYPE_ERROR,
|
||||
MESSAGE_TYPE_LOCAL,
|
||||
|
@ -95,18 +92,6 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
break;
|
||||
|
||||
case OPEN_CHAT:
|
||||
if (navigator.product === 'ReactNative') {
|
||||
if (localParticipant.name) {
|
||||
dispatch(setActiveModalId(CHAT_VIEW_MODAL_ID));
|
||||
} else {
|
||||
dispatch(openDisplayNamePrompt(() => {
|
||||
dispatch(setActiveModalId(CHAT_VIEW_MODAL_ID));
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
dispatch(setActiveModalId(CHAT_VIEW_MODAL_ID));
|
||||
}
|
||||
|
||||
unreadCount = 0;
|
||||
|
||||
if (typeof APP !== 'undefined') {
|
||||
|
@ -126,8 +111,6 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
if (isPollTabOpen) {
|
||||
dispatch(resetNbUnreadPollsMessages());
|
||||
}
|
||||
|
||||
dispatch(setActiveModalId());
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,22 +10,18 @@ import { connect } from '../../../base/redux';
|
|||
import { ASPECT_RATIO_NARROW } from '../../../base/responsive-ui/constants';
|
||||
import { TestConnectionInfo } from '../../../base/testing';
|
||||
import { ConferenceNotification, isCalendarEnabled } from '../../../calendar-sync';
|
||||
import { Chat } from '../../../chat';
|
||||
import { DisplayNameLabel } from '../../../display-name';
|
||||
import { SharedDocument } from '../../../etherpad';
|
||||
import {
|
||||
FILMSTRIP_SIZE,
|
||||
Filmstrip,
|
||||
isFilmstripVisible,
|
||||
TileView
|
||||
} from '../../../filmstrip';
|
||||
import { AddPeopleDialog, CalleeInfoContainer } from '../../../invite';
|
||||
import { CalleeInfoContainer } from '../../../invite';
|
||||
import { LargeVideo } from '../../../large-video';
|
||||
import { KnockingParticipantList } from '../../../lobby';
|
||||
import { LobbyScreen } from '../../../lobby/components/native';
|
||||
import { getIsLobbyVisible } from '../../../lobby/functions';
|
||||
import { BackButtonRegistry } from '../../../mobile/back-button';
|
||||
import { ParticipantsPane } from '../../../participants-pane/components/native';
|
||||
import { Captions } from '../../../subtitles';
|
||||
import { setToolboxVisible } from '../../../toolbox/actions';
|
||||
import { Toolbox } from '../../../toolbox/components/native';
|
||||
|
@ -36,8 +32,10 @@ import {
|
|||
} from '../AbstractConference';
|
||||
import type { AbstractProps } from '../AbstractConference';
|
||||
|
||||
import { navigate } from './ConferenceNavigationContainerRef';
|
||||
import LonelyMeetingExperience from './LonelyMeetingExperience';
|
||||
import NavigationBar from './NavigationBar';
|
||||
import { screen } from './routes';
|
||||
import styles from './styles';
|
||||
|
||||
|
||||
|
@ -141,6 +139,23 @@ class Conference extends AbstractConference<Props, *> {
|
|||
BackButtonRegistry.addListener(this._onHardwareBackPress);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements {@code Component#componentDidUpdate}.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
componentDidUpdate(prevProps) {
|
||||
const { _showLobby } = this.props;
|
||||
|
||||
if (!prevProps._showLobby && _showLobby) {
|
||||
navigate(screen.lobby);
|
||||
}
|
||||
|
||||
if (prevProps._showLobby && !_showLobby) {
|
||||
navigate(screen.conference.main);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements {@link Component#componentWillUnmount()}. Invoked immediately
|
||||
* before this component is unmounted and destroyed. Disconnects the
|
||||
|
@ -161,11 +176,7 @@ class Conference extends AbstractConference<Props, *> {
|
|||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const { _fullscreenEnabled, _showLobby } = this.props;
|
||||
|
||||
if (_showLobby) {
|
||||
return <LobbyScreen />;
|
||||
}
|
||||
const { _fullscreenEnabled } = this.props;
|
||||
|
||||
return (
|
||||
<Container style = { styles.conference }>
|
||||
|
@ -217,19 +228,6 @@ class Conference extends AbstractConference<Props, *> {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders JitsiModals that are supposed to be on the conference screen.
|
||||
*
|
||||
* @returns {Array<ReactElement>}
|
||||
*/
|
||||
_renderConferenceModals() {
|
||||
return [
|
||||
<AddPeopleDialog key = 'addPeopleDialog' />,
|
||||
<Chat key = 'chat' />,
|
||||
<SharedDocument key = 'sharedDocument' />
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the conference notification badge if the feature is enabled.
|
||||
*
|
||||
|
@ -254,7 +252,6 @@ class Conference extends AbstractConference<Props, *> {
|
|||
_renderContent() {
|
||||
const {
|
||||
_connecting,
|
||||
_isParticipantsPaneOpen,
|
||||
_largeVideoParticipantId,
|
||||
_reducedUI,
|
||||
_shouldDisplayTileView
|
||||
|
@ -316,12 +313,7 @@ class Conference extends AbstractConference<Props, *> {
|
|||
<TestConnectionInfo />
|
||||
{ this._renderConferenceNotification() }
|
||||
|
||||
{ this._renderConferenceModals() }
|
||||
|
||||
{_shouldDisplayTileView && <Toolbox />}
|
||||
|
||||
{ _isParticipantsPaneOpen && <ParticipantsPane /> }
|
||||
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
// @flow
|
||||
|
||||
import { NavigationContainer } from '@react-navigation/native';
|
||||
import { createStackNavigator } from '@react-navigation/stack';
|
||||
import React from 'react';
|
||||
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { Chat, ChatAndPolls } from '../../../chat';
|
||||
import { SharedDocument } from '../../../etherpad';
|
||||
import AddPeopleDialog
|
||||
from '../../../invite/components/add-people-dialog/native/AddPeopleDialog';
|
||||
import LobbyScreen from '../../../lobby/components/native/LobbyScreen';
|
||||
import { ParticipantsPane } from '../../../participants-pane/components/native';
|
||||
import { getDisablePolls } from '../../functions';
|
||||
|
||||
import Conference from './Conference';
|
||||
import {
|
||||
conferenceNavigationRef
|
||||
} from './ConferenceNavigationContainerRef';
|
||||
import {
|
||||
chatScreenOptions,
|
||||
conferenceScreenOptions,
|
||||
inviteScreenOptions,
|
||||
lobbyScreenOptions,
|
||||
participantsScreenOptions,
|
||||
sharedDocumentScreenOptions
|
||||
} from './ConferenceNavigatorScreenOptions';
|
||||
import { screen } from './routes';
|
||||
|
||||
const ConferenceStack = createStackNavigator();
|
||||
|
||||
const ConferenceNavigationContainer = () => {
|
||||
const isPollsDisabled = useSelector(getDisablePolls);
|
||||
const ChatScreen
|
||||
= isPollsDisabled
|
||||
? Chat
|
||||
: ChatAndPolls;
|
||||
const chatScreenName
|
||||
= isPollsDisabled
|
||||
? screen.conference.chat
|
||||
: screen.conference.chatandpolls.main;
|
||||
|
||||
return (
|
||||
<SafeAreaProvider>
|
||||
<NavigationContainer
|
||||
independent = { true }
|
||||
ref = { conferenceNavigationRef }
|
||||
theme = {{
|
||||
colors: {
|
||||
background: '#fff'
|
||||
}
|
||||
}}>
|
||||
<ConferenceStack.Navigator
|
||||
initialRouteName = { screen.conference.main }
|
||||
mode = 'modal'>
|
||||
<ConferenceStack.Screen
|
||||
component = { Conference }
|
||||
name = { screen.conference.main }
|
||||
options = {{
|
||||
...conferenceScreenOptions
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
/* eslint-disable-next-line react/jsx-no-bind */
|
||||
component = { ChatScreen }
|
||||
name = { chatScreenName }
|
||||
options = {{
|
||||
...chatScreenOptions
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
component = { ParticipantsPane }
|
||||
name = { screen.conference.participants }
|
||||
options = {{
|
||||
...participantsScreenOptions
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
component = { LobbyScreen }
|
||||
name = { screen.lobby }
|
||||
options = {{
|
||||
...lobbyScreenOptions
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
component = { AddPeopleDialog }
|
||||
name = { screen.conference.invite }
|
||||
options = {{
|
||||
...inviteScreenOptions
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
component = { SharedDocument }
|
||||
name = { screen.conference.sharedDocument }
|
||||
options = {{
|
||||
...sharedDocumentScreenOptions
|
||||
}} />
|
||||
</ConferenceStack.Navigator>
|
||||
</NavigationContainer>
|
||||
</SafeAreaProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConferenceNavigationContainer;
|
|
@ -0,0 +1,40 @@
|
|||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
|
||||
// $FlowExpectedError
|
||||
export const conferenceNavigationRef = React.createRef();
|
||||
|
||||
/**
|
||||
* User defined navigation action included inside the reference to the container.
|
||||
*
|
||||
* @param {string} name - Destination name of the route that has been defined somewhere.
|
||||
* @param {Object} params - Params to pass to the destination route.
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function navigate(name: string, params: Object) {
|
||||
// $FlowExpectedError
|
||||
return conferenceNavigationRef.current?.navigate(name, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* User defined navigation action included inside the reference to the container.
|
||||
*
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function goBack() {
|
||||
// $FlowExpectedError
|
||||
return conferenceNavigationRef.current?.goBack();
|
||||
}
|
||||
|
||||
/**
|
||||
* User defined navigation action included inside the reference to the container.
|
||||
*
|
||||
* @param {Object} params - Params to pass to the destination route.
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function setParams(params: Object) {
|
||||
// $FlowExpectedError
|
||||
return conferenceNavigationRef.current?.setParams(params);
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
import { TransitionPresets } from '@react-navigation/stack';
|
||||
import React from 'react';
|
||||
import { Platform } from 'react-native';
|
||||
|
||||
import { IconClose } from '../../../base/icons';
|
||||
import BaseTheme from '../../../base/ui/components/BaseTheme';
|
||||
|
||||
import { goBack } from './ConferenceNavigationContainerRef';
|
||||
import HeaderNavigationButton from './HeaderNavigationButton';
|
||||
|
||||
|
||||
/**
|
||||
* Default modal transition for the current platform.
|
||||
*/
|
||||
export const conferenceModalPresentation = Platform.select({
|
||||
ios: TransitionPresets.ModalPresentationIOS,
|
||||
default: TransitionPresets.DefaultTransition
|
||||
});
|
||||
|
||||
/**
|
||||
* Screen options and transition types.
|
||||
*/
|
||||
export const screenOptions = {
|
||||
...TransitionPresets.ModalTransition,
|
||||
gestureEnabled: false,
|
||||
headerShown: false
|
||||
};
|
||||
|
||||
/**
|
||||
* Screen options for conference.
|
||||
*/
|
||||
export const conferenceScreenOptions = {
|
||||
...screenOptions
|
||||
};
|
||||
|
||||
/**
|
||||
* Screen options for lobby modal.
|
||||
*/
|
||||
export const lobbyScreenOptions = {
|
||||
...screenOptions
|
||||
};
|
||||
|
||||
/**
|
||||
* Tab bar options for chat screen.
|
||||
*/
|
||||
export const chatTabBarOptions = {
|
||||
activeTintColor: BaseTheme.palette.screen01Header,
|
||||
labelStyle: {
|
||||
fontSize: BaseTheme.typography.labelRegular.fontSize
|
||||
},
|
||||
inactiveTintColor: BaseTheme.palette.field02Disabled,
|
||||
indicatorStyle: {
|
||||
backgroundColor: BaseTheme.palette.screen01Header
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Screen options for presentation type modals.
|
||||
*/
|
||||
export const presentationScreenOptions = {
|
||||
...conferenceModalPresentation,
|
||||
headerBackTitleVisible: false,
|
||||
headerLeft: () => (
|
||||
<HeaderNavigationButton
|
||||
onPress = { goBack }
|
||||
src = { IconClose } />
|
||||
),
|
||||
headerStatusBarHeight: 0,
|
||||
headerStyle: {
|
||||
backgroundColor: BaseTheme.palette.screen01Header
|
||||
},
|
||||
headerTitleStyle: {
|
||||
color: BaseTheme.palette.text01
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Screen options for chat.
|
||||
*/
|
||||
export const chatScreenOptions = {
|
||||
...presentationScreenOptions
|
||||
};
|
||||
|
||||
/**
|
||||
* Screen options for invite modal.
|
||||
*/
|
||||
export const inviteScreenOptions = {
|
||||
...presentationScreenOptions
|
||||
};
|
||||
|
||||
/**
|
||||
* Screen options for participants modal.
|
||||
*/
|
||||
export const participantsScreenOptions = {
|
||||
...presentationScreenOptions
|
||||
};
|
||||
|
||||
/**
|
||||
* Screen options for shared document.
|
||||
*/
|
||||
export const sharedDocumentScreenOptions = {
|
||||
...TransitionPresets.DefaultTransition,
|
||||
headerBackTitleVisible: false,
|
||||
headerShown: true,
|
||||
headerStyle: {
|
||||
backgroundColor: BaseTheme.palette.screen01Header
|
||||
},
|
||||
headerTitleStyle: {
|
||||
color: BaseTheme.palette.text01
|
||||
}
|
||||
};
|
|
@ -0,0 +1,39 @@
|
|||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
import { TouchableWithoutFeedback } from 'react-native';
|
||||
|
||||
import { Icon } from '../../../base/icons';
|
||||
|
||||
import styles from './styles';
|
||||
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* Callback to invoke when the {@code HeaderNavigationButton} is clicked/pressed.
|
||||
*/
|
||||
onPress: Function,
|
||||
|
||||
/**
|
||||
* The ImageSource to be rendered as image.
|
||||
*/
|
||||
src: Object,
|
||||
|
||||
/**
|
||||
* The component's external style
|
||||
*/
|
||||
style: Object
|
||||
}
|
||||
|
||||
const HeaderNavigationButton = ({ onPress, src, style }: Props) => (
|
||||
<TouchableWithoutFeedback
|
||||
onPress = { onPress } >
|
||||
<Icon
|
||||
size = { 20 }
|
||||
src = { src }
|
||||
style = { [ styles.headerNavigationButton, style ] } />
|
||||
</TouchableWithoutFeedback>
|
||||
);
|
||||
|
||||
|
||||
export default HeaderNavigationButton;
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
|
||||
export { default as Conference } from './Conference';
|
||||
export { default as ConferenceNavigationContainer } from './ConferenceNavigationContainer';
|
||||
export { default as renderConferenceTimer } from './ConferenceTimerDisplay';
|
||||
export { default as InsecureRoomNameLabel } from './InsecureRoomNameLabel';
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
export const screen = {
|
||||
conference: {
|
||||
main: 'Conference',
|
||||
chat: 'Chat',
|
||||
chatandpolls: {
|
||||
main: 'Chat and Polls',
|
||||
tab: {
|
||||
chat: 'Chat',
|
||||
polls: 'Polls'
|
||||
}
|
||||
},
|
||||
participants: 'Participants',
|
||||
invite: 'Invite',
|
||||
sharedDocument: 'Shared document'
|
||||
},
|
||||
lobby: 'Lobby'
|
||||
};
|
|
@ -23,6 +23,10 @@ export default {
|
|||
margin: 10
|
||||
},
|
||||
|
||||
headerNavigationButton: {
|
||||
marginLeft: 12
|
||||
},
|
||||
|
||||
/**
|
||||
* View that contains the indicators.
|
||||
*/
|
||||
|
|
|
@ -1 +1,21 @@
|
|||
// @flow
|
||||
|
||||
import { toState } from '../base/redux';
|
||||
|
||||
export * from './functions.any';
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns true if polls feature is disabled.
|
||||
*
|
||||
* @param {(Function|Object)} stateful - The (whole) redux state, or redux's
|
||||
* {@code getState} function to be used to retrieve the state
|
||||
* features/base/config.
|
||||
* @returns {boolean}.
|
||||
*/
|
||||
export function getDisablePolls(stateful: Object) {
|
||||
const state = toState(stateful['features/base/config']);
|
||||
|
||||
return state.disablePolls;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
// @flow
|
||||
|
||||
import type { Dispatch } from 'redux';
|
||||
|
||||
import { createToolbarEvent, sendAnalytics } from '../../analytics';
|
||||
import { translate } from '../../base/i18n';
|
||||
import { IconShareDoc } from '../../base/icons';
|
||||
import { connect } from '../../base/redux';
|
||||
import { AbstractButton, type AbstractButtonProps } from '../../base/toolbox/components';
|
||||
import { toggleDocument } from '../actions';
|
||||
import { navigate } from '../../conference/components/native/ConferenceNavigationContainerRef';
|
||||
import { screen } from '../../conference/components/native/routes';
|
||||
|
||||
|
||||
type Props = AbstractButtonProps & {
|
||||
|
@ -15,12 +14,7 @@ type Props = AbstractButtonProps & {
|
|||
/**
|
||||
* Whether the shared document is being edited or not.
|
||||
*/
|
||||
_editing: boolean,
|
||||
|
||||
/**
|
||||
* Redux dispatch function.
|
||||
*/
|
||||
dispatch: Dispatch<any>,
|
||||
_editing: boolean
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -59,7 +53,7 @@ class SharedDocumentButton extends AbstractButton<Props, *> {
|
|||
* @returns {void}
|
||||
*/
|
||||
_handleClick() {
|
||||
const { _editing, dispatch, handleClick } = this.props;
|
||||
const { _editing, handleClick } = this.props;
|
||||
|
||||
if (handleClick) {
|
||||
handleClick();
|
||||
|
@ -72,7 +66,8 @@ class SharedDocumentButton extends AbstractButton<Props, *> {
|
|||
{
|
||||
enable: !_editing
|
||||
}));
|
||||
dispatch(toggleDocument());
|
||||
|
||||
navigate(screen.conference.sharedDocument);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,15 +3,16 @@
|
|||
import React, { PureComponent } from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { WebView } from 'react-native-webview';
|
||||
import type { Dispatch } from 'redux';
|
||||
|
||||
import { ColorSchemeRegistry } from '../../../base/color-scheme';
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { JitsiModal } from '../../../base/modal';
|
||||
import { IconArrowBack } from '../../../base/icons';
|
||||
import JitsiScreen from '../../../base/modal/components/JitsiScreen';
|
||||
import { LoadingIndicator } from '../../../base/react';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { toggleDocument } from '../../actions';
|
||||
import { SHARE_DOCUMENT_VIEW_ID } from '../../constants';
|
||||
import { goBack } from '../../../conference/components/native/ConferenceNavigationContainerRef';
|
||||
import HeaderNavigationButton
|
||||
from '../../../conference/components/native/HeaderNavigationButton';
|
||||
import { getSharedDocumentUrl } from '../../functions';
|
||||
|
||||
import styles, { INDICATOR_COLOR } from './styles';
|
||||
|
@ -32,14 +33,9 @@ type Props = {
|
|||
_headerStyles: Object,
|
||||
|
||||
/**
|
||||
* True if the chat window should be rendered.
|
||||
* Default prop for navigation between screen components(React Navigation)
|
||||
*/
|
||||
_isOpen: boolean,
|
||||
|
||||
/**
|
||||
* The Redux dispatch function.
|
||||
*/
|
||||
dispatch: Dispatch<any>,
|
||||
navigation: Object,
|
||||
|
||||
/**
|
||||
* Function to be used to translate i18n labels.
|
||||
|
@ -59,11 +55,29 @@ class SharedDocument extends PureComponent<Props> {
|
|||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
this._onClose = this._onClose.bind(this);
|
||||
this._onError = this._onError.bind(this);
|
||||
this._renderLoading = this._renderLoading.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements React's {@link Component#componentDidMount()}. Invoked
|
||||
* immediately after this component is mounted.
|
||||
*
|
||||
* @inheritdoc
|
||||
* @returns {void}
|
||||
*/
|
||||
componentDidMount() {
|
||||
const { navigation } = this.props;
|
||||
|
||||
navigation.setOptions({
|
||||
headerLeft: () => (
|
||||
<HeaderNavigationButton
|
||||
onPress = { goBack }
|
||||
src = { IconArrowBack }
|
||||
style = { styles.headerArrowBack } />
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements React's {@link Component#render()}.
|
||||
*
|
||||
|
@ -73,55 +87,18 @@ class SharedDocument extends PureComponent<Props> {
|
|||
const { _documentUrl } = this.props;
|
||||
|
||||
return (
|
||||
<JitsiModal
|
||||
headerProps = {{
|
||||
headerLabelKey: 'documentSharing.title'
|
||||
}}
|
||||
modalId = { SHARE_DOCUMENT_VIEW_ID }
|
||||
style = { styles.webView }>
|
||||
<JitsiScreen
|
||||
addHeaderHeightValue = { true }
|
||||
hasTabNavigator = { false }
|
||||
style = { styles.sharedDocContainer }>
|
||||
<WebView
|
||||
onError = { this._onError }
|
||||
renderLoading = { this._renderLoading }
|
||||
source = {{ uri: _documentUrl }}
|
||||
startInLoadingState = { true } />
|
||||
</JitsiModal>
|
||||
</JitsiScreen>
|
||||
);
|
||||
}
|
||||
|
||||
_onClose: () => boolean
|
||||
|
||||
/**
|
||||
* Closes the window.
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
_onClose() {
|
||||
const { _isOpen, dispatch } = this.props;
|
||||
|
||||
if (_isOpen) {
|
||||
dispatch(toggleDocument());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
_onError: () => void;
|
||||
|
||||
/**
|
||||
* Callback to handle the error if the page fails to load.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_onError() {
|
||||
const { _isOpen, dispatch } = this.props;
|
||||
|
||||
if (_isOpen) {
|
||||
dispatch(toggleDocument());
|
||||
}
|
||||
}
|
||||
|
||||
_renderLoading: () => React$Component<any>;
|
||||
|
||||
/**
|
||||
|
@ -148,13 +125,11 @@ class SharedDocument extends PureComponent<Props> {
|
|||
* @returns {Object}
|
||||
*/
|
||||
export function _mapStateToProps(state: Object) {
|
||||
const { editing } = state['features/etherpad'];
|
||||
const documentUrl = getSharedDocumentUrl(state);
|
||||
|
||||
return {
|
||||
_documentUrl: documentUrl,
|
||||
_headerStyles: ColorSchemeRegistry.get(state, 'Header'),
|
||||
_isOpen: editing
|
||||
_headerStyles: ColorSchemeRegistry.get(state, 'Header')
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,10 @@ export const INDICATOR_COLOR = ColorPalette.lightGrey;
|
|||
|
||||
export default {
|
||||
|
||||
headerArrowBack: {
|
||||
marginLeft: 12
|
||||
},
|
||||
|
||||
indicatorWrapper: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: ColorPalette.white,
|
||||
|
@ -13,6 +17,10 @@ export default {
|
|||
justifyContent: 'center'
|
||||
},
|
||||
|
||||
sharedDocContainer: {
|
||||
flex: 1
|
||||
},
|
||||
|
||||
webView: {
|
||||
backgroundColor: 'rgb(242, 242, 242)'
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
import type { Dispatch } from 'redux';
|
||||
|
||||
import { getFeatureFlag, ADD_PEOPLE_ENABLED } from '../base/flags';
|
||||
import { setActiveModalId } from '../base/modal';
|
||||
import { navigate } from '../conference/components/native/ConferenceNavigationContainerRef';
|
||||
import { screen } from '../conference/components/native/routes';
|
||||
import { beginShareRoom } from '../share-room';
|
||||
|
||||
import { ADD_PEOPLE_DIALOG_VIEW_ID } from './constants';
|
||||
import { isAddPeopleEnabled, isDialOutEnabled } from './functions';
|
||||
|
||||
export * from './actions.any';
|
||||
|
@ -24,7 +24,7 @@ export function doInvitePeople() {
|
|||
&& (isAddPeopleEnabled(state) || isDialOutEnabled(state));
|
||||
|
||||
if (addPeopleEnabled) {
|
||||
return dispatch(setActiveModalId(ADD_PEOPLE_DIALOG_VIEW_ID));
|
||||
return navigate(screen.conference.invite);
|
||||
}
|
||||
|
||||
return dispatch(beginShareRoom());
|
||||
|
|
|
@ -6,13 +6,12 @@ import {
|
|||
ActivityIndicator,
|
||||
FlatList,
|
||||
Platform,
|
||||
SafeAreaView,
|
||||
TextInput,
|
||||
TouchableOpacity,
|
||||
View
|
||||
} from 'react-native';
|
||||
import { Text, TouchableRipple, withTheme } from 'react-native-paper';
|
||||
|
||||
import { ColorSchemeRegistry } from '../../../../base/color-scheme';
|
||||
import { AlertDialog, openDialog } from '../../../../base/dialog';
|
||||
import { translate } from '../../../../base/i18n';
|
||||
import {
|
||||
|
@ -24,15 +23,14 @@ import {
|
|||
IconSearch,
|
||||
IconShare
|
||||
} from '../../../../base/icons';
|
||||
import { JitsiModal, setActiveModalId } from '../../../../base/modal';
|
||||
import JitsiScreen from '../../../../base/modal/components/JitsiScreen';
|
||||
import {
|
||||
AvatarListItem,
|
||||
type Item
|
||||
} from '../../../../base/react';
|
||||
import { connect } from '../../../../base/redux';
|
||||
import { ColorPalette } from '../../../../base/styles';
|
||||
import { beginShareRoom } from '../../../../share-room';
|
||||
import { ADD_PEOPLE_DIALOG_VIEW_ID, INVITE_TYPES } from '../../../constants';
|
||||
import { INVITE_TYPES } from '../../../constants';
|
||||
import AbstractAddPeopleDialog, {
|
||||
type Props as AbstractProps,
|
||||
type State as AbstractState,
|
||||
|
@ -46,20 +44,25 @@ import styles, {
|
|||
|
||||
type Props = AbstractProps & {
|
||||
|
||||
/**
|
||||
* The color schemed style of the Header.
|
||||
*/
|
||||
_headerStyles: Object,
|
||||
|
||||
/**
|
||||
* True if the invite dialog should be open, false otherwise.
|
||||
*/
|
||||
_isVisible: boolean,
|
||||
|
||||
/**
|
||||
* Default prop for navigation between screen components(React Navigation)
|
||||
*/
|
||||
navigation: Object,
|
||||
|
||||
/**
|
||||
* Function used to translate i18n labels.
|
||||
*/
|
||||
t: Function
|
||||
t: Function,
|
||||
|
||||
/**
|
||||
* Theme used for styles.
|
||||
*/
|
||||
theme: Object
|
||||
};
|
||||
|
||||
type State = AbstractState & {
|
||||
|
@ -136,12 +139,54 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
|||
this._setFieldRef = this._setFieldRef.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements React's {@link Component#componentDidMount()}. Invoked
|
||||
* immediately after this component is mounted.
|
||||
*
|
||||
* @inheritdoc
|
||||
* @returns {void}
|
||||
*/
|
||||
componentDidMount() {
|
||||
const { navigation, t, theme } = this.props;
|
||||
const { palette } = theme;
|
||||
|
||||
navigation.setOptions({
|
||||
headerRight: () => (
|
||||
<TouchableRipple
|
||||
disabled = { this._isAddDisabled() }
|
||||
rippleColor = { palette.screen01Header } >
|
||||
<Text
|
||||
style = { styles.headerSendInvite }>{ t('inviteDialog.send') }
|
||||
</Text>
|
||||
</TouchableRipple>
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements {@code Component#componentDidUpdate}.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
componentDidUpdate(prevProps) {
|
||||
const { navigation, t, theme } = this.props;
|
||||
const { palette } = theme;
|
||||
|
||||
navigation.setOptions({
|
||||
// eslint-disable-next-line react/no-multi-comp
|
||||
headerRight: () => (
|
||||
<TouchableRipple
|
||||
disabled = { this._isAddDisabled() }
|
||||
onPress = { this._onInvite }
|
||||
rippleColor = { palette.screen01Header } >
|
||||
<Text
|
||||
/* eslint-disable-next-line react-native/no-inline-styles */
|
||||
style = { styles.headerSendInvite }>{ t('inviteDialog.send') }
|
||||
</Text>
|
||||
</TouchableRipple>
|
||||
)
|
||||
});
|
||||
|
||||
if (prevProps._isVisible !== this.props._isVisible) {
|
||||
// Clear state
|
||||
this._clearState();
|
||||
|
@ -159,6 +204,8 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
|||
_dialOutEnabled
|
||||
} = this.props;
|
||||
const { inviteItems, selectableItems } = this.state;
|
||||
const { theme } = this.props;
|
||||
const { palette } = theme;
|
||||
|
||||
let placeholderKey = 'searchPlaceholder';
|
||||
|
||||
|
@ -169,15 +216,10 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
|||
}
|
||||
|
||||
return (
|
||||
<JitsiModal
|
||||
<JitsiScreen
|
||||
footerComponent = { this._renderShareMeetingButton }
|
||||
headerProps = {{
|
||||
forwardDisabled: this._isAddDisabled(),
|
||||
forwardLabelKey: 'inviteDialog.send',
|
||||
headerLabelKey: 'inviteDialog.header',
|
||||
onPressForward: this._onInvite
|
||||
}}
|
||||
modalId = { ADD_PEOPLE_DIALOG_VIEW_ID }>
|
||||
hasTabNavigator = { false }
|
||||
style = { styles.addPeopleContainer }>
|
||||
<View
|
||||
style = { styles.searchFieldWrapper }>
|
||||
<View style = { styles.searchIconWrapper }>
|
||||
|
@ -198,7 +240,7 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
|||
placeholder = {
|
||||
this.props.t(`inviteDialog.${placeholderKey}`)
|
||||
}
|
||||
placeholderTextColor = { ColorPalette.lightGrey }
|
||||
placeholderTextColor = { palette.text04 }
|
||||
ref = { this._setFieldRef }
|
||||
spellCheck = { false }
|
||||
style = { styles.searchField }
|
||||
|
@ -222,7 +264,7 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
|||
keyboardShouldPersistTaps = 'always'
|
||||
renderItem = { this._renderItem } />
|
||||
</View>
|
||||
</JitsiModal>
|
||||
</JitsiScreen>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -326,8 +368,6 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
|||
inviteItems: invitesLeftToSend
|
||||
});
|
||||
this._showFailedInviteAlert();
|
||||
} else {
|
||||
this.props.dispatch(setActiveModalId());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -562,22 +602,20 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
|||
* @returns {React#Element<*>}
|
||||
*/
|
||||
_renderShareMeetingButton() {
|
||||
const { _headerStyles } = this.props;
|
||||
|
||||
return (
|
||||
<SafeAreaView
|
||||
<View
|
||||
style = { [
|
||||
styles.bottomBar,
|
||||
_headerStyles.headerOverlay,
|
||||
this.state.bottomPadding ? styles.extraBarPadding : null
|
||||
] }>
|
||||
<TouchableOpacity
|
||||
onPress = { this._onShareMeeting }>
|
||||
<Icon
|
||||
src = { IconShare }
|
||||
style = { [ _headerStyles.headerButtonText, styles.shareIcon ] } />
|
||||
style = { styles.shareIcon } />
|
||||
</TouchableOpacity>
|
||||
</SafeAreaView>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -621,10 +659,8 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
|||
*/
|
||||
function _mapStateToProps(state: Object) {
|
||||
return {
|
||||
..._abstractMapStateToProps(state),
|
||||
_headerStyles: ColorSchemeRegistry.get(state, 'Header'),
|
||||
_isVisible: state['features/base/modal'].activeModalId === ADD_PEOPLE_DIALOG_VIEW_ID
|
||||
..._abstractMapStateToProps(state)
|
||||
};
|
||||
}
|
||||
|
||||
export default translate(connect(_mapStateToProps)(AddPeopleDialog));
|
||||
export default translate(connect(_mapStateToProps)(withTheme(AddPeopleDialog)));
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
// @flow
|
||||
|
||||
import { BoxModel } from '../../../../base/styles';
|
||||
import BaseTheme from '../../../../base/ui/components/BaseTheme.native';
|
||||
|
||||
export const AVATAR_SIZE = 40;
|
||||
export const DARK_GREY = 'rgb(28, 32, 37)';
|
||||
export const LIGHT_GREY = 'rgb(209, 219, 232)';
|
||||
export const ICON_SIZE = 15;
|
||||
|
||||
const FIELD_COLOR = 'rgb(240, 243, 247)';
|
||||
|
||||
export default {
|
||||
|
||||
addPeopleContainer: {
|
||||
flex: 1
|
||||
},
|
||||
|
||||
avatar: {
|
||||
backgroundColor: LIGHT_GREY
|
||||
},
|
||||
|
@ -21,8 +25,9 @@ export default {
|
|||
|
||||
bottomBar: {
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-around'
|
||||
justifyContent: 'center',
|
||||
backgroundColor: BaseTheme.palette.screen01Header,
|
||||
height: BaseTheme.spacing[10]
|
||||
},
|
||||
|
||||
clearButton: {
|
||||
|
@ -39,7 +44,7 @@ export default {
|
|||
|
||||
clearIconContainer: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: FIELD_COLOR,
|
||||
backgroundColor: BaseTheme.palette.section01,
|
||||
borderRadius: 12,
|
||||
justifyContent: 'center',
|
||||
height: 24,
|
||||
|
@ -53,6 +58,15 @@ export default {
|
|||
paddingBottom: 30
|
||||
},
|
||||
|
||||
headerCloseIcon: {
|
||||
marginLeft: 12
|
||||
},
|
||||
|
||||
headerSendInvite: {
|
||||
color: BaseTheme.palette.text01,
|
||||
marginRight: 12
|
||||
},
|
||||
|
||||
invitedList: {
|
||||
padding: 3
|
||||
},
|
||||
|
@ -80,7 +94,7 @@ export default {
|
|||
},
|
||||
|
||||
searchField: {
|
||||
backgroundColor: FIELD_COLOR,
|
||||
backgroundColor: BaseTheme.palette.section01,
|
||||
borderBottomRightRadius: 10,
|
||||
borderTopRightRadius: 10,
|
||||
color: DARK_GREY,
|
||||
|
@ -106,7 +120,7 @@ export default {
|
|||
alignItems: 'stretch',
|
||||
flexDirection: 'row',
|
||||
height: 52,
|
||||
paddingHorizontal: 15,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 8
|
||||
},
|
||||
|
||||
|
@ -117,7 +131,7 @@ export default {
|
|||
|
||||
searchIconWrapper: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: FIELD_COLOR,
|
||||
backgroundColor: BaseTheme.palette.section01,
|
||||
borderBottomLeftRadius: 10,
|
||||
borderTopLeftRadius: 10,
|
||||
flexDirection: 'row',
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
// @flow
|
||||
|
||||
/**
|
||||
* Modal ID for the AddPeopleDialog modal.
|
||||
*/
|
||||
export const ADD_PEOPLE_DIALOG_VIEW_ID = 'ADD_PEOPLE_DIALOG_VIEW_ID';
|
||||
|
||||
/**
|
||||
* Modal ID for the DialInSummary modal.
|
||||
*/
|
||||
|
|
|
@ -2,11 +2,12 @@
|
|||
|
||||
import React from 'react';
|
||||
import { Text, View, TouchableOpacity, TextInput } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
|
||||
import { Avatar } from '../../../base/avatar';
|
||||
import { CustomDialog } from '../../../base/dialog';
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { Icon, IconEdit } from '../../../base/icons';
|
||||
import JitsiScreen from '../../../base/modal/components/JitsiScreen';
|
||||
import { LoadingIndicator } from '../../../base/react';
|
||||
import { connect } from '../../../base/redux';
|
||||
import AbstractLobbyScreen, { _mapStateToProps } from '../AbstractLobbyScreen';
|
||||
|
@ -26,9 +27,10 @@ class LobbyScreen extends AbstractLobbyScreen {
|
|||
const { _meetingName, t } = this.props;
|
||||
|
||||
return (
|
||||
<CustomDialog
|
||||
onCancel = { this._onCancel }>
|
||||
<View style = { styles.contentWrapper }>
|
||||
<JitsiScreen
|
||||
hasTabNavigator = { false }
|
||||
style = { styles.contentWrapper }>
|
||||
<SafeAreaView>
|
||||
<Text style = { styles.dialogTitle }>
|
||||
{ t(this._getScreenTitleKey()) }
|
||||
</Text>
|
||||
|
@ -36,8 +38,8 @@ class LobbyScreen extends AbstractLobbyScreen {
|
|||
{ _meetingName }
|
||||
</Text>
|
||||
{ this._renderContent() }
|
||||
</View>
|
||||
</CustomDialog>
|
||||
</SafeAreaView>
|
||||
</JitsiScreen>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -234,6 +236,13 @@ class LobbyScreen extends AbstractLobbyScreen {
|
|||
{ t('lobby.enterPasswordButton') }
|
||||
</Text>
|
||||
</TouchableOpacity> }
|
||||
<TouchableOpacity
|
||||
onPress = { this._onCancel }
|
||||
style = { styles.cancelButton }>
|
||||
<Text>
|
||||
{ t('dialog.Cancel') }
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -12,20 +12,29 @@ export default {
|
|||
button: {
|
||||
alignItems: 'center',
|
||||
borderRadius: 4,
|
||||
marginVertical: 8,
|
||||
paddingVertical: 10
|
||||
marginVertical: 4,
|
||||
paddingVertical: 8
|
||||
},
|
||||
|
||||
contentWrapper: {
|
||||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
padding: 32
|
||||
justifyItems: 'center',
|
||||
height: '100%'
|
||||
},
|
||||
|
||||
closeIcon: {
|
||||
color: 'red',
|
||||
fontSize: 20
|
||||
},
|
||||
|
||||
dialogTitle: {
|
||||
fontSize: 18,
|
||||
fontWeight: 'bold',
|
||||
marginBottom: 10
|
||||
margin: 'auto',
|
||||
marginVertical: 24,
|
||||
textAlign: 'center'
|
||||
},
|
||||
|
||||
displayNameText: {
|
||||
|
@ -71,6 +80,8 @@ export default {
|
|||
},
|
||||
|
||||
joiningMessage: {
|
||||
color: 'rgba(0, 0, 0, .7)',
|
||||
paddingBottom: 36,
|
||||
textAlign: 'center'
|
||||
},
|
||||
|
||||
|
@ -103,7 +114,15 @@ export default {
|
|||
},
|
||||
|
||||
secondaryText: {
|
||||
color: 'rgba(0, 0, 0, .7)'
|
||||
color: 'rgba(0, 0, 0, .7)',
|
||||
margin: 'auto',
|
||||
textAlign: 'center'
|
||||
},
|
||||
|
||||
cancelButton: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: 'transparent',
|
||||
marginVertical: 4
|
||||
},
|
||||
|
||||
// KnockingParticipantList
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import React, { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ScrollView, Text, View } from 'react-native';
|
||||
import { Text, View } from 'react-native';
|
||||
import { Button, withTheme } from 'react-native-paper';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
|
@ -36,7 +36,8 @@ const LobbyParticipantList = ({ theme }: Props) => {
|
|||
}
|
||||
|
||||
return (
|
||||
<View style = { styles.lobbyList }>
|
||||
<View
|
||||
style = { styles.lobbyListContainer } >
|
||||
<View style = { styles.lobbyListDetails } >
|
||||
<Text style = { styles.lobbyListDescription }>
|
||||
{t('participantsPane.headings.waitingLobby',
|
||||
|
@ -54,15 +55,13 @@ const LobbyParticipantList = ({ theme }: Props) => {
|
|||
)
|
||||
}
|
||||
</View>
|
||||
<ScrollView>
|
||||
{
|
||||
participants.map(p => (
|
||||
<LobbyParticipantItem
|
||||
key = { p.id }
|
||||
participant = { p } />)
|
||||
)
|
||||
}
|
||||
</ScrollView>
|
||||
{
|
||||
participants.map(p => (
|
||||
<LobbyParticipantItem
|
||||
key = { p.id }
|
||||
participant = { p } />)
|
||||
)
|
||||
}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -134,7 +134,8 @@ class MeetingParticipantList extends PureComponent<Props> {
|
|||
} = this.props;
|
||||
|
||||
return (
|
||||
<View style = { styles.meetingList }>
|
||||
<View
|
||||
style = { styles.meetingListContainer }>
|
||||
<Text style = { styles.meetingListDescription }>
|
||||
{t('participantsPane.headings.participantsList',
|
||||
{ count: _participantsCount })}
|
||||
|
@ -155,7 +156,9 @@ class MeetingParticipantList extends PureComponent<Props> {
|
|||
horizontal = { false }
|
||||
keyExtractor = { this._keyExtractor }
|
||||
renderItem = { this._renderParticipant }
|
||||
scrollEnabled = { false }
|
||||
showsHorizontalScrollIndicator = { false }
|
||||
style = { styles.meetingList }
|
||||
windowSize = { 2 } />
|
||||
</View>
|
||||
);
|
||||
|
|
|
@ -2,18 +2,17 @@
|
|||
|
||||
import React, { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { View } from 'react-native';
|
||||
import { ScrollView, View } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import { openDialog } from '../../../base/dialog';
|
||||
import { JitsiModal } from '../../../base/modal';
|
||||
import JitsiScreen from '../../../base/modal/components/JitsiScreen';
|
||||
import {
|
||||
isLocalParticipantModerator
|
||||
} from '../../../base/participants';
|
||||
import MuteEveryoneDialog
|
||||
from '../../../video-menu/components/native/MuteEveryoneDialog';
|
||||
import { close } from '../../actions.native';
|
||||
|
||||
import { ContextMenuMore } from './ContextMenuMore';
|
||||
import HorizontalDotsIcon from './HorizontalDotsIcon';
|
||||
|
@ -29,21 +28,19 @@ import styles from './styles';
|
|||
const ParticipantsPane = () => {
|
||||
const dispatch = useDispatch();
|
||||
const openMoreMenu = useCallback(() => dispatch(openDialog(ContextMenuMore)), [ dispatch ]);
|
||||
const closePane = useCallback(() => dispatch(close()), [ dispatch ]);
|
||||
const isLocalModerator = useSelector(isLocalParticipantModerator);
|
||||
const muteAll = useCallback(() => dispatch(openDialog(MuteEveryoneDialog)),
|
||||
[ dispatch ]);
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<JitsiModal
|
||||
headerProps = {{
|
||||
headerLabelKey: 'participantsPane.header'
|
||||
}}
|
||||
onClose = { closePane }
|
||||
<JitsiScreen
|
||||
hasTabNavigator = { false }
|
||||
style = { styles.participantsPane }>
|
||||
<LobbyParticipantList />
|
||||
<MeetingParticipantList />
|
||||
<ScrollView bounces = { false }>
|
||||
<LobbyParticipantList />
|
||||
<MeetingParticipantList />
|
||||
</ScrollView>
|
||||
{
|
||||
isLocalModerator
|
||||
&& <View style = { styles.footer }>
|
||||
|
@ -61,7 +58,7 @@ const ParticipantsPane = () => {
|
|||
style = { styles.moreButton } />
|
||||
</View>
|
||||
}
|
||||
</JitsiModal>
|
||||
</JitsiScreen>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -6,7 +6,9 @@ import { translate } from '../../../base/i18n';
|
|||
import { IconParticipants } from '../../../base/icons';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { AbstractButton, type AbstractButtonProps } from '../../../base/toolbox/components';
|
||||
import { open } from '../../actions.native';
|
||||
import { navigate }
|
||||
from '../../../conference/components/native/ConferenceNavigationContainerRef';
|
||||
import { screen } from '../../../conference/components/native/routes';
|
||||
|
||||
type Props = AbstractButtonProps & {
|
||||
|
||||
|
@ -32,9 +34,7 @@ class ParticipantsPaneButton extends AbstractButton<Props, *> {
|
|||
* @returns {void}
|
||||
*/
|
||||
_handleClick() {
|
||||
const { dispatch } = this.props;
|
||||
|
||||
dispatch(open());
|
||||
return navigate(screen.conference.participants);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -165,11 +165,13 @@ export default {
|
|||
isLocal: {
|
||||
alignSelf: 'center',
|
||||
color: BaseTheme.palette.text01,
|
||||
marginLeft: 4
|
||||
marginLeft: BaseTheme.spacing[1]
|
||||
},
|
||||
|
||||
participantsPane: {
|
||||
backgroundColor: BaseTheme.palette.ui01
|
||||
backgroundColor: BaseTheme.palette.ui01,
|
||||
flex: 1,
|
||||
justifyContent: 'center'
|
||||
},
|
||||
|
||||
participantStatesContainer: {
|
||||
|
@ -196,13 +198,12 @@ export default {
|
|||
top: BaseTheme.spacing[1]
|
||||
},
|
||||
|
||||
lobbyList: {
|
||||
lobbyListContainer: {
|
||||
position: 'relative'
|
||||
},
|
||||
|
||||
meetingList: {
|
||||
position: 'relative',
|
||||
marginTop: BaseTheme.spacing[3]
|
||||
lobbyListDescription: {
|
||||
...participantListDescription
|
||||
},
|
||||
|
||||
lobbyListDetails: {
|
||||
|
@ -216,8 +217,8 @@ export default {
|
|||
width: '100%'
|
||||
},
|
||||
|
||||
lobbyListDescription: {
|
||||
...participantListDescription
|
||||
meetingListContainer: {
|
||||
flex: 1
|
||||
},
|
||||
|
||||
meetingListDescription: {
|
||||
|
@ -227,21 +228,18 @@ export default {
|
|||
|
||||
footer: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: BaseTheme.palette.ui01,
|
||||
bottom: BaseTheme.spacing[0],
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
height: BaseTheme.spacing[10],
|
||||
justifyContent: 'space-between',
|
||||
paddingRight: BaseTheme.spacing[3],
|
||||
position: 'relative',
|
||||
right: BaseTheme.spacing[0],
|
||||
left: BaseTheme.spacing[0]
|
||||
paddingHorizontal: BaseTheme.spacing[3],
|
||||
paddingVertical: BaseTheme.spacing[2]
|
||||
},
|
||||
|
||||
headerCloseIcon: {
|
||||
marginLeft: 12
|
||||
},
|
||||
|
||||
inviteButton: {
|
||||
backgroundColor: BaseTheme.palette.action01,
|
||||
marginTop: BaseTheme.spacing[2],
|
||||
marginBottom: BaseTheme.spacing[4],
|
||||
marginLeft: BaseTheme.spacing[3],
|
||||
marginRight: BaseTheme.spacing[3]
|
||||
},
|
||||
|
|
|
@ -141,39 +141,38 @@ const PollCreate = (props: AbstractProps) => {
|
|||
keyExtractor = { (item, index) => index.toString() }
|
||||
ref = { answerListRef }
|
||||
renderItem = { renderListItem } />
|
||||
<View style = { chatStyles.pollCreateButtons }>
|
||||
<Button
|
||||
color = '#3D3D3D'
|
||||
mode = { BUTTON_MODES.CONTAINED }
|
||||
onPress = { () => {
|
||||
// adding and answer
|
||||
addAnswer();
|
||||
requestFocus(answers.length);
|
||||
} }
|
||||
style = { chatStyles.pollCreateAddButton }>
|
||||
{t('polls.create.addOption')}
|
||||
</Button>
|
||||
<View
|
||||
style = { chatStyles.buttonRow }>
|
||||
<Button
|
||||
color = '#3D3D3D'
|
||||
mode = { BUTTON_MODES.CONTAINED }
|
||||
onPress = { () => setCreateMode(false) }
|
||||
style = { chatStyles.pollCreateButton } >
|
||||
{t('polls.create.cancel')}
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
color = '#3D3D3D'
|
||||
mode = { BUTTON_MODES.CONTAINED }
|
||||
onPress = { () => {
|
||||
// adding and answer
|
||||
addAnswer();
|
||||
requestFocus(answers.length);
|
||||
} }
|
||||
style = { chatStyles.pollCreateAddButton }>
|
||||
{t('polls.create.addOption')}
|
||||
</Button>
|
||||
</View>
|
||||
|
||||
<View
|
||||
style = { chatStyles.buttonRow }>
|
||||
|
||||
<Button
|
||||
color = '#3D3D3D'
|
||||
mode = { BUTTON_MODES.CONTAINED }
|
||||
onPress = { () => setCreateMode(false) }
|
||||
style = { chatStyles.pollCreateButton } >
|
||||
{t('polls.create.cancel')}
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
color = '#17a0db'
|
||||
disabled = { isSubmitDisabled }
|
||||
mode = { BUTTON_MODES.CONTAINED }
|
||||
onPress = { onSubmit }
|
||||
style = { chatStyles.pollCreateButton } >
|
||||
{t('polls.create.send')}
|
||||
</Button>
|
||||
<Button
|
||||
color = '#17a0db'
|
||||
disabled = { isSubmitDisabled }
|
||||
mode = { BUTTON_MODES.CONTAINED }
|
||||
onPress = { onSubmit }
|
||||
style = { chatStyles.pollCreateButton } >
|
||||
{t('polls.create.send')}
|
||||
</Button>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
/* eslint-disable react-native/no-color-literals */
|
||||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
import { useNavigation, useIsFocused } from '@react-navigation/native';
|
||||
import React, { useEffect } from 'react';
|
||||
import { Button, useTheme } from 'react-native-paper';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import JitsiScreen from '../../../base/modal/components/JitsiScreen';
|
||||
import { BUTTON_MODES } from '../../../chat/constants';
|
||||
import { screen } from '../../../conference/components/native/routes';
|
||||
import { getUnreadPollCount } from '../../functions';
|
||||
import AbstractPollsPane from '../AbstractPollsPane';
|
||||
import type { AbstractProps } from '../AbstractPollsPane';
|
||||
|
||||
|
@ -13,26 +17,45 @@ import PollCreate from './PollCreate';
|
|||
import PollsList from './PollsList';
|
||||
import { chatStyles } from './styles';
|
||||
|
||||
const PollsPane = (props: AbstractProps) => {
|
||||
|
||||
const PollsPane = (props: AbstractProps) => {
|
||||
const { createMode, onCreate, setCreateMode, t } = props;
|
||||
const isPollsScreenFocused = useIsFocused();
|
||||
const navigation = useNavigation();
|
||||
const nbUnreadPolls = useSelector(getUnreadPollCount);
|
||||
const { palette } = useTheme();
|
||||
|
||||
const nrUnreadPolls = !isPollsScreenFocused && nbUnreadPolls > 0
|
||||
? `(${nbUnreadPolls})`
|
||||
: '';
|
||||
|
||||
useEffect(() => {
|
||||
navigation.setOptions({
|
||||
tabBarLabel: `${screen.conference.chatandpolls.tab.polls} ${nrUnreadPolls}`
|
||||
});
|
||||
}, [ nrUnreadPolls ]);
|
||||
|
||||
return (
|
||||
<View style = { chatStyles.PollPane }>
|
||||
{ createMode
|
||||
? <PollCreate setCreateMode = { setCreateMode } />
|
||||
: <View style = { chatStyles.PollPaneContent }>
|
||||
{/* <View /> */}
|
||||
<PollsList />
|
||||
<Button
|
||||
color = '#17a0db'
|
||||
mode = { BUTTON_MODES.CONTAINED }
|
||||
onPress = { onCreate }
|
||||
style = { chatStyles.createPollButton } >
|
||||
{t('polls.create.create')}
|
||||
</Button>
|
||||
</View>}
|
||||
</View>
|
||||
<JitsiScreen
|
||||
contentContainerStyle = { chatStyles.PollPane }
|
||||
hasTabNavigator = { true }
|
||||
style = { chatStyles.PollPaneContainer }>
|
||||
{
|
||||
createMode
|
||||
? <PollCreate setCreateMode = { setCreateMode } />
|
||||
: <PollsList />
|
||||
|
||||
}
|
||||
{
|
||||
!createMode && <Button
|
||||
color = { palette.screen01Header }
|
||||
mode = { BUTTON_MODES.CONTAINED }
|
||||
onPress = { onCreate }
|
||||
style = { chatStyles.createPollButton } >
|
||||
{t('polls.create.create')}
|
||||
</Button>
|
||||
}
|
||||
</JitsiScreen>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// @flow
|
||||
|
||||
import { schemeColor } from '../../../base/color-scheme';
|
||||
import { ColorPalette, createStyleSheet } from '../../../base/styles';
|
||||
import BaseTheme from '../../../base/ui/components/BaseTheme';
|
||||
|
||||
export const answerStyles = createStyleSheet({
|
||||
question: {
|
||||
|
@ -110,6 +110,7 @@ export const resultsStyles = createStyleSheet({
|
|||
|
||||
export const chatStyles = createStyleSheet({
|
||||
messageFooter: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
|
@ -123,9 +124,9 @@ export const chatStyles = createStyleSheet({
|
|||
|
||||
noPollText: {
|
||||
flex: 1,
|
||||
color: schemeColor('displayName'),
|
||||
color: BaseTheme.palette.ui05,
|
||||
textAlign: 'center',
|
||||
paddingTop: '10%'
|
||||
paddingTop: '8%'
|
||||
},
|
||||
|
||||
pollItemContainer: {
|
||||
|
@ -165,17 +166,17 @@ export const chatStyles = createStyleSheet({
|
|||
},
|
||||
|
||||
pollCreateAddButton: {
|
||||
margin: 8
|
||||
margin: BaseTheme.spacing[2]
|
||||
},
|
||||
|
||||
toggleText: {
|
||||
color: ColorPalette.blue,
|
||||
paddingTop: 16
|
||||
paddingTop: BaseTheme.spacing[3]
|
||||
},
|
||||
|
||||
createPollButton: {
|
||||
padding: 8,
|
||||
margin: 4
|
||||
margin: BaseTheme.spacing[2]
|
||||
},
|
||||
|
||||
PollPane: {
|
||||
|
@ -183,8 +184,13 @@ export const chatStyles = createStyleSheet({
|
|||
padding: 8
|
||||
},
|
||||
|
||||
PollPaneContainer: {
|
||||
flex: 1
|
||||
},
|
||||
|
||||
PollPaneContent: {
|
||||
justifyContent: 'space-between',
|
||||
padding: BaseTheme.spacing[3],
|
||||
flex: 1
|
||||
},
|
||||
|
||||
|
|
|
@ -44,12 +44,7 @@ type Props = {
|
|||
/**
|
||||
* Whether or not the reactions feature is enabled.
|
||||
*/
|
||||
_reactionsEnabled: boolean,
|
||||
|
||||
/**
|
||||
* The redux {@code dispatch} function.
|
||||
*/
|
||||
dispatch: Function
|
||||
_reactionsEnabled: boolean
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -88,10 +83,12 @@ function Toolbox(props: Props) {
|
|||
<VideoMuteButton
|
||||
styles = { buttonStylesBorderless }
|
||||
toggledStyles = { toggledButtonStyles } />
|
||||
{ additionalButtons.has('chat')
|
||||
{
|
||||
additionalButtons.has('chat')
|
||||
&& <ChatButton
|
||||
styles = { buttonStylesBorderless }
|
||||
toggledStyles = { backgroundToggledStyle } />}
|
||||
toggledStyles = { backgroundToggledStyle } />
|
||||
}
|
||||
|
||||
{ additionalButtons.has('raisehand') && (_reactionsEnabled
|
||||
? <ReactionsMenuButton
|
||||
|
|
Loading…
Reference in New Issue