feat(security) created SecurityOptions React Navigation screen (#10509)
* feat(security) Security Options screen
This commit is contained in:
parent
75e6dd389f
commit
bf3cc65f4c
|
@ -68,6 +68,7 @@ dependencies {
|
|||
implementation project(':react-native-async-storage')
|
||||
implementation project(':react-native-background-timer')
|
||||
implementation project(':react-native-calendar-events')
|
||||
implementation project(':react-native-community_clipboard')
|
||||
implementation project(':react-native-community_netinfo')
|
||||
implementation project(':react-native-default-preference')
|
||||
implementation project(':react-native-gesture-handler')
|
||||
|
|
|
@ -180,6 +180,7 @@ class ReactInstanceManagerHolder {
|
|||
new com.calendarevents.CalendarEventsPackage(),
|
||||
new com.corbt.keepawake.KCKeepAwakePackage(),
|
||||
new com.facebook.react.shell.MainReactPackage(),
|
||||
new com.reactnativecommunity.clipboard.ClipboardPackage(),
|
||||
new com.reactnativecommunity.netinfo.NetInfoPackage(),
|
||||
new com.oblador.performance.PerformancePackage(),
|
||||
new com.reactnativecommunity.slider.ReactSliderPackage(),
|
||||
|
|
|
@ -9,6 +9,8 @@ include ':react-native-background-timer'
|
|||
project(':react-native-background-timer').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-background-timer/android')
|
||||
include ':react-native-calendar-events'
|
||||
project(':react-native-calendar-events').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-calendar-events/android')
|
||||
include ':react-native-community_clipboard'
|
||||
project(':react-native-community_clipboard').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/clipboard/android')
|
||||
include ':react-native-community_netinfo'
|
||||
project(':react-native-community_netinfo').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/netinfo/android')
|
||||
include ':react-native-default-preference'
|
||||
|
|
13
ios/Podfile
13
ios/Podfile
|
@ -61,23 +61,24 @@ target 'JitsiMeetSDK' do
|
|||
pod 'react-native-keep-awake', :path => '../node_modules/react-native-keep-awake'
|
||||
pod 'react-native-netinfo', :path => '../node_modules/@react-native-community/netinfo'
|
||||
pod 'react-native-performance', :path => '../node_modules/react-native-performance/ios'
|
||||
pod 'react-native-safe-area-context', :path => '../node_modules/react-native-safe-area-context'
|
||||
pod 'react-native-slider', :path => '../node_modules/@react-native-community/slider'
|
||||
pod 'react-native-splash-screen', :path => '../node_modules/react-native-splash-screen'
|
||||
pod 'react-native-video', :path => '../node_modules/react-native-video/react-native-video.podspec'
|
||||
pod 'react-native-webview', :path => '../node_modules/react-native-webview'
|
||||
pod 'react-native-webrtc', :path => '../node_modules/react-native-webrtc'
|
||||
pod 'RNCAsyncStorage', :path => '../node_modules/@react-native-async-storage/async-storage'
|
||||
pod 'RNCClipboard', :path => '../node_modules/@react-native-community/clipboard'
|
||||
pod 'RNCMaskedView', :path => '../node_modules/@react-native-masked-view/masked-view'
|
||||
pod 'RNDefaultPreference', :path => '../node_modules/react-native-default-preference'
|
||||
pod 'RNDeviceInfo', :path => '../node_modules/react-native-device-info'
|
||||
pod 'RNGestureHandler', :path => '../node_modules/react-native-gesture-handler'
|
||||
pod 'RNGoogleSignin', :path => '../node_modules/@react-native-community/google-signin'
|
||||
pod 'RNReanimated', :path => '../node_modules/react-native-reanimated'
|
||||
pod 'RNScreens', :path => '../node_modules/react-native-screens'
|
||||
pod 'RNSound', :path => '../node_modules/react-native-sound'
|
||||
pod 'RNSVG', :path => '../node_modules/react-native-svg'
|
||||
pod 'RNWatch', :path => '../node_modules/react-native-watch-connectivity'
|
||||
pod 'RNDefaultPreference', :path => '../node_modules/react-native-default-preference'
|
||||
pod 'RNGestureHandler', :path => '../node_modules/react-native-gesture-handler'
|
||||
pod 'RNReanimated', :path => '../node_modules/react-native-reanimated'
|
||||
pod 'RNScreens', :path => '../node_modules/react-native-screens'
|
||||
pod 'react-native-safe-area-context', :path => '../node_modules/react-native-safe-area-context'
|
||||
pod 'RNCMaskedView', :path => '../node_modules/@react-native-masked-view/masked-view'
|
||||
|
||||
# Native pod dependencies
|
||||
#
|
||||
|
|
|
@ -363,6 +363,8 @@ PODS:
|
|||
- ReactCommon/turbomodule/core (= 0.61.5-jitsi.2)
|
||||
- RNCAsyncStorage (1.15.5):
|
||||
- React-Core
|
||||
- RNCClipboard (1.5.1):
|
||||
- React-Core
|
||||
- RNCMaskedView (0.2.6):
|
||||
- React-Core
|
||||
- RNDefaultPreference (1.4.2):
|
||||
|
@ -435,6 +437,7 @@ DEPENDENCIES:
|
|||
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
|
||||
- ReactCommon/turbomodule (from `../node_modules/react-native/ReactCommon`)
|
||||
- "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)"
|
||||
- "RNCClipboard (from `../node_modules/@react-native-community/clipboard`)"
|
||||
- "RNCMaskedView (from `../node_modules/@react-native-masked-view/masked-view`)"
|
||||
- RNDefaultPreference (from `../node_modules/react-native-default-preference`)
|
||||
- RNDeviceInfo (from `../node_modules/react-native-device-info`)
|
||||
|
@ -547,6 +550,8 @@ EXTERNAL SOURCES:
|
|||
:path: "../node_modules/react-native/ReactCommon"
|
||||
RNCAsyncStorage:
|
||||
:path: "../node_modules/@react-native-async-storage/async-storage"
|
||||
RNCClipboard:
|
||||
:path: "../node_modules/@react-native-community/clipboard"
|
||||
RNCMaskedView:
|
||||
:path: "../node_modules/@react-native-masked-view/masked-view"
|
||||
RNDefaultPreference:
|
||||
|
@ -629,6 +634,7 @@ SPEC CHECKSUMS:
|
|||
React-RCTVibration: c1041024893fdfdb8371e7c720c437751b711676
|
||||
ReactCommon: 18014e1d98dbeb9141e935cfe35fc93bd511ffb6
|
||||
RNCAsyncStorage: 56a3355a10b5d660c48c6e37325ac85ebfd09885
|
||||
RNCClipboard: 41d8d918092ae8e676f18adada19104fa3e68495
|
||||
RNCMaskedView: c298b644a10c0c142055b3ae24d83879ecb13ccd
|
||||
RNDefaultPreference: 1f8133ec0bc0f9453cdada578564ba1ef551fb44
|
||||
RNDeviceInfo: 87d2d175c760f6bcf58acd036f887e8b2392802c
|
||||
|
@ -641,6 +647,6 @@ SPEC CHECKSUMS:
|
|||
RNWatch: a5320c959c75e72845c07985f3e935e58998f1d3
|
||||
Yoga: 96b469c5e81ff51b917b92e8c3390642d4ded30c
|
||||
|
||||
PODFILE CHECKSUM: 836d4804218c0608e1326471ec83fe31cfa9c86d
|
||||
PODFILE CHECKSUM: 0cfc1f35e2872ceb0a86252e14e226bd489a2602
|
||||
|
||||
COCOAPODS: 1.11.2
|
||||
|
|
|
@ -470,7 +470,7 @@
|
|||
"noPassword": "None",
|
||||
"noRoom": "No room was specified to dial-in into.",
|
||||
"numbers": "Dial-in Numbers",
|
||||
"password": "$t(lockRoomPasswordUppercase):",
|
||||
"password": "$t(lockRoomPasswordUppercase): ",
|
||||
"sip": "SIP address",
|
||||
"title": "Share",
|
||||
"tooltip": "Share link and dial-in info for this meeting",
|
||||
|
@ -824,8 +824,8 @@
|
|||
"security": {
|
||||
"about": "You can add a $t(lockRoomPassword) to your meeting. Participants will need to provide the $t(lockRoomPassword) before they are allowed to join the meeting.",
|
||||
"aboutReadOnly": "Moderator participants can add a $t(lockRoomPassword) to the meeting. Participants will need to provide the $t(lockRoomPassword) before they are allowed to join the meeting.",
|
||||
"insecureRoomNameWarning": "The room name is unsafe. Unwanted participants may join your conference. Consider securing your meeting using the security button.",
|
||||
"securityOptions": "Security options"
|
||||
"header": "Security Options",
|
||||
"insecureRoomNameWarning": "The room name is unsafe. Unwanted participants may join your conference. Consider securing your meeting using the security button."
|
||||
},
|
||||
"settings": {
|
||||
"calendar": {
|
||||
|
@ -893,20 +893,20 @@
|
|||
},
|
||||
"speaker": "Speaker",
|
||||
"speakerStats": {
|
||||
"search": "Search",
|
||||
"angry": "Angry",
|
||||
"disgusted": "Disgusted",
|
||||
"fearful": "Fearful",
|
||||
"happy": "Happy",
|
||||
"hours": "{{count}}h",
|
||||
"minutes": "{{count}}m",
|
||||
"name": "Name",
|
||||
"seconds": "{{count}}s",
|
||||
"speakerStats": "Speaker Stats",
|
||||
"speakerTime": "Speaker Time",
|
||||
"happy": "Happy",
|
||||
"neutral": "Neutral",
|
||||
"sad": "Sad",
|
||||
"surprised": "Surprised",
|
||||
"angry": "Angry",
|
||||
"fearful": "Fearful",
|
||||
"disgusted": "Disgusted"
|
||||
"search": "Search",
|
||||
"seconds": "{{count}}s",
|
||||
"speakerTime": "Speaker Time",
|
||||
"speakerStats": "Speaker Stats",
|
||||
"surprised": "Surprised"
|
||||
},
|
||||
"startupoverlay": {
|
||||
"policyText": " ",
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz",
|
||||
"@microsoft/microsoft-graph-client": "1.1.0",
|
||||
"@react-native-async-storage/async-storage": "1.15.5",
|
||||
"@react-native-community/clipboard": "1.5.1",
|
||||
"@react-native-community/google-signin": "3.0.1",
|
||||
"@react-native-community/netinfo": "4.1.5",
|
||||
"@react-native-community/slider": "3.0.3",
|
||||
|
@ -4097,6 +4098,15 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native-community/clipboard": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@react-native-community/clipboard/-/clipboard-1.5.1.tgz",
|
||||
"integrity": "sha512-AHAmrkLEH5UtPaDiRqoULERHh3oNv7Dgs0bTC0hO5Z2GdNokAMPT5w8ci8aMcRemcwbtdHjxChgtjbeA38GBdA==",
|
||||
"peerDependencies": {
|
||||
"react": ">=16.0",
|
||||
"react-native": ">=0.57.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native-community/google-signin": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@react-native-community/google-signin/-/google-signin-3.0.1.tgz",
|
||||
|
@ -23388,6 +23398,11 @@
|
|||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-types/-/cli-types-3.0.0.tgz",
|
||||
"integrity": "sha512-ng6Tm537E/M42GjE4TRUxQyL8sRfClcL7bQWblOCoxPZzJ2J3bdALsjeG3vDnVCIfI/R0AeFalN9KjMt0+Z/Zg=="
|
||||
},
|
||||
"@react-native-community/clipboard": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@react-native-community/clipboard/-/clipboard-1.5.1.tgz",
|
||||
"integrity": "sha512-AHAmrkLEH5UtPaDiRqoULERHh3oNv7Dgs0bTC0hO5Z2GdNokAMPT5w8ci8aMcRemcwbtdHjxChgtjbeA38GBdA=="
|
||||
},
|
||||
"@react-native-community/google-signin": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@react-native-community/google-signin/-/google-signin-3.0.1.tgz",
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz",
|
||||
"@microsoft/microsoft-graph-client": "1.1.0",
|
||||
"@react-native-async-storage/async-storage": "1.15.5",
|
||||
"@react-native-community/clipboard": "1.5.1",
|
||||
"@react-native-community/google-signin": "3.0.1",
|
||||
"@react-native-community/netinfo": "4.1.5",
|
||||
"@react-native-community/slider": "3.0.3",
|
||||
|
|
|
@ -19,6 +19,7 @@ export const colors = {
|
|||
primary09: '#CCDDF9',
|
||||
primary10: '#17A0DB',
|
||||
primary11: '#1081B2',
|
||||
primary12: '#B8C7E0',
|
||||
|
||||
surface00: '#111111',
|
||||
surface01: '#040404',
|
||||
|
@ -158,6 +159,9 @@ export const colorMap = {
|
|||
// Text for drawer menu displayed name
|
||||
text05: 'surface06',
|
||||
|
||||
// Text for saved input values
|
||||
text06: 'surface03',
|
||||
|
||||
// error messages
|
||||
textError: 'error06',
|
||||
|
||||
|
@ -226,6 +230,8 @@ export const colorMap = {
|
|||
// Line separators
|
||||
border03: 'surface04',
|
||||
|
||||
border04: 'primary12',
|
||||
|
||||
// Color for error border & message
|
||||
borderError: 'error06',
|
||||
|
||||
|
|
|
@ -17,12 +17,12 @@ import {
|
|||
setVideoMuted
|
||||
} from '../base/media';
|
||||
import { getRemoteParticipants } from '../base/participants';
|
||||
import { createDesiredLocalTracks } from '../base/tracks/actions';
|
||||
import {
|
||||
getLocalTracks,
|
||||
isLocalCameraTrackMuted,
|
||||
isLocalTrackMuted
|
||||
} from '../base/tracks';
|
||||
import { createDesiredLocalTracks } from '../base/tracks/actions';
|
||||
import {
|
||||
NOTIFICATION_TIMEOUT_TYPE,
|
||||
clearNotifications,
|
||||
|
|
|
@ -13,6 +13,8 @@ import AddPeopleDialog
|
|||
from '../../../invite/components/add-people-dialog/native/AddPeopleDialog';
|
||||
import LobbyScreen from '../../../lobby/components/native/LobbyScreen';
|
||||
import { ParticipantsPane } from '../../../participants-pane/components/native';
|
||||
import SecurityDialog
|
||||
from '../../../security/components/security-dialog/native/SecurityDialog';
|
||||
import SpeakerStats
|
||||
from '../../../speaker-stats/components/native/SpeakerStats';
|
||||
import { getDisablePolls } from '../../functions';
|
||||
|
@ -28,6 +30,7 @@ import {
|
|||
lobbyScreenOptions,
|
||||
navigationContainerTheme,
|
||||
participantsScreenOptions,
|
||||
securityScreenOptions,
|
||||
sharedDocumentScreenOptions,
|
||||
speakerStatsScreenOptions
|
||||
} from './ConferenceNavigatorScreenOptions';
|
||||
|
@ -80,11 +83,19 @@ const ConferenceNavigationContainer = () => {
|
|||
...participantsScreenOptions,
|
||||
title: t('participantsPane.header')
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
component = { SecurityDialog }
|
||||
name = { screen.conference.security }
|
||||
options = {{
|
||||
...securityScreenOptions,
|
||||
title: t('security.header')
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
component = { SpeakerStats }
|
||||
name = { screen.conference.speakerStats }
|
||||
options = {{
|
||||
...speakerStatsScreenOptions
|
||||
...speakerStatsScreenOptions,
|
||||
title: t('speakerStats.speakerStats')
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
component = { LobbyScreen }
|
||||
|
|
|
@ -222,6 +222,13 @@ export const speakerStatsScreenOptions = {
|
|||
...presentationScreenOptions
|
||||
};
|
||||
|
||||
/**
|
||||
* Screen options for security options modal.
|
||||
*/
|
||||
export const securityScreenOptions = {
|
||||
...presentationScreenOptions
|
||||
};
|
||||
|
||||
/**
|
||||
* Screen options for shared document.
|
||||
*/
|
||||
|
|
|
@ -21,6 +21,7 @@ export const screen = {
|
|||
polls: 'Polls'
|
||||
}
|
||||
},
|
||||
security: 'Security Options',
|
||||
speakerStats: 'Speaker Stats',
|
||||
participants: 'Participants',
|
||||
invite: 'Invite',
|
||||
|
|
|
@ -147,8 +147,8 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
|||
<TouchableRipple
|
||||
disabled = { this._isAddDisabled() }
|
||||
rippleColor = { palette.screen01Header } >
|
||||
<Text
|
||||
style = { styles.headerSendInvite }>{ t('inviteDialog.send') }
|
||||
<Text style = { styles.headerSendInvite }>
|
||||
{ t('inviteDialog.send') }
|
||||
</Text>
|
||||
</TouchableRipple>
|
||||
)
|
||||
|
@ -171,9 +171,8 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
|||
disabled = { this._isAddDisabled() }
|
||||
onPress = { this._onInvite }
|
||||
rippleColor = { palette.screen01Header } >
|
||||
<Text
|
||||
/* eslint-disable-next-line react-native/no-inline-styles */
|
||||
style = { styles.headerSendInvite }>{ t('inviteDialog.send') }
|
||||
<Text style = { styles.headerSendInvite }>
|
||||
{ t('inviteDialog.send') }
|
||||
</Text>
|
||||
</TouchableRipple>
|
||||
)
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
// @flow
|
||||
|
||||
import { ColorPalette } from '../../../base/styles';
|
||||
import BaseTheme from '../../../base/ui/components/BaseTheme';
|
||||
|
||||
const SECONDARY_COLOR = '#B8C7E0';
|
||||
const SECONDARY_COLOR = BaseTheme.palette.border04;
|
||||
|
||||
export const ENABLED_THUMB_COLOR = ColorPalette.blueHighlight;
|
||||
export const ENABLED_TRACK_COLOR = ColorPalette.blue;
|
||||
export const DISABLED_THUMB_COLOR = ColorPalette.darkGrey;
|
||||
export const ENABLED_THUMB_COLOR = BaseTheme.palette.action04;
|
||||
export const ENABLED_TRACK_COLOR = BaseTheme.palette.screen01Header;
|
||||
export const DISABLED_THUMB_COLOR = BaseTheme.palette.icon04;
|
||||
|
||||
export default {
|
||||
button: {
|
||||
|
@ -61,7 +61,7 @@ export default {
|
|||
},
|
||||
|
||||
fieldError: {
|
||||
color: ColorPalette.warning,
|
||||
color: BaseTheme.palette.warning07,
|
||||
fontSize: 10
|
||||
},
|
||||
|
||||
|
@ -165,7 +165,7 @@ export default {
|
|||
|
||||
lobbySwitchContainer: {
|
||||
flexDirection: 'column',
|
||||
marginTop: 16
|
||||
marginTop: BaseTheme.spacing[2]
|
||||
},
|
||||
|
||||
lobbySwitchIcon: {
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
import { Switch, Text, View } from 'react-native';
|
||||
|
||||
import { translate } from '../../base/i18n';
|
||||
import { connect } from '../../base/redux';
|
||||
import { LOCKED_REMOTELY } from '../constants';
|
||||
|
||||
import styles, {
|
||||
DISABLED_THUMB_COLOR,
|
||||
ENABLED_THUMB_COLOR, ENABLED_TRACK_COLOR
|
||||
} from './styles';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link RoomLockSwitch}.
|
||||
*/
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* Checks if the room is locked based on defined room lock constants.
|
||||
*/
|
||||
locked: string,
|
||||
|
||||
/**
|
||||
* Whether the switch is disabled.
|
||||
*/
|
||||
disabled: boolean,
|
||||
|
||||
/**
|
||||
* Callback to be invoked when the user toggles room lock.
|
||||
*/
|
||||
onToggleRoomLock: Function,
|
||||
|
||||
/**
|
||||
* Control for room lock.
|
||||
*/
|
||||
toggleRoomLock: boolean,
|
||||
|
||||
/**
|
||||
* Invoked to obtain translated strings.
|
||||
*/
|
||||
t: Function
|
||||
};
|
||||
|
||||
/**
|
||||
* Component meant to Add/Remove meeting password.
|
||||
*
|
||||
* @returns {React$Element<any>}
|
||||
*/
|
||||
function RoomLockSwitch(
|
||||
{
|
||||
locked,
|
||||
disabled,
|
||||
onToggleRoomLock,
|
||||
toggleRoomLock,
|
||||
t
|
||||
}: Props) {
|
||||
|
||||
return (
|
||||
<View style = { styles.roomLockSwitchContainer }>
|
||||
<Text>
|
||||
{
|
||||
locked === LOCKED_REMOTELY
|
||||
&& t('passwordSetRemotely')
|
||||
}
|
||||
</Text>
|
||||
<Switch
|
||||
disabled = { disabled }
|
||||
onValueChange = { onToggleRoomLock }
|
||||
thumbColor = {
|
||||
toggleRoomLock
|
||||
? ENABLED_THUMB_COLOR
|
||||
: DISABLED_THUMB_COLOR
|
||||
}
|
||||
trackColor = {{ true: ENABLED_TRACK_COLOR }}
|
||||
value = { toggleRoomLock } />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
export default translate(connect()(RoomLockSwitch));
|
|
@ -1,16 +0,0 @@
|
|||
// @flow
|
||||
|
||||
import { ColorPalette } from '../../base/styles';
|
||||
|
||||
export const ENABLED_THUMB_COLOR = ColorPalette.blueHighlight;
|
||||
export const ENABLED_TRACK_COLOR = ColorPalette.blue;
|
||||
export const DISABLED_THUMB_COLOR = ColorPalette.darkGrey;
|
||||
|
||||
export default {
|
||||
roomLockSwitchContainer: {
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
marginTop: 16
|
||||
}
|
||||
};
|
|
@ -9,15 +9,11 @@ import {
|
|||
MEETING_PASSWORD_ENABLED,
|
||||
SECURITY_OPTIONS_ENABLED
|
||||
} from '../../../base/flags';
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { IconSecurityOff, IconSecurityOn } from '../../../base/icons';
|
||||
import { isLocalParticipantModerator } from '../../../base/participants';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { AbstractButton, type AbstractButtonProps } from '../../../base/toolbox/components';
|
||||
import { toggleSecurityDialog } from '../../actions';
|
||||
|
||||
|
||||
type Props = AbstractButtonProps & {
|
||||
export type Props = AbstractButtonProps & {
|
||||
|
||||
/**
|
||||
* Whether the shared document is being edited or not.
|
||||
|
@ -32,9 +28,10 @@ type Props = AbstractButtonProps & {
|
|||
|
||||
|
||||
/**
|
||||
* Implements an {@link AbstractButton} to open the security dialog.
|
||||
* Implements an {@link AbstractButton} to open the security dialog/screen.
|
||||
*/
|
||||
class SecurityDialogButton extends AbstractButton<Props, *> {
|
||||
export default class AbstractSecurityDialogButton<P: Props, S:*>
|
||||
extends AbstractButton<P, S> {
|
||||
accessibilityLabel = 'toolbar.accessibilityLabel.security';
|
||||
icon = IconSecurityOff;
|
||||
label = 'toolbar.security';
|
||||
|
@ -42,13 +39,24 @@ class SecurityDialogButton extends AbstractButton<Props, *> {
|
|||
tooltip = 'toolbar.security';
|
||||
|
||||
/**
|
||||
* Handles clicking / pressing the button, and opens / closes the appropriate dialog.
|
||||
* Helper function to be implemented by subclasses, which should be used
|
||||
* to handle the security button being clicked / pressed.
|
||||
*
|
||||
* @protected
|
||||
* @returns {void}
|
||||
*/
|
||||
_handleClickSecurityButton() {
|
||||
// To be implemented by subclass.
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles clicking / pressing the button.
|
||||
*
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_handleClick() {
|
||||
const { _locked, dispatch, handleClick } = this.props;
|
||||
const { _locked, handleClick } = this.props;
|
||||
|
||||
if (handleClick) {
|
||||
handleClick();
|
||||
|
@ -57,7 +65,7 @@ class SecurityDialogButton extends AbstractButton<Props, *> {
|
|||
}
|
||||
|
||||
sendAnalytics(createToolbarEvent('toggle.security', { enable: !_locked }));
|
||||
dispatch(toggleSecurityDialog());
|
||||
this._handleClickSecurityButton();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -77,7 +85,7 @@ class SecurityDialogButton extends AbstractButton<Props, *> {
|
|||
* @param {Object} state - The redux store/state.
|
||||
* @returns {Props}
|
||||
*/
|
||||
function mapStateToProps(state: Object) {
|
||||
export function _mapStateToProps(state: Object) {
|
||||
const { conference } = state['features/base/conference'];
|
||||
const { hideLobbyButton } = state['features/base/config'];
|
||||
const { locked } = state['features/base/conference'];
|
||||
|
@ -93,5 +101,3 @@ function mapStateToProps(state: Object) {
|
|||
visible: enabledFlag || (enabledLobbyModeFlag || enabledMeetingPassFlag)
|
||||
};
|
||||
}
|
||||
|
||||
export default translate(connect(mapStateToProps)(SecurityDialogButton));
|
|
@ -1,35 +1,39 @@
|
|||
// @flow
|
||||
|
||||
import Clipboard from '@react-native-community/clipboard';
|
||||
import React, { PureComponent } from 'react';
|
||||
import {
|
||||
KeyboardAvoidingView,
|
||||
Platform,
|
||||
Text,
|
||||
TextInput,
|
||||
View
|
||||
} from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import { TouchableRipple } from 'react-native-paper';
|
||||
import type { Dispatch } from 'redux';
|
||||
|
||||
import { ColorSchemeRegistry } from '../../../../base/color-scheme';
|
||||
import {
|
||||
FIELD_UNDERLINE,
|
||||
CustomSubmitDialog
|
||||
} from '../../../../base/dialog';
|
||||
import { FIELD_UNDERLINE } from '../../../../base/dialog';
|
||||
import { getFeatureFlag, MEETING_PASSWORD_ENABLED } from '../../../../base/flags';
|
||||
import { translate } from '../../../../base/i18n';
|
||||
import { IconClose } from '../../../../base/icons';
|
||||
import JitsiScreen from '../../../../base/modal/components/JitsiScreen';
|
||||
import { isLocalParticipantModerator } from '../../../../base/participants';
|
||||
import { connect } from '../../../../base/redux';
|
||||
import { StyleType } from '../../../../base/styles';
|
||||
import BaseTheme from '../../../../base/ui/components/BaseTheme';
|
||||
import { isInBreakoutRoom } from '../../../../breakout-rooms/functions';
|
||||
import { goBack } from '../../../../conference/components/native/ConferenceNavigationContainerRef';
|
||||
import HeaderNavigationButton
|
||||
from '../../../../conference/components/native/HeaderNavigationButton';
|
||||
import { toggleLobbyMode } from '../../../../lobby/actions.any';
|
||||
import LobbyModeSwitch
|
||||
from '../../../../lobby/components/native/LobbyModeSwitch';
|
||||
import { LOCKED_LOCALLY } from '../../../../room-lock';
|
||||
import { LOCKED_LOCALLY, LOCKED_REMOTELY } from '../../../../room-lock';
|
||||
import {
|
||||
endRoomLockRequest,
|
||||
unlockRoom
|
||||
} from '../../../../room-lock/actions';
|
||||
import RoomLockSwitch from '../../../../room-lock/components/RoomLockSwitch';
|
||||
|
||||
import styles from './styles';
|
||||
|
||||
/**
|
||||
* The style of the {@link TextInput} rendered by {@code SecurityDialog}. As it
|
||||
|
@ -93,20 +97,20 @@ type Props = {
|
|||
_passwordNumberOfDigits: number,
|
||||
|
||||
/**
|
||||
* Whether the room lock switch is available or not.
|
||||
* Whether setting a room password is available or not.
|
||||
*/
|
||||
_roomLockSwitchVisible: boolean,
|
||||
|
||||
/**
|
||||
* The color-schemed stylesheet of the security dialog feature.
|
||||
*/
|
||||
_securityDialogStyles: StyleType,
|
||||
_roomPasswordControls: boolean,
|
||||
|
||||
/**
|
||||
* Redux store dispatch function.
|
||||
*/
|
||||
dispatch: Dispatch<any>,
|
||||
|
||||
/**
|
||||
* Default prop for navigation between screen components(React Navigation).
|
||||
*/
|
||||
navigation: Object,
|
||||
|
||||
/**
|
||||
* Invoked to obtain translated strings.
|
||||
*/
|
||||
|
@ -150,9 +154,31 @@ class SecurityDialog extends PureComponent<Props, State> {
|
|||
};
|
||||
|
||||
this._onChangeText = this._onChangeText.bind(this);
|
||||
this._onCancel = this._onCancel.bind(this);
|
||||
this._onCopy = this._onCopy.bind(this);
|
||||
this._onSubmit = this._onSubmit.bind(this);
|
||||
this._onToggleLobbyMode = this._onToggleLobbyMode.bind(this);
|
||||
this._onToggleRoomLock = this._onToggleRoomLock.bind(this);
|
||||
this._onAddPassword = this._onAddPassword.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements React's {@link Component#componentDidMount()}. Invoked
|
||||
* immediately after this component is mounted.
|
||||
*
|
||||
* @inheritdoc
|
||||
* @returns {void}
|
||||
*/
|
||||
componentDidMount() {
|
||||
const { navigation } = this.props;
|
||||
|
||||
navigation.setOptions({
|
||||
headerLeft: () => (
|
||||
<HeaderNavigationButton
|
||||
onPress = { goBack }
|
||||
src = { IconClose }
|
||||
style = { styles.headerCloseButton } />
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -162,19 +188,10 @@ class SecurityDialog extends PureComponent<Props, State> {
|
|||
*/
|
||||
render() {
|
||||
return (
|
||||
<CustomSubmitDialog
|
||||
onSubmit = { this._onSubmit }>
|
||||
<KeyboardAvoidingView
|
||||
behavior =
|
||||
{
|
||||
Platform.OS === 'ios'
|
||||
? 'padding' : 'height'
|
||||
}
|
||||
enabled = { true }>
|
||||
{ this._renderLobbyMode() }
|
||||
{ this._renderRoomLock() }
|
||||
</KeyboardAvoidingView>
|
||||
</CustomSubmitDialog>
|
||||
<JitsiScreen style = { styles.securityDialogContainer }>
|
||||
{ this._renderLobbyMode() }
|
||||
{ this._renderSetRoomPassword() }
|
||||
</JitsiScreen>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -188,7 +205,6 @@ class SecurityDialog extends PureComponent<Props, State> {
|
|||
const {
|
||||
_lobbyEnabled,
|
||||
_lobbyModeSwitchVisible,
|
||||
_securityDialogStyles,
|
||||
t
|
||||
} = this.props;
|
||||
|
||||
|
@ -197,55 +213,151 @@ class SecurityDialog extends PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
return (
|
||||
<View>
|
||||
<Text style = { _securityDialogStyles.title } >
|
||||
{ t('lobby.dialogTitle') }
|
||||
</Text>
|
||||
<Text style = { _securityDialogStyles.text } >
|
||||
{ t('lobby.enableDialogText') }
|
||||
</Text>
|
||||
<LobbyModeSwitch
|
||||
lobbyEnabled = { _lobbyEnabled }
|
||||
onToggleLobbyMode = { this._onToggleLobbyMode } />
|
||||
<View style = { styles.lobbyModeContainer }>
|
||||
<View style = { styles.lobbyModeContent } >
|
||||
<Text>
|
||||
{ t('lobby.enableDialogText') }
|
||||
</Text>
|
||||
<View style = { styles.lobbyModeSection }>
|
||||
<Text style = { styles.lobbyModeLabel } >
|
||||
{ t('lobby.toggleLabel') }
|
||||
</Text>
|
||||
<LobbyModeSwitch
|
||||
lobbyEnabled = { _lobbyEnabled }
|
||||
onToggleLobbyMode = { this._onToggleLobbyMode } />
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders room lock.
|
||||
* Renders setting the password.
|
||||
*
|
||||
* @returns {ReactElement}
|
||||
* @private
|
||||
*/
|
||||
_renderRoomLock() {
|
||||
_renderSetRoomPassword() {
|
||||
const {
|
||||
_isModerator,
|
||||
_locked,
|
||||
_lockedConference,
|
||||
_roomLockSwitchVisible,
|
||||
_securityDialogStyles,
|
||||
_password,
|
||||
_roomPasswordControls,
|
||||
t
|
||||
} = this.props;
|
||||
const { showElement } = this.state;
|
||||
let setPasswordControls;
|
||||
|
||||
if (!_roomLockSwitchVisible) {
|
||||
if (!_roomPasswordControls) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (_locked && showElement) {
|
||||
setPasswordControls = (
|
||||
<>
|
||||
<TouchableRipple
|
||||
onPress = { this._onCancel }
|
||||
rippleColor = { BaseTheme.palette.field02 } >
|
||||
<Text style = { styles.passwordSetupButton }>
|
||||
{ t('dialog.Remove') }
|
||||
</Text>
|
||||
</TouchableRipple>
|
||||
{
|
||||
_password
|
||||
&& <TouchableRipple
|
||||
onPress = { this._onCopy }
|
||||
rippleColor = { BaseTheme.palette.field02 } >
|
||||
<Text style = { styles.passwordSetupButton }>
|
||||
{ t('dialog.copy') }
|
||||
</Text>
|
||||
</TouchableRipple>
|
||||
}
|
||||
</>
|
||||
);
|
||||
} else if (!_lockedConference && showElement) {
|
||||
setPasswordControls = (
|
||||
<>
|
||||
<TouchableRipple
|
||||
onPress = { this._onCancel }
|
||||
rippleColor = { BaseTheme.palette.field02 } >
|
||||
<Text style = { styles.passwordSetupButton }>
|
||||
{ t('dialog.Cancel') }
|
||||
</Text>
|
||||
</TouchableRipple>
|
||||
<TouchableRipple
|
||||
onPress = { this._onSubmit }
|
||||
rippleColor = { BaseTheme.palette.field02 } >
|
||||
<Text style = { styles.passwordSetupButton }>
|
||||
{ t('dialog.add') }
|
||||
</Text>
|
||||
</TouchableRipple>
|
||||
</>
|
||||
);
|
||||
} else if (!_lockedConference && !showElement) {
|
||||
setPasswordControls = (
|
||||
<TouchableRipple
|
||||
disabled = { !_isModerator }
|
||||
onPress = { this._onAddPassword }
|
||||
rippleColor = { BaseTheme.palette.field02 } >
|
||||
<Text style = { styles.passwordSetupButton }>
|
||||
{ t('info.addPassword') }
|
||||
</Text>
|
||||
</TouchableRipple>
|
||||
);
|
||||
}
|
||||
|
||||
if (_locked === LOCKED_REMOTELY) {
|
||||
if (_isModerator) {
|
||||
setPasswordControls = (
|
||||
<View style = { styles.passwordSetRemotelyContainer }>
|
||||
<Text style = { styles.passwordSetRemotelyText }>
|
||||
{ t('passwordSetRemotely') }
|
||||
</Text>
|
||||
<TouchableRipple
|
||||
onPress = { this._onCancel }
|
||||
rippleColor = { BaseTheme.palette.field02 } >
|
||||
<Text style = { styles.passwordSetupButton }>
|
||||
{ t('dialog.Remove') }
|
||||
</Text>
|
||||
</TouchableRipple>
|
||||
</View>
|
||||
);
|
||||
} else {
|
||||
setPasswordControls = (
|
||||
<View style = { styles.passwordSetRemotelyContainer }>
|
||||
<Text style = { styles.passwordSetRemotelyTextDisabled }>
|
||||
{ t('passwordSetRemotely') }
|
||||
</Text>
|
||||
<TouchableRipple
|
||||
disabled = { !_isModerator }
|
||||
onPress = { this._onAddPassword }
|
||||
rippleColor = { BaseTheme.palette.field02 } >
|
||||
<Text style = { styles.passwordSetupButton }>
|
||||
{ t('info.addPassword') }
|
||||
</Text>
|
||||
</TouchableRipple>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<View>
|
||||
<Text style = { _securityDialogStyles.title } >
|
||||
{ t('dialog.lockRoom') }
|
||||
</Text>
|
||||
<Text style = { _securityDialogStyles.text } >
|
||||
<View
|
||||
style = { styles.passwordContainer } >
|
||||
<Text>
|
||||
{ t('security.about') }
|
||||
</Text>
|
||||
<RoomLockSwitch
|
||||
disabled = { !_isModerator }
|
||||
locked = { _locked }
|
||||
onToggleRoomLock = { this._onToggleRoomLock }
|
||||
toggleRoomLock = { showElement || _lockedConference } />
|
||||
{ this._renderRoomLockMessage() }
|
||||
<View
|
||||
style = {
|
||||
_locked !== LOCKED_REMOTELY
|
||||
&& styles.passwordContainerControls
|
||||
}>
|
||||
<View>
|
||||
{ this._setRoomPasswordMessage() }
|
||||
</View>
|
||||
{ setPasswordControls }
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
@ -256,14 +368,13 @@ class SecurityDialog extends PureComponent<Props, State> {
|
|||
* @returns {ReactElement}
|
||||
* @private
|
||||
*/
|
||||
_renderRoomLockMessage() {
|
||||
_setRoomPasswordMessage() {
|
||||
let textInputProps = _TEXT_INPUT_PROPS;
|
||||
const {
|
||||
_isModerator,
|
||||
_locked,
|
||||
_password,
|
||||
_passwordNumberOfDigits,
|
||||
_securityDialogStyles,
|
||||
t
|
||||
} = this.props;
|
||||
const { passwordInputValue, showElement } = this.state;
|
||||
|
@ -284,9 +395,12 @@ class SecurityDialog extends PureComponent<Props, State> {
|
|||
if (typeof _locked === 'undefined') {
|
||||
return (
|
||||
<TextInput
|
||||
autoFocus = { true }
|
||||
onChangeText = { this._onChangeText }
|
||||
placeholder = { t('lobby.passwordField') }
|
||||
style = { _securityDialogStyles.field }
|
||||
placeholderTextColor = { BaseTheme.palette.text03 }
|
||||
selectionColor = { BaseTheme.palette.action03Active }
|
||||
style = { styles.passwordInput }
|
||||
underlineColorAndroid = { FIELD_UNDERLINE }
|
||||
value = { passwordInputValue }
|
||||
{ ...textInputProps } />
|
||||
|
@ -294,13 +408,14 @@ class SecurityDialog extends PureComponent<Props, State> {
|
|||
} else if (_locked) {
|
||||
if (_locked === LOCKED_LOCALLY && typeof _password !== 'undefined') {
|
||||
return (
|
||||
<TextInput
|
||||
onChangeText = { this._onChangeText }
|
||||
placeholder = { _password }
|
||||
style = { _securityDialogStyles.field }
|
||||
underlineColorAndroid = { FIELD_UNDERLINE }
|
||||
value = { passwordInputValue }
|
||||
{ ...textInputProps } />
|
||||
<View style = { styles.savedPasswordContainer }>
|
||||
<Text style = { styles.savedPasswordLabel }>
|
||||
{ t('info.password') }
|
||||
</Text>
|
||||
<Text style = { styles.savedPassword }>
|
||||
{ passwordInputValue }
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -325,28 +440,19 @@ class SecurityDialog extends PureComponent<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
_onToggleRoomLock: () => void;
|
||||
_onAddPassword: () => void;
|
||||
|
||||
/**
|
||||
* Callback to be invoked when room lock button is pressed.
|
||||
* Callback to be invoked when add password button is pressed.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_onToggleRoomLock() {
|
||||
const { _isModerator, _locked, dispatch } = this.props;
|
||||
_onAddPassword() {
|
||||
const { showElement } = this.state;
|
||||
|
||||
this.setState({
|
||||
showElement: !showElement
|
||||
});
|
||||
|
||||
if (_locked && _isModerator) {
|
||||
dispatch(unlockRoom());
|
||||
|
||||
this.setState({
|
||||
showElement: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -389,14 +495,41 @@ class SecurityDialog extends PureComponent<Props, State> {
|
|||
});
|
||||
}
|
||||
|
||||
_onSubmit: () => boolean;
|
||||
_onCancel: () => void;
|
||||
|
||||
/**
|
||||
* Cancels value typed in text input.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_onCancel() {
|
||||
this.setState({
|
||||
passwordInputValue: '',
|
||||
showElement: false
|
||||
});
|
||||
|
||||
this.props.dispatch(unlockRoom());
|
||||
}
|
||||
|
||||
_onCopy: () => void;
|
||||
|
||||
/**
|
||||
* Copies room password.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_onCopy() {
|
||||
const { passwordInputValue } = this.state;
|
||||
|
||||
Clipboard.setString(passwordInputValue);
|
||||
}
|
||||
|
||||
_onSubmit: () => void;
|
||||
|
||||
/**
|
||||
* Submits value typed in text input.
|
||||
*
|
||||
* @returns {boolean} False because we do not want to hide this
|
||||
* dialog/prompt as the hiding will be handled inside endRoomLockRequest
|
||||
* after setting the password is resolved.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onSubmit() {
|
||||
const {
|
||||
|
@ -406,8 +539,6 @@ class SecurityDialog extends PureComponent<Props, State> {
|
|||
const { passwordInputValue } = this.state;
|
||||
|
||||
dispatch(endRoomLockRequest(_conference, passwordInputValue));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -436,8 +567,7 @@ function _mapStateToProps(state: Object): Object {
|
|||
_lockedConference: Boolean(conference && locked),
|
||||
_password: password,
|
||||
_passwordNumberOfDigits: roomPasswordNumberOfDigits,
|
||||
_roomLockSwitchVisible: visible,
|
||||
_securityDialogStyles: ColorSchemeRegistry.get(state, 'SecurityDialog')
|
||||
_roomPasswordControls: visible
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
// @flow
|
||||
|
||||
import { translate } from '../../../../base/i18n';
|
||||
import { connect } from '../../../../base/redux';
|
||||
import { navigate } from '../../../../conference/components/native/ConferenceNavigationContainerRef';
|
||||
import { screen } from '../../../../conference/components/native/routes';
|
||||
import AbstractSecurityDialogButton, {
|
||||
_mapStateToProps as _abstractMapStateToProps,
|
||||
type Props as AbstractSecurityDialogButtonProps
|
||||
} from '../AbstractSecurityDialogButton';
|
||||
|
||||
type Props = AbstractSecurityDialogButtonProps;
|
||||
|
||||
/**
|
||||
* Implements an {@link AbstractSecurityDialogButton} to open the security screen.
|
||||
*/
|
||||
class SecurityDialogButton<P: Props, S:*> extends AbstractSecurityDialogButton<P, S> {
|
||||
|
||||
/**
|
||||
* Opens / closes the security screen.
|
||||
*
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_handleClickSecurityButton() {
|
||||
navigate(screen.conference.security);
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(connect(_abstractMapStateToProps)(SecurityDialogButton));
|
|
@ -0,0 +1,98 @@
|
|||
// @flow
|
||||
|
||||
import BaseTheme from '../../../../base/ui/components/BaseTheme.native';
|
||||
|
||||
/**
|
||||
* The styles of the feature security.
|
||||
*/
|
||||
export default {
|
||||
|
||||
securityDialogContainer: {
|
||||
flex: 1,
|
||||
marginTop: BaseTheme.spacing[4]
|
||||
},
|
||||
|
||||
headerCloseButton: {
|
||||
marginLeft: 12
|
||||
},
|
||||
|
||||
lobbyModeContainer: {
|
||||
borderBottomColor: BaseTheme.palette.border01,
|
||||
borderBottomWidth: 1
|
||||
},
|
||||
|
||||
lobbyModeContent: {
|
||||
marginHorizontal: BaseTheme.spacing[3],
|
||||
marginBottom: BaseTheme.spacing[4]
|
||||
},
|
||||
|
||||
lobbyModeLabel: {
|
||||
fontWeight: 'bold',
|
||||
marginTop: BaseTheme.spacing[2]
|
||||
},
|
||||
|
||||
lobbyModeSection: {
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
marginTop: BaseTheme.spacing[1]
|
||||
},
|
||||
|
||||
passwordContainer: {
|
||||
marginHorizontal: BaseTheme.spacing[3],
|
||||
marginTop: BaseTheme.spacing[4]
|
||||
},
|
||||
|
||||
passwordContainerControls: {
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between'
|
||||
},
|
||||
|
||||
savedPasswordContainer: {
|
||||
flexDirection: 'row',
|
||||
marginTop: 20,
|
||||
width: 208
|
||||
},
|
||||
|
||||
savedPasswordLabel: {
|
||||
fontWeight: 'bold'
|
||||
},
|
||||
|
||||
savedPassword: {
|
||||
color: BaseTheme.palette.text06
|
||||
},
|
||||
|
||||
passwordInput: {
|
||||
borderColor: BaseTheme.palette.action03Active,
|
||||
borderRadius: BaseTheme.spacing[1],
|
||||
borderWidth: 2,
|
||||
height: BaseTheme.spacing[6],
|
||||
marginTop: BaseTheme.spacing[2],
|
||||
paddingLeft: BaseTheme.spacing[1],
|
||||
width: 208
|
||||
},
|
||||
|
||||
passwordSetupButton: {
|
||||
...BaseTheme.typography.heading7,
|
||||
color: BaseTheme.palette.screen01Header,
|
||||
marginTop: BaseTheme.spacing[4],
|
||||
textTransform: 'uppercase'
|
||||
},
|
||||
|
||||
passwordSetRemotelyContainer: {
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between'
|
||||
},
|
||||
|
||||
passwordSetRemotelyText: {
|
||||
color: BaseTheme.palette.text06,
|
||||
marginTop: 22
|
||||
},
|
||||
|
||||
passwordSetRemotelyTextDisabled: {
|
||||
color: BaseTheme.palette.text03,
|
||||
marginTop: 22
|
||||
}
|
||||
};
|
|
@ -77,7 +77,7 @@ function SecurityDialog({
|
|||
<Dialog
|
||||
hideCancelButton = { true }
|
||||
submitDisabled = { true }
|
||||
titleKey = 'security.securityOptions'
|
||||
titleKey = 'security.header'
|
||||
width = { 'small' }>
|
||||
<div className = 'security-dialog'>
|
||||
<LobbySection />
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
// @flow
|
||||
|
||||
import { translate } from '../../../../base/i18n';
|
||||
import { connect } from '../../../../base/redux';
|
||||
import { toggleSecurityDialog } from '../../../actions';
|
||||
import AbstractSecurityDialogButton, {
|
||||
_mapStateToProps as _abstractMapStateToProps,
|
||||
type Props as AbstractSecurityDialogButtonProps
|
||||
} from '../AbstractSecurityDialogButton';
|
||||
|
||||
type Props = AbstractSecurityDialogButtonProps;
|
||||
|
||||
/**
|
||||
* Implements an {@link AbstractSecurityDialogButton} to open the security dialog.
|
||||
*/
|
||||
class SecurityDialogButton<P: Props, S:*> extends AbstractSecurityDialogButton<P, S> {
|
||||
|
||||
/**
|
||||
* Opens / closes the security dialog.
|
||||
*
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_handleClickSecurityButton() {
|
||||
const { dispatch } = this.props;
|
||||
|
||||
dispatch(toggleSecurityDialog());
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(connect(_abstractMapStateToProps)(SecurityDialogButton));
|
|
@ -15,7 +15,6 @@ import style from './styles';
|
|||
*/
|
||||
const SpeakerStats = () => (
|
||||
<JitsiScreen
|
||||
hasTabNavigator = { false }
|
||||
style = { style.speakerStatsContainer }>
|
||||
<SpeakerStatsLabels />
|
||||
<SpeakerStatsList />
|
||||
|
|
|
@ -13,7 +13,8 @@ import { ParticipantsPaneButton } from '../../../participants-pane/components/na
|
|||
import { ReactionMenu } from '../../../reactions/components';
|
||||
import { isReactionsEnabled } from '../../../reactions/functions.any';
|
||||
import { LiveStreamButton, RecordButton } from '../../../recording';
|
||||
import SecurityDialogButton from '../../../security/components/security-dialog/SecurityDialogButton';
|
||||
import SecurityDialogButton
|
||||
from '../../../security/components/security-dialog/native/SecurityDialogButton';
|
||||
import { SharedVideoButton } from '../../../shared-video/components';
|
||||
import SpeakerStatsButton from '../../../speaker-stats/components/native/SpeakerStatsButton';
|
||||
import { ClosedCaptionButton } from '../../../subtitles';
|
||||
|
|
|
@ -54,7 +54,7 @@ import {
|
|||
ShareAudioButton,
|
||||
startScreenShareFlow
|
||||
} from '../../../screen-share/';
|
||||
import SecurityDialogButton from '../../../security/components/security-dialog/SecurityDialogButton';
|
||||
import SecurityDialogButton from '../../../security/components/security-dialog/web/SecurityDialogButton';
|
||||
import { SettingsButton } from '../../../settings';
|
||||
import { SharedVideoButton } from '../../../shared-video/components';
|
||||
import { SpeakerStatsButton } from '../../../speaker-stats/components/web';
|
||||
|
|
Loading…
Reference in New Issue