Compare commits
12 Commits
jitihouse/
...
mobile-22.
Author | SHA1 | Date |
---|---|---|
Saúl Ibarra Corretgé | 9fedbab80a | |
Calin-Teodor | 2039feae94 | |
Calin-Teodor | 2842d3acef | |
Calin-Teodor | 00e1a1d79d | |
Calinteodor | 1843516ec7 | |
Calinteodor | 7f34818cd4 | |
Calin-Teodor | c8229a590c | |
Calin-Teodor | e339325afc | |
Calin-Teodor | 2aecbcaab1 | |
Calin-Teodor | f8037966f4 | |
Calin-Teodor | 057dceb178 | |
Saúl Ibarra Corretgé | f8917b2d3f |
|
@ -26,5 +26,5 @@ android.useAndroidX=true
|
|||
android.enableJetifier=true
|
||||
android.bundle.enableUncompressedNativeLibs=false
|
||||
|
||||
appVersion=22.3.0
|
||||
sdkVersion=5.2.0
|
||||
appVersion=22.4.0
|
||||
sdkVersion=6.0.0
|
||||
|
|
|
@ -51,15 +51,10 @@ dependencies {
|
|||
implementation 'com.google.code.gson:gson:2.8.6'
|
||||
implementation "androidx.startup:startup-runtime:1.1.0"
|
||||
|
||||
if (rootProject.ext.libreBuild) {
|
||||
implementation(project(':react-native-device-info')) {
|
||||
exclude group: 'com.google.firebase'
|
||||
exclude group: 'com.google.android.gms'
|
||||
exclude group: 'com.android.installreferrer'
|
||||
}
|
||||
} else {
|
||||
// Only add these packages if we are NOT doing a LIBRE_BUILD
|
||||
if (!rootProject.ext.libreBuild) {
|
||||
implementation project(':react-native-amplitude')
|
||||
implementation project(':react-native-device-info')
|
||||
implementation project(':react-native-giphy')
|
||||
implementation(project(":react-native-google-signin")) {
|
||||
exclude group: 'com.google.android.gms'
|
||||
exclude group: 'androidx'
|
||||
|
@ -72,9 +67,13 @@ dependencies {
|
|||
implementation project(':react-native-community_clipboard')
|
||||
implementation project(':react-native-community_netinfo')
|
||||
implementation project(':react-native-default-preference')
|
||||
implementation(project(':react-native-device-info')) {
|
||||
exclude group: 'com.google.firebase'
|
||||
exclude group: 'com.google.android.gms'
|
||||
exclude group: 'com.android.installreferrer'
|
||||
}
|
||||
implementation project(':react-native-gesture-handler')
|
||||
implementation project(':react-native-get-random-values')
|
||||
implementation project(':react-native-giphy')
|
||||
implementation project(':react-native-immersive')
|
||||
implementation project(':react-native-keep-awake')
|
||||
implementation project(':react-native-masked-view_masked-view')
|
||||
|
|
|
@ -46,6 +46,8 @@ import java.util.Arrays;
|
|||
import java.util.List;
|
||||
|
||||
class ReactInstanceManagerHolder {
|
||||
private static final String TAG = ReactInstanceManagerHolder.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* FIXME (from linter): Do not place Android context classes in static
|
||||
* fields (static reference to ReactInstanceManager which has field
|
||||
|
@ -110,7 +112,6 @@ class ReactInstanceManagerHolder {
|
|||
new com.corbt.keepawake.KCKeepAwakePackage(),
|
||||
new com.facebook.react.shell.MainReactPackage(),
|
||||
new com.reactnativecommunity.clipboard.ClipboardPackage(),
|
||||
new com.giphyreactnativesdk.GiphyReactNativeSdkPackage(),
|
||||
new com.reactnativecommunity.netinfo.NetInfoPackage(),
|
||||
new com.reactnativepagerview.PagerViewPackage(),
|
||||
new com.oblador.performance.PerformancePackage(),
|
||||
|
@ -146,6 +147,17 @@ class ReactInstanceManagerHolder {
|
|||
packages.add((ReactPackage)constructor.newInstance());
|
||||
} catch (Exception e) {
|
||||
// Ignore any error, the module is not compiled when LIBRE_BUILD is enabled.
|
||||
Log.d(TAG, "Not loading AmplitudeReactNativePackage");
|
||||
}
|
||||
|
||||
// GiphyReactNativeSdkPackage
|
||||
try {
|
||||
Class<?> giphyPackageClass = Class.forName("com.giphyreactnativesdk.GiphyReactNativeSdkPackage");
|
||||
Constructor constructor = giphyPackageClass.getConstructor();
|
||||
packages.add((ReactPackage)constructor.newInstance());
|
||||
} catch (Exception e) {
|
||||
// Ignore any error, the module is not compiled when LIBRE_BUILD is enabled.
|
||||
Log.d(TAG, "Not loading GiphyReactNativeSdkPackage");
|
||||
}
|
||||
|
||||
// RNGoogleSignInPackage
|
||||
|
@ -155,6 +167,7 @@ class ReactInstanceManagerHolder {
|
|||
packages.add((ReactPackage)constructor.newInstance());
|
||||
} catch (Exception e) {
|
||||
// Ignore any error, the module is not compiled when LIBRE_BUILD is enabled.
|
||||
Log.d(TAG, "Not loading RNGoogleSignInPackage");
|
||||
}
|
||||
|
||||
return packages;
|
||||
|
@ -240,7 +253,7 @@ class ReactInstanceManagerHolder {
|
|||
return;
|
||||
}
|
||||
|
||||
Log.d(ReactInstanceManagerHolder.class.getCanonicalName(), "initializing RN with Application");
|
||||
Log.d(TAG, "initializing RN with Application");
|
||||
|
||||
reactInstanceManager
|
||||
= ReactInstanceManager.builder()
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>22.3.0</string>
|
||||
<string>22.4.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSExtension</key>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>22.3.0</string>
|
||||
<string>22.4.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>22.3.0</string>
|
||||
<string>22.4.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>22.3.0</string>
|
||||
<string>22.4.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>CLKComplicationPrincipalClass</key>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>5.2.0</string>
|
||||
<string>6.0.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
"@react-navigation/elements": "1.2.1",
|
||||
"@react-navigation/material-top-tabs": "6.0.6",
|
||||
"@react-navigation/native": "6.0.6",
|
||||
"@react-navigation/native-stack": "6.6.2",
|
||||
"@react-navigation/stack": "6.2.2",
|
||||
"@svgr/webpack": "4.3.2",
|
||||
"@tensorflow/tfjs-backend-wasm": "3.13.0",
|
||||
"@tensorflow/tfjs-core": "3.13.0",
|
||||
|
@ -5026,33 +5026,6 @@
|
|||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-navigation/native-stack": {
|
||||
"version": "6.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/native-stack/-/native-stack-6.6.2.tgz",
|
||||
"integrity": "sha512-pFMuzhxbPml5MBvJVAzHWoaUkQaefAOKpuUnAs/AxNQuHQwwnxRmDit1PQLuIPo7g7DlfwFXagDHE1R0tbnS8Q==",
|
||||
"dependencies": {
|
||||
"@react-navigation/elements": "^1.3.3",
|
||||
"warn-once": "^0.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@react-navigation/native": "^6.0.0",
|
||||
"react": "*",
|
||||
"react-native": "*",
|
||||
"react-native-safe-area-context": ">= 3.0.0",
|
||||
"react-native-screens": ">= 3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-navigation/native-stack/node_modules/@react-navigation/elements": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.3.tgz",
|
||||
"integrity": "sha512-Lv2lR7si5gNME8dRsqz57d54m4FJtrwHRjNQLOyQO546ZxO+g864cSvoLC6hQedQU0+IJnPTsZiEI2hHqfpEpw==",
|
||||
"peerDependencies": {
|
||||
"@react-navigation/native": "^6.0.0",
|
||||
"react": "*",
|
||||
"react-native": "*",
|
||||
"react-native-safe-area-context": ">= 3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-navigation/routers": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.0.tgz",
|
||||
|
@ -5061,6 +5034,63 @@
|
|||
"nanoid": "^3.1.23"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-navigation/stack": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-6.2.2.tgz",
|
||||
"integrity": "sha512-P9ZfmluOXNmbs7YdG1UWS1fAh87Yse9aX8TgqOz4FlHEm5q7g5eaM35QgWByt+wif3UiqE40D8wXpqRQvMgPWg==",
|
||||
"dependencies": {
|
||||
"@react-navigation/elements": "^1.3.4",
|
||||
"color": "^4.2.3",
|
||||
"warn-once": "^0.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@react-navigation/native": "^6.0.0",
|
||||
"react": "*",
|
||||
"react-native": "*",
|
||||
"react-native-gesture-handler": ">= 1.0.0",
|
||||
"react-native-safe-area-context": ">= 3.0.0",
|
||||
"react-native-screens": ">= 3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-navigation/stack/node_modules/@react-navigation/elements": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.4.tgz",
|
||||
"integrity": "sha512-O0jICpjn3jskVo4yiWzZozmj7DZy1ZBbn3O7dbenuUjZSj/cscjwaapmZZFGcI/IMmjmx8UTKsybhCFEIbGf3g==",
|
||||
"peerDependencies": {
|
||||
"@react-navigation/native": "^6.0.0",
|
||||
"react": "*",
|
||||
"react-native": "*",
|
||||
"react-native-safe-area-context": ">= 3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-navigation/stack/node_modules/color": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
|
||||
"integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1",
|
||||
"color-string": "^1.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-navigation/stack/node_modules/color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-navigation/stack/node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"node_modules/@sideway/address": {
|
||||
"version": "4.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz",
|
||||
|
@ -23766,22 +23796,6 @@
|
|||
"nanoid": "^3.1.23"
|
||||
}
|
||||
},
|
||||
"@react-navigation/native-stack": {
|
||||
"version": "6.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/native-stack/-/native-stack-6.6.2.tgz",
|
||||
"integrity": "sha512-pFMuzhxbPml5MBvJVAzHWoaUkQaefAOKpuUnAs/AxNQuHQwwnxRmDit1PQLuIPo7g7DlfwFXagDHE1R0tbnS8Q==",
|
||||
"requires": {
|
||||
"@react-navigation/elements": "^1.3.3",
|
||||
"warn-once": "^0.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-navigation/elements": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.3.tgz",
|
||||
"integrity": "sha512-Lv2lR7si5gNME8dRsqz57d54m4FJtrwHRjNQLOyQO546ZxO+g864cSvoLC6hQedQU0+IJnPTsZiEI2hHqfpEpw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@react-navigation/routers": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.0.tgz",
|
||||
|
@ -23790,6 +23804,45 @@
|
|||
"nanoid": "^3.1.23"
|
||||
}
|
||||
},
|
||||
"@react-navigation/stack": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-6.2.2.tgz",
|
||||
"integrity": "sha512-P9ZfmluOXNmbs7YdG1UWS1fAh87Yse9aX8TgqOz4FlHEm5q7g5eaM35QgWByt+wif3UiqE40D8wXpqRQvMgPWg==",
|
||||
"requires": {
|
||||
"@react-navigation/elements": "^1.3.4",
|
||||
"color": "^4.2.3",
|
||||
"warn-once": "^0.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-navigation/elements": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.4.tgz",
|
||||
"integrity": "sha512-O0jICpjn3jskVo4yiWzZozmj7DZy1ZBbn3O7dbenuUjZSj/cscjwaapmZZFGcI/IMmjmx8UTKsybhCFEIbGf3g=="
|
||||
},
|
||||
"color": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
|
||||
"integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1",
|
||||
"color-string": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@sideway/address": {
|
||||
"version": "4.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz",
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
"@react-navigation/elements": "1.2.1",
|
||||
"@react-navigation/material-top-tabs": "6.0.6",
|
||||
"@react-navigation/native": "6.0.6",
|
||||
"@react-navigation/native-stack": "6.6.2",
|
||||
"@react-navigation/stack": "6.2.2",
|
||||
"@svgr/webpack": "4.3.2",
|
||||
"@tensorflow/tfjs-backend-wasm": "3.13.0",
|
||||
"@tensorflow/tfjs-core": "3.13.0",
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import React from 'react';
|
||||
import { Platform, StyleSheet, View } from 'react-native';
|
||||
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
||||
import { FullWindowOverlay } from 'react-native-screens';
|
||||
import SplashScreen from 'react-native-splash-screen';
|
||||
|
||||
import { DialogContainer } from '../../base/dialog';
|
||||
|
@ -24,7 +23,6 @@ import '../reducers';
|
|||
declare var __DEV__;
|
||||
|
||||
const DialogContainerWrapper = Platform.select({
|
||||
ios: FullWindowOverlay,
|
||||
default: View
|
||||
});
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ export function _cleanupConfig(config: Object) {
|
|||
delete config.analytics?.googleAnalyticsTrackingId;
|
||||
delete config.callStatsID;
|
||||
delete config.callStatsSecret;
|
||||
config.giphy = { enabled: false };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// @flow
|
||||
|
||||
import { getDefaultHeaderHeight } from '@react-navigation/elements';
|
||||
import { useHeaderHeight } from '@react-navigation/elements';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import {
|
||||
Keyboard,
|
||||
|
@ -8,7 +8,7 @@ import {
|
|||
Platform,
|
||||
StatusBar
|
||||
} from 'react-native';
|
||||
import { useSafeAreaFrame, useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
|
||||
import { StyleType } from '../../styles';
|
||||
|
||||
|
@ -34,11 +34,6 @@ type Props = {
|
|||
*/
|
||||
hasTabNavigator: boolean,
|
||||
|
||||
/**
|
||||
* Is the screen presented as a modal?
|
||||
*/
|
||||
isModalPresentation: boolean,
|
||||
|
||||
/**
|
||||
* Additional style to be appended to the KeyboardAvoidingView.
|
||||
*/
|
||||
|
@ -51,33 +46,26 @@ const JitsiKeyboardAvoidingView = (
|
|||
contentContainerStyle,
|
||||
hasTabNavigator,
|
||||
hasBottomTextInput,
|
||||
isModalPresentation,
|
||||
style
|
||||
}: Props) => {
|
||||
const frame = useSafeAreaFrame();
|
||||
const headerHeight = useHeaderHeight();
|
||||
const insets = useSafeAreaInsets();
|
||||
const [ bottomPadding, setBottomPadding ] = useState(insets.bottom);
|
||||
const [ topPadding, setTopPadding ] = useState(insets.top);
|
||||
|
||||
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);
|
||||
setTopPadding(insets.top);
|
||||
}, [ insets.bottom, insets.top ]);
|
||||
}, [ insets.bottom ]);
|
||||
|
||||
const headerHeight = getDefaultHeaderHeight(frame, isModalPresentation, topPadding);
|
||||
|
||||
// Notch devices have in general a header height between 103 and 106px
|
||||
const topNotchDevice = headerHeight > 100;
|
||||
const deviceHeight = topNotchDevice ? headerHeight - 50 : headerHeight;
|
||||
const tabNavigatorPadding
|
||||
= hasTabNavigator ? deviceHeight : 0;
|
||||
= hasTabNavigator ? headerHeight : 0;
|
||||
const noNotchDevicePadding = bottomPadding || 10;
|
||||
const iosVerticalOffset
|
||||
= deviceHeight + noNotchDevicePadding + tabNavigatorPadding;
|
||||
= headerHeight + noNotchDevicePadding + tabNavigatorPadding;
|
||||
const androidVerticalOffset = hasBottomTextInput
|
||||
? deviceHeight + StatusBar.currentHeight : deviceHeight;
|
||||
? headerHeight + StatusBar.currentHeight : headerHeight;
|
||||
|
||||
// Tells the view what to do with taps
|
||||
const shouldSetResponse = useCallback(() => true);
|
||||
|
|
|
@ -37,11 +37,6 @@ type Props = {
|
|||
*/
|
||||
hasTabNavigator?: boolean,
|
||||
|
||||
/**
|
||||
* Is the screen presented as a modal?
|
||||
*/
|
||||
isModalPresentation?: boolean,
|
||||
|
||||
/**
|
||||
* Insets for the SafeAreaView.
|
||||
*/
|
||||
|
@ -59,7 +54,6 @@ const JitsiScreen = ({
|
|||
footerComponent,
|
||||
hasTabNavigator = false,
|
||||
hasBottomTextInput = false,
|
||||
isModalPresentation = true,
|
||||
safeAreaInsets = [ 'left', 'right' ],
|
||||
style
|
||||
}: Props) => (
|
||||
|
@ -69,7 +63,6 @@ const JitsiScreen = ({
|
|||
contentContainerStyle = { contentContainerStyle }
|
||||
hasBottomTextInput = { hasBottomTextInput }
|
||||
hasTabNavigator = { hasTabNavigator }
|
||||
isModalPresentation = { isModalPresentation }
|
||||
style = { style }>
|
||||
<SafeAreaView
|
||||
edges = { safeAreaInsets }
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
/* @flow */
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { Text, TouchableOpacity } from 'react-native';
|
||||
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* React Elements to display within the component.
|
||||
*/
|
||||
children: React$Node | Object,
|
||||
|
||||
/**
|
||||
* Handler called when the user presses the button.
|
||||
*/
|
||||
onValueChange: Function,
|
||||
|
||||
/**
|
||||
* The component's external style.
|
||||
*/
|
||||
style: Object
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a button.
|
||||
*/
|
||||
export default class ButtonImpl extends Component<Props> {
|
||||
/**
|
||||
* Implements React's {@link Component#render()}, renders the button.
|
||||
*
|
||||
* @inheritdoc
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress = { this.props.onValueChange } >
|
||||
<Text style = { this.props.style }>
|
||||
{ this.props.children }
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
Button as NativePaperButton,
|
||||
Text,
|
||||
TouchableRipple
|
||||
} from 'react-native-paper';
|
||||
|
||||
import BaseTheme from '../../../ui/components/BaseTheme.native';
|
||||
import styles from './styles';
|
||||
import { BUTTON_MODES, BUTTON_TYPES } from '../../constants';
|
||||
import { ButtonProps } from '../../types';
|
||||
|
||||
|
||||
const Button: React.FC<ButtonProps> = ({
|
||||
accessibilityLabel,
|
||||
color: buttonColor,
|
||||
disabled,
|
||||
icon,
|
||||
label,
|
||||
labelStyle,
|
||||
onPress,
|
||||
style,
|
||||
type
|
||||
}: ButtonProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { CONTAINED } = BUTTON_MODES;
|
||||
const { DESTRUCTIVE, PRIMARY, SECONDARY, TERTIARY } = BUTTON_TYPES;
|
||||
|
||||
let buttonLabelStyles;
|
||||
let buttonStyles;
|
||||
let color;
|
||||
let mode;
|
||||
|
||||
if (type === PRIMARY) {
|
||||
buttonLabelStyles = styles.buttonLabelPrimary;
|
||||
color = BaseTheme.palette.action01;
|
||||
mode = CONTAINED
|
||||
} else if (type === SECONDARY) {
|
||||
buttonLabelStyles = styles.buttonLabelSecondary;
|
||||
color = BaseTheme.palette.action02;
|
||||
mode = CONTAINED
|
||||
} else if (type === DESTRUCTIVE) {
|
||||
color = BaseTheme.palette.actionDanger;
|
||||
buttonLabelStyles = styles.buttonLabelDestructive;
|
||||
mode = CONTAINED
|
||||
} else {
|
||||
color = buttonColor;
|
||||
buttonLabelStyles = styles.buttonLabel;
|
||||
}
|
||||
|
||||
if (disabled) {
|
||||
buttonLabelStyles = styles.buttonLabelDisabled;
|
||||
buttonStyles = styles.buttonDisabled;
|
||||
} else {
|
||||
buttonStyles = styles.button;
|
||||
}
|
||||
|
||||
if ( type === TERTIARY) {
|
||||
return (
|
||||
<TouchableRipple
|
||||
accessibilityLabel = { accessibilityLabel }
|
||||
disabled = { disabled }
|
||||
onPress = { onPress }
|
||||
rippleColor = 'transparent'
|
||||
style = { [
|
||||
buttonStyles,
|
||||
style
|
||||
] }>
|
||||
<Text
|
||||
style = { [
|
||||
buttonLabelStyles,
|
||||
labelStyle
|
||||
] }>{ t(label) }</Text>
|
||||
</TouchableRipple>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<NativePaperButton
|
||||
accessibilityLabel = { t(accessibilityLabel) }
|
||||
children = { t(label) }
|
||||
color = { color }
|
||||
disabled = { disabled }
|
||||
icon = { icon }
|
||||
labelStyle = { [
|
||||
buttonLabelStyles,
|
||||
labelStyle
|
||||
] }
|
||||
mode = { mode }
|
||||
onPress = { onPress }
|
||||
style = { [
|
||||
buttonStyles,
|
||||
style
|
||||
] } />
|
||||
);
|
||||
};
|
||||
|
||||
export default Button;
|
|
@ -0,0 +1,64 @@
|
|||
import React from 'react';
|
||||
import { TouchableRipple } from 'react-native-paper';
|
||||
|
||||
import { Icon } from '../../../icons';
|
||||
import BaseTheme from '../../../ui/components/BaseTheme.native';
|
||||
import styles from './styles';
|
||||
import { BUTTON_TYPES } from '../../constants';
|
||||
import { IconButtonProps } from '../../types';
|
||||
|
||||
|
||||
const IconButton: React.FC<IconButtonProps> = ({
|
||||
accessibilityLabel,
|
||||
color: iconColor,
|
||||
disabled,
|
||||
onPress,
|
||||
size,
|
||||
src,
|
||||
style,
|
||||
tapColor,
|
||||
type
|
||||
}: IconButtonProps) => {
|
||||
const { PRIMARY, SECONDARY, TERTIARY } = BUTTON_TYPES;
|
||||
|
||||
let color;
|
||||
let rippleColor;
|
||||
let iconButtonContainerStyles;
|
||||
|
||||
if (type === PRIMARY) {
|
||||
color = BaseTheme.palette.icon01;
|
||||
iconButtonContainerStyles = styles.iconButtonContainerPrimary;
|
||||
rippleColor = BaseTheme.palette.action01;
|
||||
} else if (type === SECONDARY) {
|
||||
color = BaseTheme.palette.icon02;
|
||||
iconButtonContainerStyles = styles.iconButtonContainerSecondary;
|
||||
rippleColor = BaseTheme.palette.action02;
|
||||
} else if ( type === TERTIARY) {
|
||||
color = BaseTheme.palette.icon01;
|
||||
iconButtonContainerStyles = styles.iconButtonContainer;
|
||||
rippleColor = BaseTheme.palette.action03;
|
||||
} else {
|
||||
color = iconColor;
|
||||
rippleColor = tapColor;
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<TouchableRipple
|
||||
accessibilityLabel = { accessibilityLabel }
|
||||
disabled = { disabled }
|
||||
onPress = { onPress }
|
||||
rippleColor = { rippleColor }
|
||||
style = { [
|
||||
iconButtonContainerStyles,
|
||||
style
|
||||
] }>
|
||||
<Icon
|
||||
color = { color }
|
||||
size = { 20 || size }
|
||||
src = { src } />
|
||||
</TouchableRipple>
|
||||
);
|
||||
};
|
||||
|
||||
export default IconButton;
|
|
@ -1,296 +0,0 @@
|
|||
// @flow
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { SafeAreaView, Text, TouchableOpacity, View } from 'react-native';
|
||||
|
||||
import { Icon } from '../../../icons';
|
||||
import { connect } from '../../../redux';
|
||||
|
||||
import styles from './styles';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link PagedList}.
|
||||
*/
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* The zero-based index of the page that should be rendered (selected) by
|
||||
* default.
|
||||
*/
|
||||
defaultPage: number,
|
||||
|
||||
/**
|
||||
* Indicates if the list is disabled or not.
|
||||
*/
|
||||
disabled: boolean,
|
||||
|
||||
/**
|
||||
* The Redux dispatch function.
|
||||
*/
|
||||
dispatch: Function,
|
||||
|
||||
/**
|
||||
* Callback to execute on page change.
|
||||
*/
|
||||
onSelectPage: ?Function,
|
||||
|
||||
/**
|
||||
* The pages of the PagedList component to be rendered.
|
||||
*
|
||||
* NOTE 1: An element's {@code component} may be {@code undefined} and then
|
||||
* it won't need to be rendered.
|
||||
*
|
||||
* NOTE 2: There must be at least one page available and enabled.
|
||||
*/
|
||||
pages: Array<{
|
||||
component: ?Object,
|
||||
icon: string | number,
|
||||
title: string
|
||||
}>
|
||||
};
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} state of {@link PagedList}.
|
||||
*/
|
||||
type State = {
|
||||
|
||||
/**
|
||||
* The currently selected page.
|
||||
*/
|
||||
pageIndex: number
|
||||
};
|
||||
|
||||
/**
|
||||
* A component that renders a paged list.
|
||||
*
|
||||
* @augments PagedList
|
||||
*/
|
||||
class PagedList extends Component<Props, State> {
|
||||
|
||||
/**
|
||||
* Initializes a new {@code PagedList} instance.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
pageIndex: this._validatePageIndex(props.defaultPage)
|
||||
};
|
||||
|
||||
// Bind event handlers so they are only bound once per instance.
|
||||
this._maybeRefreshSelectedPage
|
||||
= this._maybeRefreshSelectedPage.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the component.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
render() {
|
||||
const { disabled } = this.props;
|
||||
const pages = this.props.pages.filter(({ component }) => component);
|
||||
let children;
|
||||
|
||||
if (pages.length > 1) {
|
||||
children = this._renderPagedList(disabled);
|
||||
} else {
|
||||
children = React.createElement(
|
||||
|
||||
// $FlowExpectedError
|
||||
/* type */ pages[0].component,
|
||||
/* props */ {
|
||||
disabled,
|
||||
style: styles.pagedList
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<View
|
||||
style = { [
|
||||
styles.pagedListContainer,
|
||||
disabled ? styles.pagedListContainerDisabled : null
|
||||
] }>
|
||||
{
|
||||
|
||||
// $FlowExpectedError
|
||||
children
|
||||
}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the style of an indicator.
|
||||
*
|
||||
* @param {number} indicatorIndex - The index of the indicator.
|
||||
* @private
|
||||
* @returns {Object}
|
||||
*/
|
||||
_getIndicatorStyle(indicatorIndex) {
|
||||
if (this.state.pageIndex === indicatorIndex) {
|
||||
return styles.pageIndicatorActive;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
_maybeRefreshSelectedPage: ?boolean => void;
|
||||
|
||||
/**
|
||||
* Components that this PagedList displays may have a refresh function to
|
||||
* refresh its content when displayed (or based on custom logic). This
|
||||
* function invokes this logic if it's present.
|
||||
*
|
||||
* @private
|
||||
* @param {boolean} isInteractive - If true this refresh was caused by
|
||||
* direct user interaction, false otherwise.
|
||||
* @returns {void}
|
||||
*/
|
||||
_maybeRefreshSelectedPage(isInteractive: boolean = true) {
|
||||
const selectedPage = this.props.pages[this.state.pageIndex];
|
||||
let component;
|
||||
|
||||
if (selectedPage && (component = selectedPage.component)) {
|
||||
// react-i18n / react-redux wrap components and thus we cannot access
|
||||
// the wrapped component's static methods directly.
|
||||
const component_ = component.WrappedComponent || component;
|
||||
const { refresh } = component_;
|
||||
|
||||
refresh.call(component, this.props.dispatch, isInteractive);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the selected page.
|
||||
*
|
||||
* @param {number} pageIndex - The index of the selected page.
|
||||
* @protected
|
||||
* @returns {void}
|
||||
*/
|
||||
_onSelectPage(pageIndex: number) {
|
||||
return () => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
pageIndex = this._validatePageIndex(pageIndex);
|
||||
|
||||
const { onSelectPage } = this.props;
|
||||
|
||||
onSelectPage && onSelectPage(pageIndex);
|
||||
|
||||
this.setState({ pageIndex }, this._maybeRefreshSelectedPage);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a single page of the page list.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} page - The page to render.
|
||||
* @param {boolean} disabled - Renders the page disabled.
|
||||
* @returns {React$Node}
|
||||
*/
|
||||
_renderPage(page, disabled) {
|
||||
if (!page.component) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<View style = { styles.pageContainer }>
|
||||
{
|
||||
React.createElement(
|
||||
page.component,
|
||||
{
|
||||
disabled
|
||||
})
|
||||
}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the paged list if multiple pages are to be rendered.
|
||||
*
|
||||
* @param {boolean} disabled - True if the rendered lists should be
|
||||
* disabled.
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderPagedList(disabled) {
|
||||
const { pages } = this.props;
|
||||
const { pageIndex } = this.state;
|
||||
|
||||
return (
|
||||
<View style = { styles.pagedListContainer }>
|
||||
{
|
||||
this._renderPage(pages[pageIndex], disabled)
|
||||
}
|
||||
<SafeAreaView style = { styles.pageIndicatorContainer }>
|
||||
{
|
||||
pages.map((page, index) => this._renderPageIndicator(
|
||||
page, index, disabled
|
||||
))
|
||||
}
|
||||
</SafeAreaView>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a page indicator (icon) for the page.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} page - The page the indicator is rendered for.
|
||||
* @param {number} index - The index of the page the indicator is rendered
|
||||
* for.
|
||||
* @param {boolean} disabled - Renders the indicator disabled.
|
||||
* @returns {React$Node}
|
||||
*/
|
||||
_renderPageIndicator(page, index, disabled) {
|
||||
if (!page.component) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
disabled = { disabled }
|
||||
key = { index }
|
||||
onPress = { this._onSelectPage(index) }
|
||||
style = { styles.pageIndicator } >
|
||||
<View style = { styles.pageIndicatorContent }>
|
||||
<Icon
|
||||
src = { page.icon }
|
||||
style = { [
|
||||
styles.pageIndicatorIcon,
|
||||
this._getIndicatorStyle(index)
|
||||
] } />
|
||||
<Text
|
||||
style = { [
|
||||
styles.pageIndicatorText,
|
||||
this._getIndicatorStyle(index)
|
||||
] }>
|
||||
{ page.title }
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the requested page index and returns a safe value.
|
||||
*
|
||||
* @private
|
||||
* @param {number} pageIndex - The requested page index.
|
||||
* @returns {number}
|
||||
*/
|
||||
_validatePageIndex(pageIndex) {
|
||||
// pageIndex may point to a non-existing page if some of the pages are
|
||||
// disabled (their component property is undefined).
|
||||
const maxPageIndex
|
||||
= this.props.pages.filter(({ component }) => component).length - 1;
|
||||
|
||||
return Math.max(0, Math.min(maxPageIndex, pageIndex));
|
||||
}
|
||||
}
|
||||
|
||||
export default connect()(PagedList);
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
export { default as AvatarListItem } from './AvatarListItem';
|
||||
export { default as BaseIndicator } from './BaseIndicator';
|
||||
export { default as Button } from './Button';
|
||||
export { default as Container } from './Container';
|
||||
export { default as Image } from './Image';
|
||||
export { default as Link } from './Link';
|
||||
|
@ -15,7 +14,6 @@ export { default as NavigateSectionListItem }
|
|||
from './NavigateSectionListItem';
|
||||
export { default as NavigateSectionListSectionHeader }
|
||||
from './NavigateSectionListSectionHeader';
|
||||
export { default as PagedList } from './PagedList';
|
||||
export { default as Pressable } from './Pressable';
|
||||
export { default as SectionList } from './SectionList';
|
||||
export { default as SlidingView } from './SlidingView';
|
||||
|
|
|
@ -5,93 +5,12 @@ import BaseTheme from '../../../ui/components/BaseTheme.native';
|
|||
|
||||
const OVERLAY_FONT_COLOR = 'rgba(255, 255, 255, 0.6)';
|
||||
const SECONDARY_ACTION_BUTTON_SIZE = 30;
|
||||
const BUTTON_HEIGHT = BaseTheme.spacing[7];
|
||||
const BUTTON_WIDTH = BaseTheme.spacing[7];
|
||||
|
||||
export const AVATAR_SIZE = 65;
|
||||
export const UNDERLAY_COLOR = 'rgba(255, 255, 255, 0.2)';
|
||||
|
||||
/**
|
||||
* Style classes of the PagedList-based components.
|
||||
*/
|
||||
const PAGED_LIST_STYLES = {
|
||||
|
||||
/**
|
||||
* Outermost container of a page in {@code PagedList}.
|
||||
*/
|
||||
pageContainer: {
|
||||
flex: 1
|
||||
},
|
||||
|
||||
/**
|
||||
* Style of the page indicator (Android).
|
||||
*/
|
||||
pageIndicator: {
|
||||
alignItems: 'center',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
padding: BoxModel.padding / 2
|
||||
},
|
||||
|
||||
/**
|
||||
* Additional style for the active indicator icon (Android).
|
||||
*/
|
||||
pageIndicatorActive: {
|
||||
color: ColorPalette.white
|
||||
},
|
||||
|
||||
/**
|
||||
* Container for the page indicators (Android).
|
||||
*/
|
||||
pageIndicatorContainer: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: ColorPalette.blue,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-around'
|
||||
},
|
||||
|
||||
pageIndicatorContent: {
|
||||
alignItems: 'center',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
|
||||
/**
|
||||
* Icon of the page indicator (Android).
|
||||
*/
|
||||
pageIndicatorIcon: {
|
||||
color: ColorPalette.blueHighlight,
|
||||
fontSize: 24
|
||||
},
|
||||
|
||||
/**
|
||||
* Label of the page indicator (Android).
|
||||
*/
|
||||
pageIndicatorText: {
|
||||
color: ColorPalette.blueHighlight
|
||||
},
|
||||
|
||||
/**
|
||||
* Top level style of the paged list.
|
||||
*/
|
||||
pagedList: {
|
||||
flex: 1
|
||||
},
|
||||
|
||||
/**
|
||||
* The paged list container View.
|
||||
*/
|
||||
pagedListContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'column'
|
||||
},
|
||||
|
||||
/**
|
||||
* Disabled style for the container.
|
||||
*/
|
||||
pagedListContainerDisabled: {
|
||||
opacity: 0.2
|
||||
}
|
||||
};
|
||||
|
||||
const SECTION_LIST_STYLES = {
|
||||
/**
|
||||
* The style of the avatar container that makes the avatar rounded.
|
||||
|
@ -217,11 +136,82 @@ export const BASE_INDICATOR = {
|
|||
justifyContent: 'center'
|
||||
};
|
||||
|
||||
const button = {
|
||||
borderRadius: BaseTheme.shape.borderRadius,
|
||||
height: BUTTON_HEIGHT
|
||||
};
|
||||
|
||||
const buttonLabel = {
|
||||
...BaseTheme.typography.bodyShortBold,
|
||||
padding: 6,
|
||||
textTransform: 'capitalize'
|
||||
};
|
||||
|
||||
const iconButtonContainer = {
|
||||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
borderRadius: BaseTheme.shape.borderRadius,
|
||||
height: BUTTON_HEIGHT,
|
||||
width: BUTTON_WIDTH
|
||||
};
|
||||
|
||||
/**
|
||||
* The styles of the generic React {@code Component}s implemented by the feature
|
||||
* base/react.
|
||||
*/
|
||||
export default {
|
||||
...PAGED_LIST_STYLES,
|
||||
...SECTION_LIST_STYLES
|
||||
...SECTION_LIST_STYLES,
|
||||
|
||||
button: {
|
||||
...button
|
||||
},
|
||||
|
||||
buttonLabel: {
|
||||
...buttonLabel
|
||||
},
|
||||
|
||||
buttonLabelDisabled: {
|
||||
...buttonLabel,
|
||||
color: BaseTheme.palette.text03
|
||||
},
|
||||
|
||||
buttonDisabled: {
|
||||
...button,
|
||||
backgroundColor: BaseTheme.palette.actionDisabled
|
||||
},
|
||||
|
||||
buttonLabelPrimary: {
|
||||
...buttonLabel,
|
||||
color: BaseTheme.palette.text01
|
||||
},
|
||||
|
||||
buttonLabelSecondary: {
|
||||
...buttonLabel,
|
||||
color: BaseTheme.palette.text02
|
||||
},
|
||||
|
||||
buttonLabelDestructive: {
|
||||
...buttonLabel,
|
||||
color: BaseTheme.palette.text01
|
||||
},
|
||||
|
||||
buttonLabelTertiary: {
|
||||
...buttonLabel,
|
||||
color: BaseTheme.palette.text01
|
||||
},
|
||||
|
||||
iconButtonContainer: {
|
||||
...iconButtonContainer
|
||||
},
|
||||
|
||||
iconButtonContainerPrimary: {
|
||||
...iconButtonContainer,
|
||||
backgroundColor: BaseTheme.palette.action01
|
||||
},
|
||||
|
||||
iconButtonContainerSecondary: {
|
||||
...iconButtonContainer,
|
||||
backgroundColor: BaseTheme.palette.action02
|
||||
}
|
||||
};
|
||||
|
|
|
@ -5,3 +5,20 @@
|
|||
* everything, such as modal-type of components, or dialogs.
|
||||
*/
|
||||
export const OVERLAY_Z_INDEX = 1000;
|
||||
|
||||
/**
|
||||
* The types of the buttons.
|
||||
*/
|
||||
export const BUTTON_TYPES = {
|
||||
PRIMARY: 'primary',
|
||||
SECONDARY: 'secondary',
|
||||
TERTIARY: 'tertiary',
|
||||
DESTRUCTIVE: 'destructive'
|
||||
};
|
||||
|
||||
/**
|
||||
* The modes of the buttons.
|
||||
*/
|
||||
export const BUTTON_MODES = {
|
||||
CONTAINED: 'contained'
|
||||
};
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
export interface ButtonProps {
|
||||
accessibilityLabel?: string;
|
||||
color?: string;
|
||||
disabled?: boolean;
|
||||
icon?: JSX.Element;
|
||||
label?: string;
|
||||
labelStyle?: Object|undefined;
|
||||
onPress?: Function;
|
||||
style?: Object|undefined;
|
||||
type?: string;
|
||||
}
|
||||
|
||||
export interface IconButtonProps {
|
||||
accessibilityLabel?: string;
|
||||
color?: string;
|
||||
disabled?: boolean;
|
||||
onPress?: Function;
|
||||
size?: number|string;
|
||||
src?: Function;
|
||||
style?: Object|undefined;
|
||||
tapColor?: string;
|
||||
type?: string;
|
||||
}
|
|
@ -89,6 +89,8 @@ export const colorMap = {
|
|||
// Status bar
|
||||
status01Bar: 'primary11',
|
||||
|
||||
actionDisabled: 'surface09',
|
||||
|
||||
// Hover state for primary buttons
|
||||
action01Hover: 'primary06',
|
||||
|
||||
|
@ -102,7 +104,7 @@ export const colorMap = {
|
|||
action01Disabled: 'primary02',
|
||||
|
||||
// Secondary buttons
|
||||
action02: 'surface04',
|
||||
action02: 'surface10',
|
||||
|
||||
// Hover state for secondary buttons
|
||||
action02Hover: 'surface05',
|
||||
|
@ -156,7 +158,7 @@ export const colorMap = {
|
|||
text01: 'surface11',
|
||||
|
||||
// Secondary text with medium contrast
|
||||
text02: 'surface09',
|
||||
text02: 'surface01',
|
||||
|
||||
// Tertiary text with low contrast – placeholders, disabled actions, label for disabled buttons
|
||||
text03: 'surface07',
|
||||
|
@ -180,7 +182,7 @@ export const colorMap = {
|
|||
icon01: 'surface11',
|
||||
|
||||
// Secondary color for input fields
|
||||
icon02: 'surface09',
|
||||
icon02: 'surface01',
|
||||
|
||||
// Tertiary color for disabled actions
|
||||
icon03: 'surface07',
|
||||
|
|
|
@ -35,11 +35,3 @@ export const SMALL_WIDTH_THRESHOLD = 580;
|
|||
* Lobby message type.
|
||||
*/
|
||||
export const LOBBY_CHAT_MESSAGE = 'LOBBY_CHAT_MESSAGE';
|
||||
|
||||
/**
|
||||
* The modes of the buttons of the chat and polls tabs.
|
||||
*/
|
||||
export const BUTTON_MODES = {
|
||||
CONTAINED: 'contained',
|
||||
TEXT: 'text'
|
||||
};
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import React, { PureComponent } from 'react';
|
||||
import { Text, TouchableOpacity, View } from 'react-native';
|
||||
import { Text, View } from 'react-native';
|
||||
|
||||
import { getFeatureFlag, INVITE_ENABLED } from '../../../base/flags';
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { Icon, IconAddPeople } from '../../../base/icons';
|
||||
import { getParticipantCountWithFake } from '../../../base/participants';
|
||||
import Button from '../../../base/react/components/native/Button';
|
||||
import { BUTTON_TYPES } from '../../../base/react/constants';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { isInBreakoutRoom } from '../../../breakout-rooms/functions';
|
||||
import { doInvitePeople } from '../../../invite/actions.native';
|
||||
|
@ -57,6 +59,19 @@ class LonelyMeetingExperience extends PureComponent<Props> {
|
|||
this._onPress = this._onPress.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the "add people" icon.
|
||||
*
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderAddPeopleIcon() {
|
||||
return (
|
||||
<Icon
|
||||
size = { 20 }
|
||||
src = { IconAddPeople } />
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements {@code PureComponent#render}.
|
||||
*
|
||||
|
@ -80,17 +95,13 @@ class LonelyMeetingExperience extends PureComponent<Props> {
|
|||
{ t('lonelyMeetingExperience.youAreAlone') }
|
||||
</Text>
|
||||
{ !_isInviteFunctionsDiabled && !_isInBreakoutRoom && (
|
||||
<TouchableOpacity
|
||||
<Button
|
||||
accessibilityLabel = 'lonelyMeetingExperience.button'
|
||||
icon = { this._renderAddPeopleIcon }
|
||||
label = 'lonelyMeetingExperience.button'
|
||||
onPress = { this._onPress }
|
||||
style = { styles.lonelyButton }>
|
||||
<Icon
|
||||
size = { 24 }
|
||||
src = { IconAddPeople }
|
||||
style = { styles.lonelyButtonComponents } />
|
||||
<Text style = { styles.lonelyButtonComponents }>
|
||||
{ t('lonelyMeetingExperience.button') }
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
style = { styles.lonelyButton }
|
||||
type = { BUTTON_TYPES.PRIMARY } />
|
||||
) }
|
||||
</View>
|
||||
);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Text, View } from 'react-native';
|
||||
import { View } from 'react-native';
|
||||
import { withSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
|
@ -12,20 +11,18 @@ import { setIsCarmode } from '../../../../video-layout/actions';
|
|||
import ConferenceTimer from '../../ConferenceTimer';
|
||||
import { isConnecting } from '../../functions';
|
||||
|
||||
import EndMeetingButton from './EndMeetingButton';
|
||||
import CarModeFooter from './CarModeFooter';
|
||||
import MicrophoneButton from './MicrophoneButton';
|
||||
import SoundDeviceButton from './SoundDeviceButton';
|
||||
import TitleBar from './TitleBar';
|
||||
import styles from './styles';
|
||||
|
||||
/**
|
||||
* Implements the carmode tab.
|
||||
* Implements the carmode component.
|
||||
*
|
||||
* @returns { JSX.Element} - The carmode tab.
|
||||
* @returns { JSX.Element} - The carmode component.
|
||||
*/
|
||||
const CarmodeTab = (): JSX.Element => {
|
||||
const CarMode = (): JSX.Element => {
|
||||
const dispatch = useDispatch();
|
||||
const { t } = useTranslation();
|
||||
const connecting = useSelector(isConnecting);
|
||||
const isSharing = useSelector(isLocalVideoTrackDesktop);
|
||||
|
||||
|
@ -42,7 +39,9 @@ const CarmodeTab = (): JSX.Element => {
|
|||
}, []);
|
||||
|
||||
return (
|
||||
<JitsiScreen style = { styles.conference }>
|
||||
<JitsiScreen
|
||||
footerComponent = { CarModeFooter }
|
||||
style = { styles.conference }>
|
||||
{/*
|
||||
* The activity/loading indicator goes above everything, except
|
||||
* the toolbox/toolbars and the dialogs.
|
||||
|
@ -66,17 +65,8 @@ const CarmodeTab = (): JSX.Element => {
|
|||
style = { styles.microphoneContainer }>
|
||||
<MicrophoneButton />
|
||||
</View>
|
||||
<View
|
||||
pointerEvents = 'box-none'
|
||||
style = { styles.bottomContainer }>
|
||||
<Text style = { styles.videoStoppedLabel }>
|
||||
{t('carmode.labels.videoStopped')}
|
||||
</Text>
|
||||
<SoundDeviceButton />
|
||||
<EndMeetingButton />
|
||||
</View>
|
||||
</JitsiScreen>
|
||||
);
|
||||
};
|
||||
|
||||
export default withSafeAreaInsets(CarmodeTab);
|
||||
export default withSafeAreaInsets(CarMode);
|
|
@ -0,0 +1,30 @@
|
|||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Text, View } from 'react-native';
|
||||
|
||||
import EndMeetingButton from './EndMeetingButton';
|
||||
import SoundDeviceButton from './SoundDeviceButton';
|
||||
import styles from './styles';
|
||||
|
||||
/**
|
||||
* Implements the car mode footer component.
|
||||
*
|
||||
* @returns { JSX.Element} - The car mode footer component.
|
||||
*/
|
||||
const CarModeFooter = (): JSX.Element => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<View
|
||||
pointerEvents = 'box-none'
|
||||
style = { styles.bottomContainer }>
|
||||
<Text style = { styles.videoStoppedLabel }>
|
||||
{t('carmode.labels.videoStopped')}
|
||||
</Text>
|
||||
<SoundDeviceButton />
|
||||
<EndMeetingButton />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default CarModeFooter;
|
|
@ -1,10 +1,10 @@
|
|||
import React, { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button } from 'react-native-paper';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { createToolbarEvent, sendAnalytics } from '../../../../analytics';
|
||||
import { appNavigate } from '../../../../app/actions';
|
||||
import Button from '../../../../base/react/components/native/Button';
|
||||
import { BUTTON_TYPES } from '../../../../base/react/constants';
|
||||
|
||||
import EndMeetingIcon from './EndMeetingIcon';
|
||||
import styles from './styles';
|
||||
|
@ -15,7 +15,6 @@ import styles from './styles';
|
|||
* @returns {JSX.Element} - The end meeting button.
|
||||
*/
|
||||
const EndMeetingButton = () : JSX.Element => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const onSelect = useCallback(() => {
|
||||
|
@ -26,13 +25,12 @@ const EndMeetingButton = () : JSX.Element => {
|
|||
|
||||
return (
|
||||
<Button
|
||||
accessibilityLabel = { t('carmode.actions.leaveMeeting') }
|
||||
children = { t('carmode.actions.leaveMeeting') }
|
||||
accessibilityLabel = 'carmode.actions.leaveMeeting'
|
||||
icon = { EndMeetingIcon }
|
||||
labelStyle = { styles.endMeetingButtonLabel }
|
||||
mode = 'contained'
|
||||
label = 'carmode.actions.leaveMeeting'
|
||||
onPress = { onSelect }
|
||||
style = { styles.endMeetingButton } />
|
||||
style = { styles.endMeetingButton }
|
||||
type = { BUTTON_TYPES.DESTRUCTIVE } />
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import React, { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button } from 'react-native-paper';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { openSheet } from '../../../../base/dialog/actions';
|
||||
import Button from '../../../../base/react/components/native/Button';
|
||||
import { BUTTON_TYPES } from '../../../../base/react/constants';
|
||||
import AudioRoutePickerDialog from '../../../../mobile/audio-mode/components/AudioRoutePickerDialog';
|
||||
|
||||
import AudioIcon from './AudioIcon';
|
||||
|
@ -15,7 +15,6 @@ import styles from './styles';
|
|||
* @returns {JSX.Element} - The sound device button.
|
||||
*/
|
||||
const SelectSoundDevice = () : JSX.Element => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const onSelect = useCallback(() =>
|
||||
|
@ -24,13 +23,12 @@ const SelectSoundDevice = () : JSX.Element => {
|
|||
|
||||
return (
|
||||
<Button
|
||||
accessibilityLabel = { t('carmode.actions.selectSoundDevice') }
|
||||
children = { t('carmode.actions.selectSoundDevice') }
|
||||
accessibilityLabel = 'carmode.actions.selectSoundDevice'
|
||||
icon = { AudioIcon }
|
||||
labelStyle = { styles.soundDeviceButtonLabel }
|
||||
mode = 'contained'
|
||||
label = 'carmode.actions.selectSoundDevice'
|
||||
onPress = { onSelect }
|
||||
style = { styles.soundDeviceButton } />
|
||||
style = { styles.soundDeviceButton }
|
||||
type = { BUTTON_TYPES.SECONDARY } />
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -5,29 +5,6 @@ import BaseTheme from '../../../../base/ui/components/BaseTheme.native';
|
|||
*/
|
||||
const MICROPHONE_SIZE = 180;
|
||||
|
||||
/**
|
||||
* Base button style.
|
||||
*/
|
||||
const baseButton = {
|
||||
borderRadius: BaseTheme.shape.borderRadius,
|
||||
height: BaseTheme.spacing[7],
|
||||
marginTop: BaseTheme.spacing[3],
|
||||
marginLeft: BaseTheme.spacing[10],
|
||||
marginRight: BaseTheme.spacing[10],
|
||||
display: 'flex',
|
||||
justifyContent: 'space-around',
|
||||
width: 300
|
||||
};
|
||||
|
||||
/**
|
||||
* Base label style.
|
||||
*/
|
||||
const baseLabel = {
|
||||
display: 'flex',
|
||||
fontSize: 16,
|
||||
textTransform: 'capitalize'
|
||||
};
|
||||
|
||||
/**
|
||||
* The styles of the safe area view that contains the title bar.
|
||||
*/
|
||||
|
@ -47,7 +24,7 @@ export default {
|
|||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
bottom: 0,
|
||||
bottom: BaseTheme.spacing[8],
|
||||
left: 0,
|
||||
right: 0,
|
||||
position: 'absolute'
|
||||
|
@ -106,10 +83,8 @@ export default {
|
|||
},
|
||||
|
||||
roomTimer: {
|
||||
color: BaseTheme.palette.text01,
|
||||
...BaseTheme.typography.bodyShortBold,
|
||||
paddingHorizontal: 8,
|
||||
paddingVertical: 6,
|
||||
color: BaseTheme.palette.text01,
|
||||
textAlign: 'center'
|
||||
},
|
||||
|
||||
|
@ -129,25 +104,13 @@ export default {
|
|||
color: BaseTheme.palette.text02
|
||||
},
|
||||
|
||||
soundDeviceButtonLabel: {
|
||||
...baseLabel,
|
||||
color: BaseTheme.palette.text06
|
||||
},
|
||||
|
||||
soundDeviceButton: {
|
||||
...baseButton,
|
||||
backgroundColor: BaseTheme.palette.section01
|
||||
marginBottom: BaseTheme.spacing[3],
|
||||
width: 240
|
||||
},
|
||||
|
||||
endMeetingButton: {
|
||||
...baseButton,
|
||||
backgroundColor: BaseTheme.palette.actionDanger,
|
||||
marginBottom: 60
|
||||
},
|
||||
|
||||
endMeetingButtonLabel: {
|
||||
...baseLabel,
|
||||
color: BaseTheme.palette.text01
|
||||
width: 240
|
||||
},
|
||||
|
||||
headerLabels: {
|
||||
|
@ -196,13 +159,14 @@ export default {
|
|||
},
|
||||
|
||||
titleBar: {
|
||||
alignSelf: 'center'
|
||||
alignSelf: 'center',
|
||||
marginTop: BaseTheme.spacing[1]
|
||||
},
|
||||
|
||||
videoStoppedLabel: {
|
||||
...BaseTheme.typography.bodyShortRegularLarge,
|
||||
color: BaseTheme.palette.text01,
|
||||
marginBottom: 32,
|
||||
...BaseTheme.typography.bodyShortRegularLarge
|
||||
marginBottom: BaseTheme.spacing[3]
|
||||
},
|
||||
|
||||
connectionIndicatorIcon: {
|
||||
|
|
|
@ -41,14 +41,20 @@ export default {
|
|||
width: BaseTheme.spacing[6]
|
||||
},
|
||||
|
||||
headerNavigationIcon: {
|
||||
marginLeft: 12
|
||||
},
|
||||
|
||||
headerNavigationText: {
|
||||
color: BaseTheme.palette.text01,
|
||||
marginLeft: BaseTheme.spacing[3],
|
||||
fontSize: HEADER_ACTION_BUTTON_SIZE
|
||||
},
|
||||
|
||||
headerNavigationTextBold: {
|
||||
...BaseTheme.typography.labelButton,
|
||||
color: BaseTheme.palette.text01,
|
||||
marginRight: BaseTheme.spacing[3],
|
||||
fontSize: HEADER_ACTION_BUTTON_SIZE
|
||||
},
|
||||
|
||||
|
@ -79,18 +85,8 @@ export default {
|
|||
},
|
||||
|
||||
lonelyButton: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: BaseTheme.palette.action01,
|
||||
borderRadius: 24,
|
||||
flexDirection: 'row',
|
||||
height: BaseTheme.spacing[6],
|
||||
justifyContent: 'space-around',
|
||||
paddingHorizontal: 12
|
||||
},
|
||||
|
||||
lonelyButtonComponents: {
|
||||
color: BaseTheme.palette.text01,
|
||||
marginHorizontal: 6
|
||||
borderRadius: BaseTheme.spacing[4],
|
||||
paddingHorizontal: BaseTheme.spacing[1]
|
||||
},
|
||||
|
||||
lonelyMeetingContainer: {
|
||||
|
@ -170,7 +166,7 @@ export default {
|
|||
},
|
||||
|
||||
roomTimerView: {
|
||||
backgroundColor: BaseTheme.palette.action02,
|
||||
backgroundColor: BaseTheme.palette.ui03,
|
||||
borderRadius: 3,
|
||||
justifyContent: 'center',
|
||||
minWidth: 50
|
||||
|
|
|
@ -59,9 +59,11 @@ class SharedDocument extends PureComponent<Props> {
|
|||
addHeaderHeightValue = { true }
|
||||
style = { styles.sharedDocContainer }>
|
||||
<WebView
|
||||
hideKeyboardAccessoryView = { true }
|
||||
renderLoading = { this._renderLoading }
|
||||
source = {{ uri: _documentUrl }}
|
||||
startInLoadingState = { true } />
|
||||
startInLoadingState = { true }
|
||||
style = { styles.sharedDoc } />
|
||||
</JitsiScreen>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,22 +1,29 @@
|
|||
// @flow
|
||||
|
||||
import { ColorPalette } from '../../../base/styles';
|
||||
import BaseTheme from '../../../base/ui/components/BaseTheme.native';
|
||||
|
||||
export const INDICATOR_COLOR = ColorPalette.lightGrey;
|
||||
|
||||
export const INDICATOR_COLOR = BaseTheme.palette.indicatorColor;
|
||||
|
||||
export default {
|
||||
indicatorWrapper: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: ColorPalette.white,
|
||||
backgroundColor: BaseTheme.palette.ui12,
|
||||
height: '100%',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
|
||||
sharedDocContainer: {
|
||||
flex: 1
|
||||
backgroundColor: BaseTheme.palette.ui12,
|
||||
flex: 1,
|
||||
paddingRight: BaseTheme.spacing[3]
|
||||
},
|
||||
|
||||
sharedDoc: {
|
||||
marginBottom: BaseTheme.spacing[3]
|
||||
},
|
||||
|
||||
webView: {
|
||||
backgroundColor: 'rgb(242, 242, 242)'
|
||||
backgroundColor: BaseTheme.palette.ui12
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { GiphyContent, GiphyGridView, GiphyMediaType } from '@giphy/react-native-sdk';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Image, Text, View } from 'react-native';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { createGifSentEvent, sendAnalytics } from '../../../analytics';
|
||||
|
@ -11,6 +10,7 @@ import { goBack } from '../../../mobile/navigation/components/conference/Confere
|
|||
import ClearableInput from '../../../participants-pane/components/native/ClearableInput';
|
||||
import { formatGifUrlMessage, getGifUrl } from '../../functions';
|
||||
|
||||
import GifsMenuFooter from './GifsMenuFooter';
|
||||
import styles from './styles';
|
||||
|
||||
const GifsMenu = () => {
|
||||
|
@ -34,19 +34,9 @@ const GifsMenu = () => {
|
|||
goBack();
|
||||
}, []);
|
||||
|
||||
|
||||
const footerComponent = () => (
|
||||
<View style = { styles.credit }>
|
||||
<Text
|
||||
style = { styles.creditText }>Powered by</Text>
|
||||
<Image source = { require('../../../../../images/GIPHY_logo.png') } />
|
||||
</View>
|
||||
);
|
||||
|
||||
return (
|
||||
<JitsiScreen
|
||||
/* eslint-disable-next-line react/jsx-no-bind */
|
||||
footerComponent = { footerComponent }
|
||||
footerComponent = { GifsMenuFooter }
|
||||
style = { styles.container }>
|
||||
<ClearableInput
|
||||
customStyles = { styles.clearableInput }
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Image, Text, View } from 'react-native';
|
||||
|
||||
import styles from './styles';
|
||||
|
||||
|
||||
/**
|
||||
* Implements the gifs menu footer component.
|
||||
*
|
||||
* @returns { JSX.Element} - The gifs menu footer component.
|
||||
*/
|
||||
const GifsMenuFooter = (): JSX.Element => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return(
|
||||
<View style={ styles.credit }>
|
||||
<Text
|
||||
style={ styles.creditText }>{ t('poweredby') }</Text>
|
||||
<Image
|
||||
source = { require('../../../../../images/GIPHY_logo.png') } />
|
||||
</View>
|
||||
)
|
||||
};
|
||||
|
||||
export default GifsMenuFooter;
|
|
@ -12,7 +12,9 @@ export default {
|
|||
marginTop: BaseTheme.spacing[3]
|
||||
},
|
||||
|
||||
input: { textAlign: 'left' }
|
||||
input: {
|
||||
textAlign: 'left'
|
||||
}
|
||||
},
|
||||
|
||||
grid: {
|
||||
|
@ -34,7 +36,7 @@ export default {
|
|||
},
|
||||
|
||||
creditText: {
|
||||
color: 'white',
|
||||
color: BaseTheme.palette.text01,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
import { Text, View, TouchableOpacity, TextInput } from 'react-native';
|
||||
import { Text, View, TextInput } from 'react-native';
|
||||
|
||||
import { translate } from '../../../base/i18n';
|
||||
import JitsiScreen from '../../../base/modal/components/JitsiScreen';
|
||||
import { LoadingIndicator } from '../../../base/react';
|
||||
import Button from '../../../base/react/components/native/Button';
|
||||
import { BUTTON_TYPES } from '../../../base/react/constants';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { ASPECT_RATIO_NARROW } from '../../../base/responsive-ui';
|
||||
import BaseTheme from '../../../base/ui/components/BaseTheme';
|
||||
|
@ -22,7 +24,6 @@ import AbstractLobbyScreen, {
|
|||
|
||||
import styles from './styles';
|
||||
|
||||
|
||||
type Props = AbstractProps & {
|
||||
|
||||
/**
|
||||
|
@ -185,31 +186,21 @@ class LobbyScreen extends AbstractLobbyScreen<Props> {
|
|||
* @inheritdoc
|
||||
*/
|
||||
_renderPasswordJoinButtons() {
|
||||
const { t } = this.props;
|
||||
|
||||
return (
|
||||
<View style = { styles.passwordJoinButtonsWrapper }>
|
||||
<TouchableOpacity
|
||||
<Button
|
||||
accessibilityLabel = 'lobby.backToKnockModeButton'
|
||||
label = 'lobby.backToKnockModeButton'
|
||||
onPress = { this._onSwitchToKnockMode }
|
||||
style = { [
|
||||
styles.button,
|
||||
styles.primaryButton
|
||||
] }>
|
||||
<Text style = { styles.primaryButtonText }>
|
||||
{ t('lobby.backToKnockModeButton') }
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style = { styles.lobbyButton }
|
||||
type = { BUTTON_TYPES.PRIMARY } />
|
||||
<Button
|
||||
accessibilityLabel = 'lobby.passwordJoinButton'
|
||||
disabled = { !this.state.password }
|
||||
label = 'lobby.passwordJoinButton'
|
||||
onPress = { this._onJoinWithPassword }
|
||||
style = { [
|
||||
styles.button,
|
||||
styles.primaryButton
|
||||
] }>
|
||||
<Text style = { styles.primaryButtonText }>
|
||||
{ t('lobby.passwordJoinButton') }
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
style = { styles.lobbyButton }
|
||||
type = { BUTTON_TYPES.PRIMARY } />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
@ -245,44 +236,39 @@ class LobbyScreen extends AbstractLobbyScreen<Props> {
|
|||
* @inheritdoc
|
||||
*/
|
||||
_renderStandardButtons() {
|
||||
const { _knocking, _renderPassword, _isLobbyChatActive, t } = this.props;
|
||||
const { _knocking, _renderPassword, _isLobbyChatActive } = this.props;
|
||||
const { displayName } = this.state;
|
||||
const askToJoinButtonStyles
|
||||
= displayName ? styles.primaryButton : styles.primaryButtonDisabled;
|
||||
|
||||
return (
|
||||
<View style = { styles.standardButtonWrapper }>
|
||||
{ _knocking && _isLobbyChatActive && <TouchableOpacity
|
||||
{
|
||||
_knocking && _isLobbyChatActive
|
||||
&& <Button
|
||||
accessibilityLabel = 'toolbar.openChat'
|
||||
label = 'toolbar.openChat'
|
||||
onPress = { this._onNavigateToLobbyChat }
|
||||
style = { [
|
||||
styles.button,
|
||||
styles.primaryButton
|
||||
] }>
|
||||
<Text style = { styles.primaryButtonText }>
|
||||
{ t('toolbar.openChat') }
|
||||
</Text>
|
||||
</TouchableOpacity>}
|
||||
{ _knocking || <TouchableOpacity
|
||||
style = { styles.lobbyButton }
|
||||
type = { BUTTON_TYPES.PRIMARY } />
|
||||
}
|
||||
{
|
||||
_knocking
|
||||
|| <Button
|
||||
accessibilityLabel = 'lobby.knockButton'
|
||||
disabled = { !displayName }
|
||||
label = 'lobby.knockButton'
|
||||
onPress = { this._onAskToJoin }
|
||||
style = { [
|
||||
styles.button,
|
||||
askToJoinButtonStyles
|
||||
] }>
|
||||
<Text style = { styles.primaryButtonText }>
|
||||
{ t('lobby.knockButton') }
|
||||
</Text>
|
||||
</TouchableOpacity> }
|
||||
{ _renderPassword && <TouchableOpacity
|
||||
style = { styles.lobbyButton }
|
||||
type = { BUTTON_TYPES.PRIMARY } />
|
||||
}
|
||||
{
|
||||
_renderPassword
|
||||
&& <Button
|
||||
accessibilityLabel = 'lobby.enterPasswordButton'
|
||||
label = 'lobby.enterPasswordButton'
|
||||
onPress = { this._onSwitchToPasswordMode }
|
||||
style = { [
|
||||
styles.button,
|
||||
styles.primaryButton
|
||||
] }>
|
||||
<Text style = { styles.primaryButtonText }>
|
||||
{ t('lobby.enterPasswordButton') }
|
||||
</Text>
|
||||
</TouchableOpacity> }
|
||||
style = { styles.enterPasswordButton }
|
||||
type = { BUTTON_TYPES.PRIMARY } />
|
||||
}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,13 +5,6 @@ import BaseTheme from '../../../base/ui/components/BaseTheme.native';
|
|||
const SECONDARY_COLOR = BaseTheme.palette.border04;
|
||||
|
||||
export default {
|
||||
button: {
|
||||
alignItems: 'center',
|
||||
borderRadius: BaseTheme.shape.borderRadius,
|
||||
padding: BaseTheme.spacing[2],
|
||||
height: BaseTheme.spacing[7],
|
||||
width: '100%'
|
||||
},
|
||||
|
||||
buttonStylesBorderless: {
|
||||
iconStyle: {
|
||||
|
@ -137,7 +130,7 @@ export default {
|
|||
color: BaseTheme.palette.text06,
|
||||
height: BaseTheme.spacing[7],
|
||||
marginTop: BaseTheme.spacing[3],
|
||||
marginHorizontal: 12,
|
||||
marginHorizontal: BaseTheme.spacing[3],
|
||||
padding: BaseTheme.spacing[2],
|
||||
textAlign: 'center'
|
||||
},
|
||||
|
@ -155,8 +148,7 @@ export default {
|
|||
},
|
||||
|
||||
standardButtonWrapper: {
|
||||
alignSelf: 'stretch',
|
||||
marginHorizontal: 12
|
||||
alignSelf: 'stretch'
|
||||
},
|
||||
|
||||
joiningMessage: {
|
||||
|
@ -185,26 +177,13 @@ export default {
|
|||
paddingVertical: 12
|
||||
},
|
||||
|
||||
primaryButton: {
|
||||
backgroundColor: BaseTheme.palette.action01,
|
||||
lobbyButton: {
|
||||
marginTop: BaseTheme.spacing[3]
|
||||
},
|
||||
|
||||
primaryButtonDisabled: {
|
||||
backgroundColor: BaseTheme.palette.action03Disabled,
|
||||
marginTop: BaseTheme.spacing[3]
|
||||
},
|
||||
|
||||
primaryButtonText: {
|
||||
...BaseTheme.typography.labelButtonLarge,
|
||||
color: BaseTheme.palette.text01,
|
||||
lineHeight: 30
|
||||
},
|
||||
|
||||
primaryText: {
|
||||
color: BaseTheme.palette.text01,
|
||||
margin: 'auto',
|
||||
textAlign: 'center'
|
||||
enterPasswordButton: {
|
||||
marginHorizontal: BaseTheme.spacing[3],
|
||||
marginTop: BaseTheme.spacing[6]
|
||||
},
|
||||
|
||||
// KnockingParticipantList
|
||||
|
|
|
@ -61,7 +61,8 @@ const HeaderNavigationButton
|
|||
styles.headerNavigationButton ] } >
|
||||
<Icon
|
||||
size = { 24 }
|
||||
src = { src } />
|
||||
src = { src }
|
||||
style = { styles.headerNavigationIcon } />
|
||||
</TouchableRipple>
|
||||
) : (
|
||||
<TouchableRipple
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { NavigationContainer } from '@react-navigation/native';
|
||||
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
||||
import { createStackNavigator } from '@react-navigation/stack';
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
import { connect } from '../../../base/redux';
|
||||
|
@ -24,7 +24,7 @@ import ConferenceNavigationContainer
|
|||
import WelcomePageNavigationContainer
|
||||
from './welcome/components/WelcomePageNavigationContainer';
|
||||
|
||||
const RootStack = createNativeStackNavigator();
|
||||
const RootStack = createStackNavigator();
|
||||
|
||||
|
||||
type Props = {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { NavigationContainer } from '@react-navigation/native';
|
||||
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
||||
import { createStackNavigator } from '@react-navigation/stack';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
@ -7,7 +7,7 @@ import { useSelector } from 'react-redux';
|
|||
import { Chat, ChatAndPolls } from '../../../../../chat';
|
||||
|
||||
import Conference from '../../../../../conference/components/native/Conference';
|
||||
import CarmodeTab from '../../../../../conference/components/native/carmode/Conference';
|
||||
import CarMode from '../../../../../conference/components/native/carmode/CarMode';
|
||||
import { getDisablePolls } from '../../../../../conference/functions';
|
||||
import { SharedDocument } from '../../../../../etherpad';
|
||||
import { GifsMenu } from '../../../../../gifs/components';
|
||||
|
@ -46,7 +46,7 @@ import {
|
|||
conferenceNavigationRef
|
||||
} from '../ConferenceNavigationContainerRef';
|
||||
|
||||
const ConferenceStack = createNativeStackNavigator();
|
||||
const ConferenceStack = createStackNavigator();
|
||||
|
||||
const ConferenceNavigationContainer = () => {
|
||||
const isPollsDisabled = useSelector(getDisablePolls);
|
||||
|
@ -147,7 +147,7 @@ const ConferenceNavigationContainer = () => {
|
|||
title: t('documentSharing.title')
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
component = { CarmodeTab }
|
||||
component = { CarMode }
|
||||
name = { screen.conference.carmode }
|
||||
options = {{
|
||||
...carmodeScreenOptions,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { NavigationContainer } from '@react-navigation/native';
|
||||
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
||||
import { createStackNavigator } from '@react-navigation/stack';
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
|
@ -12,7 +12,7 @@ import {
|
|||
} from '../../../screenOptions';
|
||||
import { lobbyNavigationContainerRef } from '../LobbyNavigationContainerRef';
|
||||
|
||||
const LobbyStack = createNativeStackNavigator();
|
||||
const LobbyStack = createStackNavigator();
|
||||
|
||||
|
||||
const LobbyNavigationContainer = () => {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { TransitionPresets } from '@react-navigation/stack';
|
||||
import React from 'react';
|
||||
import { Platform } from 'react-native';
|
||||
|
||||
|
@ -16,6 +17,23 @@ import { lobbyScreenHeaderCloseButton, screenHeaderCloseButton } from './functio
|
|||
import { goBack as goBackToWelcomeScreen } from './rootNavigationContainerRef';
|
||||
|
||||
|
||||
/**
|
||||
* Default modal transition for the current platform.
|
||||
*/
|
||||
export const modalPresentation = Platform.select({
|
||||
ios: TransitionPresets.ModalPresentationIOS,
|
||||
default: TransitionPresets.DefaultTransition
|
||||
});
|
||||
|
||||
/**
|
||||
* Screen options and transition types.
|
||||
*/
|
||||
export const fullScreenOptions = {
|
||||
...TransitionPresets.ModalTransition,
|
||||
gestureEnabled: false,
|
||||
headerShown: false
|
||||
};
|
||||
|
||||
/**
|
||||
* Navigation container theme.
|
||||
*/
|
||||
|
@ -29,7 +47,7 @@ export const navigationContainerTheme = {
|
|||
* Drawer navigator screens options and transition types.
|
||||
*/
|
||||
export const drawerNavigatorScreenOptions = {
|
||||
animation: 'default',
|
||||
...TransitionPresets.ModalTransition,
|
||||
gestureEnabled: true,
|
||||
headerShown: false
|
||||
};
|
||||
|
@ -39,16 +57,12 @@ export const drawerNavigatorScreenOptions = {
|
|||
* Drawer screen options and transition types.
|
||||
*/
|
||||
export const drawerScreenOptions = {
|
||||
animation: 'default',
|
||||
...TransitionPresets.ModalTransition,
|
||||
gestureEnabled: true,
|
||||
headerShown: true,
|
||||
headerStyle: {
|
||||
backgroundColor: BaseTheme.palette.screen02Header
|
||||
},
|
||||
orientation: Platform.select({
|
||||
ios: 'default',
|
||||
android: 'all'
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -57,7 +71,7 @@ export const drawerScreenOptions = {
|
|||
export const drawerContentOptions = {
|
||||
drawerActiveBackgroundColor: BaseTheme.palette.uiBackground,
|
||||
drawerActiveTintColor: BaseTheme.palette.screen01Header,
|
||||
drawerInactiveTintColor: BaseTheme.palette.text02,
|
||||
drawerInactiveTintColor: BaseTheme.palette.text01,
|
||||
drawerLabelStyle: {
|
||||
marginLeft: BaseTheme.spacing[2]
|
||||
},
|
||||
|
@ -75,7 +89,7 @@ export const welcomeScreenOptions = {
|
|||
...drawerScreenOptions,
|
||||
drawerIcon: ({ focused }) => (
|
||||
<Icon
|
||||
color = { focused ? BaseTheme.palette.screen01Header : BaseTheme.palette.icon02 }
|
||||
color = { focused ? BaseTheme.palette.screen01Header : BaseTheme.palette.icon01 }
|
||||
size = { 20 }
|
||||
src = { IconHome } />
|
||||
),
|
||||
|
@ -94,7 +108,7 @@ export const settingsScreenOptions = {
|
|||
...drawerScreenOptions,
|
||||
drawerIcon: ({ focused }) => (
|
||||
<Icon
|
||||
color = { focused ? BaseTheme.palette.screen01Header : BaseTheme.palette.icon02 }
|
||||
color = { focused ? BaseTheme.palette.screen01Header : BaseTheme.palette.icon01 }
|
||||
size = { 20 }
|
||||
src = { IconSettings } />
|
||||
),
|
||||
|
@ -110,7 +124,7 @@ export const termsAndPrivacyScreenOptions = {
|
|||
...drawerScreenOptions,
|
||||
drawerIcon: ({ focused }) => (
|
||||
<Icon
|
||||
color = { focused ? BaseTheme.palette.screen01Header : BaseTheme.palette.icon02 }
|
||||
color = { focused ? BaseTheme.palette.screen01Header : BaseTheme.palette.icon01 }
|
||||
size = { 20 }
|
||||
src = { IconInfo } />
|
||||
),
|
||||
|
@ -126,7 +140,7 @@ export const helpScreenOptions = {
|
|||
...drawerScreenOptions,
|
||||
drawerIcon: ({ focused }) => (
|
||||
<Icon
|
||||
color = { focused ? BaseTheme.palette.screen01Header : BaseTheme.palette.icon02 }
|
||||
color = { focused ? BaseTheme.palette.screen01Header : BaseTheme.palette.icon01 }
|
||||
size = { 20 }
|
||||
src = { IconHelp } />
|
||||
),
|
||||
|
@ -138,15 +152,7 @@ export const helpScreenOptions = {
|
|||
/**
|
||||
* Screen options for conference.
|
||||
*/
|
||||
export const conferenceScreenOptions = {
|
||||
animation: 'default',
|
||||
gestureEnabled: false,
|
||||
headerShown: false,
|
||||
orientation: Platform.select({
|
||||
ios: 'default',
|
||||
android: 'all'
|
||||
})
|
||||
};
|
||||
export const conferenceScreenOptions = fullScreenOptions;
|
||||
|
||||
/**
|
||||
* Tab bar options for chat screen.
|
||||
|
@ -172,6 +178,7 @@ export const chatTabBarOptions = {
|
|||
* Screen options for presentation type modals.
|
||||
*/
|
||||
export const presentationScreenOptions = {
|
||||
...modalPresentation,
|
||||
headerBackTitleVisible: false,
|
||||
headerLeft: () => screenHeaderCloseButton(goBack),
|
||||
headerStatusBarHeight: 0,
|
||||
|
@ -180,20 +187,13 @@ export const presentationScreenOptions = {
|
|||
},
|
||||
headerTitleStyle: {
|
||||
color: BaseTheme.palette.text01
|
||||
},
|
||||
orientation: Platform.select({
|
||||
ios: 'default',
|
||||
android: 'all'
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Screen options for car mode.
|
||||
*/
|
||||
export const carmodeScreenOptions = {
|
||||
...presentationScreenOptions,
|
||||
orientation: 'portrait'
|
||||
};
|
||||
export const carmodeScreenOptions = presentationScreenOptions;
|
||||
|
||||
/**
|
||||
* Screen options for chat.
|
||||
|
@ -205,7 +205,6 @@ export const chatScreenOptions = presentationScreenOptions;
|
|||
*/
|
||||
export const dialInSummaryScreenOptions = {
|
||||
...presentationScreenOptions,
|
||||
animation: 'slide_from_bottom',
|
||||
headerLeft: () => screenHeaderCloseButton(goBackToWelcomeScreen)
|
||||
};
|
||||
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
// @flow
|
||||
|
||||
import React, { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button } from 'react-native-paper';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import Button from '../../../../../base/react/components/native/Button';
|
||||
import { BUTTON_TYPES } from '../../../../../base/react/constants';
|
||||
import { createBreakoutRoom } from '../../../../../breakout-rooms/actions';
|
||||
|
||||
import styles from './styles';
|
||||
|
||||
const AddBreakoutRoomButton = () => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const onAdd = useCallback(() =>
|
||||
|
@ -19,12 +18,11 @@ const AddBreakoutRoomButton = () => {
|
|||
|
||||
return (
|
||||
<Button
|
||||
accessibilityLabel = { t('breakoutRooms.actions.add') }
|
||||
children = { t('breakoutRooms.actions.add') }
|
||||
labelStyle = { styles.addButtonLabel }
|
||||
mode = 'contained'
|
||||
accessibilityLabel = 'breakoutRooms.actions.add'
|
||||
label = 'breakoutRooms.actions.add'
|
||||
onPress = { onAdd }
|
||||
style = { styles.addButton } />
|
||||
style = { styles.addButton }
|
||||
type = { BUTTON_TYPES.SECONDARY } />
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
// @flow
|
||||
|
||||
import React, { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button } from 'react-native-paper';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import Button from '../../../../../base/react/components/native/Button';
|
||||
import { BUTTON_TYPES } from '../../../../../base/react/constants';
|
||||
import { autoAssignToBreakoutRooms } from '../../../../../breakout-rooms/actions';
|
||||
|
||||
import styles from './styles';
|
||||
|
||||
|
||||
const AutoAssignButton = () => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const onAutoAssign = useCallback(() => {
|
||||
|
@ -19,12 +19,12 @@ const AutoAssignButton = () => {
|
|||
|
||||
return (
|
||||
<Button
|
||||
accessibilityLabel = { t('breakoutRooms.actions.autoAssign') }
|
||||
children = { t('breakoutRooms.actions.autoAssign') }
|
||||
accessibilityLabel = 'breakoutRooms.actions.autoAssign'
|
||||
label = 'breakoutRooms.actions.autoAssign'
|
||||
labelStyle = { styles.autoAssignLabel }
|
||||
mode = 'contained'
|
||||
onPress = { onAutoAssign }
|
||||
style = { styles.transparentButton } />
|
||||
style = { styles.autoAssignButton }
|
||||
type = { BUTTON_TYPES.TERTIARY } />
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -19,14 +19,10 @@ const baseLabel = {
|
|||
*/
|
||||
export default {
|
||||
|
||||
addButtonLabel: {
|
||||
...baseLabel,
|
||||
color: BaseTheme.palette.text01
|
||||
},
|
||||
|
||||
addButton: {
|
||||
...baseButton,
|
||||
backgroundColor: BaseTheme.palette.ui03
|
||||
marginTop: BaseTheme.spacing[3],
|
||||
marginLeft: BaseTheme.spacing[3],
|
||||
marginRight: BaseTheme.spacing[3]
|
||||
},
|
||||
|
||||
collapsibleRoom: {
|
||||
|
@ -70,18 +66,18 @@ export default {
|
|||
marginLeft: BaseTheme.spacing[2]
|
||||
},
|
||||
|
||||
transparentButton: {
|
||||
backgroundColor: 'transparent',
|
||||
marginTop: BaseTheme.spacing[3]
|
||||
},
|
||||
|
||||
leaveButtonLabel: {
|
||||
...baseLabel,
|
||||
color: BaseTheme.palette.textError
|
||||
},
|
||||
|
||||
autoAssignLabel: {
|
||||
...baseLabel,
|
||||
color: BaseTheme.palette.link01
|
||||
},
|
||||
|
||||
autoAssignButton: {
|
||||
alignSelf: 'center',
|
||||
justifyContent: 'center',
|
||||
marginTop: BaseTheme.spacing[3]
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
|
||||
import { Icon, IconHorizontalPoints } from '../../../base/icons';
|
||||
|
||||
const HorizontalDotsIcon = () => (<Icon
|
||||
size = { 20 }
|
||||
src = { IconHorizontalPoints } />);
|
||||
|
||||
export default HorizontalDotsIcon;
|
|
@ -1,11 +1,11 @@
|
|||
// @flow
|
||||
|
||||
import React, { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button } from 'react-native-paper';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { hasRaisedHand } from '../../../base/participants';
|
||||
import Button from '../../../base/react/components/native/Button';
|
||||
import { BUTTON_TYPES } from '../../../base/react/constants';
|
||||
import { approveKnockingParticipant } from '../../../lobby/actions.native';
|
||||
import { showContextMenuReject } from '../../actions.native';
|
||||
import { MEDIA_STATE } from '../../constants';
|
||||
|
@ -25,7 +25,6 @@ export const LobbyParticipantItem = ({ participant: p }: Props) => {
|
|||
const dispatch = useDispatch();
|
||||
const admit = useCallback(() => dispatch(approveKnockingParticipant(p.id), [ dispatch ]));
|
||||
const openContextMenuReject = useCallback(() => dispatch(showContextMenuReject(p), [ dispatch ]));
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<ParticipantItem
|
||||
|
@ -39,12 +38,11 @@ export const LobbyParticipantItem = ({ participant: p }: Props) => {
|
|||
raisedHand = { hasRaisedHand(p) }
|
||||
videoMediaState = { MEDIA_STATE.NONE }>
|
||||
<Button
|
||||
children = { t('lobby.admit') }
|
||||
contentStyle = { styles.participantActionsButtonContent }
|
||||
labelStyle = { styles.participantActionsButtonText }
|
||||
mode = 'contained'
|
||||
accessibilityLabel = 'lobby.admit'
|
||||
label = 'lobby.admit'
|
||||
onPress = { admit }
|
||||
style = { styles.participantActionsButtonAdmit } />
|
||||
style = { styles.participantActionsButtonAdmit }
|
||||
type = { BUTTON_TYPES.PRIMARY } />
|
||||
</ParticipantItem>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -3,9 +3,10 @@
|
|||
import React, { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ScrollView, Text, View } from 'react-native';
|
||||
import { Button, withTheme } from 'react-native-paper';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import Button from '../../../base/react/components/native/Button';
|
||||
import { BUTTON_TYPES } from '../../../base/react/constants';
|
||||
import { admitMultiple } from '../../../lobby/actions.native';
|
||||
import { getKnockingParticipants, getLobbyEnabled } from '../../../lobby/functions';
|
||||
|
||||
|
@ -13,15 +14,8 @@ import CollapsibleList from './CollapsibleList';
|
|||
import { LobbyParticipantItem } from './LobbyParticipantItem';
|
||||
import styles from './styles';
|
||||
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* Theme used for styles.
|
||||
*/
|
||||
theme: Object
|
||||
};
|
||||
|
||||
const LobbyParticipantList = ({ theme }: Props) => {
|
||||
const LobbyParticipantList = () => {
|
||||
const lobbyEnabled = useSelector(getLobbyEnabled);
|
||||
const participants = useSelector(getKnockingParticipants);
|
||||
|
||||
|
@ -30,11 +24,11 @@ const LobbyParticipantList = ({ theme }: Props) => {
|
|||
dispatch(admitMultiple(participants)),
|
||||
[ dispatch, participants ]);
|
||||
const { t } = useTranslation();
|
||||
const { palette } = theme;
|
||||
|
||||
if (!lobbyEnabled || !participants.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const title = (
|
||||
<View style = { styles.lobbyListDetails } >
|
||||
<Text style = { styles.lobbyListDescription }>
|
||||
|
@ -44,12 +38,11 @@ const LobbyParticipantList = ({ theme }: Props) => {
|
|||
{
|
||||
participants.length > 1 && (
|
||||
<Button
|
||||
color = { palette.action02 }
|
||||
labelStyle = { styles.admitAllParticipantsActionButtonLabel }
|
||||
mode = 'text'
|
||||
onPress = { admitAll }>
|
||||
{t('lobby.admitAll')}
|
||||
</Button>
|
||||
accessibilityLabel = 'lobby.admitAll'
|
||||
label = 'lobby.admitAll'
|
||||
labelStyle = { styles.admitAllButtonLabel }
|
||||
onPress = { admitAll }
|
||||
type = { BUTTON_TYPES.TERTIARY } />
|
||||
)
|
||||
}
|
||||
</View>
|
||||
|
@ -78,4 +71,4 @@ const LobbyParticipantList = ({ theme }: Props) => {
|
|||
);
|
||||
};
|
||||
|
||||
export default withTheme(LobbyParticipantList);
|
||||
export default LobbyParticipantList;
|
||||
|
|
|
@ -2,12 +2,15 @@
|
|||
|
||||
import React, { PureComponent } from 'react';
|
||||
import { FlatList } from 'react-native';
|
||||
import { Button, withTheme } from 'react-native-paper';
|
||||
|
||||
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { Icon, IconInviteMore } from '../../../base/icons';
|
||||
import { getLocalParticipant, getParticipantCountWithFake, getRemoteParticipants } from '../../../base/participants';
|
||||
import Button from '../../../base/react/components/native/Button';
|
||||
import { BUTTON_TYPES } from '../../../base/react/constants';
|
||||
import { connect } from '../../../base/redux';
|
||||
import BaseTheme from '../../../base/ui/components/BaseTheme.native';
|
||||
import { getBreakoutRooms, getCurrentRoomId } from '../../../breakout-rooms/functions';
|
||||
import { doInvitePeople } from '../../../invite/actions.native';
|
||||
import { participantMatchesSearch, shouldRenderInviteButton } from '../../functions';
|
||||
|
@ -83,12 +86,7 @@ type Props = {
|
|||
/**
|
||||
* Translation function.
|
||||
*/
|
||||
t: Function,
|
||||
|
||||
/**
|
||||
* Theme used for styles.
|
||||
*/
|
||||
theme: Object
|
||||
t: Function
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -230,17 +228,17 @@ class MeetingParticipantList extends PureComponent<Props> {
|
|||
{
|
||||
_showInviteButton
|
||||
&& <Button
|
||||
children = { t('participantsPane.actions.invite') }
|
||||
accessibilityLabel = 'participantsPane.actions.invite'
|
||||
icon = { this._renderInviteMoreIcon }
|
||||
labelStyle = { styles.inviteLabel }
|
||||
mode = 'contained'
|
||||
label = 'participantsPane.actions.invite'
|
||||
onPress = { this._onInvite }
|
||||
style = { styles.inviteButton } />
|
||||
style = { styles.inviteButton }
|
||||
type = { BUTTON_TYPES.PRIMARY } />
|
||||
}
|
||||
<ClearableInput
|
||||
onChange = { this._onSearchStringChange }
|
||||
placeholder = { t('participantsPane.search') }
|
||||
selectionColor = { this.props.theme.palette.text01 } />
|
||||
selectionColor = { BaseTheme.palette.text01 } />
|
||||
<FlatList
|
||||
bounces = { false }
|
||||
data = { [ _localParticipant?.id, ..._sortedRemoteParticipants ] }
|
||||
|
@ -280,4 +278,4 @@ function _mapStateToProps(state): Object {
|
|||
};
|
||||
}
|
||||
|
||||
export default translate(connect(_mapStateToProps)(withTheme(MeetingParticipantList)));
|
||||
export default translate(connect(_mapStateToProps)(MeetingParticipantList));
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
// @flow
|
||||
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { View } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import React, { useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { openDialog, openSheet } from '../../../base/dialog';
|
||||
import JitsiScreen from '../../../base/modal/components/JitsiScreen';
|
||||
import { isLocalParticipantModerator } from '../../../base/participants';
|
||||
import { equals } from '../../../base/redux';
|
||||
|
@ -18,9 +14,6 @@ import {
|
|||
isInBreakoutRoom
|
||||
} from '../../../breakout-rooms/functions';
|
||||
import { getKnockingParticipants } from '../../../lobby/functions';
|
||||
import MuteEveryoneDialog
|
||||
from '../../../video-menu/components/native/MuteEveryoneDialog';
|
||||
import { isMoreActionsVisible, isMuteAllVisible } from '../../functions';
|
||||
import {
|
||||
AddBreakoutRoomButton,
|
||||
AutoAssignButton,
|
||||
|
@ -28,26 +21,20 @@ import {
|
|||
} from '../breakout-rooms/components/native';
|
||||
import { CollapsibleRoom } from '../breakout-rooms/components/native/CollapsibleRoom';
|
||||
|
||||
import { ContextMenuMore } from './ContextMenuMore';
|
||||
import HorizontalDotsIcon from './HorizontalDotsIcon';
|
||||
import LobbyParticipantList from './LobbyParticipantList';
|
||||
import MeetingParticipantList from './MeetingParticipantList';
|
||||
import ParticipantsPaneFooter from './ParticipantsPaneFooter';
|
||||
import styles from './styles';
|
||||
|
||||
|
||||
/**
|
||||
* Participant pane.
|
||||
* Participants pane.
|
||||
*
|
||||
* @returns {React$Element<any>}
|
||||
*/
|
||||
const ParticipantsPane = () => {
|
||||
const dispatch = useDispatch();
|
||||
const [ searchString, setSearchString ] = useState('');
|
||||
const openMoreMenu = useCallback(() => dispatch(openSheet(ContextMenuMore)), [ dispatch ]);
|
||||
const isLocalModerator = useSelector(isLocalParticipantModerator);
|
||||
const muteAll = useCallback(() => dispatch(openDialog(MuteEveryoneDialog)),
|
||||
[ dispatch ]);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { conference } = useSelector(state => state['features/base/conference']);
|
||||
const _isBreakoutRoomsSupported = conference?.getBreakoutRooms()?.isSupported();
|
||||
const currentRoomId = useSelector(getCurrentRoomId);
|
||||
|
@ -57,12 +44,12 @@ const ParticipantsPane = () => {
|
|||
const inBreakoutRoom = useSelector(isInBreakoutRoom);
|
||||
const showAddBreakoutRoom = useSelector(isAddBreakoutRoomButtonVisible);
|
||||
const showAutoAssign = useSelector(isAutoAssignParticipantsVisible);
|
||||
const showMoreActions = useSelector(isMoreActionsVisible);
|
||||
const showMuteAll = useSelector(isMuteAllVisible);
|
||||
const lobbyParticipants = useSelector(getKnockingParticipants);
|
||||
|
||||
return (
|
||||
<JitsiScreen style = { styles.participantsPaneContainer }>
|
||||
<JitsiScreen
|
||||
footerComponent = { isLocalModerator && ParticipantsPaneFooter }
|
||||
style = { styles.participantsPaneContainer }>
|
||||
<LobbyParticipantList />
|
||||
<MeetingParticipantList
|
||||
breakoutRooms = { rooms }
|
||||
|
@ -86,31 +73,6 @@ const ParticipantsPane = () => {
|
|||
{
|
||||
showAddBreakoutRoom && <AddBreakoutRoomButton />
|
||||
}
|
||||
{
|
||||
isLocalModerator
|
||||
&& <View style = { styles.participantsPaneFooter }>
|
||||
{
|
||||
showMuteAll && (
|
||||
<Button
|
||||
children = { t('participantsPane.actions.muteAll') }
|
||||
labelStyle = { styles.muteAllLabel }
|
||||
mode = 'contained'
|
||||
onPress = { muteAll }
|
||||
style = { styles.muteAllMoreButton } />
|
||||
)
|
||||
}
|
||||
{
|
||||
showMoreActions && (
|
||||
<Button
|
||||
icon = { HorizontalDotsIcon }
|
||||
labelStyle = { styles.moreIcon }
|
||||
mode = 'contained'
|
||||
onPress = { openMoreMenu }
|
||||
style = { styles.moreButton } />
|
||||
)
|
||||
}
|
||||
</View>
|
||||
}
|
||||
</JitsiScreen>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
import React, { useCallback } from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { useDispatch, useSelector} from "react-redux";
|
||||
|
||||
import { openDialog, openSheet } from '../../../base/dialog';
|
||||
import { IconHorizontalPoints } from '../../../base/icons';
|
||||
import Button from '../../../base/react/components/native/Button';
|
||||
import IconButton from '../../../base/react/components/native/IconButton';
|
||||
import { BUTTON_TYPES } from '../../../base/react/constants';
|
||||
import MuteEveryoneDialog
|
||||
from '../../../video-menu/components/native/MuteEveryoneDialog';
|
||||
import { isMoreActionsVisible, isMuteAllVisible } from '../../functions';
|
||||
|
||||
import { ContextMenuMore } from './ContextMenuMore';
|
||||
import styles from './styles';
|
||||
|
||||
|
||||
/**
|
||||
* Implements the participants pane footer component.
|
||||
*
|
||||
* @returns { JSX.Element} - The participants pane footer component.
|
||||
*/
|
||||
const ParticipantsPaneFooter = (): JSX.Element => {
|
||||
const dispatch = useDispatch();
|
||||
const openMoreMenu = useCallback(() => dispatch(openSheet(ContextMenuMore)), [ dispatch ]);
|
||||
const muteAll = useCallback(() => dispatch(openDialog(MuteEveryoneDialog)),
|
||||
[ dispatch ]);
|
||||
const showMoreActions = useSelector(isMoreActionsVisible);
|
||||
const showMuteAll = useSelector(isMuteAllVisible);
|
||||
|
||||
return(
|
||||
<View style = { styles.participantsPaneFooter }>
|
||||
{
|
||||
showMuteAll && (
|
||||
<Button
|
||||
accessibilityLabel = 'participantsPane.actions.muteAll'
|
||||
label = 'participantsPane.actions.muteAll'
|
||||
onPress = { muteAll }
|
||||
type = { BUTTON_TYPES.SECONDARY } />
|
||||
)
|
||||
}
|
||||
{
|
||||
showMoreActions && (
|
||||
<IconButton
|
||||
onPress = { openMoreMenu }
|
||||
src = { IconHorizontalPoints }
|
||||
style = { styles.moreButton }
|
||||
type = { BUTTON_TYPES.SECONDARY } />
|
||||
)
|
||||
}
|
||||
</View>
|
||||
)
|
||||
};
|
||||
|
||||
export default ParticipantsPaneFooter;
|
|
@ -35,39 +35,8 @@ const contextMenuItemText = {
|
|||
* The style of the participants pane buttons.
|
||||
*/
|
||||
export const button = {
|
||||
backgroundColor: BaseTheme.palette.action02,
|
||||
borderRadius: BaseTheme.shape.borderRadius,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
minWidth: 0
|
||||
};
|
||||
|
||||
/**
|
||||
* Small buttons.
|
||||
*/
|
||||
const smallButton = {
|
||||
...button,
|
||||
height: BaseTheme.spacing[7],
|
||||
width: BaseTheme.spacing[7]
|
||||
};
|
||||
|
||||
/**
|
||||
* Mute all button.
|
||||
*/
|
||||
const muteAllButton = {
|
||||
...button,
|
||||
marginLeft: 'auto'
|
||||
};
|
||||
|
||||
/**
|
||||
* The style of the participants pane buttons description.
|
||||
*/
|
||||
const buttonContent = {
|
||||
...BaseTheme.typography.labelButton,
|
||||
alignContent: 'center',
|
||||
color: BaseTheme.palette.text01,
|
||||
display: 'flex',
|
||||
justifyContent: 'center'
|
||||
};
|
||||
|
||||
|
@ -88,34 +57,15 @@ const contextMenuItem = {
|
|||
export default {
|
||||
|
||||
participantActionsButtonAdmit: {
|
||||
backgroundColor: BaseTheme.palette.action01,
|
||||
borderRadius: BaseTheme.shape.borderRadius,
|
||||
flexDirection: 'row',
|
||||
height: BaseTheme.spacing[6],
|
||||
marginRight: BaseTheme.spacing[3],
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
zIndex: 1
|
||||
right: 0
|
||||
},
|
||||
|
||||
participantActionsButtonContent: {
|
||||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
height: BaseTheme.spacing[5],
|
||||
top: BaseTheme.spacing[1]
|
||||
},
|
||||
|
||||
participantActionsButtonText: {
|
||||
color: BaseTheme.palette.text01,
|
||||
textTransform: 'capitalize'
|
||||
},
|
||||
|
||||
admitAllParticipantsActionButtonLabel: {
|
||||
...BaseTheme.typography.heading6,
|
||||
admitAllButtonLabel: {
|
||||
color: BaseTheme.palette.link01,
|
||||
textTransform: 'capitalize',
|
||||
marginRight: BaseTheme.spacing[5],
|
||||
marginTop: BaseTheme.spacing[3]
|
||||
marginRight: BaseTheme.spacing[6],
|
||||
marginTop: 14
|
||||
},
|
||||
|
||||
participantContainer: {
|
||||
|
@ -263,49 +213,13 @@ export default {
|
|||
},
|
||||
|
||||
inviteButton: {
|
||||
backgroundColor: BaseTheme.palette.action01,
|
||||
borderRadius: BaseTheme.shape.borderRadius,
|
||||
height: BaseTheme.spacing[7],
|
||||
marginLeft: BaseTheme.spacing[3],
|
||||
marginRight: BaseTheme.spacing[3],
|
||||
marginVertical: BaseTheme.spacing[3]
|
||||
},
|
||||
|
||||
inviteLabel: {
|
||||
fontSize: 15,
|
||||
lineHeight: 30,
|
||||
textTransform: 'capitalize'
|
||||
},
|
||||
|
||||
moreButton: {
|
||||
...smallButton,
|
||||
marginLeft: BaseTheme.spacing[3]
|
||||
},
|
||||
|
||||
moreIcon: {
|
||||
...buttonContent,
|
||||
height: BaseTheme.spacing[5],
|
||||
marginLeft: 'auto'
|
||||
},
|
||||
|
||||
muteAllButton: {
|
||||
...muteAllButton
|
||||
},
|
||||
|
||||
muteAllMoreButton: {
|
||||
...muteAllButton
|
||||
},
|
||||
|
||||
muteAllLabel: {
|
||||
...BaseTheme.typography.labelButtonLarge,
|
||||
color: BaseTheme.palette.text01,
|
||||
height: BaseTheme.spacing[7],
|
||||
marginVertical: BaseTheme.spacing[0],
|
||||
marginHorizontal: BaseTheme.spacing[0],
|
||||
paddingTop: 12,
|
||||
paddingBottom: 12,
|
||||
textTransform: 'capitalize',
|
||||
width: 94
|
||||
marginLeft: BaseTheme.spacing[2]
|
||||
},
|
||||
|
||||
contextMenuItem: {
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
import React from 'react';
|
||||
import { Switch, Text, View } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { getLocalParticipant } from '../../../base/participants';
|
||||
import Button from '../../../base/react/components/native/Button';
|
||||
import { BUTTON_TYPES } from '../../../base/react/constants';
|
||||
import BaseTheme from '../../../base/ui/components/BaseTheme.native';
|
||||
import { BUTTON_MODES } from '../../../chat/constants';
|
||||
import { isSubmitAnswerDisabled } from '../../functions';
|
||||
import AbstractPollAnswer from '../AbstractPollAnswer';
|
||||
import type { AbstractProps } from '../AbstractPollAnswer';
|
||||
|
@ -27,6 +27,7 @@ const PollAnswer = (props: AbstractProps) => {
|
|||
} = props;
|
||||
const { changingVote } = poll;
|
||||
const localParticipant = useSelector(getLocalParticipant);
|
||||
const { PRIMARY, SECONDARY } = BUTTON_TYPES;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -51,26 +52,18 @@ const PollAnswer = (props: AbstractProps) => {
|
|||
</View>
|
||||
<View style = { chatStyles.buttonRow }>
|
||||
<Button
|
||||
color = { BaseTheme.palette.action02 }
|
||||
labelStyle = { chatStyles.pollButtonLabel }
|
||||
mode = { BUTTON_MODES.CONTAINED }
|
||||
accessibilityLabel = 'polls.answer.skip'
|
||||
label = 'polls.answer.skip'
|
||||
onPress = { changingVote ? skipChangeVote : skipAnswer }
|
||||
style = { chatStyles.pollCreateButton } >
|
||||
{ t('polls.answer.skip') }
|
||||
</Button>
|
||||
style = { chatStyles.pollCreateButton }
|
||||
type = { SECONDARY } />
|
||||
<Button
|
||||
color = { BaseTheme.palette.action01 }
|
||||
accessibilityLabel = 'polls.answer.submit'
|
||||
disabled = { isSubmitAnswerDisabled(checkBoxStates) }
|
||||
labelStyle = {
|
||||
isSubmitAnswerDisabled(checkBoxStates)
|
||||
? chatStyles.pollSendDisabledLabel
|
||||
: chatStyles.pollSendLabel
|
||||
}
|
||||
mode = { BUTTON_MODES.CONTAINED }
|
||||
label = 'polls.answer.submit'
|
||||
onPress = { submitAnswer }
|
||||
style = { chatStyles.pollCreateButton } >
|
||||
{ t('polls.answer.submit') }
|
||||
</Button>
|
||||
style = { chatStyles.pollCreateButton }
|
||||
type = { PRIMARY } />
|
||||
</View>
|
||||
</>
|
||||
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
// @flow
|
||||
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { View, Text, TextInput, FlatList } from 'react-native';
|
||||
import { Button, Divider, TouchableRipple } from 'react-native-paper';
|
||||
import { View, Text, TextInput, FlatList, Platform } from 'react-native';
|
||||
import { Divider, TouchableRipple } from 'react-native-paper';
|
||||
|
||||
import Button from '../../../base/react/components/native/Button';
|
||||
import { BUTTON_TYPES } from '../../../base/react/constants';
|
||||
import BaseTheme from '../../../base/ui/components/BaseTheme.native';
|
||||
import { BUTTON_MODES } from '../../../chat/constants';
|
||||
import styles
|
||||
from '../../../welcome/components/native/settings/components/styles';
|
||||
import { ANSWERS_LIMIT, CHAR_LIMIT } from '../../constants';
|
||||
|
@ -16,8 +17,6 @@ import { chatStyles, dialogStyles } from './styles';
|
|||
|
||||
|
||||
const PollCreate = (props: AbstractProps) => {
|
||||
|
||||
|
||||
const {
|
||||
addAnswer,
|
||||
answers,
|
||||
|
@ -56,6 +55,7 @@ const PollCreate = (props: AbstractProps) => {
|
|||
* about whether a newly created input field has been rendered yet or not.
|
||||
*/
|
||||
const [ lastFocus, requestFocus ] = useState(null);
|
||||
const { PRIMARY, SECONDARY } = BUTTON_TYPES;
|
||||
|
||||
useEffect(() => {
|
||||
if (lastFocus === null) {
|
||||
|
@ -127,6 +127,8 @@ const PollCreate = (props: AbstractProps) => {
|
|||
}
|
||||
</View>
|
||||
);
|
||||
const buttonRowStyles = Platform.OS === 'android'
|
||||
? chatStyles.buttonRowAndroid : chatStyles.buttonRowIos;
|
||||
|
||||
return (
|
||||
<View style = { chatStyles.pollCreateContainer }>
|
||||
|
@ -156,47 +158,36 @@ const PollCreate = (props: AbstractProps) => {
|
|||
renderItem = { renderListItem } />
|
||||
<View style = { chatStyles.pollCreateButtonsContainer }>
|
||||
<Button
|
||||
color = { BaseTheme.palette.action02 }
|
||||
accessibilityLabel = 'polls.create.addOption'
|
||||
disabled = { answers.length >= ANSWERS_LIMIT }
|
||||
labelStyle = { chatStyles.pollButtonLabel }
|
||||
mode = { BUTTON_MODES.CONTAINED }
|
||||
label = 'polls.create.addOption'
|
||||
onPress = { () => {
|
||||
// adding and answer
|
||||
addAnswer();
|
||||
requestFocus(answers.length);
|
||||
} }
|
||||
style = { chatStyles.pollCreateAddButton }>
|
||||
{ t('polls.create.addOption') }
|
||||
</Button>
|
||||
style = { chatStyles.pollCreateAddButton }
|
||||
type = { SECONDARY } />
|
||||
<View
|
||||
style = { chatStyles.buttonRow }>
|
||||
style = { buttonRowStyles }>
|
||||
<Button
|
||||
color = { BaseTheme.palette.action02 }
|
||||
labelStyle = { chatStyles.pollButtonLabel }
|
||||
mode = { BUTTON_MODES.CONTAINED }
|
||||
accessibilityLabel = 'polls.create.cancel'
|
||||
label = 'polls.create.cancel'
|
||||
onPress = { () => setCreateMode(false) }
|
||||
style = { chatStyles.pollCreateButton } >
|
||||
{ t('polls.create.cancel') }
|
||||
</Button>
|
||||
style = { chatStyles.pollCreateButton }
|
||||
type = { SECONDARY } />
|
||||
<Button
|
||||
color = { BaseTheme.palette.action01 }
|
||||
accessibilityLabel = 'polls.create.send'
|
||||
disabled = { isSubmitDisabled }
|
||||
labelStyle = {
|
||||
isSubmitDisabled
|
||||
? chatStyles.pollSendDisabledLabel
|
||||
: chatStyles.pollSendLabel
|
||||
}
|
||||
mode = { BUTTON_MODES.CONTAINED }
|
||||
label = 'polls.create.send'
|
||||
onPress = { onSubmit }
|
||||
style = { chatStyles.pollCreateButton } >
|
||||
{ t('polls.create.send') }
|
||||
</Button>
|
||||
style = { chatStyles.pollCreateButton }
|
||||
type = { PRIMARY } />
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
|
||||
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 Button from '../../../base/react/components/native/Button';
|
||||
import { BUTTON_TYPES } from '../../../base/react/constants';
|
||||
import { getUnreadPollCount } from '../../functions';
|
||||
import AbstractPollsPane from '../AbstractPollsPane';
|
||||
import type { AbstractProps } from '../AbstractPollsPane';
|
||||
|
@ -22,7 +22,6 @@ const PollsPane = (props: AbstractProps) => {
|
|||
const isPollsScreenFocused = useIsFocused();
|
||||
const navigation = useNavigation();
|
||||
const nbUnreadPolls = useSelector(getUnreadPollCount);
|
||||
const { palette } = useTheme();
|
||||
|
||||
const nrUnreadPolls = !isPollsScreenFocused && nbUnreadPolls > 0
|
||||
? `(${nbUnreadPolls})`
|
||||
|
@ -47,13 +46,11 @@ const PollsPane = (props: AbstractProps) => {
|
|||
}
|
||||
{
|
||||
!createMode && <Button
|
||||
color = { palette.action01 }
|
||||
labelStyle = { chatStyles.pollButtonLabel }
|
||||
mode = { BUTTON_MODES.CONTAINED }
|
||||
accessibilityLabel = 'polls.create.create'
|
||||
label = 'polls.create.create'
|
||||
onPress = { onCreate }
|
||||
style = { chatStyles.createPollButton } >
|
||||
{t('polls.create.create')}
|
||||
</Button>
|
||||
style = { chatStyles.createPollButton }
|
||||
type = { BUTTON_TYPES.PRIMARY } />
|
||||
}
|
||||
</JitsiScreen>
|
||||
);
|
||||
|
|
|
@ -167,7 +167,6 @@ export const chatStyles = createStyleSheet({
|
|||
|
||||
pollCreateButton: {
|
||||
flex: 1,
|
||||
padding: 4,
|
||||
marginHorizontal: BaseTheme.spacing[2]
|
||||
},
|
||||
|
||||
|
@ -185,6 +184,15 @@ export const chatStyles = createStyleSheet({
|
|||
flexDirection: 'row'
|
||||
},
|
||||
|
||||
buttonRowAndroid: {
|
||||
flexDirection: 'row',
|
||||
marginBottom: BaseTheme.spacing[3]
|
||||
},
|
||||
|
||||
buttonRowIos: {
|
||||
flexDirection: 'row'
|
||||
},
|
||||
|
||||
answerContent: {
|
||||
paddingBottom: 8
|
||||
},
|
||||
|
@ -200,13 +208,8 @@ export const chatStyles = createStyleSheet({
|
|||
marginLeft: BaseTheme.spacing[2]
|
||||
},
|
||||
|
||||
pollButtonLabel: {
|
||||
textTransform: 'capitalize'
|
||||
},
|
||||
|
||||
pollCreateAddButton: {
|
||||
margin: BaseTheme.spacing[2],
|
||||
padding: BaseTheme.spacing[1]
|
||||
margin: BaseTheme.spacing[2]
|
||||
},
|
||||
|
||||
toggleText: {
|
||||
|
@ -215,7 +218,6 @@ export const chatStyles = createStyleSheet({
|
|||
},
|
||||
|
||||
createPollButton: {
|
||||
padding: 4,
|
||||
marginHorizontal: BaseTheme.spacing[4],
|
||||
marginVertical: '8%'
|
||||
},
|
||||
|
|
|
@ -2,9 +2,7 @@ import React, { useCallback, useEffect, useLayoutEffect, useState } from 'react'
|
|||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
BackHandler,
|
||||
Text,
|
||||
View,
|
||||
TouchableOpacity,
|
||||
TextInput,
|
||||
Platform
|
||||
} from 'react-native';
|
||||
|
@ -17,6 +15,8 @@ import { IconClose } from '../../base/icons';
|
|||
import JitsiScreen from '../../base/modal/components/JitsiScreen';
|
||||
import { getLocalParticipant } from '../../base/participants';
|
||||
import { getFieldValue } from '../../base/react';
|
||||
import Button from '../../base/react/components/native/Button';
|
||||
import { BUTTON_TYPES } from '../../base/react/constants';
|
||||
import { ASPECT_RATIO_NARROW } from '../../base/responsive-ui';
|
||||
import { updateSettings } from '../../base/settings';
|
||||
import BaseTheme from '../../base/ui/components/BaseTheme.native';
|
||||
|
@ -28,15 +28,11 @@ import { screen } from '../../mobile/navigation/routes';
|
|||
import AudioMuteButton from '../../toolbox/components/AudioMuteButton';
|
||||
import VideoMuteButton from '../../toolbox/components/VideoMuteButton';
|
||||
import { isDisplayNameRequired } from '../functions';
|
||||
|
||||
import { PrejoinProps } from '../types';
|
||||
import styles from './styles';
|
||||
|
||||
|
||||
interface Props {
|
||||
navigation: any;
|
||||
}
|
||||
|
||||
const Prejoin: ({ navigation }: Props) => JSX.Element = ({ navigation }: Props) => {
|
||||
const Prejoin: React.FC<PrejoinProps> = ({ navigation }: PrejoinProps) => {
|
||||
const dispatch = useDispatch();
|
||||
const { t } = useTranslation();
|
||||
const aspectRatio = useSelector(
|
||||
|
@ -88,9 +84,8 @@ const Prejoin: ({ navigation }: Props) => JSX.Element = ({ navigation }: Props)
|
|||
);
|
||||
}, []);
|
||||
|
||||
const { PRIMARY, SECONDARY } = BUTTON_TYPES;
|
||||
const joinButtonDisabled = !displayName && isDisplayNameMandatory;
|
||||
const joinButtonStyles = joinButtonDisabled
|
||||
? styles.primaryButtonDisabled : styles.primaryButton;
|
||||
|
||||
useEffect(() => {
|
||||
BackHandler.addEventListener('hardwareBackPress', goBack);
|
||||
|
@ -122,6 +117,7 @@ const Prejoin: ({ navigation }: Props) => JSX.Element = ({ navigation }: Props)
|
|||
toolboxContainerStyles = styles.toolboxContainerWide;
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<JitsiScreen
|
||||
safeAreaInsets = { [ 'left' ] }
|
||||
|
@ -138,27 +134,19 @@ const Prejoin: ({ navigation }: Props) => JSX.Element = ({ navigation }: Props)
|
|||
placeholderTextColor = { BaseTheme.palette.text03 }
|
||||
style = { styles.field }
|
||||
value = { displayName } />
|
||||
<TouchableOpacity
|
||||
<Button
|
||||
accessibilityLabel = 'prejoin.joinMeeting'
|
||||
disabled = { joinButtonDisabled }
|
||||
label = 'prejoin.joinMeeting'
|
||||
onPress = { onJoin }
|
||||
style = { [
|
||||
styles.button,
|
||||
joinButtonStyles
|
||||
] }>
|
||||
<Text style = { styles.primaryButtonText }>
|
||||
{ t('prejoin.joinMeeting') }
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style = { styles.prejoinButton }
|
||||
type = { PRIMARY } />
|
||||
<Button
|
||||
accessibilityLabel = 'prejoin.joinMeetingInLowBandwidthMode'
|
||||
label = 'prejoin.joinMeetingInLowBandwidthMode'
|
||||
onPress = { onJoinLowBandwidth }
|
||||
style = { [
|
||||
styles.button,
|
||||
styles.secondaryButton
|
||||
] }>
|
||||
<Text style = { styles.secondaryButtonText }>
|
||||
{ t('prejoin.joinMeetingInLowBandwidthMode') }
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
style = { styles.prejoinButton }
|
||||
type = { SECONDARY } />
|
||||
</View>
|
||||
<View style = { toolboxContainerStyles }>
|
||||
<AudioMuteButton
|
||||
|
|
|
@ -1,47 +1,13 @@
|
|||
import BaseTheme from '../../base/ui/components/BaseTheme.native';
|
||||
|
||||
const SECONDARY_COLOR = BaseTheme.palette.border04;
|
||||
const btn = {
|
||||
marginTop: BaseTheme.spacing[4]
|
||||
};
|
||||
const btnText = {
|
||||
...BaseTheme.typography.labelButtonLarge,
|
||||
color: BaseTheme.palette.text01,
|
||||
lineHeight: 30
|
||||
};
|
||||
|
||||
|
||||
export default {
|
||||
button: {
|
||||
alignItems: 'center',
|
||||
borderRadius: BaseTheme.shape.borderRadius,
|
||||
padding: BaseTheme.spacing[2],
|
||||
height: BaseTheme.spacing[7]
|
||||
},
|
||||
|
||||
primaryButton: {
|
||||
...btn,
|
||||
backgroundColor: BaseTheme.palette.action01
|
||||
},
|
||||
|
||||
primaryButtonDisabled: {
|
||||
backgroundColor: BaseTheme.palette.action03Disabled,
|
||||
prejoinButton: {
|
||||
marginTop: BaseTheme.spacing[4]
|
||||
},
|
||||
|
||||
primaryButtonText: {
|
||||
...btnText
|
||||
},
|
||||
|
||||
secondaryButton: {
|
||||
...btn,
|
||||
backgroundColor: BaseTheme.palette.action02
|
||||
},
|
||||
|
||||
|
||||
secondaryButtonText: {
|
||||
...btnText
|
||||
},
|
||||
|
||||
buttonStylesBorderless: {
|
||||
iconStyle: {
|
||||
color: BaseTheme.palette.icon01,
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
interface PrejoinProps {
|
||||
navigation: Object;
|
||||
}
|
|
@ -1,14 +1,13 @@
|
|||
// @flow
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { Text, TouchableHighlight, View } from 'react-native';
|
||||
import { Text } from 'react-native-paper';
|
||||
import { type Dispatch } from 'redux';
|
||||
|
||||
import {
|
||||
createToolbarEvent,
|
||||
sendAnalytics
|
||||
} from '../../../analytics';
|
||||
import { ColorSchemeRegistry } from '../../../base/color-scheme';
|
||||
import { RAISE_HAND_ENABLED, getFeatureFlag } from '../../../base/flags';
|
||||
import { translate } from '../../../base/i18n';
|
||||
import {
|
||||
|
@ -16,10 +15,12 @@ import {
|
|||
hasRaisedHand,
|
||||
raiseHand
|
||||
} from '../../../base/participants';
|
||||
import Button from '../../../base/react/components/native/Button';
|
||||
import { BUTTON_TYPES } from '../../../base/react/constants';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { type AbstractButtonProps } from '../../../base/toolbox/components';
|
||||
|
||||
import { type ReactionStyles } from './ReactionButton';
|
||||
import styles from './styles';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link RaiseHandButton}.
|
||||
|
@ -54,12 +55,7 @@ type Props = AbstractButtonProps & {
|
|||
/**
|
||||
* Used to close the overflow menu after raise hand is clicked.
|
||||
*/
|
||||
onCancel: Function,
|
||||
|
||||
/**
|
||||
* Styles for the button.
|
||||
*/
|
||||
_styles: ReactionStyles
|
||||
onCancel: Function
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -127,6 +123,17 @@ class RaiseHandButton extends Component<Props, *> {
|
|||
return t(_raisedHand ? this.toggledLabel : this.label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the "raise hand" emoji.
|
||||
*
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderRaiseHandEmoji() {
|
||||
return (
|
||||
<Text>✋</Text>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements React's {@link Component#render()}.
|
||||
*
|
||||
|
@ -134,24 +141,20 @@ class RaiseHandButton extends Component<Props, *> {
|
|||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const { _enabled, _styles, t } = this.props;
|
||||
const { _enabled } = this.props;
|
||||
|
||||
if (!_enabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<TouchableHighlight
|
||||
accessibilityLabel = { t(this.accessibilityLabel) }
|
||||
accessibilityRole = 'button'
|
||||
<Button
|
||||
accessibilityLabel = { this.accessibilityLabel }
|
||||
icon = { this._renderRaiseHandEmoji }
|
||||
label = { this._getLabel() }
|
||||
onPress = { this._onClick }
|
||||
style = { _styles.style }
|
||||
underlayColor = { _styles.underlayColor }>
|
||||
<View style = { _styles.container }>
|
||||
<Text style = { _styles.emoji }>✋</Text>
|
||||
<Text style = { _styles.text }>{this._getLabel()}</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
style = { styles.raiseHandButton }
|
||||
type = { BUTTON_TYPES.SECONDARY } />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -170,8 +173,7 @@ function _mapStateToProps(state): Object {
|
|||
return {
|
||||
_enabled: enabled,
|
||||
_localParticipant,
|
||||
_raisedHand: hasRaisedHand(_localParticipant),
|
||||
_styles: ColorSchemeRegistry.get(state, 'Toolbox').raiseHandButton
|
||||
_raisedHand: hasRaisedHand(_localParticipant)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -49,13 +49,16 @@ function ReactionMenu({
|
|||
return (
|
||||
<View style = { overflowMenu ? _styles.overflowReactionMenu : _styles.reactionMenu }>
|
||||
<View style = { _styles.reactionRow }>
|
||||
{Object.keys(REACTIONS).map(key => (
|
||||
{
|
||||
Object.keys(REACTIONS).map(key => (
|
||||
<ReactionButton
|
||||
key = { key }
|
||||
reaction = { key }
|
||||
styles = { _styles.reactionButton } />
|
||||
))}
|
||||
{gifEnabled && (
|
||||
))
|
||||
}
|
||||
{
|
||||
gifEnabled && (
|
||||
<ReactionButton
|
||||
onClick = { openGifMenu }
|
||||
styles = { _styles.reactionButton }>
|
||||
|
@ -63,7 +66,8 @@ function ReactionMenu({
|
|||
height = { 22 }
|
||||
source = { require('../../../../../images/GIPHY_icon.png') } />
|
||||
</ReactionButton>
|
||||
)}
|
||||
)
|
||||
}
|
||||
</View>
|
||||
<RaiseHandButton onCancel = { onCancel } />
|
||||
</View>
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
import BaseTheme from '../../../base/ui/components/BaseTheme.native';
|
||||
|
||||
/**
|
||||
* The styles of the native components of the feature {@code reactions}.
|
||||
*/
|
||||
export default {
|
||||
raiseHandButton: {
|
||||
marginVertical: BaseTheme.spacing[3],
|
||||
width: 240
|
||||
}
|
||||
};
|
|
@ -1,10 +1,11 @@
|
|||
import React, { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Text, View } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
import { useDispatch, batch } from 'react-redux';
|
||||
|
||||
import { BottomSheet, hideSheet } from '../../../../base/dialog';
|
||||
import Button from '../../../../base/react/components/native/Button';
|
||||
import { BUTTON_TYPES } from '../../../../base/react/constants';
|
||||
import { highlightMeetingMoment } from '../../../actions.any';
|
||||
import styles from '../styles.native';
|
||||
|
||||
|
@ -28,20 +29,16 @@ const HighlightDialog = () => {
|
|||
</Text>
|
||||
<View style = { styles.highlightDialogButtonsContainer } >
|
||||
<Button
|
||||
accessibilityLabel = { t('dialog.Cancel') }
|
||||
children = { t('dialog.Cancel') }
|
||||
labelStyle = { styles.highlightDialogCancelLabel }
|
||||
mode = 'contained'
|
||||
accessibilityLabel = 'dialog.Cancel'
|
||||
label = 'dialog.Cancel'
|
||||
onPress = { closeDialog }
|
||||
style = { styles.highlightDialogCancelButton } />
|
||||
type = { BUTTON_TYPES.SECONDARY } />
|
||||
<View style = { styles.highlightDialogButtonsSpace } />
|
||||
<Button
|
||||
accessibilityLabel = { t('recording.highlight') }
|
||||
children = { t('recording.highlight') }
|
||||
labelStyle = { styles.highlightDialogHighlighLabel }
|
||||
mode = 'contained'
|
||||
accessibilityLabel = 'recording.highlight'
|
||||
label = 'recording.highlight'
|
||||
onPress = { highlightMoment }
|
||||
style = { styles.highlightDialogHighlightButton } />
|
||||
type = { BUTTON_TYPES.PRIMARY } />
|
||||
</View>
|
||||
</View>
|
||||
</BottomSheet>
|
||||
|
|
|
@ -39,18 +39,6 @@ const title = {
|
|||
paddingLeft: BoxModel.padding
|
||||
};
|
||||
|
||||
const baseHighlightDialogButton = {
|
||||
borderRadius: BaseTheme.shape.borderRadius,
|
||||
height: BaseTheme.spacing[7],
|
||||
flex: 1,
|
||||
justifyContent: 'space-around'
|
||||
};
|
||||
|
||||
const baseHighlightDialogLabel = {
|
||||
...BaseTheme.typography.bodyShortBoldLarge,
|
||||
textTransform: 'none'
|
||||
};
|
||||
|
||||
export default {
|
||||
/**
|
||||
* Container for the StartRecordingDialog screen.
|
||||
|
@ -104,22 +92,6 @@ export default {
|
|||
display: 'flex',
|
||||
flexDirection: 'column-reverse'
|
||||
},
|
||||
highlightDialogCancelButton: {
|
||||
...baseHighlightDialogButton,
|
||||
backgroundColor: BaseTheme.palette.section01
|
||||
},
|
||||
highlightDialogHighlightButton: {
|
||||
...baseHighlightDialogButton,
|
||||
backgroundColor: BaseTheme.palette.action01
|
||||
},
|
||||
highlightDialogCancelLabel: {
|
||||
...baseHighlightDialogLabel,
|
||||
color: BaseTheme.palette.field01
|
||||
},
|
||||
highlightDialogHighlighLabel: {
|
||||
...baseHighlightDialogLabel,
|
||||
color: BaseTheme.palette.text01
|
||||
},
|
||||
highlightDialogButtonsSpace: {
|
||||
height: 16,
|
||||
width: '100%'
|
||||
|
|
|
@ -161,8 +161,7 @@ ColorSchemeRegistry.register('Toolbox', {
|
|||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
width: '100%',
|
||||
marginBottom: 16
|
||||
width: '100%'
|
||||
},
|
||||
|
||||
reactionButton: {
|
||||
|
@ -172,28 +171,6 @@ ColorSchemeRegistry.register('Toolbox', {
|
|||
emoji: reactionEmoji
|
||||
},
|
||||
|
||||
raiseHandButton: {
|
||||
style: {
|
||||
...reactionButton,
|
||||
backgroundColor: BaseTheme.palette.ui13,
|
||||
width: '100%',
|
||||
borderRadius: 6
|
||||
},
|
||||
underlayColor: BaseTheme.palette.ui13,
|
||||
emoji: reactionEmoji,
|
||||
text: {
|
||||
color: BaseTheme.palette.text01,
|
||||
fontWeight: '600',
|
||||
marginLeft: 8,
|
||||
lineHeight: 24
|
||||
},
|
||||
container: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}
|
||||
},
|
||||
|
||||
emojiAnimation: {
|
||||
color: BaseTheme.palette.icon01,
|
||||
position: 'absolute',
|
||||
|
|
|
@ -103,7 +103,7 @@ export default {
|
|||
* Global {@code Text} color for the components.
|
||||
*/
|
||||
text: {
|
||||
color: BaseTheme.palette.text02
|
||||
color: BaseTheme.palette.text01
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue